]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
e4ff2d08949050d73d207a5d23061277099482da
[tmp/jakarta-migration.git] /
1 /**
2  *  This document is a part of the source code and related artifacts
3  *  for CollectionSpace, an open source collections management system
4  *  for museums and related institutions:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 package org.collectionspace.services.common;
25
26 import java.util.List;
27
28 import javax.ws.rs.GET;
29 import javax.ws.rs.Path;
30 import javax.ws.rs.Produces;
31 import javax.ws.rs.WebApplicationException;
32 import javax.ws.rs.core.MultivaluedMap;
33 import javax.ws.rs.core.Response;
34 import javax.ws.rs.core.UriInfo;
35
36 import org.collectionspace.services.common.CSWebApplicationException;
37 import org.collectionspace.services.common.api.Tools;
38 import org.collectionspace.services.common.context.ServiceContext;
39 import org.collectionspace.services.common.context.ServiceContextProperties;
40 import org.collectionspace.services.common.document.BadRequestException;
41 import org.collectionspace.services.common.document.DocumentException;
42 import org.collectionspace.services.common.document.DocumentHandler;
43 import org.collectionspace.services.common.document.DocumentNotFoundException;
44 import org.collectionspace.services.common.document.TransactionException;
45 import org.collectionspace.services.common.repository.RepositoryClient;
46 import org.collectionspace.services.common.repository.RepositoryClientFactory;
47 import org.collectionspace.services.common.security.UnauthorizedException;
48 import org.collectionspace.services.common.storage.StorageClient;
49 import org.collectionspace.services.common.storage.jpa.JpaStorageClientImpl;
50
51 import org.jboss.resteasy.core.ResourceMethod;
52 import org.jboss.resteasy.spi.HttpRequest;
53
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 /**
58  * The Class AbstractCollectionSpaceResourceImpl.
59  *
60  * @param <IT> the generic type
61  * @param <OT> the generic type
62  */
63 public abstract class AbstractCollectionSpaceResourceImpl<IT, OT>
64         implements CollectionSpaceResource<IT, OT> {
65
66     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
67
68
69     // Fields for default client factory and client
70     /** The repository client factory. */
71     private RepositoryClientFactory repositoryClientFactory;
72     
73     /** The repository client. */
74     private RepositoryClient repositoryClient;
75     
76     /** The storage client. */
77     private StorageClient storageClient;
78
79     /**
80      * Extract id.
81      *
82      * @param res the res
83      * @return the string
84      */
85     protected static String extractId(Response res) {
86         MultivaluedMap<String, Object> mvm = res.getMetadata();
87         String uri = (String) ((List<Object>) mvm.get("Location")).get(0);
88         String[] segments = uri.split("/");
89         String id = segments[segments.length - 1];
90         return id;
91     }    
92     
93     /**
94      * Instantiates a new abstract collection space resource.
95      */
96     public AbstractCollectionSpaceResourceImpl() {
97         repositoryClientFactory = RepositoryClientFactory.getInstance();
98     }
99
100     /* (non-Javadoc)
101      * @see org.collectionspace.services.common.CollectionSpaceResource#getServiceName()
102      */
103     @Override
104     abstract public String getServiceName();
105
106
107     /* (non-Javadoc)
108      * @see org.collectionspace.services.common.CollectionSpaceResource#getRepositoryClient(org.collectionspace.services.common.context.ServiceContext)
109      */
110     @Override
111     synchronized public RepositoryClient getRepositoryClient(ServiceContext<IT, OT> ctx) {
112         if(repositoryClient != null){
113             return repositoryClient;
114         }
115         repositoryClient = repositoryClientFactory.getClient(ctx.getRepositoryClientName());
116         return repositoryClient;
117     }
118
119     /* (non-Javadoc)
120      * @see org.collectionspace.services.common.CollectionSpaceResource#getStorageClient(org.collectionspace.services.common.context.ServiceContext)
121      */
122     @Override
123     synchronized public StorageClient getStorageClient(ServiceContext<IT, OT> ctx) {
124         if(storageClient != null) {
125             return storageClient;
126         }
127         storageClient = new JpaStorageClientImpl();
128         return storageClient;
129     }
130     
131     /* (non-Javadoc)
132      * @see org.collectionspace.services.common.CollectionSpaceResource#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext)
133      */
134     @Override
135     public DocumentHandler createDocumentHandler(ServiceContext<IT, OT> ctx) throws Exception {
136         DocumentHandler docHandler = createDocumentHandler(ctx, ctx.getInput());
137         return docHandler;
138     }
139     
140     /**
141      * Creates the document handler.
142      * 
143      * @param ctx the ctx
144      * @param commonPart the common part
145      * 
146      * @return the document handler
147      * 
148      * @throws Exception the exception
149      */
150     public DocumentHandler createDocumentHandler(ServiceContext<IT, OT> ctx,
151                 Object commonPart) throws Exception {
152         DocumentHandler docHandler = ctx.getDocumentHandler();
153         docHandler.setCommonPart(commonPart);
154         return docHandler;
155     }    
156     
157     /**
158      * Creates the service context.
159      * 
160      * @return the service context< i t, o t>
161      * 
162      * @throws Exception the exception
163      */
164     protected ServiceContext<IT, OT> createServiceContext() throws Exception {          
165         ServiceContext<IT, OT> ctx = createServiceContext(this.getServiceName(),
166                         (IT)null, //inputType
167                         null, // The resource map
168                         (UriInfo)null, // The query params
169                         this.getCommonPartClass());
170         return ctx;
171     }    
172     
173     /**
174      * Creates the service context.
175      * 
176      * @param serviceName the service name
177      * 
178      * @return the service context< i t, o t>
179      * 
180      * @throws Exception the exception
181      */
182     protected ServiceContext<IT, OT> createServiceContext(String serviceName) throws Exception {        
183         ServiceContext<IT, OT> ctx = createServiceContext(
184                         serviceName,
185                         (IT)null, // The input part
186                         null, // The resource map
187                         (UriInfo)null, // The queryParams
188                         (Class<?>)null  /*input type's Class*/);
189         return ctx;
190     }
191     
192     protected ServiceContext<IT, OT> createServiceContext(String serviceName, UriInfo ui) throws Exception {            
193         ServiceContext<IT, OT> ctx = createServiceContext(
194                         serviceName,
195                         (IT)null, // The input part
196                         null, // The resource map
197                         (UriInfo)null, // The queryParams
198                         (Class<?>)null  /*input type's Class*/);
199         ctx.setUriInfo(ui);
200         return ctx;
201     }    
202     
203     /**
204      * Creates the service context.
205      * 
206      * @param serviceName the service name
207      * @param input the input
208      * 
209      * @return the service context< i t, o t>
210      * 
211      * @throws Exception the exception
212      */
213     protected ServiceContext<IT, OT> createServiceContext(String serviceName,
214                 IT input) throws Exception {            
215         ServiceContext<IT, OT> ctx = createServiceContext(serviceName,
216                         input,
217                         null, // The resource map
218                         (UriInfo)null, /*queryParams*/
219                         (Class<?>)null  /*input type's Class*/);
220         return ctx;
221     }
222     
223     protected ServiceContext<IT, OT> createServiceContext(String serviceName,
224                 IT input,
225                 UriInfo uriInfo) throws Exception {     
226         ServiceContext<IT, OT> ctx = createServiceContext(serviceName,
227                         input,
228                         null, // The resource map
229                         uriInfo, /*queryParams*/
230                         (Class<?>)null  /*input type's Class*/);
231         return ctx;
232     }
233     
234     protected ServiceContext<IT, OT> createServiceContext(UriInfo uriInfo) throws Exception {
235         ServiceContext<IT, OT> ctx = createServiceContext(
236                         (IT)null, /*input*/
237                         uriInfo,
238                         (Class<?>)null  /*input type's Class*/);
239         return ctx;
240     }
241
242     /**
243      * Creates the service context.
244      * 
245      * @param input the input
246      * 
247      * @return the service context< i t, o t>
248      * 
249      * @throws Exception the exception
250      */
251     protected ServiceContext<IT, OT> createServiceContext(IT input) throws Exception {          
252         ServiceContext<IT, OT> ctx = createServiceContext(
253                         input,
254                         (Class<?>)null /*input type's Class*/);
255         return ctx;
256     }
257     
258     protected ServiceContext<IT, OT> createServiceContext(IT input, UriInfo uriInfo) throws Exception {         
259         ServiceContext<IT, OT> ctx = createServiceContext(
260                         input,
261                         uriInfo,
262                         null ); // The class param/argument
263         return ctx;
264     }    
265     
266     /**
267      * Creates the service context.
268      * 
269      * @param input the input
270      * @param theClass the the class
271      * 
272      * @return the service context
273      * 
274      * @throws Exception the exception
275      */
276     protected ServiceContext<IT, OT> createServiceContext(IT input, Class<?> theClass) throws Exception {       
277         ServiceContext<IT, OT> ctx = createServiceContext(
278                         input,
279                         (UriInfo)null, //queryParams,
280                         theClass);
281         return ctx;
282     }
283     
284     protected ServiceContext<IT, OT> createServiceContext(IT input, Class<?> theClass, UriInfo uriInfo) throws Exception {      
285         ServiceContext<IT, OT> ctx = createServiceContext(
286                         input,
287                         uriInfo,
288                         theClass);
289         return ctx;
290     }
291     
292     protected ServiceContext<IT, OT> createServiceContext(
293                 String serviceName,
294                 ResourceMap resourceMap,
295                 UriInfo uriInfo) throws Exception {
296         ServiceContext<IT, OT> ctx = createServiceContext(
297                         serviceName,
298                         null, // The input object
299                         resourceMap,
300                         uriInfo,
301                         null /* the class of the input type */);
302         return ctx;
303     }
304         
305     protected ServiceContext<IT, OT> createServiceContext(
306                 IT input,
307                 ResourceMap resourceMap,
308                 UriInfo uriInfo) throws Exception {
309         ServiceContext<IT, OT> ctx = createServiceContext(
310                         this.getServiceName(),
311                         input,
312                         resourceMap,
313                         uriInfo,
314                         null /* the class of the input type */);
315         return ctx;
316     }
317     
318     protected ServiceContext<IT, OT> createServiceContext(
319                 String serviceName,
320                 IT input,
321                 ResourceMap resourceMap,
322                 UriInfo uriInfo) throws Exception {
323         ServiceContext<IT, OT> ctx = createServiceContext(
324                         serviceName,
325                         input,
326                         resourceMap,
327                         uriInfo,
328                         null /* the class of the input type */);
329         return ctx;
330     }
331         
332     /**
333      * Creates the service context.
334      * 
335      * @param input the input
336      * @param queryParams the query params
337      * @param theClass the the class
338      * 
339      * @return the service context< i t, o t>
340      * 
341      * @throws Exception the exception
342      */
343     private ServiceContext<IT, OT> createServiceContext(
344                 IT input,
345                 UriInfo uriInfo,
346                 Class<?> theClass) throws Exception {
347         return createServiceContext(this.getServiceName(),
348                         input,
349                         null, // The resource map
350                         uriInfo,
351                         theClass);
352     }
353
354     /**
355      * Creates the service context.
356      * 
357      * @param serviceName the service name
358      * @param input the input
359      * @param queryParams the query params
360      * @param theClass the the class
361      * 
362      * @return the service context< i t, o t>
363      * 
364      * @throws Exception the exception
365      */
366     private ServiceContext<IT, OT> createServiceContext(
367                 String serviceName,
368                 IT input,
369                 ResourceMap resourceMap,
370                 UriInfo uriInfo,
371                 Class<?> theClass) throws Exception {
372         ServiceContext<IT, OT> ctx = getServiceContextFactory().createServiceContext(
373                         serviceName,
374                         input,
375                         resourceMap,
376                         uriInfo,
377                         theClass != null ? theClass.getPackage().getName() : null,
378                         theClass != null ? theClass.getName() : null);
379         if (theClass != null) {
380             ctx.setProperty(ServiceContextProperties.ENTITY_CLASS, theClass);
381         }
382         
383         return ctx;
384     }
385         
386     /**
387      * Gets the version string.
388      * 
389      * @return the version string
390      */
391     abstract protected String getVersionString();
392     
393     /**
394      * Gets the version.
395      * 
396      * @return the version
397      */
398     @GET
399     @Path("/version")    
400     @Produces("application/xml")
401     public Version getVersion() {
402         Version result = new Version();
403         
404         result.setVersionString(getVersionString());
405         
406         return result;
407     }
408
409     public void checkResult(Object resultToCheck, String csid, String serviceMessage) throws CSWebApplicationException {
410         if (resultToCheck == null) {
411             Response response = Response.status(Response.Status.NOT_FOUND).entity(
412                     serviceMessage + "csid=" + csid
413                     + ": was not found.").type(
414                     "text/plain").build();
415             throw new CSWebApplicationException(response);
416         }
417     }
418
419     protected void ensureCSID(String csid, String crudType) throws CSWebApplicationException {
420         ensureCSID(csid, crudType, "csid");
421     }
422
423     protected void ensureCSID(String csid, String crudType, String whichCsid) throws CSWebApplicationException {
424            if (logger.isDebugEnabled()) {
425                logger.debug(crudType + " for " + getClass().getName() + " with csid=" + csid);
426            }
427            if (csid == null || "".equals(csid)) {
428                logger.error(crudType + " for " + getClass().getName() + " missing csid!");
429                Response response = Response.status(Response.Status.BAD_REQUEST).entity(crudType + " failed on " + getClass().getName() + ' '+whichCsid+'=' + csid).type("text/plain").build();
430                throw new CSWebApplicationException(response);
431            }
432        }
433
434     protected CSWebApplicationException bigReThrow(Exception e, String serviceMsg) throws CSWebApplicationException {
435         return bigReThrow(e, serviceMsg, "");
436     }
437
438     protected CSWebApplicationException bigReThrow(Exception e, String serviceMsg, String csid) throws CSWebApplicationException {
439         boolean logException = true;
440         CSWebApplicationException result = null;
441         Response response;
442         String detail = Tools.errorToString(e, true);
443         String detailNoTrace = Tools.errorToString(e, true, 3);
444         
445         if (e instanceof UnauthorizedException) {
446             response = Response.status(Response.Status.UNAUTHORIZED).entity(serviceMsg + e.getMessage()).type("text/plain").build();
447             result = new CSWebApplicationException(e, response);
448
449         } else if (e instanceof DocumentNotFoundException) {
450                 //
451                 // Don't log this error unless we're in 'trace' mode
452                 //
453                 logException = false;
454             response = Response.status(Response.Status.NOT_FOUND).entity(serviceMsg + " on " + getClass().getName() + " csid=" + csid).type("text/plain").build();
455             result = new CSWebApplicationException(e, response);
456             
457         } else if (e instanceof TransactionException) {
458             int code = ((TransactionException) e).getErrorCode();
459             response = Response.status(code).entity(e.getMessage()).type("text/plain").build();
460             result = new CSWebApplicationException(e, response);
461
462         } else if (e instanceof BadRequestException) {
463             int code = ((BadRequestException) e).getErrorCode();
464             if (code == 0) {
465                 code = Response.Status.BAD_REQUEST.getStatusCode();
466             }
467             // CSPACE-1110
468             response = Response.status(code).entity(serviceMsg + e.getMessage()).type("text/plain").build();
469             // return new WebApplicationException(e, code);
470             result = new CSWebApplicationException(e, response);
471
472         } else if (e instanceof DocumentException) {
473             int code = ((DocumentException) e).getErrorCode();
474             if (code == 0){
475                code = Response.Status.BAD_REQUEST.getStatusCode();
476             }
477             // CSPACE-1110
478             response = Response.status(code).entity(serviceMsg + e.getMessage()).type("text/plain").build();
479             // return new WebApplicationException(e, code);
480             result = new CSWebApplicationException(e, response);
481            
482         } else if (e instanceof CSWebApplicationException) {
483             // subresource may have already thrown this exception
484             // so just pass it on
485             result = (CSWebApplicationException) e;
486
487         } else { // e is now instanceof Exception
488             response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(serviceMsg + " detail: " + detailNoTrace).type("text/plain").build();
489             result = new CSWebApplicationException(e, response);
490         }
491         //
492         // Some exceptions like DocumentNotFoundException won't be logged unless we're in 'trace' mode
493         //
494         boolean traceEnabled = logger.isTraceEnabled();
495         if (logException == true || traceEnabled == true) {
496                 if (traceEnabled == true) {
497                         logger.error(getClass().getName() + " detail: " + detail, e);
498                 } else {
499                         logger.error(getClass().getName() + " detail: " + detailNoTrace);
500                 }
501         }
502         
503         return result;
504     }
505     
506         @Override
507         public boolean allowAnonymousAccess(HttpRequest request,
508                         ResourceMethod method) {
509                 return false;
510         }    
511 }