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 package org.collectionspace.services.vocabulary;
26 import java.util.List;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.QueryParam;
38 import javax.ws.rs.WebApplicationException;
39 import javax.ws.rs.core.Context;
40 import javax.ws.rs.core.MultivaluedMap;
41 import javax.ws.rs.core.Response;
42 import javax.ws.rs.core.UriBuilder;
43 import javax.ws.rs.core.UriInfo;
45 import org.collectionspace.services.common.AbstractCollectionSpaceResource;
46 import org.collectionspace.services.common.ClientType;
47 import org.collectionspace.services.common.ServiceMain;
48 import org.collectionspace.services.common.context.RemoteServiceContext;
49 import org.collectionspace.services.common.context.ServiceContext;
50 import org.collectionspace.services.common.document.DocumentFilter;
51 import org.collectionspace.services.common.document.DocumentHandler;
52 import org.collectionspace.services.common.document.DocumentNotFoundException;
53 import org.collectionspace.services.vocabulary.nuxeo.VocabularyHandlerFactory;
54 import org.collectionspace.services.vocabulary.nuxeo.VocabularyItemDocumentModelHandler;
55 import org.collectionspace.services.vocabulary.nuxeo.VocabularyItemHandlerFactory;
56 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
57 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
58 import org.jboss.resteasy.util.HttpResponseCodes;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 @Path("/vocabularies")
63 @Consumes("multipart/mixed")
64 @Produces("multipart/mixed")
65 public class VocabularyResource extends AbstractCollectionSpaceResource {
67 private final static String vocabularyServiceName = "vocabularies";
68 private final static String vocabularyItemServiceName = "vocabularyitems";
69 final Logger logger = LoggerFactory.getLogger(VocabularyResource.class);
70 //FIXME retrieve client type from configuration
71 final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
73 public VocabularyResource() {
78 public String getServiceName() {
79 return vocabularyServiceName;
82 public String getItemServiceName() {
83 return vocabularyItemServiceName;
87 public RemoteServiceContext createItemServiceContext(MultipartInput input) throws Exception {
88 RemoteServiceContext ctx = new RemoteServiceContextImpl(getItemServiceName());
95 public DocumentHandler createDocumentHandler(RemoteServiceContext ctx) throws Exception {
96 DocumentHandler docHandler = VocabularyHandlerFactory.getInstance().getHandler(
97 ctx.getRepositoryClientType().toString());
98 docHandler.setServiceContext(ctx);
99 if(ctx.getInput() != null){
100 Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), VocabulariesCommon.class);
102 docHandler.setCommonPart((VocabulariesCommon) obj);
108 private DocumentHandler createItemDocumentHandler(
109 RemoteServiceContext ctx,
110 String inVocabulary) throws Exception {
111 DocumentHandler docHandler = VocabularyItemHandlerFactory.getInstance().getHandler(
112 ctx.getRepositoryClientType().toString());
113 docHandler.setServiceContext(ctx);
114 ((VocabularyItemDocumentModelHandler)docHandler).setInVocabulary(inVocabulary);
115 if(ctx.getInput() != null){
116 Object obj = ctx.getInputPart(ctx.getCommonPartLabel(getItemServiceName()),
117 VocabularyitemsCommon.class);
119 docHandler.setCommonPart((VocabularyitemsCommon) obj);
126 public Response createVocabulary(MultipartInput input) {
128 RemoteServiceContext ctx = createServiceContext(input);
129 DocumentHandler handler = createDocumentHandler(ctx);
130 String csid = getRepositoryClient(ctx).create(ctx, handler);
131 //vocabularyObject.setCsid(csid);
132 UriBuilder path = UriBuilder.fromResource(VocabularyResource.class);
133 path.path("" + csid);
134 Response response = Response.created(path.build()).build();
137 if(logger.isDebugEnabled()){
138 logger.debug("Caught exception in createVocabulary", e);
140 Response response = Response.status(
141 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
142 throw new WebApplicationException(response);
148 public MultipartOutput getVocabulary(@PathParam("csid") String csid) {
149 String idValue = null;
151 logger.error("getVocabulary: missing csid!");
152 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
153 "get failed on Vocabulary csid=" + csid).type(
154 "text/plain").build();
155 throw new WebApplicationException(response);
157 if(logger.isDebugEnabled()){
158 logger.debug("getVocabulary with path(id)=" + csid);
160 MultipartOutput result = null;
162 RemoteServiceContext ctx = createServiceContext(null);
163 DocumentHandler handler = createDocumentHandler(ctx);
164 getRepositoryClient(ctx).get(ctx, csid, handler);
165 result = ctx.getOutput();
166 }catch(DocumentNotFoundException dnfe){
167 if(logger.isDebugEnabled()){
168 logger.debug("getVocabulary", dnfe);
170 Response response = Response.status(Response.Status.NOT_FOUND).entity(
171 "Get failed on Vocabulary csid=" + csid).type(
172 "text/plain").build();
173 throw new WebApplicationException(response);
175 if(logger.isDebugEnabled()){
176 logger.debug("getVocabulary", e);
178 Response response = Response.status(
179 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
180 throw new WebApplicationException(response);
183 Response response = Response.status(Response.Status.NOT_FOUND).entity(
184 "Get failed, the requested Vocabulary CSID:" + csid + ": was not found.").type(
185 "text/plain").build();
186 throw new WebApplicationException(response);
192 @Produces("application/xml")
193 public VocabulariesCommonList getVocabularyList(@Context UriInfo ui) {
194 VocabulariesCommonList vocabularyObjectList = new VocabulariesCommonList();
196 RemoteServiceContext ctx = createServiceContext(null);
197 MultivaluedMap<String,String> queryParams = ui.getQueryParameters();
198 DocumentHandler handler = createDocumentHandler(ctx);
199 DocumentFilter myFilter =
200 DocumentFilter.CreatePaginatedDocumentFilter(queryParams);
201 String nameQ = queryParams.getFirst("name");
203 myFilter.setWhereClause("vocabularies_common:refName='"+nameQ+"'");
205 handler.setDocumentFilter(myFilter);
206 getRepositoryClient(ctx).getFiltered(ctx, handler);
207 vocabularyObjectList = (VocabulariesCommonList) handler.getCommonPartList();
209 if(logger.isDebugEnabled()){
210 logger.debug("Caught exception in getVocabularyList", e);
212 Response response = Response.status(
213 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
214 throw new WebApplicationException(response);
216 return vocabularyObjectList;
221 public MultipartOutput updateVocabulary(
222 @PathParam("csid") String csid,
223 MultipartInput theUpdate) {
224 if(logger.isDebugEnabled()){
225 logger.debug("updateVocabulary with csid=" + csid);
227 if(csid == null || "".equals(csid)){
228 logger.error("updateVocabulary: missing csid!");
229 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
230 "update failed on Vocabulary csid=" + csid).type(
231 "text/plain").build();
232 throw new WebApplicationException(response);
234 MultipartOutput result = null;
236 RemoteServiceContext ctx = createServiceContext(theUpdate);
237 DocumentHandler handler = createDocumentHandler(ctx);
238 getRepositoryClient(ctx).update(ctx, csid, handler);
239 result = ctx.getOutput();
240 }catch(DocumentNotFoundException dnfe){
241 if(logger.isDebugEnabled()){
242 logger.debug("caugth exception in updateVocabulary", dnfe);
244 Response response = Response.status(Response.Status.NOT_FOUND).entity(
245 "Update failed on Vocabulary csid=" + csid).type(
246 "text/plain").build();
247 throw new WebApplicationException(response);
249 Response response = Response.status(
250 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
251 throw new WebApplicationException(response);
258 public Response deleteVocabulary(@PathParam("csid") String csid) {
260 if(logger.isDebugEnabled()){
261 logger.debug("deleteVocabulary with csid=" + csid);
263 if(csid == null || "".equals(csid)){
264 logger.error("deleteVocabulary: missing csid!");
265 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
266 "delete failed on Vocabulary csid=" + csid).type(
267 "text/plain").build();
268 throw new WebApplicationException(response);
271 ServiceContext ctx = createServiceContext(null);
272 getRepositoryClient(ctx).delete(ctx, csid);
273 return Response.status(HttpResponseCodes.SC_OK).build();
274 }catch(DocumentNotFoundException dnfe){
275 if(logger.isDebugEnabled()){
276 logger.debug("caught exception in deleteVocabulary", dnfe);
278 Response response = Response.status(Response.Status.NOT_FOUND).entity(
279 "Delete failed on Vocabulary csid=" + csid).type(
280 "text/plain").build();
281 throw new WebApplicationException(response);
283 Response response = Response.status(
284 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
285 throw new WebApplicationException(response);
290 /*************************************************************************
291 * VocabularyItem parts - this is a sub-resource of Vocabulary
292 *************************************************************************/
295 @Path("{csid}/items")
296 public Response createVocabularyItem(@PathParam("csid") String parentcsid, MultipartInput input) {
298 RemoteServiceContext ctx = createServiceContext(input, getItemServiceName());
299 DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
300 String itemcsid = getRepositoryClient(ctx).create(ctx, handler);
301 UriBuilder path = UriBuilder.fromResource(VocabularyResource.class);
302 path.path(parentcsid + "/items/" + itemcsid);
303 Response response = Response.created(path.build()).build();
306 if(logger.isDebugEnabled()){
307 logger.debug("Caught exception in createVocabularyItem", e);
309 Response response = Response.status(
310 Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
311 throw new WebApplicationException(response);
316 @Path("{csid}/items/{itemcsid}")
317 public MultipartOutput getVocabularyItem(
318 @PathParam("csid") String parentcsid,
319 @PathParam("itemcsid") String itemcsid) {
320 if(logger.isDebugEnabled()){
321 logger.debug("getVocabularyItem with parentcsid="
322 + parentcsid + " and itemcsid=" + itemcsid);
324 if(parentcsid == null || "".equals(parentcsid)){
325 logger.error("getVocabularyItem: missing csid!");
326 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
327 "get failed on VocabularyItem csid=" + parentcsid).type(
328 "text/plain").build();
329 throw new WebApplicationException(response);
331 if(itemcsid == null || "".equals(itemcsid)){
332 logger.error("getVocabularyItem: missing itemcsid!");
333 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
334 "get failed on VocabularyItem itemcsid=" + itemcsid).type(
335 "text/plain").build();
336 throw new WebApplicationException(response);
338 MultipartOutput result = null;
340 // Note that we have to create the service context for the Items, not the main service
341 RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
342 DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
343 getRepositoryClient(ctx).get(ctx, itemcsid, handler);
344 // TODO should we assert that the item is in the passed vocab?
345 result = ctx.getOutput();
346 }catch(DocumentNotFoundException dnfe){
347 if(logger.isDebugEnabled()){
348 logger.debug("getVocabularyItem", dnfe);
350 Response response = Response.status(Response.Status.NOT_FOUND).entity(
351 "Get failed on VocabularyItem csid=" + itemcsid).type(
352 "text/plain").build();
353 throw new WebApplicationException(response);
355 if(logger.isDebugEnabled()){
356 logger.debug("getVocabularyItem", e);
358 Response response = Response.status(
359 Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
360 throw new WebApplicationException(response);
363 Response response = Response.status(Response.Status.NOT_FOUND).entity(
364 "Get failed, the requested VocabularyItem CSID:" + itemcsid + ": was not found.").type(
365 "text/plain").build();
366 throw new WebApplicationException(response);
372 @Path("{csid}/items")
373 @Produces("application/xml")
374 public VocabularyitemsCommonList getVocabularyItemList(
375 @PathParam("csid") String parentcsid,
376 @Context UriInfo ui) {
377 VocabularyitemsCommonList vocabularyItemObjectList = new VocabularyitemsCommonList();
379 // Note that docType defaults to the ServiceName, so we're fine with that.
380 RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
381 DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
382 DocumentFilter myFilter = new DocumentFilter(
383 "vocabularyitems_common:inVocabulary='"+parentcsid+"'", 0, 0);
384 handler.setDocumentFilter(myFilter);
385 getRepositoryClient(ctx).getFiltered(ctx, handler);
386 vocabularyItemObjectList = (VocabularyitemsCommonList) handler.getCommonPartList();
388 if(logger.isDebugEnabled()){
389 logger.debug("Caught exception in getVocabularyItemList", e);
391 Response response = Response.status(
392 Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
393 throw new WebApplicationException(response);
395 return vocabularyItemObjectList;
399 @Path("{csid}/items/{itemcsid}")
400 public MultipartOutput updateVocabularyItem(
401 @PathParam("csid") String parentcsid,
402 @PathParam("itemcsid") String itemcsid,
403 MultipartInput theUpdate) {
404 if(logger.isDebugEnabled()){
405 logger.debug("updateVocabularyItem with parentcsid=" + parentcsid + " and itemcsid=" + itemcsid);
407 if(parentcsid == null || "".equals(parentcsid)){
408 logger.error("updateVocabularyItem: missing csid!");
409 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
410 "update failed on VocabularyItem parentcsid=" + parentcsid).type(
411 "text/plain").build();
412 throw new WebApplicationException(response);
414 if(itemcsid == null || "".equals(itemcsid)){
415 logger.error("updateVocabularyItem: missing itemcsid!");
416 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
417 "update failed on VocabularyItem=" + itemcsid).type(
418 "text/plain").build();
419 throw new WebApplicationException(response);
421 MultipartOutput result = null;
423 // Note that we have to create the service context for the Items, not the main service
424 RemoteServiceContext ctx = createServiceContext(theUpdate, getItemServiceName());
425 DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
426 getRepositoryClient(ctx).update(ctx, itemcsid, handler);
427 result = ctx.getOutput();
428 }catch(DocumentNotFoundException dnfe){
429 if(logger.isDebugEnabled()){
430 logger.debug("caugth exception in updateVocabularyItem", dnfe);
432 Response response = Response.status(Response.Status.NOT_FOUND).entity(
433 "Update failed on VocabularyItem csid=" + itemcsid).type(
434 "text/plain").build();
435 throw new WebApplicationException(response);
437 Response response = Response.status(
438 Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
439 throw new WebApplicationException(response);
445 @Path("{csid}/items/{itemcsid}")
446 public Response deleteVocabularyItem(
447 @PathParam("csid") String parentcsid,
448 @PathParam("itemcsid") String itemcsid) {
449 if(logger.isDebugEnabled()){
450 logger.debug("deleteVocabularyItem with parentcsid=" + parentcsid + " and itemcsid=" + itemcsid);
452 if(parentcsid == null || "".equals(parentcsid)){
453 logger.error("deleteVocabularyItem: missing csid!");
454 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
455 "delete failed on VocabularyItem parentcsid=" + parentcsid).type(
456 "text/plain").build();
457 throw new WebApplicationException(response);
459 if(itemcsid == null || "".equals(itemcsid)){
460 logger.error("deleteVocabularyItem: missing itemcsid!");
461 Response response = Response.status(Response.Status.BAD_REQUEST).entity(
462 "delete failed on VocabularyItem=" + itemcsid).type(
463 "text/plain").build();
464 throw new WebApplicationException(response);
467 // Note that we have to create the service context for the Items, not the main service
468 RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
469 getRepositoryClient(ctx).delete(ctx, itemcsid);
470 return Response.status(HttpResponseCodes.SC_OK).build();
471 }catch(DocumentNotFoundException dnfe){
472 if(logger.isDebugEnabled()){
473 logger.debug("caught exception in deleteVocabulary", dnfe);
475 Response response = Response.status(Response.Status.NOT_FOUND).entity(
476 "Delete failed on VocabularyItem itemcsid=" + itemcsid).type(
477 "text/plain").build();
478 throw new WebApplicationException(response);
480 Response response = Response.status(
481 Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
482 throw new WebApplicationException(response);