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