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;
46 import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl;
47 import org.collectionspace.services.common.authorityref.AuthorityRefList;
48 import org.collectionspace.services.common.context.MultipartServiceContext;
49 import org.collectionspace.services.common.context.MultipartServiceContextFactory;
50 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
51 import org.collectionspace.services.common.context.ServiceContext;
52 import org.collectionspace.services.common.document.BadRequestException;
53 import org.collectionspace.services.common.document.DocumentFilter;
54 import org.collectionspace.services.common.document.DocumentHandler;
55 import org.collectionspace.services.common.document.DocumentNotFoundException;
56 import org.collectionspace.services.common.document.DocumentWrapper;
57 import org.collectionspace.services.common.query.IQueryManager;
58 import org.collectionspace.services.common.query.QueryManager;
59 import org.collectionspace.services.common.security.UnauthorizedException;
60 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
61 import org.collectionspace.services.intake.IntakeResource;
62 import org.collectionspace.services.intake.IntakesCommonList;
63 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
64 import org.collectionspace.services.relation.NewRelationResource;
65 import org.collectionspace.services.relation.RelationsCommonList;
66 import org.collectionspace.services.relation.RelationshipType;
67 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
68 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
69 import org.jboss.resteasy.util.HttpResponseCodes;
70 import org.nuxeo.ecm.core.api.DocumentModel;
71 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
76 * The Class CollectionObjectResource.
78 @Path("/collectionobjects")
79 @Consumes("multipart/mixed")
80 @Produces("multipart/mixed")
81 public class CollectionObjectResource
82 extends AbstractCollectionSpaceResourceImpl {
84 /** The Constant serviceName. */
85 static final public String serviceName = "collectionobjects";
88 final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
91 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
94 protected String getVersionString() {
95 /** The last change revision. */
96 final String lastChangeRevision = "$LastChangedRevision$";
97 return lastChangeRevision;
101 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName()
104 public String getServiceName() {
109 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext)
112 public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
113 DocumentHandler docHandler = ctx.getDocumentHandler();
114 if (ctx.getInput() != null) {
115 Object obj = ((MultipartServiceContext) ctx).getInputPart(ctx.getCommonPartLabel(),
116 CollectionobjectsCommon.class);
118 docHandler.setCommonPart((CollectionobjectsCommon) obj);
125 * Creates the collection object.
127 * @param input the input
129 * @return the response
132 public Response createCollectionObject(MultipartInput input) {
134 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(input, getServiceName());
135 DocumentHandler handler = createDocumentHandler(ctx);
136 String csid = getRepositoryClient(ctx).create(ctx, handler);
137 UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
138 path.path("" + csid);
139 Response response = Response.created(path.build()).build();
141 } catch (BadRequestException bre) {
142 Response response = Response.status(
143 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
144 throw new WebApplicationException(response);
145 } catch (UnauthorizedException ue) {
146 Response response = Response.status(
147 Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build();
148 throw new WebApplicationException(response);
149 } catch (Exception e) {
150 if (logger.isDebugEnabled()) {
151 logger.debug("Caught exception in createCollectionObject", e);
153 Response response = Response.status(
154 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
155 throw new WebApplicationException(response);
160 * Gets the collection object.
162 * @param csid the csid
164 * @return the collection object
168 public MultipartOutput getCollectionObject(
169 @PathParam("csid") String csid) {
170 if (logger.isDebugEnabled()) {
171 logger.debug("getCollectionObject with csid=" + csid);
173 if (csid == null || "".equals(csid)) {
174 logger.error("getCollectionObject: missing csid!");
175 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
176 "get failed on CollectionObject csid=" + csid).type(
177 "text/plain").build();
178 throw new WebApplicationException(response);
180 MultipartOutput result = null;
182 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
183 DocumentHandler handler = createDocumentHandler(ctx);
184 getRepositoryClient(ctx).get(ctx, csid, handler);
185 result = (MultipartOutput) ctx.getOutput();
186 } catch (UnauthorizedException ue) {
187 Response response = Response.status(
188 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
189 throw new WebApplicationException(response);
190 } catch (DocumentNotFoundException dnfe) {
191 if (logger.isDebugEnabled()) {
192 logger.debug("getCollectionObject", dnfe);
194 Response response = Response.status(Response.Status.NOT_FOUND).entity(
195 "Get failed on CollectionObject csid=" + csid).type(
196 "text/plain").build();
197 throw new WebApplicationException(response);
198 } catch (Exception e) {
199 if (logger.isDebugEnabled()) {
200 logger.debug("getCollectionObject", e);
202 Response response = Response.status(
203 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
204 throw new WebApplicationException(response);
207 if (result == null) {
208 Response response = Response.status(Response.Status.NOT_FOUND).entity(
209 "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type(
210 "text/plain").build();
211 throw new WebApplicationException(response);
217 @Produces("application/xml")
218 public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui,
219 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords) {
220 CollectionobjectsCommonList result = null;
221 if (keywords != null) {
222 result = searchCollectionObjects(keywords);
224 result = getCollectionObjectList();
231 * Gets the collection object list.
233 private CollectionobjectsCommonList getCollectionObjectList() {
234 CollectionobjectsCommonList collectionObjectList;
236 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
237 DocumentHandler handler = createDocumentHandler(ctx);
238 getRepositoryClient(ctx).getAll(ctx, handler);
239 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
240 } catch (UnauthorizedException ue) {
241 Response response = Response.status(
242 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
243 throw new WebApplicationException(response);
244 } catch (Exception e) {
245 if (logger.isDebugEnabled()) {
246 logger.debug("Caught exception in getCollectionObjectList", e);
248 Response response = Response.status(
249 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
250 throw new WebApplicationException(response);
252 return collectionObjectList;
256 * Update collection object.
258 * @param csid the csid
259 * @param theUpdate the the update
261 * @return the multipart output
265 public MultipartOutput updateCollectionObject(
266 @PathParam("csid") String csid,
267 MultipartInput theUpdate) {
268 if (logger.isDebugEnabled()) {
269 logger.debug("updateCollectionObject with csid=" + csid);
271 if (csid == null || "".equals(csid)) {
272 logger.error("updateCollectionObject: missing csid!");
273 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
274 "update failed on CollectionObject csid=" + csid).type(
275 "text/plain").build();
276 throw new WebApplicationException(response);
278 MultipartOutput result = null;
280 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(theUpdate, getServiceName());
281 DocumentHandler handler = createDocumentHandler(ctx);
282 getRepositoryClient(ctx).update(ctx, csid, handler);
283 result = (MultipartOutput) ctx.getOutput();
284 } catch (BadRequestException bre) {
285 Response response = Response.status(
286 Response.Status.BAD_REQUEST).entity("Update failed reason " + bre.getErrorReason()).type("text/plain").build();
287 throw new WebApplicationException(response);
288 } catch (UnauthorizedException ue) {
289 Response response = Response.status(
290 Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build();
291 throw new WebApplicationException(response);
292 } catch (DocumentNotFoundException dnfe) {
293 if (logger.isDebugEnabled()) {
294 logger.debug("caugth exception in updateCollectionObject", dnfe);
296 Response response = Response.status(Response.Status.NOT_FOUND).entity(
297 "Update failed on CollectionObject csid=" + csid).type(
298 "text/plain").build();
299 throw new WebApplicationException(response);
300 } catch (Exception e) {
301 Response response = Response.status(
302 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
303 throw new WebApplicationException(response);
309 * Delete collection object.
311 * @param csid the csid
313 * @return the response
317 public Response deleteCollectionObject(@PathParam("csid") String csid) {
319 if (logger.isDebugEnabled()) {
320 logger.debug("deleteCollectionObject with csid=" + csid);
322 if (csid == null || "".equals(csid)) {
323 logger.error("deleteCollectionObject: missing csid!");
324 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
325 "delete failed on CollectionObject csid=" + csid).type(
326 "text/plain").build();
327 throw new WebApplicationException(response);
330 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
331 getRepositoryClient(ctx).delete(ctx, csid);
332 return Response.status(HttpResponseCodes.SC_OK).build();
333 } catch (UnauthorizedException ue) {
334 Response response = Response.status(
335 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
336 throw new WebApplicationException(response);
337 } catch (DocumentNotFoundException dnfe) {
338 if (logger.isDebugEnabled()) {
339 logger.debug("caught exception in deleteCollectionObject", dnfe);
341 Response response = Response.status(Response.Status.NOT_FOUND).entity(
342 "Delete failed on CollectionObject csid=" + csid).type(
343 "text/plain").build();
344 throw new WebApplicationException(response);
345 } catch (Exception e) {
346 Response response = Response.status(
347 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
348 throw new WebApplicationException(response);
354 * Gets the intakes common list.
357 * @param csid the csid
359 * @return the intakes common list
362 @Path("{csid}/intakes")
363 @Produces("application/xml")
364 public IntakesCommonList getIntakesCommonList(@Context UriInfo ui,
365 @PathParam("csid") String csid) {
366 IntakesCommonList result = null;
370 // Find all the intake-related relation records.
372 String subjectCsid = csid;
373 String predicate = RelationshipType.COLLECTIONOBJECT_INTAKE.value();
374 String objectCsid = null;
375 NewRelationResource relationResource = new NewRelationResource();
376 RelationsCommonList relationsCommonList = relationResource.getRelationList(subjectCsid, predicate, objectCsid);
379 // Create an array of Intake csid's
381 List<RelationsCommonList.RelationListItem> relationsListItems = relationsCommonList.getRelationListItem();
382 List<String> intakeCsidList = new ArrayList<String>();
383 for (RelationsCommonList.RelationListItem relationsListItem : relationsListItems) {
384 intakeCsidList.add(relationsListItem.getObjectCsid());
388 // Get a response list for the Intake records from the Intake resource
390 IntakeResource intakeResource = new IntakeResource();
391 result = intakeResource.getIntakeList(intakeCsidList);
392 } catch (Exception e) {
393 if (logger.isDebugEnabled()) {
394 logger.debug("Caught exception in getIntakeList", e);
396 Response response = Response.status(
397 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
398 throw new WebApplicationException(response);
405 @Path("{csid}/authorityrefs")
406 @Produces("application/xml")
407 public AuthorityRefList getAuthorityRefs(
408 @PathParam("csid") String csid,
409 @Context UriInfo ui) {
410 AuthorityRefList authRefList = null;
412 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
413 DocumentWrapper<DocumentModel> docWrapper =
414 getRepositoryClient(ctx).getDoc(ctx, csid);
415 RemoteDocumentModelHandlerImpl handler
416 = (RemoteDocumentModelHandlerImpl)createDocumentHandler(ctx);
417 List<String> authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(RefNameServiceUtils.AUTH_REF_PROP);
418 authRefList = handler.getAuthorityRefs(docWrapper, authRefFields);
419 } catch (UnauthorizedException ue) {
420 Response response = Response.status(
421 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
422 throw new WebApplicationException(response);
423 } catch (Exception e) {
424 if (logger.isDebugEnabled()) {
425 logger.debug("Caught exception in getAuthorityRefs", e);
427 Response response = Response.status(
428 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
429 throw new WebApplicationException(response);
437 * This is an intentionally empty method used for getting a rough time estimate
438 * of the overhead required for a client->server request/response cycle.
440 * @return the response
444 @Produces("application/xml")
445 public Response roundtrip() {
446 Response result = null;
448 if (logger.isDebugEnabled()) {
449 logger.debug("------------------------------------------------------------------------------");
450 logger.debug("Client to server roundtrip called.");
451 logger.debug("------------------------------------------------------------------------------");
454 result = Response.status(HttpResponseCodes.SC_OK).build();
460 * This method is deprecated. Use kwSearchCollectionObjects() method instead.
461 * Keywords search collection objects.
463 * @param keywords the keywords
465 * @return the collectionobjects common list
469 @Produces("application/xml")
470 public CollectionobjectsCommonList keywordsSearchCollectionObjects(
471 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS) String keywords) {
472 return searchCollectionObjects(keywords);
475 private CollectionobjectsCommonList searchCollectionObjects(String keywords) {
476 CollectionobjectsCommonList collectionObjectList;
478 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
479 DocumentHandler handler = createDocumentHandler(ctx);
481 // perform a keyword search
482 if (keywords != null && !keywords.isEmpty()) {
483 String whereClause = QueryManager.createWhereClauseFromKeywords(keywords);
484 DocumentFilter documentFilter = handler.createDocumentFilter(ctx);
485 documentFilter.setWhereClause(whereClause);
486 if (logger.isDebugEnabled()) {
487 logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
489 getRepositoryClient(ctx).getFiltered(ctx, handler);
491 getRepositoryClient(ctx).getAll(ctx, handler);
493 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
495 } catch (UnauthorizedException ue) {
496 Response response = Response.status(
497 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
498 throw new WebApplicationException(response);
499 } catch (Exception e) {
500 if (logger.isDebugEnabled()) {
501 logger.debug("Caught exception in getCollectionObjectList", e);
503 Response response = Response.status(
504 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
505 throw new WebApplicationException(response);
507 return collectionObjectList;