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.List;
29 import java.util.ArrayList;
30 import java.util.Iterator;
31 import java.lang.reflect.Type;
33 import javax.ws.rs.Consumes;
34 import javax.ws.rs.GET;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.DELETE;
38 import javax.ws.rs.POST;
39 import javax.ws.rs.PUT;
40 import javax.ws.rs.PathParam;
41 import javax.ws.rs.QueryParam;
42 import javax.ws.rs.WebApplicationException;
43 import javax.ws.rs.core.Context;
44 import javax.ws.rs.core.Response;
45 import javax.ws.rs.core.UriBuilder;
46 import javax.ws.rs.core.UriInfo;
48 import org.collectionspace.services.common.query.QueryManager;
49 import org.collectionspace.services.common.query.IQueryManager;
50 import org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl;
51 import org.collectionspace.services.common.context.MultipartServiceContext;
52 import org.collectionspace.services.common.context.MultipartServiceContextFactory;
53 import org.collectionspace.services.common.context.ServiceContext;
54 import org.collectionspace.services.common.document.BadRequestException;
55 import org.collectionspace.services.common.document.DocumentNotFoundException;
56 import org.collectionspace.services.common.document.DocumentHandler;
57 import org.collectionspace.services.common.document.DocumentFilter;
58 import org.collectionspace.services.common.security.UnauthorizedException;
59 import org.jboss.resteasy.plugins.providers.multipart.InputPart;
60 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
61 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
62 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
63 import org.jboss.resteasy.util.HttpResponseCodes;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 import org.collectionspace.services.intake.IntakesCommonList;
68 import org.collectionspace.services.intake.IntakeResource;
70 import org.collectionspace.services.relation.NewRelationResource;
71 import org.collectionspace.services.relation.RelationshipType;
72 import org.collectionspace.services.relation.RelationsCommonList;
73 import org.collectionspace.services.relation.RelationsCommon;
77 * The Class CollectionObjectResource.
79 @Path("/collectionobjects")
80 @Consumes("multipart/mixed")
81 @Produces("multipart/mixed")
82 public class CollectionObjectResource
83 extends AbstractCollectionSpaceResourceImpl {
85 /** The Constant serviceName. */
86 static final public String serviceName = "collectionobjects";
89 final Logger logger = LoggerFactory.getLogger(CollectionObjectResource.class);
92 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getVersionString()
95 protected String getVersionString() {
96 /** The last change revision. */
97 final String lastChangeRevision = "$LastChangedRevision$";
98 return lastChangeRevision;
102 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#getServiceName()
105 public String getServiceName() {
110 * @see org.collectionspace.services.common.AbstractCollectionSpaceResourceImpl#createDocumentHandler(org.collectionspace.services.common.context.ServiceContext)
113 public DocumentHandler createDocumentHandler(ServiceContext ctx) throws Exception {
114 DocumentHandler docHandler = ctx.getDocumentHandler();
115 if (ctx.getInput() != null) {
116 Object obj = ((MultipartServiceContext) ctx).getInputPart(ctx.getCommonPartLabel(),
117 CollectionobjectsCommon.class);
119 docHandler.setCommonPart((CollectionobjectsCommon) obj);
126 * Creates the collection object.
128 * @param input the input
130 * @return the response
133 public Response createCollectionObject(MultipartInput input) {
135 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(input, getServiceName());
136 DocumentHandler handler = createDocumentHandler(ctx);
137 String csid = getRepositoryClient(ctx).create(ctx, handler);
138 UriBuilder path = UriBuilder.fromResource(CollectionObjectResource.class);
139 path.path("" + csid);
140 Response response = Response.created(path.build()).build();
142 } catch (BadRequestException bre) {
143 Response response = Response.status(
144 Response.Status.BAD_REQUEST).entity("Create failed reason " + bre.getErrorReason()).type("text/plain").build();
145 throw new WebApplicationException(response);
146 } catch (UnauthorizedException ue) {
147 Response response = Response.status(
148 Response.Status.UNAUTHORIZED).entity("Create failed reason " + ue.getErrorReason()).type("text/plain").build();
149 throw new WebApplicationException(response);
150 } catch (Exception e) {
151 if (logger.isDebugEnabled()) {
152 logger.debug("Caught exception in createCollectionObject", e);
154 Response response = Response.status(
155 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
156 throw new WebApplicationException(response);
161 * Gets the collection object.
163 * @param csid the csid
165 * @return the collection object
169 public MultipartOutput getCollectionObject(
170 @PathParam("csid") String csid) {
171 if (logger.isDebugEnabled()) {
172 logger.debug("getCollectionObject with csid=" + csid);
174 if (csid == null || "".equals(csid)) {
175 logger.error("getCollectionObject: missing csid!");
176 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
177 "get failed on CollectionObject csid=" + csid).type(
178 "text/plain").build();
179 throw new WebApplicationException(response);
181 MultipartOutput result = null;
183 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
184 DocumentHandler handler = createDocumentHandler(ctx);
185 getRepositoryClient(ctx).get(ctx, csid, handler);
186 result = (MultipartOutput) ctx.getOutput();
187 } catch (UnauthorizedException ue) {
188 Response response = Response.status(
189 Response.Status.UNAUTHORIZED).entity("Get failed reason " + ue.getErrorReason()).type("text/plain").build();
190 throw new WebApplicationException(response);
191 } catch (DocumentNotFoundException dnfe) {
192 if (logger.isDebugEnabled()) {
193 logger.debug("getCollectionObject", dnfe);
195 Response response = Response.status(Response.Status.NOT_FOUND).entity(
196 "Get failed on CollectionObject csid=" + csid).type(
197 "text/plain").build();
198 throw new WebApplicationException(response);
199 } catch (Exception e) {
200 if (logger.isDebugEnabled()) {
201 logger.debug("getCollectionObject", e);
203 Response response = Response.status(
204 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
205 throw new WebApplicationException(response);
208 if (result == null) {
209 Response response = Response.status(Response.Status.NOT_FOUND).entity(
210 "Get failed, the requested CollectionObject CSID:" + csid + ": was not found.").type(
211 "text/plain").build();
212 throw new WebApplicationException(response);
218 * Gets the collection object list.
222 * @return the collection object list
225 @Produces("application/xml")
226 public CollectionobjectsCommonList getCollectionObjectList(@Context UriInfo ui) {
227 CollectionobjectsCommonList collectionObjectList = new CollectionobjectsCommonList();
229 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
230 DocumentHandler handler = createDocumentHandler(ctx);
231 getRepositoryClient(ctx).getAll(ctx, handler);
232 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
233 } catch (UnauthorizedException ue) {
234 Response response = Response.status(
235 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
236 throw new WebApplicationException(response);
237 } catch (Exception e) {
238 if (logger.isDebugEnabled()) {
239 logger.debug("Caught exception in getCollectionObjectList", e);
241 Response response = Response.status(
242 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
243 throw new WebApplicationException(response);
245 return collectionObjectList;
249 * Update collection object.
251 * @param csid the csid
252 * @param theUpdate the the update
254 * @return the multipart output
258 public MultipartOutput updateCollectionObject(
259 @PathParam("csid") String csid,
260 MultipartInput theUpdate) {
261 if (logger.isDebugEnabled()) {
262 logger.debug("updateCollectionObject with csid=" + csid);
264 if (csid == null || "".equals(csid)) {
265 logger.error("updateCollectionObject: missing csid!");
266 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
267 "update failed on CollectionObject csid=" + csid).type(
268 "text/plain").build();
269 throw new WebApplicationException(response);
271 MultipartOutput result = null;
273 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(theUpdate, getServiceName());
274 DocumentHandler handler = createDocumentHandler(ctx);
275 getRepositoryClient(ctx).update(ctx, csid, handler);
276 result = (MultipartOutput) ctx.getOutput();
277 } catch (BadRequestException bre) {
278 Response response = Response.status(
279 Response.Status.BAD_REQUEST).entity("Update failed reason " + bre.getErrorReason()).type("text/plain").build();
280 throw new WebApplicationException(response);
281 } catch (UnauthorizedException ue) {
282 Response response = Response.status(
283 Response.Status.UNAUTHORIZED).entity("Update failed reason " + ue.getErrorReason()).type("text/plain").build();
284 throw new WebApplicationException(response);
285 } catch (DocumentNotFoundException dnfe) {
286 if (logger.isDebugEnabled()) {
287 logger.debug("caugth exception in updateCollectionObject", dnfe);
289 Response response = Response.status(Response.Status.NOT_FOUND).entity(
290 "Update failed on CollectionObject csid=" + csid).type(
291 "text/plain").build();
292 throw new WebApplicationException(response);
293 } catch (Exception e) {
294 Response response = Response.status(
295 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
296 throw new WebApplicationException(response);
302 * Delete collection object.
304 * @param csid the csid
306 * @return the response
310 public Response deleteCollectionObject(@PathParam("csid") String csid) {
312 if (logger.isDebugEnabled()) {
313 logger.debug("deleteCollectionObject with csid=" + csid);
315 if (csid == null || "".equals(csid)) {
316 logger.error("deleteCollectionObject: missing csid!");
317 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
318 "delete failed on CollectionObject csid=" + csid).type(
319 "text/plain").build();
320 throw new WebApplicationException(response);
323 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
324 getRepositoryClient(ctx).delete(ctx, csid);
325 return Response.status(HttpResponseCodes.SC_OK).build();
326 } catch (UnauthorizedException ue) {
327 Response response = Response.status(
328 Response.Status.UNAUTHORIZED).entity("Delete failed reason " + ue.getErrorReason()).type("text/plain").build();
329 throw new WebApplicationException(response);
330 } catch (DocumentNotFoundException dnfe) {
331 if (logger.isDebugEnabled()) {
332 logger.debug("caught exception in deleteCollectionObject", dnfe);
334 Response response = Response.status(Response.Status.NOT_FOUND).entity(
335 "Delete failed on CollectionObject csid=" + csid).type(
336 "text/plain").build();
337 throw new WebApplicationException(response);
338 } catch (Exception e) {
339 Response response = Response.status(
340 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
341 throw new WebApplicationException(response);
347 * Gets the intakes common list.
350 * @param csid the csid
352 * @return the intakes common list
355 @Path("{csid}/intakes")
356 @Produces("application/xml")
357 public IntakesCommonList getIntakesCommonList(@Context UriInfo ui,
358 @PathParam("csid") String csid) {
359 IntakesCommonList result = null;
363 // Find all the intake-related relation records.
365 String subjectCsid = csid;
366 String predicate = RelationshipType.COLLECTIONOBJECT_INTAKE.value();
367 String objectCsid = null;
368 NewRelationResource relationResource = new NewRelationResource();
369 RelationsCommonList relationsCommonList = relationResource.getRelationList(subjectCsid, predicate, objectCsid);
372 // Create an array of Intake csid's
374 List<RelationsCommonList.RelationListItem> relationsListItems = relationsCommonList.getRelationListItem();
375 List<String> intakeCsidList = new ArrayList<String>();
376 for (RelationsCommonList.RelationListItem relationsListItem : relationsListItems) {
377 intakeCsidList.add(relationsListItem.getObjectCsid());
381 // Get a response list for the Intake records from the Intake resource
383 IntakeResource intakeResource = new IntakeResource();
384 result = intakeResource.getIntakeList(intakeCsidList);
385 } catch (Exception e) {
386 if (logger.isDebugEnabled()) {
387 logger.debug("Caught exception in getIntakeList", e);
389 Response response = Response.status(
390 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
391 throw new WebApplicationException(response);
400 * This is an intentionally empty method used for getting a rough time estimate
401 * of the overhead required for a client->server request/response cycle.
403 * @return the response
407 @Produces("application/xml")
408 public Response roundtrip() {
409 Response result = null;
411 if (logger.isDebugEnabled()) {
412 logger.debug("------------------------------------------------------------------------------");
413 logger.debug("Client to server roundtrip called.");
414 logger.debug("------------------------------------------------------------------------------");
417 result = Response.status(HttpResponseCodes.SC_OK).build();
423 //FIXME: Replace this "search" resource with a keyword "kw" query parameter
425 * Keywords search collection objects.
427 * @param keywords the keywords
429 * @return the collectionobjects common list
433 @Produces("application/xml")
434 public CollectionobjectsCommonList keywordsSearchCollectionObjects(
435 @QueryParam(IQueryManager.SEARCH_TYPE_KEYWORDS) String keywords) {
436 CollectionobjectsCommonList collectionObjectList = new CollectionobjectsCommonList();
438 ServiceContext ctx = MultipartServiceContextFactory.get().createServiceContext(null, getServiceName());
439 DocumentHandler handler = createDocumentHandler(ctx);
441 // perform a keyword search
442 if (keywords != null && !keywords.isEmpty()) {
443 String whereClause = QueryManager.createWhereClauseFromKeywords(keywords);
444 DocumentFilter documentFilter = handler.getDocumentFilter();
445 documentFilter.setWhereClause(whereClause);
446 if (logger.isDebugEnabled()) {
447 logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
449 getRepositoryClient(ctx).getFiltered(ctx, handler);
451 getRepositoryClient(ctx).getAll(ctx, handler);
453 collectionObjectList = (CollectionobjectsCommonList) handler.getCommonPartList();
455 } catch (UnauthorizedException ue) {
456 Response response = Response.status(
457 Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();
458 throw new WebApplicationException(response);
459 } catch (Exception e) {
460 if (logger.isDebugEnabled()) {
461 logger.debug("Caught exception in getCollectionObjectList", e);
463 Response response = Response.status(
464 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
465 throw new WebApplicationException(response);
467 return collectionObjectList;