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