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.imaging.nuxeo.NuxeoImageUtils;
48 import org.collectionspace.services.common.AbstractMultiPartCollectionSpaceResourceImpl;
49 import org.collectionspace.services.common.authorityref.AuthorityRefList;
50 import org.collectionspace.services.common.context.ServiceContextFactory;
51 //import org.collectionspace.services.common.context.MultipartServiceContext;
52 import org.collectionspace.services.common.context.MultipartServiceContextFactory;
53 import org.collectionspace.services.common.context.MultipartServiceContextImpl;
54 import org.collectionspace.services.common.context.ServiceBindingUtils;
55 import org.collectionspace.services.common.context.ServiceContext;
56 import org.collectionspace.services.common.document.BadRequestException;
57 import org.collectionspace.services.common.document.DocumentFilter;
58 import org.collectionspace.services.common.document.DocumentHandler;
59 import org.collectionspace.services.common.document.DocumentNotFoundException;
60 import org.collectionspace.services.common.document.DocumentWrapper;
61 import org.collectionspace.services.common.query.IQueryManager;
62 import org.collectionspace.services.common.query.QueryManager;
63 import org.collectionspace.services.common.security.UnauthorizedException;
64 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
65 import org.collectionspace.services.intake.IntakeResource;
66 import org.collectionspace.services.intake.IntakesCommonList;
67 //import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
68 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
69 import org.collectionspace.services.relation.NewRelationResource;
70 import org.collectionspace.services.relation.RelationsCommonList;
71 import org.collectionspace.services.relation.RelationshipType;
72 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
73 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
74 import org.jboss.resteasy.util.HttpResponseCodes;
75 import org.nuxeo.ecm.core.api.DocumentModel;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
81 * The Class CollectionObjectResource.
83 @Path("/collectionobjects")
84 @Consumes("multipart/mixed")
85 @Produces("multipart/mixed")
86 public class CollectionObjectResource
87 extends AbstractMultiPartCollectionSpaceResourceImpl {
89 /** The Constant serviceName. */
90 static final public String serviceName = "collectionobjects";
93 final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
96 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
99 public String getVersionString() {
100 /** The last change revision. */
101 final String lastChangeRevision = "$LastChangedRevision$";
102 return lastChangeRevision;
106 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName()
109 public String getServiceName() {
114 * @see org.collectionspace.services.common.CollectionSpaceResource#getCommonPartClass()
117 public Class<CollectionobjectsCommon> getCommonPartClass() {
118 return CollectionobjectsCommon.class;
122 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext)
125 // public DocumentHandler createDocumentHandler(ServiceContext<MultipartInput, MultipartOutput> ctx) throws Exception {
126 // DocumentHandler docHandler = ctx.getDocumentHandler();
127 // if (ctx.getInput() != null) {
128 // Object obj = ((MultipartServiceContext) ctx).getInputPart(ctx.getCommonPartLabel(),
129 // CollectionobjectsCommon.class);
130 // if (obj != null) {
131 // docHandler.setCommonPart((CollectionobjectsCommon) obj);
134 // return docHandler;
138 * Creates the collection object.
140 * @param input the input
142 * @return the response
145 public Response createCollectionObject(MultipartInput input) {
147 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(input); //
148 DocumentHandler handler = createDocumentHandler(ctx);
149 String csid = getRepositoryClient(ctx).create(ctx, handler);
150 UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
151 path.path("" + csid);
152 Response response = Response.created(path.build()).build();
154 } catch (BadRequestException bre) {
155 Response response = Response.status(
156 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
157 throw new WebApplicationException(response);
158 } catch (UnauthorizedException ue) {
159 Response response = Response.status(
160 Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build();
161 throw new WebApplicationException(response);
162 } catch (Exception e) {
163 if (logger.isDebugEnabled()) {
164 logger.debug("Caught exception in createCollectionObject", e);
166 Response response = Response.status(
167 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
168 throw new WebApplicationException(response);
173 * Gets the collection object.
175 * @param csid the csid
177 * @return the collection object
181 public MultipartOutput getCollectionObject(
182 @PathParam("csid") String csid) {
183 if (logger.isDebugEnabled()) {
184 logger.debug("getCollectionObject with csid=" + csid);
186 if (csid == null || "".equals(csid)) {
187 logger.error("getCollectionObject: missing csid!");
188 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
189 "get failed on CollectionObject csid=" + csid).type(
190 "text/plain").build();
191 throw new WebApplicationException(response);
193 MultipartOutput result = null;
195 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext();
196 DocumentHandler handler = createDocumentHandler(ctx);
197 getRepositoryClient(ctx).get(ctx, csid, handler);
198 result = (MultipartOutput) ctx.getOutput();
199 } catch (UnauthorizedException ue) {
200 Response response = Response.status(
201 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
202 throw new WebApplicationException(response);
203 } catch (DocumentNotFoundException dnfe) {
204 if (logger.isDebugEnabled()) {
205 logger.debug("getCollectionObject", dnfe);
207 Response response = Response.status(Response.Status.NOT_FOUND).entity(
208 "Get failed on CollectionObject csid=" + csid).type(
209 "text/plain").build();
210 throw new WebApplicationException(response);
211 } catch (Exception e) {
212 if (logger.isDebugEnabled()) {
213 logger.debug("getCollectionObject", e);
215 Response response = Response.status(
216 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
217 throw new WebApplicationException(response);
220 if (result == null) {
221 Response response = Response.status(Response.Status.NOT_FOUND).entity(
222 "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type(
223 "text/plain").build();
224 throw new WebApplicationException(response);
230 * Gets the collection object list.
233 * @param keywords the keywords
235 * @return the collection object list
238 @Produces("application/xml")
239 public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui,
240 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS_KW) String keywords) {
241 CollectionobjectsCommonList result = null;
242 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
243 if (keywords != null) {
244 result = searchCollectionObjects(queryParams, keywords);
246 result = getCollectionObjectList(queryParams);
253 * Gets the collection object list.
255 private CollectionobjectsCommonList getCollectionObjectList(MultivaluedMap<String, String> queryParams) {
256 CollectionobjectsCommonList collectionObjectList;
258 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
259 DocumentHandler handler = createDocumentHandler(ctx);
260 getRepositoryClient(ctx).getFiltered(ctx, handler);
261 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
262 } catch (UnauthorizedException ue) {
263 Response response = Response.status(
264 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
265 throw new WebApplicationException(response);
266 } catch (Exception e) {
267 if (logger.isDebugEnabled()) {
268 logger.debug("Caught exception in getCollectionObjectList", e);
270 Response response = Response.status(
271 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
272 throw new WebApplicationException(response);
274 return collectionObjectList;
278 * Update collection object.
280 * @param csid the csid
281 * @param theUpdate the the update
283 * @return the multipart output
287 public MultipartOutput updateCollectionObject(
288 @PathParam("csid") String csid,
289 MultipartInput theUpdate) {
290 if (logger.isDebugEnabled()) {
291 logger.debug("updateCollectionObject with csid=" + csid);
293 if (csid == null || "".equals(csid)) {
294 logger.error("updateCollectionObject: missing csid!");
295 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
296 "update failed on CollectionObject csid=" + csid).type(
297 "text/plain").build();
298 throw new WebApplicationException(response);
300 MultipartOutput result = null;
302 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(theUpdate);
303 DocumentHandler handler = createDocumentHandler(ctx);
304 getRepositoryClient(ctx).update(ctx, csid, handler);
305 result = (MultipartOutput) ctx.getOutput();
306 } catch (BadRequestException bre) {
307 Response response = Response.status(
308 Response.Status.BAD_REQUEST).entity("Update failed reason " + bre.getErrorReason()).type("text/plain").build();
309 throw new WebApplicationException(response);
310 } catch (UnauthorizedException ue) {
311 Response response = Response.status(
312 Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build();
313 throw new WebApplicationException(response);
314 } catch (DocumentNotFoundException dnfe) {
315 if (logger.isDebugEnabled()) {
316 logger.debug("caugth exception in updateCollectionObject", dnfe);
318 Response response = Response.status(Response.Status.NOT_FOUND).entity(
319 "Update failed on CollectionObject csid=" + csid).type(
320 "text/plain").build();
321 throw new WebApplicationException(response);
322 } catch (Exception e) {
323 Response response = Response.status(
324 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
325 throw new WebApplicationException(response);
331 * Delete collection object.
333 * @param csid the csid
335 * @return the response
339 public Response deleteCollectionObject(@PathParam("csid") String csid) {
341 if (logger.isDebugEnabled()) {
342 logger.debug("deleteCollectionObject with csid=" + csid);
344 if (csid == null || "".equals(csid)) {
345 logger.error("deleteCollectionObject: missing csid!");
346 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
347 "delete failed on CollectionObject csid=" + csid).type(
348 "text/plain").build();
349 throw new WebApplicationException(response);
352 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext();
353 getRepositoryClient(ctx).delete(ctx, csid);
354 return Response.status(HttpResponseCodes.SC_OK).build();
355 } catch (UnauthorizedException ue) {
356 Response response = Response.status(
357 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
358 throw new WebApplicationException(response);
359 } catch (DocumentNotFoundException dnfe) {
360 if (logger.isDebugEnabled()) {
361 logger.debug("caught exception in deleteCollectionObject", dnfe);
363 Response response = Response.status(Response.Status.NOT_FOUND).entity(
364 "Delete failed on CollectionObject csid=" + csid).type(
365 "text/plain").build();
366 throw new WebApplicationException(response);
367 } catch (Exception e) {
368 Response response = Response.status(
369 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
370 throw new WebApplicationException(response);
376 * Gets the intakes common list.
379 * @param csid the csid
381 * @return the intakes common list
384 @Path("{csid}/intakes")
385 @Produces("application/xml")
386 public IntakesCommonList getIntakesCommonList(@Context UriInfo ui,
387 @PathParam("csid") String csid) {
388 IntakesCommonList result = null;
389 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
393 // Find all the intake-related relation records.
395 String subjectCsid = csid;
396 String predicate = RelationshipType.COLLECTIONOBJECT_INTAKE.value();
397 String objectCsid = null;
398 NewRelationResource relationResource = new NewRelationResource();
399 RelationsCommonList relationsCommonList = relationResource.getRelationList(queryParams,
401 null, /*subjectType*/
404 null /*objectType*/);
407 // Create an array of Intake csid's
409 List<RelationsCommonList.RelationListItem> relationsListItems = relationsCommonList.getRelationListItem();
410 List<String> intakeCsidList = new ArrayList<String>();
411 for (RelationsCommonList.RelationListItem relationsListItem : relationsListItems) {
412 intakeCsidList.add(relationsListItem.getObjectCsid());
416 // Get a response list for the Intake records from the Intake resource
418 IntakeResource intakeResource = new IntakeResource();
419 result = intakeResource.getIntakeList(intakeCsidList);
420 } catch (Exception e) {
421 if (logger.isDebugEnabled()) {
422 logger.debug("Caught exception in getIntakeList", e);
424 Response response = Response.status(
425 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
426 throw new WebApplicationException(response);
433 * Gets the authority refs.
435 * @param csid the csid
438 * @return the authority refs
441 @Path("{csid}/authorityrefs")
442 @Produces("application/xml")
443 public AuthorityRefList getAuthorityRefs(
444 @PathParam("csid") String csid,
445 @Context UriInfo ui) {
446 AuthorityRefList authRefList = null;
448 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
449 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
450 DocumentWrapper<DocumentModel> docWrapper =
451 getRepositoryClient(ctx).getDoc(ctx, csid);
452 DocumentModelHandler<MultipartInput, MultipartOutput> docHandler =
453 (DocumentModelHandler<MultipartInput, MultipartOutput>)createDocumentHandler(ctx);
454 List<String> authRefFields =
455 ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(
456 ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES);
457 authRefList = docHandler.getAuthorityRefs(docWrapper, authRefFields);
458 } catch (UnauthorizedException ue) {
459 Response response = Response.status(
460 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
461 throw new WebApplicationException(response);
462 } catch (Exception e) {
463 if (logger.isDebugEnabled()) {
464 logger.debug("Caught exception in getAuthorityRefs", e);
466 Response response = Response.status(
467 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
468 throw new WebApplicationException(response);
476 * This is an intentionally empty method used for getting a rough time estimate
477 * of the overhead required for a client->server request/response cycle.
479 * @return the response
483 @Produces("application/xml")
484 public Response roundtrip() {
485 Response result = null;
487 if (logger.isDebugEnabled()) {
488 logger.debug("------------------------------------------------------------------------------");
489 logger.debug("Client to server roundtrip called.");
490 logger.debug("------------------------------------------------------------------------------");
493 result = Response.status(HttpResponseCodes.SC_OK).build();
500 @Produces("application/xml")
501 public Response createPictureDocument() {
502 Response result = null;
504 if (logger.isDebugEnabled()) {
505 logger.debug("------------------------------------------------------------------------------");
506 logger.debug("Prototype to create a Picture document in Nuxeo");
507 logger.debug("------------------------------------------------------------------------------");
511 NuxeoImageUtils.createPicture();
512 result = Response.status(HttpResponseCodes.SC_OK).build();
518 * This method is deprecated. Use kwSearchCollectionObjects() method instead.
519 * Keywords search collection objects.
522 * @param keywords the keywords
524 * @return the collectionobjects common list
528 @Produces("application/xml")
529 public CollectionobjectsCommonList keywordsSearchCollectionObjects(@Context UriInfo ui,
530 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS) String keywords) {
531 MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
532 return searchCollectionObjects(queryParams, keywords);
536 * Search collection objects.
538 * @param keywords the keywords
540 * @return the collectionobjects common list
542 private CollectionobjectsCommonList searchCollectionObjects(
543 MultivaluedMap<String, String> queryParams,
545 CollectionobjectsCommonList collectionObjectList;
547 ServiceContext<MultipartInput, MultipartOutput> ctx = createServiceContext(queryParams);
548 DocumentHandler handler = createDocumentHandler(ctx);
550 // perform a keyword search
551 if (keywords != null && !keywords.isEmpty()) {
552 String whereClause = QueryManager.createWhereClauseFromKeywords(keywords);
553 DocumentFilter documentFilter = handler.getDocumentFilter();
554 documentFilter.setWhereClause(whereClause);
555 if (logger.isDebugEnabled()) {
556 logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
559 getRepositoryClient(ctx).getFiltered(ctx, handler);
560 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
561 } catch (UnauthorizedException ue) {
562 Response response = Response.status(
563 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
564 throw new WebApplicationException(response);
565 } catch (Exception e) {
566 if (logger.isDebugEnabled()) {
567 logger.debug("Caught exception in getCollectionObjectList", e);
569 Response response = Response.status(
570 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
571 throw new WebApplicationException(response);
573 return collectionObjectList;