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