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