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