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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 * $LastChangedRevision$
26 package org.collectionspace.services.collectionobject;
28 import java.util.ArrayList;
29 import java.util.List;
31 import javax.ws.rs.Consumes;
32 import javax.ws.rs.DELETE;
33 import javax.ws.rs.GET;
34 import javax.ws.rs.POST;
35 import javax.ws.rs.PUT;
36 import javax.ws.rs.Path;
37 import javax.ws.rs.PathParam;
38 import javax.ws.rs.Produces;
39 import javax.ws.rs.QueryParam;
40 import javax.ws.rs.WebApplicationException;
41 import javax.ws.rs.core.Context;
42 import javax.ws.rs.core.Response;
43 import javax.ws.rs.core.UriBuilder;
44 import javax.ws.rs.core.UriInfo;
45 import javax.ws.rs.core.MultivaluedMap;
47 import org.collectionspace.services.common.AbstractMultiPartCollectionSpaceResourceImpl;
48 import org.collectionspace.services.common.authorityref.AuthorityRefList;
49 import org.collectionspace.services.common.context.ServiceContextFactory;
50 //import org.collectionspace.services.common.context.MultipartServiceContext;
51 import org.collectionspace.services.common.context.MultipartServiceContextFactory;
52 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
53 import org.collectionspace.services.common.context.ServiceBindingUtils;
54 import org.collectionspace.services.common.context.ServiceContext;
55 import org.collectionspace.services.common.document.BadRequestException;
56 import org.collectionspace.services.common.document.DocumentFilter;
57 import org.collectionspace.services.common.document.DocumentHandler;
58 import org.collectionspace.services.common.document.DocumentNotFoundException;
59 import org.collectionspace.services.common.document.DocumentWrapper;
60 import org.collectionspace.services.common.query.IQueryManager;
61 import org.collectionspace.services.common.query.QueryManager;
62 import org.collectionspace.services.common.security.UnauthorizedException;
63 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
64 import org.collectionspace.services.intake.IntakeResource;
65 import org.collectionspace.services.intake.IntakesCommonList;
66 //import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
67 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
68 import org.collectionspace.services.relation.NewRelationResource;
69 import org.collectionspace.services.relation.RelationsCommonList;
70 import org.collectionspace.services.relation.RelationshipType;
71 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
72 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
73 import org.jboss.resteasy.util.HttpResponseCodes;
74 import org.nuxeo.ecm.core.api.DocumentModel;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
80 * The Class CollectionObjectResource.
82 @Path("/collectionobjects")
83 @Consumes("multipart/mixed")
84 @Produces("multipart/mixed")
85 public class CollectionObjectResource
86 extends AbstractMultiPartCollectionSpaceResourceImpl {
88 /** The Constant serviceName. */
89 static final public String serviceName = "collectionobjects";
92 final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
95 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
98 public String getVersionString() {
99 /** The last change revision. */
100 final String lastChangeRevision = "$LastChangedRevision$";
101 return lastChangeRevision;
105 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName()
108 public String getServiceName() {
113 * @see org.collectionspace.services.common.CollectionSpaceResource#getCommonPartClass()
116 public Class<CollectionobjectsCommon> getCommonPartClass() {
117 return CollectionobjectsCommon.class;
121 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext)
124 // public DocumentHandler createDocumentHandler(ServiceContext<MultipartInput, MultipartOutput> ctx) throws Exception {
125 // DocumentHandler docHandler = ctx.getDocumentHandler();
126 // if (ctx.getInput() != null) {
127 // Object obj = ((MultipartServiceContext) ctx).getInputPart(ctx.getCommonPartLabel(),
128 // CollectionobjectsCommon.class);
129 // if (obj != null) {
130 // docHandler.setCommonPart((CollectionobjectsCommon) obj);
133 // return docHandler;
137 * Creates the collection object.
139 * @param input the input
141 * @return the response
144 public Response createCollectionObject(MultipartInput input) {
146 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(input); //
147 DocumentHandler handler = createDocumentHandler(ctx);
148 String csid = getRepositoryClient(ctx).create(ctx, handler);
149 UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
150 path.path("" + csid);
151 Response response = Response.created(path.build()).build();
153 } catch (BadRequestException bre) {
154 Response response = Response.status(
155 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
156 throw new WebApplicationException(response);
157 } catch (UnauthorizedException ue) {
158 Response response = Response.status(
159 Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build();
160 throw new WebApplicationException(response);
161 } catch (Exception e) {
162 if (logger.isDebugEnabled()) {
163 logger.debug("Caught exception in createCollectionObject", e);
165 Response response = Response.status(
166 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
167 throw new WebApplicationException(response);
172 * Gets the collection object.
174 * @param csid the csid
176 * @return the collection object
180 public MultipartOutput getCollectionObject(
181 @PathParam("csid") String csid) {
182 if (logger.isDebugEnabled()) {
183 logger.debug("getCollectionObject with csid=" + csid);
185 if (csid == null || "".equals(csid)) {
186 logger.error("getCollectionObject: missing csid!");
187 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
188 "get failed on CollectionObject csid=" + csid).type(
189 "text/plain").build();
190 throw new WebApplicationException(response);
192 MultipartOutput result = null;
194 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext();
195 DocumentHandler handler = createDocumentHandler(ctx);
196 getRepositoryClient(ctx).get(ctx, csid, handler);
197 result = (MultipartOutput) ctx.getOutput();
198 } catch (UnauthorizedException ue) {
199 Response response = Response.status(
200 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
201 throw new WebApplicationException(response);
202 } catch (DocumentNotFoundException dnfe) {
203 if (logger.isDebugEnabled()) {
204 logger.debug("getCollectionObject", dnfe);
206 Response response = Response.status(Response.Status.NOT_FOUND).entity(
207 "Get failed on CollectionObject csid=" + csid).type(
208 "text/plain").build();
209 throw new WebApplicationException(response);
210 } catch (Exception e) {
211 if (logger.isDebugEnabled()) {
212 logger.debug("getCollectionObject", e);
214 Response response = Response.status(
215 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
216 throw new WebApplicationException(response);
219 if (result == null) {
220 Response response = Response.status(Response.Status.NOT_FOUND).entity(
221 "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type(
222 "text/plain").build();
223 throw new WebApplicationException(response);
229 * Gets the collection object list.
232 * @param keywords the keywords
234 * @return the collection object list
237 @Produces("application/xml")
238 public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui,
239 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords) {
240 CollectionobjectsCommonList result = null;
241 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
242 if (keywords != null) {
243 result = searchCollectionObjects(queryParams, keywords);
245 result = getCollectionObjectList(queryParams);
252 * Gets the collection object list.
254 private CollectionobjectsCommonList getCollectionObjectList(MultivaluedMap<String, String> queryParams) {
255 CollectionobjectsCommonList collectionObjectList;
257 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
258 DocumentHandler handler = createDocumentHandler(ctx);
259 getRepositoryClient(ctx).getFiltered(ctx, handler);
260 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
261 } catch (UnauthorizedException ue) {
262 Response response = Response.status(
263 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
264 throw new WebApplicationException(response);
265 } catch (Exception e) {
266 if (logger.isDebugEnabled()) {
267 logger.debug("Caught exception in getCollectionObjectList", e);
269 Response response = Response.status(
270 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
271 throw new WebApplicationException(response);
273 return collectionObjectList;
277 * Update collection object.
279 * @param csid the csid
280 * @param theUpdate the the update
282 * @return the multipart output
286 public MultipartOutput updateCollectionObject(
287 @PathParam("csid") String csid,
288 MultipartInput theUpdate) {
289 if (logger.isDebugEnabled()) {
290 logger.debug("updateCollectionObject with csid=" + csid);
292 if (csid == null || "".equals(csid)) {
293 logger.error("updateCollectionObject: missing csid!");
294 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
295 "update failed on CollectionObject csid=" + csid).type(
296 "text/plain").build();
297 throw new WebApplicationException(response);
299 MultipartOutput result = null;
301 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(theUpdate);
302 DocumentHandler handler = createDocumentHandler(ctx);
303 getRepositoryClient(ctx).update(ctx, csid, handler);
304 result = (MultipartOutput) ctx.getOutput();
305 } catch (BadRequestException bre) {
306 Response response = Response.status(
307 Response.Status.BAD_REQUEST).entity("Update failed reason " + bre.getErrorReason()).type("text/plain").build();
308 throw new WebApplicationException(response);
309 } catch (UnauthorizedException ue) {
310 Response response = Response.status(
311 Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build();
312 throw new WebApplicationException(response);
313 } catch (DocumentNotFoundException dnfe) {
314 if (logger.isDebugEnabled()) {
315 logger.debug("caugth exception in updateCollectionObject", dnfe);
317 Response response = Response.status(Response.Status.NOT_FOUND).entity(
318 "Update failed on CollectionObject csid=" + csid).type(
319 "text/plain").build();
320 throw new WebApplicationException(response);
321 } catch (Exception e) {
322 Response response = Response.status(
323 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
324 throw new WebApplicationException(response);
330 * Delete collection object.
332 * @param csid the csid
334 * @return the response
338 public Response deleteCollectionObject(@PathParam("csid") String csid) {
340 if (logger.isDebugEnabled()) {
341 logger.debug("deleteCollectionObject with csid=" + csid);
343 if (csid == null || "".equals(csid)) {
344 logger.error("deleteCollectionObject: missing csid!");
345 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
346 "delete failed on CollectionObject csid=" + csid).type(
347 "text/plain").build();
348 throw new WebApplicationException(response);
351 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext();
352 getRepositoryClient(ctx).delete(ctx, csid);
353 return Response.status(HttpResponseCodes.SC_OK).build();
354 } catch (UnauthorizedException ue) {
355 Response response = Response.status(
356 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
357 throw new WebApplicationException(response);
358 } catch (DocumentNotFoundException dnfe) {
359 if (logger.isDebugEnabled()) {
360 logger.debug("caught exception in deleteCollectionObject", dnfe);
362 Response response = Response.status(Response.Status.NOT_FOUND).entity(
363 "Delete failed on CollectionObject csid=" + csid).type(
364 "text/plain").build();
365 throw new WebApplicationException(response);
366 } catch (Exception e) {
367 Response response = Response.status(
368 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
369 throw new WebApplicationException(response);
375 * Gets the intakes common list.
378 * @param csid the csid
380 * @return the intakes common list
383 @Path("{csid}/intakes")
384 @Produces("application/xml")
385 public IntakesCommonList getIntakesCommonList(@Context UriInfo ui,
386 @PathParam("csid") String csid) {
387 IntakesCommonList result = null;
388 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
392 // Find all the intake-related relation records.
394 String subjectCsid = csid;
395 String predicate = RelationshipType.COLLECTIONOBJECT_INTAKE.value();
396 String objectCsid = null;
397 NewRelationResource relationResource = new NewRelationResource();
398 RelationsCommonList relationsCommonList = relationResource.getRelationList(queryParams,
399 subjectCsid, predicate, objectCsid);
402 // Create an array of Intake csid's
404 List<RelationsCommonList.RelationListItem> relationsListItems = relationsCommonList.getRelationListItem();
405 List<String> intakeCsidList = new ArrayList<String>();
406 for (RelationsCommonList.RelationListItem relationsListItem : relationsListItems) {
407 intakeCsidList.add(relationsListItem.getObjectCsid());
411 // Get a response list for the Intake records from the Intake resource
413 IntakeResource intakeResource = new IntakeResource();
414 result = intakeResource.getIntakeList(intakeCsidList);
415 } catch (Exception e) {
416 if (logger.isDebugEnabled()) {
417 logger.debug("Caught exception in getIntakeList", e);
419 Response response = Response.status(
420 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
421 throw new WebApplicationException(response);
428 * Gets the authority refs.
430 * @param csid the csid
433 * @return the authority refs
436 @Path("{csid}/authorityrefs")
437 @Produces("application/xml")
438 public AuthorityRefList getAuthorityRefs(
439 @PathParam("csid") String csid,
440 @Context UriInfo ui) {
441 AuthorityRefList authRefList = null;
443 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
444 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
445 DocumentWrapper<DocumentModel> docWrapper =
446 getRepositoryClient(ctx).getDoc(ctx, csid);
447 DocumentModelHandler<MultipartInput, MultipartOutput> docHandler =
448 (DocumentModelHandler<MultipartInput, MultipartOutput>)createDocumentHandler(ctx);
449 List<String> authRefFields =
450 ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(
451 ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES);
452 authRefList = docHandler.getAuthorityRefs(docWrapper, authRefFields);
453 } catch (UnauthorizedException ue) {
454 Response response = Response.status(
455 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
456 throw new WebApplicationException(response);
457 } catch (Exception e) {
458 if (logger.isDebugEnabled()) {
459 logger.debug("Caught exception in getAuthorityRefs", e);
461 Response response = Response.status(
462 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
463 throw new WebApplicationException(response);
471 * This is an intentionally empty method used for getting a rough time estimate
472 * of the overhead required for a client->server request/response cycle.
474 * @return the response
478 @Produces("application/xml")
479 public Response roundtrip() {
480 Response result = null;
482 if (logger.isDebugEnabled()) {
483 logger.debug("------------------------------------------------------------------------------");
484 logger.debug("Client to server roundtrip called.");
485 logger.debug("------------------------------------------------------------------------------");
488 result = Response.status(HttpResponseCodes.SC_OK).build();
494 * This method is deprecated. Use kwSearchCollectionObjects() method instead.
495 * Keywords search collection objects.
498 * @param keywords the keywords
500 * @return the collectionobjects common list
504 @Produces("application/xml")
505 public CollectionobjectsCommonList keywordsSearchCollectionObjects(@Context UriInfo ui,
506 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS) String keywords) {
507 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
508 return searchCollectionObjects(queryParams, keywords);
512 * Search collection objects.
514 * @param keywords the keywords
516 * @return the collectionobjects common list
518 private CollectionobjectsCommonList searchCollectionObjects(
519 MultivaluedMap<String, String> queryParams,
521 CollectionobjectsCommonList collectionObjectList;
523 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
524 DocumentHandler handler = createDocumentHandler(ctx);
526 // perform a keyword search
527 if (keywords != null && !keywords.isEmpty()) {
528 String whereClause = QueryManager.createWhereClauseFromKeywords(keywords);
529 DocumentFilter documentFilter = handler.getDocumentFilter();
530 documentFilter.setWhereClause(whereClause);
531 if (logger.isDebugEnabled()) {
532 logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
535 getRepositoryClient(ctx).getFiltered(ctx, handler);
536 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
537 } catch (UnauthorizedException ue) {
538 Response response = Response.status(
539 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
540 throw new WebApplicationException(response);
541 } catch (Exception e) {
542 if (logger.isDebugEnabled()) {
543 logger.debug("Caught exception in getCollectionObjectList", e);
545 Response response = Response.status(
546 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
547 throw new WebApplicationException(response);
549 return collectionObjectList;