]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a210df869ff2d82b5f0623a960fbfdb765b885c3
[tmp/jakarta-migration.git] /
1 /**
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:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
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.
23  */
24 package org.collectionspace.services.vocabulary;
25
26 import java.util.List;
27 import java.util.Map;
28
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;
44
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.repository.DocumentFilter;
51 import org.collectionspace.services.common.repository.DocumentHandler;
52 import org.collectionspace.services.common.repository.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.nuxeo.ecm.core.api.repository.RepositoryInstance;
60 import org.nuxeo.ecm.core.client.NuxeoClient;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 @Path("/vocabularies")
65 @Consumes("multipart/mixed")
66 @Produces("multipart/mixed")
67 public class VocabularyResource extends AbstractCollectionSpaceResource {
68
69     private final static String vocabularyServiceName = "vocabularies";
70     private final static String vocabularyItemServiceName = "vocabularyitems";
71     final Logger logger = LoggerFactory.getLogger(VocabularyResource.class);
72     //FIXME retrieve client type from configuration
73     final static ClientType CLIENT_TYPE = ServiceMain.getInstance().getClientType();
74
75     public VocabularyResource() {
76         // do nothing
77     }
78
79     @Override
80     public String getServiceName() {
81         return vocabularyServiceName;
82     }
83
84     public String getItemServiceName() {
85         return vocabularyItemServiceName;
86     }
87
88     /*
89     public RemoteServiceContext createItemServiceContext(MultipartInput input) throws Exception {
90         RemoteServiceContext ctx = new RemoteServiceContextImpl(getItemServiceName());
91         ctx.setInput(input);
92         return ctx;
93     }
94     */
95
96     @Override
97     public DocumentHandler createDocumentHandler(RemoteServiceContext ctx) throws Exception {
98         DocumentHandler docHandler = VocabularyHandlerFactory.getInstance().getHandler(
99                 ctx.getRepositoryClientType().toString());
100         docHandler.setServiceContext(ctx);
101         if(ctx.getInput() != null){
102             Object obj = ctx.getInputPart(ctx.getCommonPartLabel(), VocabulariesCommon.class);
103             if(obj != null){
104                 docHandler.setCommonPart((VocabulariesCommon) obj);
105             }
106         }
107         return docHandler;
108     }
109
110     private DocumentHandler createItemDocumentHandler(
111                 RemoteServiceContext ctx,
112                 String inVocabulary) throws Exception {
113         DocumentHandler docHandler = VocabularyItemHandlerFactory.getInstance().getHandler(
114                 ctx.getRepositoryClientType().toString());
115         docHandler.setServiceContext(ctx);
116         ((VocabularyItemDocumentModelHandler)docHandler).setInVocabulary(inVocabulary);
117         if(ctx.getInput() != null){
118             Object obj = ctx.getInputPart(ctx.getCommonPartLabel(getItemServiceName()),
119                                                                                                 VocabularyitemsCommon.class);
120             if(obj != null){
121                 docHandler.setCommonPart((VocabularyitemsCommon) obj);
122             }
123         }
124         return docHandler;
125     }
126
127     @POST
128     public Response createVocabulary(MultipartInput input) {
129         try{
130             RemoteServiceContext ctx = createServiceContext(input);
131             DocumentHandler handler = createDocumentHandler(ctx);
132             String csid = getRepositoryClient(ctx).create(ctx, handler);
133             //vocabularyObject.setCsid(csid);
134             UriBuilder path = UriBuilder.fromResource(VocabularyResource.class);
135             path.path("" + csid);
136             Response response = Response.created(path.build()).build();
137             return response;
138         }catch(Exception e){
139             if(logger.isDebugEnabled()){
140                 logger.debug("Caught exception in createVocabulary", e);
141             }
142             Response response = Response.status(
143                     Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
144             throw new WebApplicationException(response);
145         }
146     }
147
148     @GET
149     @Path("{csid}")
150     public MultipartOutput getVocabulary(@PathParam("csid") String csid) {
151         String idValue = null;
152         if(csid == null){
153             logger.error("getVocabulary: missing csid!");
154             Response response = Response.status(Response.Status.BAD_REQUEST).entity(
155                     "get failed on Vocabulary csid=" + csid).type(
156                     "text/plain").build();
157             throw new WebApplicationException(response);
158         }
159         if(logger.isDebugEnabled()){
160             logger.debug("getVocabulary with path(id)=" + csid);
161         }
162         MultipartOutput result = null;
163         try{
164             RemoteServiceContext ctx = createServiceContext(null);
165             DocumentHandler handler = createDocumentHandler(ctx);
166                 getRepositoryClient(ctx).get(ctx, csid, handler);
167             result = ctx.getOutput();
168         }catch(DocumentNotFoundException dnfe){
169             if(logger.isDebugEnabled()){
170                 logger.debug("getVocabulary", dnfe);
171             }
172             Response response = Response.status(Response.Status.NOT_FOUND).entity(
173                     "Get failed on Vocabulary csid=" + csid).type(
174                     "text/plain").build();
175             throw new WebApplicationException(response);
176         }catch(Exception e){
177             if(logger.isDebugEnabled()){
178                 logger.debug("getVocabulary", e);
179             }
180             Response response = Response.status(
181                     Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
182             throw new WebApplicationException(response);
183         }
184         if(result == null){
185             Response response = Response.status(Response.Status.NOT_FOUND).entity(
186                     "Get failed, the requested Vocabulary CSID:" + csid + ": was not found.").type(
187                     "text/plain").build();
188             throw new WebApplicationException(response);
189         }
190         return result;
191     }
192
193     @GET
194     @Produces("application/xml")
195     public VocabulariesCommonList getVocabularyList(@Context UriInfo ui) {
196         VocabulariesCommonList vocabularyObjectList = new VocabulariesCommonList();
197         try{
198             RemoteServiceContext ctx = createServiceContext(null);
199             DocumentHandler handler = createDocumentHandler(ctx);
200             MultivaluedMap<String,String> queryParams = ui.getQueryParameters(); 
201             if(queryParams.size()>0) {
202                 String nameQ = queryParams.getFirst("name");
203                 if(nameQ!= null) {
204                     DocumentFilter myFilter = new DocumentFilter(
205                                  "vocabularies_common:refName='"+nameQ+"'", 0, 0);
206                     handler.setDocumentFilter(myFilter);
207                 }
208             }
209             getRepositoryClient(ctx).getFiltered(ctx, handler);
210             vocabularyObjectList = (VocabulariesCommonList) handler.getCommonPartList();
211         }catch(Exception e){
212             if(logger.isDebugEnabled()){
213                 logger.debug("Caught exception in getVocabularyList", e);
214             }
215             Response response = Response.status(
216                     Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
217             throw new WebApplicationException(response);
218         }
219         return vocabularyObjectList;
220     }
221
222     @PUT
223     @Path("{csid}")
224     public MultipartOutput updateVocabulary(
225             @PathParam("csid") String csid,
226             MultipartInput theUpdate) {
227         if(logger.isDebugEnabled()){
228             logger.debug("updateVocabulary with csid=" + csid);
229         }
230         if(csid == null || "".equals(csid)){
231             logger.error("updateVocabulary: missing csid!");
232             Response response = Response.status(Response.Status.BAD_REQUEST).entity(
233                     "update failed on Vocabulary csid=" + csid).type(
234                     "text/plain").build();
235             throw new WebApplicationException(response);
236         }
237         MultipartOutput result = null;
238         try{
239             RemoteServiceContext ctx = createServiceContext(theUpdate);
240             DocumentHandler handler = createDocumentHandler(ctx);
241             getRepositoryClient(ctx).update(ctx, csid, handler);
242             result = ctx.getOutput();
243         }catch(DocumentNotFoundException dnfe){
244             if(logger.isDebugEnabled()){
245                 logger.debug("caugth exception in updateVocabulary", dnfe);
246             }
247             Response response = Response.status(Response.Status.NOT_FOUND).entity(
248                     "Update failed on Vocabulary csid=" + csid).type(
249                     "text/plain").build();
250             throw new WebApplicationException(response);
251         }catch(Exception e){
252             Response response = Response.status(
253                     Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
254             throw new WebApplicationException(response);
255         }
256         return result;
257     }
258
259     @DELETE
260     @Path("{csid}")
261     public Response deleteVocabulary(@PathParam("csid") String csid) {
262
263         if(logger.isDebugEnabled()){
264             logger.debug("deleteVocabulary with csid=" + csid);
265         }
266         if(csid == null || "".equals(csid)){
267             logger.error("deleteVocabulary: missing csid!");
268             Response response = Response.status(Response.Status.BAD_REQUEST).entity(
269                     "delete failed on Vocabulary csid=" + csid).type(
270                     "text/plain").build();
271             throw new WebApplicationException(response);
272         }
273         try{
274             ServiceContext ctx = createServiceContext(null);
275             getRepositoryClient(ctx).delete(ctx, csid);
276             return Response.status(HttpResponseCodes.SC_OK).build();
277         }catch(DocumentNotFoundException dnfe){
278             if(logger.isDebugEnabled()){
279                 logger.debug("caught exception in deleteVocabulary", dnfe);
280             }
281             Response response = Response.status(Response.Status.NOT_FOUND).entity(
282                     "Delete failed on Vocabulary csid=" + csid).type(
283                     "text/plain").build();
284             throw new WebApplicationException(response);
285         }catch(Exception e){
286             Response response = Response.status(
287                     Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
288             throw new WebApplicationException(response);
289         }
290
291     }
292
293     /*************************************************************************
294      * VocabularyItem parts - this is a sub-resource of Vocabulary
295      *************************************************************************/
296
297      @POST
298      @Path("{csid}/items")
299      public Response createVocabularyItem(@PathParam("csid") String parentcsid, MultipartInput input) {
300          try{
301              RemoteServiceContext ctx = createServiceContext(input, getItemServiceName());
302              DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
303              String itemcsid = getRepositoryClient(ctx).create(ctx, handler);
304              UriBuilder path = UriBuilder.fromResource(VocabularyResource.class);
305              path.path(parentcsid + "/items/" + itemcsid);
306              Response response = Response.created(path.build()).build();
307              return response;
308          }catch(Exception e){
309              if(logger.isDebugEnabled()){
310                  logger.debug("Caught exception in createVocabularyItem", e);
311              }
312              Response response = Response.status(
313                      Response.Status.INTERNAL_SERVER_ERROR).entity("Create failed").type("text/plain").build();
314              throw new WebApplicationException(response);
315          }
316      }
317
318      @GET
319      @Path("{csid}/items/{itemcsid}")
320      public MultipartOutput getVocabularyItem(
321                  @PathParam("csid") String parentcsid,
322              @PathParam("itemcsid") String itemcsid) {
323          if(logger.isDebugEnabled()){
324              logger.debug("getVocabularyItem with parentcsid=" 
325                          + parentcsid + " and itemcsid=" + itemcsid);
326          }
327          if(parentcsid == null || "".equals(parentcsid)){
328              logger.error("getVocabularyItem: missing csid!");
329              Response response = Response.status(Response.Status.BAD_REQUEST).entity(
330                      "get failed on VocabularyItem csid=" + parentcsid).type(
331                      "text/plain").build();
332              throw new WebApplicationException(response);
333          }
334          if(itemcsid == null || "".equals(itemcsid)){
335              logger.error("getVocabularyItem: missing itemcsid!");
336              Response response = Response.status(Response.Status.BAD_REQUEST).entity(
337                      "get failed on VocabularyItem itemcsid=" + itemcsid).type(
338                      "text/plain").build();
339              throw new WebApplicationException(response);
340          }
341          MultipartOutput result = null;
342          try{
343                  // Note that we have to create the service context for the Items, not the main service 
344              RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
345              DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
346              getRepositoryClient(ctx).get(ctx, itemcsid, handler);
347              // TODO should we assert that the item is in the passed vocab?
348              result = ctx.getOutput();
349          }catch(DocumentNotFoundException dnfe){
350              if(logger.isDebugEnabled()){
351                  logger.debug("getVocabularyItem", dnfe);
352              }
353              Response response = Response.status(Response.Status.NOT_FOUND).entity(
354                      "Get failed on VocabularyItem csid=" + itemcsid).type(
355                      "text/plain").build();
356              throw new WebApplicationException(response);
357          }catch(Exception e){
358              if(logger.isDebugEnabled()){
359                  logger.debug("getVocabularyItem", e);
360              }
361              Response response = Response.status(
362                      Response.Status.INTERNAL_SERVER_ERROR).entity("Get failed").type("text/plain").build();
363              throw new WebApplicationException(response);
364          }
365          if(result == null){
366              Response response = Response.status(Response.Status.NOT_FOUND).entity(
367                      "Get failed, the requested VocabularyItem CSID:" + itemcsid + ": was not found.").type(
368                      "text/plain").build();
369              throw new WebApplicationException(response);
370          }
371          return result;
372      }
373
374      @GET
375      @Path("{csid}/items")
376      @Produces("application/xml")
377      public VocabularyitemsCommonList getVocabularyItemList(
378                  @PathParam("csid") String parentcsid,
379                  @Context UriInfo ui) {
380          VocabularyitemsCommonList vocabularyItemObjectList = new VocabularyitemsCommonList();
381          RepositoryInstance repoSession = null;
382          NuxeoClient client = null;
383          try{
384                  // Note that docType defaults to the ServiceName, so we're fine with that.
385              RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
386              DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
387              /*
388              // Note that we replace the getAll() call with a basic search on the parent vocab
389              handler.prepare(Action.GET_ALL);
390                  client = NuxeoConnector.getInstance().getClient();
391              repoSession = client.openRepository();
392              if (logger.isDebugEnabled()) {
393                  logger.debug("getVocabularyItemList() repository root: " + repoSession.getRootDocument());
394              }
395              DocumentModelList docList = 
396                  repoSession.query("SELECT * FROM Vocabularyitem WHERE vocabularyitems_common:inVocabulary='"
397                                                         +parentcsid+"'");
398              //set repoSession to handle the document
399              ((DocumentModelHandler) handler).setRepositorySession(repoSession);
400              DocumentModelListWrapper wrapDoc = new DocumentModelListWrapper(
401                      docList);
402              handler.handle(Action.GET_ALL, wrapDoc);
403              handler.complete(Action.GET_ALL, wrapDoc);
404              */
405              DocumentFilter myFilter = new DocumentFilter(
406                          "vocabularyitems_common:inVocabulary='"+parentcsid+"'", 0, 0);
407              handler.setDocumentFilter(myFilter);
408              getRepositoryClient(ctx).getFiltered(ctx, handler);
409              vocabularyItemObjectList = (VocabularyitemsCommonList) handler.getCommonPartList();
410          }catch(Exception e){
411              if(logger.isDebugEnabled()){
412                  logger.debug("Caught exception in getVocabularyItemList", e);
413              }
414              Response response = Response.status(
415                      Response.Status.INTERNAL_SERVER_ERROR).entity("Index failed").type("text/plain").build();
416              throw new WebApplicationException(response);
417          } finally {
418              if(repoSession != null) {
419                      try {
420                          // release session
421                          client.releaseRepository(repoSession);
422                      } catch (Exception e) {
423                          logger.error("Could not close the repository session", e);
424                          // no need to throw this service specific exception
425                      }
426              }
427          }
428          return vocabularyItemObjectList;
429      }
430
431      @PUT
432      @Path("{csid}/items/{itemcsid}")
433      public MultipartOutput updateVocabularyItem(
434                  @PathParam("csid") String parentcsid,
435              @PathParam("itemcsid") String itemcsid,
436              MultipartInput theUpdate) {
437          if(logger.isDebugEnabled()){
438              logger.debug("updateVocabularyItem with parentcsid=" + parentcsid + " and itemcsid=" + itemcsid);
439          }
440          if(parentcsid == null || "".equals(parentcsid)){
441              logger.error("updateVocabularyItem: missing csid!");
442              Response response = Response.status(Response.Status.BAD_REQUEST).entity(
443                      "update failed on VocabularyItem parentcsid=" + parentcsid).type(
444                      "text/plain").build();
445              throw new WebApplicationException(response);
446          }
447          if(itemcsid == null || "".equals(itemcsid)){
448              logger.error("updateVocabularyItem: missing itemcsid!");
449              Response response = Response.status(Response.Status.BAD_REQUEST).entity(
450                      "update failed on VocabularyItem=" + itemcsid).type(
451                      "text/plain").build();
452              throw new WebApplicationException(response);
453          }
454          MultipartOutput result = null;
455          try{
456                  // Note that we have to create the service context for the Items, not the main service 
457              RemoteServiceContext ctx = createServiceContext(theUpdate, getItemServiceName());
458              DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid);
459              getRepositoryClient(ctx).update(ctx, itemcsid, handler);
460              result = ctx.getOutput();
461          }catch(DocumentNotFoundException dnfe){
462              if(logger.isDebugEnabled()){
463                  logger.debug("caugth exception in updateVocabularyItem", dnfe);
464              }
465              Response response = Response.status(Response.Status.NOT_FOUND).entity(
466                      "Update failed on VocabularyItem csid=" + itemcsid).type(
467                      "text/plain").build();
468              throw new WebApplicationException(response);
469          }catch(Exception e){
470              Response response = Response.status(
471                      Response.Status.INTERNAL_SERVER_ERROR).entity("Update failed").type("text/plain").build();
472              throw new WebApplicationException(response);
473          }
474          return result;
475      }
476
477      @DELETE
478      @Path("{csid}/items/{itemcsid}")
479      public Response deleteVocabularyItem(
480                  @PathParam("csid") String parentcsid,
481          @PathParam("itemcsid") String itemcsid) {
482          if(logger.isDebugEnabled()){
483              logger.debug("deleteVocabularyItem with parentcsid=" + parentcsid + " and itemcsid=" + itemcsid);
484          }
485          if(parentcsid == null || "".equals(parentcsid)){
486              logger.error("deleteVocabularyItem: missing csid!");
487              Response response = Response.status(Response.Status.BAD_REQUEST).entity(
488                      "delete failed on VocabularyItem parentcsid=" + parentcsid).type(
489                      "text/plain").build();
490              throw new WebApplicationException(response);
491          }
492          if(itemcsid == null || "".equals(itemcsid)){
493              logger.error("deleteVocabularyItem: missing itemcsid!");
494              Response response = Response.status(Response.Status.BAD_REQUEST).entity(
495                      "delete failed on VocabularyItem=" + itemcsid).type(
496                      "text/plain").build();
497              throw new WebApplicationException(response);
498          }
499          try{
500                  // Note that we have to create the service context for the Items, not the main service 
501              RemoteServiceContext ctx = createServiceContext(null, getItemServiceName());
502              getRepositoryClient(ctx).delete(ctx, itemcsid);
503              return Response.status(HttpResponseCodes.SC_OK).build();
504          }catch(DocumentNotFoundException dnfe){
505              if(logger.isDebugEnabled()){
506                  logger.debug("caught exception in deleteVocabulary", dnfe);
507              }
508              Response response = Response.status(Response.Status.NOT_FOUND).entity(
509                      "Delete failed on VocabularyItem itemcsid=" + itemcsid).type(
510                      "text/plain").build();
511              throw new WebApplicationException(response);
512          }catch(Exception e){
513              Response response = Response.status(
514                      Response.Status.INTERNAL_SERVER_ERROR).entity("Delete failed").type("text/plain").build();
515              throw new WebApplicationException(response);
516          }
517
518      }
519 }