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 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 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;
391 // Find all the intake-related relation records.
393 String subjectCsid = csid;
394 String predicate = RelationshipType.COLLECTIONOBJECT_INTAKE.value();
395 String objectCsid = null;
396 NewRelationResource relationResource = new NewRelationResource();
397 RelationsCommonList relationsCommonList = relationResource.getRelationList(subjectCsid, predicate, objectCsid);
400 // Create an array of Intake csid's
402 List<RelationsCommonList.RelationListItem> relationsListItems = relationsCommonList.getRelationListItem();
403 List<String> intakeCsidList = new ArrayList<String>();
404 for (RelationsCommonList.RelationListItem relationsListItem : relationsListItems) {
405 intakeCsidList.add(relationsListItem.getObjectCsid());
409 // Get a response list for the Intake records from the Intake resource
411 IntakeResource intakeResource = new IntakeResource();
412 result = intakeResource.getIntakeList(intakeCsidList);
413 } catch (Exception e) {
414 if (logger.isDebugEnabled()) {
415 logger.debug("Caught exception in getIntakeList", e);
417 Response response = Response.status(
418 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
419 throw new WebApplicationException(response);
426 * Gets the authority refs.
428 * @param csid the csid
431 * @return the authority refs
434 @Path("{csid}/authorityrefs")
435 @Produces("application/xml")
436 public AuthorityRefList getAuthorityRefs(
437 @PathParam("csid") String csid,
438 @Context UriInfo ui) {
439 AuthorityRefList authRefList = null;
441 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext();
442 DocumentWrapper<DocumentModel> docWrapper =
443 getRepositoryClient(ctx).getDoc(ctx, csid);
444 DocumentModelHandler<MultipartInput, MultipartOutput> docHandler =
445 (DocumentModelHandler<MultipartInput, MultipartOutput>)createDocumentHandler(ctx);
446 List<String> authRefFields =
447 ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(
448 ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES);
449 authRefList = docHandler.getAuthorityRefs(docWrapper, authRefFields);
450 } catch (UnauthorizedException ue) {
451 Response response = Response.status(
452 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
453 throw new WebApplicationException(response);
454 } catch (Exception e) {
455 if (logger.isDebugEnabled()) {
456 logger.debug("Caught exception in getAuthorityRefs", e);
458 Response response = Response.status(
459 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
460 throw new WebApplicationException(response);
468 * This is an intentionally empty method used for getting a rough time estimate
469 * of the overhead required for a client->server request/response cycle.
471 * @return the response
475 @Produces("application/xml")
476 public Response roundtrip() {
477 Response result = null;
479 if (logger.isDebugEnabled()) {
480 logger.debug("------------------------------------------------------------------------------");
481 logger.debug("Client to server roundtrip called.");
482 logger.debug("------------------------------------------------------------------------------");
485 result = Response.status(HttpResponseCodes.SC_OK).build();
491 * This method is deprecated. Use kwSearchCollectionObjects() method instead.
492 * Keywords search collection objects.
495 * @param keywords the keywords
497 * @return the collectionobjects common list
501 @Produces("application/xml")
502 public CollectionobjectsCommonList keywordsSearchCollectionObjects(@Context UriInfo ui,
503 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS) String keywords) {
504 MultivaluedMap queryParams = ui.getQueryParameters();
505 return searchCollectionObjects(queryParams, keywords);
509 * Search collection objects.
511 * @param keywords the keywords
513 * @return the collectionobjects common list
515 private CollectionobjectsCommonList searchCollectionObjects(
516 MultivaluedMap<String, String> queryParams,
518 CollectionobjectsCommonList collectionObjectList;
520 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
521 DocumentHandler handler = createDocumentHandler(ctx);
523 // perform a keyword search
524 if (keywords != null && !keywords.isEmpty()) {
525 String whereClause = QueryManager.createWhereClauseFromKeywords(keywords);
526 DocumentFilter documentFilter = handler.getDocumentFilter();
527 documentFilter.setWhereClause(whereClause);
528 if (logger.isDebugEnabled()) {
529 logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
532 getRepositoryClient(ctx).getFiltered(ctx, handler);
533 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
534 } catch (UnauthorizedException ue) {
535 Response response = Response.status(
536 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
537 throw new WebApplicationException(response);
538 } catch (Exception e) {
539 if (logger.isDebugEnabled()) {
540 logger.debug("Caught exception in getCollectionObjectList", e);
542 Response response = Response.status(
543 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
544 throw new WebApplicationException(response);
546 return collectionObjectList;