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.intake.IntakeResource;
61 import org.collectionspace.services.intake.IntakesCommonList;
62 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
63 import org.collectionspace.services.relation.NewRelationResource;
64 import org.collectionspace.services.relation.RelationsCommonList;
65 import org.collectionspace.services.relation.RelationshipType;
66 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
67 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
68 import org.jboss.resteasy.util.HttpResponseCodes;
69 import org.nuxeo.ecm.core.api.DocumentModel;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
75 * The Class CollectionObjectResource.
77 @Path("/collectionobjects")
78 @Consumes("multipart/mixed")
79 @Produces("multipart/mixed")
80 public class CollectionObjectResource
81 extends AbstractCollectionSpaceResourceImpl {
83 /** The Constant serviceName. */
84 static final public String serviceName = "collectionobjects";
87 final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
90 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
93 protected String getVersionString() {
94 /** The last change revision. */
95 final String lastChangeRevision = "$LastChangedRevision$";
96 return lastChangeRevision;
100 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName()
103 public String getServiceName() {
108 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext)
111 public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
112 DocumentHandler docHandler = ctx.getDocumentHandler();
113 if (ctx.getInput() != null) {
114 Object obj = ((MultipartServiceContext) ctx).getInputPart(ctx.getCommonPartLabel(),
115 CollectionobjectsCommon.class);
117 docHandler.setCommonPart((CollectionobjectsCommon) obj);
124 * Creates the collection object.
126 * @param input the input
128 * @return the response
131 public Response createCollectionObject(MultipartInput input) {
133 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(input, getServiceName());
134 DocumentHandler handler = createDocumentHandler(ctx);
135 String csid = getRepositoryClient(ctx).create(ctx, handler);
136 UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
137 path.path("" + csid);
138 Response response = Response.created(path.build()).build();
140 } catch (BadRequestException bre) {
141 Response response = Response.status(
142 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
143 throw new WebApplicationException(response);
144 } catch (UnauthorizedException ue) {
145 Response response = Response.status(
146 Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build();
147 throw new WebApplicationException(response);
148 } catch (Exception e) {
149 if (logger.isDebugEnabled()) {
150 logger.debug("Caught exception in createCollectionObject", e);
152 Response response = Response.status(
153 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
154 throw new WebApplicationException(response);
159 * Gets the collection object.
161 * @param csid the csid
163 * @return the collection object
167 public MultipartOutput getCollectionObject(
168 @PathParam("csid") String csid) {
169 if (logger.isDebugEnabled()) {
170 logger.debug("getCollectionObject with csid=" + csid);
172 if (csid == null || "".equals(csid)) {
173 logger.error("getCollectionObject: missing csid!");
174 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
175 "get failed on CollectionObject csid=" + csid).type(
176 "text/plain").build();
177 throw new WebApplicationException(response);
179 MultipartOutput result = null;
181 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
182 DocumentHandler handler = createDocumentHandler(ctx);
183 getRepositoryClient(ctx).get(ctx, csid, handler);
184 result = (MultipartOutput) ctx.getOutput();
185 } catch (UnauthorizedException ue) {
186 Response response = Response.status(
187 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
188 throw new WebApplicationException(response);
189 } catch (DocumentNotFoundException dnfe) {
190 if (logger.isDebugEnabled()) {
191 logger.debug("getCollectionObject", dnfe);
193 Response response = Response.status(Response.Status.NOT_FOUND).entity(
194 "Get failed on CollectionObject csid=" + csid).type(
195 "text/plain").build();
196 throw new WebApplicationException(response);
197 } catch (Exception e) {
198 if (logger.isDebugEnabled()) {
199 logger.debug("getCollectionObject", e);
201 Response response = Response.status(
202 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
203 throw new WebApplicationException(response);
206 if (result == null) {
207 Response response = Response.status(Response.Status.NOT_FOUND).entity(
208 "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type(
209 "text/plain").build();
210 throw new WebApplicationException(response);
216 * Gets the collection object list.
220 * @return the collection object list
223 @Produces("application/xml")
224 public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui) {
225 CollectionobjectsCommonList collectionObjectList = new CollectionobjectsCommonList();
227 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
228 DocumentHandler handler = createDocumentHandler(ctx);
229 getRepositoryClient(ctx).getAll(ctx, handler);
230 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
231 } catch (UnauthorizedException ue) {
232 Response response = Response.status(
233 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
234 throw new WebApplicationException(response);
235 } catch (Exception e) {
236 if (logger.isDebugEnabled()) {
237 logger.debug("Caught exception in getCollectionObjectList", e);
239 Response response = Response.status(
240 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
241 throw new WebApplicationException(response);
243 return collectionObjectList;
247 * Update collection object.
249 * @param csid the csid
250 * @param theUpdate the the update
252 * @return the multipart output
256 public MultipartOutput updateCollectionObject(
257 @PathParam("csid") String csid,
258 MultipartInput theUpdate) {
259 if (logger.isDebugEnabled()) {
260 logger.debug("updateCollectionObject with csid=" + csid);
262 if (csid == null || "".equals(csid)) {
263 logger.error("updateCollectionObject: missing csid!");
264 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
265 "update failed on CollectionObject csid=" + csid).type(
266 "text/plain").build();
267 throw new WebApplicationException(response);
269 MultipartOutput result = null;
271 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(theUpdate, getServiceName());
272 DocumentHandler handler = createDocumentHandler(ctx);
273 getRepositoryClient(ctx).update(ctx, csid, handler);
274 result = (MultipartOutput) ctx.getOutput();
275 } catch (BadRequestException bre) {
276 Response response = Response.status(
277 Response.Status.BAD_REQUEST).entity("Update failed reason " + bre.getErrorReason()).type("text/plain").build();
278 throw new WebApplicationException(response);
279 } catch (UnauthorizedException ue) {
280 Response response = Response.status(
281 Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build();
282 throw new WebApplicationException(response);
283 } catch (DocumentNotFoundException dnfe) {
284 if (logger.isDebugEnabled()) {
285 logger.debug("caugth exception in updateCollectionObject", dnfe);
287 Response response = Response.status(Response.Status.NOT_FOUND).entity(
288 "Update failed on CollectionObject csid=" + csid).type(
289 "text/plain").build();
290 throw new WebApplicationException(response);
291 } catch (Exception e) {
292 Response response = Response.status(
293 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
294 throw new WebApplicationException(response);
300 * Delete collection object.
302 * @param csid the csid
304 * @return the response
308 public Response deleteCollectionObject(@PathParam("csid") String csid) {
310 if (logger.isDebugEnabled()) {
311 logger.debug("deleteCollectionObject with csid=" + csid);
313 if (csid == null || "".equals(csid)) {
314 logger.error("deleteCollectionObject: missing csid!");
315 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
316 "delete failed on CollectionObject csid=" + csid).type(
317 "text/plain").build();
318 throw new WebApplicationException(response);
321 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
322 getRepositoryClient(ctx).delete(ctx, csid);
323 return Response.status(HttpResponseCodes.SC_OK).build();
324 } catch (UnauthorizedException ue) {
325 Response response = Response.status(
326 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
327 throw new WebApplicationException(response);
328 } catch (DocumentNotFoundException dnfe) {
329 if (logger.isDebugEnabled()) {
330 logger.debug("caught exception in deleteCollectionObject", dnfe);
332 Response response = Response.status(Response.Status.NOT_FOUND).entity(
333 "Delete failed on CollectionObject csid=" + csid).type(
334 "text/plain").build();
335 throw new WebApplicationException(response);
336 } catch (Exception e) {
337 Response response = Response.status(
338 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
339 throw new WebApplicationException(response);
345 * Gets the intakes common list.
348 * @param csid the csid
350 * @return the intakes common list
353 @Path("{csid}/intakes")
354 @Produces("application/xml")
355 public IntakesCommonList getIntakesCommonList(@Context UriInfo ui,
356 @PathParam("csid") String csid) {
357 IntakesCommonList result = null;
361 // Find all the intake-related relation records.
363 String subjectCsid = csid;
364 String predicate = RelationshipType.COLLECTIONOBJECT_INTAKE.value();
365 String objectCsid = null;
366 NewRelationResource relationResource = new NewRelationResource();
367 RelationsCommonList relationsCommonList = relationResource.getRelationList(subjectCsid, predicate, objectCsid);
370 // Create an array of Intake csid's
372 List<RelationsCommonList.RelationListItem> relationsListItems = relationsCommonList.getRelationListItem();
373 List<String> intakeCsidList = new ArrayList<String>();
374 for (RelationsCommonList.RelationListItem relationsListItem : relationsListItems) {
375 intakeCsidList.add(relationsListItem.getObjectCsid());
379 // Get a response list for the Intake records from the Intake resource
381 IntakeResource intakeResource = new IntakeResource();
382 result = intakeResource.getIntakeList(intakeCsidList);
383 } catch (Exception e) {
384 if (logger.isDebugEnabled()) {
385 logger.debug("Caught exception in getIntakeList", e);
387 Response response = Response.status(
388 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
389 throw new WebApplicationException(response);
396 @Path("{csid}/authorityrefs")
397 @Produces("application/xml")
398 public AuthorityRefList getAuthorityRefs(
399 @PathParam("csid") String csid,
400 @Context UriInfo ui) {
401 AuthorityRefList authRefList = null;
403 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
404 DocumentWrapper<DocumentModel> docWrapper =
405 getRepositoryClient(ctx).getDoc(ctx, csid);
406 RemoteDocumentModelHandlerImpl handler
407 = (RemoteDocumentModelHandlerImpl)createDocumentHandler(ctx);
408 List<String> authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues("authRef");
409 String prefix = ctx.getCommonPartLabel()+":";
410 authRefList = handler.getAuthorityRefs(docWrapper, prefix, authRefFields);
411 } catch (UnauthorizedException ue) {
412 Response response = Response.status(
413 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
414 throw new WebApplicationException(response);
415 } catch (Exception e) {
416 if (logger.isDebugEnabled()) {
417 logger.debug("Caught exception in getAuthorityRefs", e);
419 Response response = Response.status(
420 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
421 throw new WebApplicationException(response);
429 * This is an intentionally empty method used for getting a rough time estimate
430 * of the overhead required for a client->server request/response cycle.
432 * @return the response
436 @Produces("application/xml")
437 public Response roundtrip() {
438 Response result = null;
440 if (logger.isDebugEnabled()) {
441 logger.debug("------------------------------------------------------------------------------");
442 logger.debug("Client to server roundtrip called.");
443 logger.debug("------------------------------------------------------------------------------");
446 result = Response.status(HttpResponseCodes.SC_OK).build();
452 //FIXME: Replace this "search" resource with a keyword "kw" query parameter
454 * Keywords search collection objects.
456 * @param keywords the keywords
458 * @return the collectionobjects common list
462 @Produces("application/xml")
463 public CollectionobjectsCommonList keywordsSearchCollectionObjects(
464 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS) String keywords) {
465 CollectionobjectsCommonList collectionObjectList = new CollectionobjectsCommonList();
467 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
468 DocumentHandler handler = createDocumentHandler(ctx);
470 // perform a keyword search
471 if (keywords != null && !keywords.isEmpty()) {
472 String whereClause = QueryManager.createWhereClauseFromKeywords(keywords);
473 DocumentFilter documentFilter = handler.getDocumentFilter();
474 documentFilter.setWhereClause(whereClause);
475 if (logger.isDebugEnabled()) {
476 logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
478 getRepositoryClient(ctx).getFiltered(ctx, handler);
480 getRepositoryClient(ctx).getAll(ctx, handler);
482 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
484 } catch (UnauthorizedException ue) {
485 Response response = Response.status(
486 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
487 throw new WebApplicationException(response);
488 } catch (Exception e) {
489 if (logger.isDebugEnabled()) {
490 logger.debug("Caught exception in getCollectionObjectList", e);
492 Response response = Response.status(
493 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
494 throw new WebApplicationException(response);
496 return collectionObjectList;