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