]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
034535d643bf81e247c008e126576e8ef413b694
[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 org.collectionspace.services.client.IClientQueryParams;
27 import org.collectionspace.services.client.PayloadInputPart;
28 import org.collectionspace.services.client.PoxPayload;
29 import org.collectionspace.services.client.PoxPayloadIn;
30 import org.collectionspace.services.client.PoxPayloadOut;
31 import org.collectionspace.services.client.VocabularyClient;
32 import org.collectionspace.services.client.workflow.WorkflowClient;
33 import org.collectionspace.services.common.CSWebApplicationException;
34 import org.collectionspace.services.common.ResourceMap;
35 import org.collectionspace.services.common.ServiceMessages;
36 import org.collectionspace.services.common.UriInfoWrapper;
37 import org.collectionspace.services.common.api.Tools;
38 import org.collectionspace.services.common.context.ServiceBindingUtils;
39 import org.collectionspace.services.common.context.ServiceContext;
40 import org.collectionspace.services.common.document.DocumentException;
41 import org.collectionspace.services.common.document.DocumentHandler;
42 import org.collectionspace.services.common.document.JaxbUtils;
43 import org.collectionspace.services.common.repository.RepositoryClient;
44 import org.collectionspace.services.common.vocabulary.AuthorityResource;
45 import org.collectionspace.services.common.vocabulary.AuthorityServiceUtils;
46 import org.collectionspace.services.jaxb.AbstractCommonList;
47 import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
48 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
49 import org.collectionspace.services.nuxeo.client.java.NuxeoRepositoryClientImpl;
50 import org.collectionspace.services.vocabulary.nuxeo.VocabularyItemDocumentModelHandler;
51 import org.collectionspace.services.workflow.WorkflowCommon;
52 import org.nuxeo.ecm.core.api.DocumentModel;
53 import org.nuxeo.ecm.core.api.DocumentModelList;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56 import org.w3c.dom.Element;
57
58 import javax.ws.rs.GET;
59 import javax.ws.rs.POST;
60 import javax.ws.rs.Path;
61 import javax.ws.rs.PathParam;
62 import javax.ws.rs.core.Context;
63 import javax.ws.rs.core.MultivaluedMap;
64 import javax.ws.rs.core.Request;
65 import javax.ws.rs.core.Response;
66 import javax.ws.rs.core.UriBuilder;
67 import javax.ws.rs.core.UriInfo;
68
69 @Path("/" + VocabularyClient.SERVICE_PATH_COMPONENT)
70 public class VocabularyResource extends 
71         AuthorityResource<VocabulariesCommon, VocabularyItemDocumentModelHandler> {
72
73     private final static String vocabularyServiceName = VocabularyClient.SERVICE_PATH_COMPONENT;
74
75         private final static String VOCABULARIES_COMMON = "vocabularies_common";
76     
77     private final static String vocabularyItemServiceName = "vocabularyitems";
78         private final static String VOCABULARYITEMS_COMMON = "vocabularyitems_common";
79     
80     final Logger logger = LoggerFactory.getLogger(VocabularyResource.class);
81
82         public VocabularyResource() {
83                 super(VocabulariesCommon.class, VocabularyResource.class,
84                                 VOCABULARIES_COMMON, VOCABULARYITEMS_COMMON);
85         }
86
87     @Override
88         @POST
89     public Response createAuthority(
90                 @Context ResourceMap resourceMap,
91                 @Context UriInfo uriInfo,
92                 String xmlPayload) {
93         //
94         // Requests to create new authorities come in on new threads. Unfortunately, we need to synchronize those threads on this block because, as of 8/27/2015, we can't seem to get Nuxeo
95         // transaction code to deal with a database level UNIQUE constraint violations on the 'shortidentifier' column of the vocabularies_common table.
96         // Therefore, to prevent having multiple authorities with the same shortid, we need to synchronize
97         // the code that creates new authorities.  The authority document model handler will first check for authorities with the same short id before
98         // trying to create a new authority.
99         //
100         synchronized(AuthorityResource.class) {
101                 try {
102                     PoxPayloadIn input = new PoxPayloadIn(xmlPayload);
103                     ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(input);
104                                 RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient = this.getRepositoryClient(ctx);
105                                 
106                                 CoreSessionInterface repoSession = repoClient.getRepositorySession(ctx);
107                                 try {
108                             DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createDocumentHandler(ctx);                          
109                             String csid = repoClient.create(ctx, handler);
110                             handleItemsPayload(repoSession, csid, resourceMap, uriInfo, input);
111                             UriBuilder path = UriBuilder.fromResource(resourceClass);
112                             path.path("" + csid);
113                             Response response = Response.created(path.build()).build();
114                             return response;
115                     } catch (Throwable t) {
116                         repoSession.setTransactionRollbackOnly();
117                         throw t;
118                     } finally {
119                         repoClient.releaseRepositorySession(ctx, repoSession);
120                     }
121                 } catch (Exception e) {
122                     throw bigReThrow(e, ServiceMessages.CREATE_FAILED);
123                 }
124         }
125     }
126     
127     private void handleItemsPayload(CoreSessionInterface repoSession,
128                 String parentIdentifier,
129                 ResourceMap resourceMap,
130                 UriInfo uriInfo,
131                 PoxPayloadIn input) throws Exception {
132         PayloadInputPart abstractCommonListPart  = input.getPart(PoxPayload.ABSTRACT_COMMON_LIST_ROOT_ELEMENT_LABEL);
133         if (abstractCommonListPart != null) {
134                 AbstractCommonList itemsList = (AbstractCommonList) abstractCommonListPart.getBody();
135                 for (ListItem item : itemsList.getListItem()) {
136                         PoxPayloadIn itemXmlPayload = getItemXmlPayload(item);
137                         Response res = this.createAuthorityItem(repoSession, resourceMap, uriInfo, parentIdentifier, itemXmlPayload);
138                 }
139         }
140         
141         }
142     
143     /**
144      * This is very brittle.  If the class VocabularyitemsCommon changed with new fields we'd have to
145      * update this method.
146      * 
147      * @param item
148      * @return
149      * @throws DocumentException 
150      */
151         private PoxPayloadIn getItemXmlPayload(ListItem item) throws DocumentException {
152                 PoxPayloadIn result = null;
153
154                 VocabularyitemsCommon vocabularyItem = new VocabularyitemsCommon();
155                 for (Element ele : item.getAny()) {
156                         String fieldName = ele.getTagName();
157                         String fieldValue = ele.getTextContent();
158                         switch (fieldName) {
159                                 case "displayName":
160                                         vocabularyItem.setDisplayName(fieldValue);
161                                         break;
162                                         
163                                 case "shortIdentifier":
164                                         vocabularyItem.setShortIdentifier(fieldValue);
165                                         break;
166                                         
167                                 case "order":
168                                         vocabularyItem.setOrder(fieldValue);
169                                         break;
170                                         
171                                 case "source":
172                                         vocabularyItem.setSource(fieldValue);
173                                         break;
174                                         
175                                 case "sourcePage":
176                                         vocabularyItem.setSourcePage(fieldValue);
177                                         break;
178                                         
179                                 case "description":
180                                         vocabularyItem.setDescription(fieldValue);
181                                         
182                                 default:
183                                         throw new DocumentException(String.format("Unknown field '%s' in vocabulary item payload.",
184                                                         fieldName));
185                         }
186                 }
187                 
188                 result = new PoxPayloadIn(VocabularyClient.SERVICE_ITEM_PAYLOAD_NAME, vocabularyItem, 
189                         VOCABULARYITEMS_COMMON);
190
191                 return result;
192         }
193     
194         private Response createAuthorityItem(
195                 CoreSessionInterface repoSession,
196                 ResourceMap resourceMap,
197                 UriInfo uriInfo,
198                 String parentIdentifier, // Either a CSID or a URN form -e.g., a8ad38ec-1d7d-4bf2-bd31 or urn:cspace:name(bugsbunny)
199                 PoxPayloadIn input) throws Exception {
200         Response result = null;
201         
202         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), input, resourceMap, uriInfo);
203         ctx.setCurrentRepositorySession(repoSession);
204         
205         result = createAuthorityItem(ctx, parentIdentifier, AuthorityServiceUtils.UPDATE_REV,
206                         AuthorityServiceUtils.PROPOSED, AuthorityServiceUtils.NOT_SAS_ITEM);
207
208         return result;
209     }
210     
211
212         @GET
213     @Path("{csid}")
214     @Override
215     public Response get(
216             @Context Request request,
217             @Context UriInfo uriInfo,
218             @PathParam("csid") String specifier) {
219         Response result = null;
220         uriInfo = new UriInfoWrapper(uriInfo);
221         
222         try {
223                 MultivaluedMap<String,String> queryParams = uriInfo.getQueryParameters();
224                 String showItemsValue = (String)queryParams.getFirst(VocabularyClient.SHOW_ITEMS_QP);
225             boolean showItems = Tools.isTrue(showItemsValue);
226             if (showItems == true) {
227                 //
228                 // We'll honor paging params if we find any; otherwise we'll set the page size to 0 to get ALL the items
229                 //
230                 if (queryParams.containsKey(IClientQueryParams.PAGE_SIZE_PARAM) == false) {
231                         queryParams.add(IClientQueryParams.PAGE_SIZE_PARAM, "0");
232                 }
233             }
234
235             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(request, uriInfo);
236             PoxPayloadOut payloadout = getAuthority(ctx, request, uriInfo, specifier, showItems);
237             result = buildResponse(ctx, payloadout);
238         } catch (Exception e) {
239             throw bigReThrow(e, ServiceMessages.GET_FAILED, specifier);
240         }
241
242         if (result == null) {
243             Response response = Response.status(Response.Status.NOT_FOUND).entity(
244                     "GET request failed. The requested Authority specifier:" + specifier + ": was not found.").type(
245                     "text/plain").build();
246             throw new CSWebApplicationException(response);
247         }
248
249         return result;
250     }
251     
252     @Override
253     public String getServiceName() {
254         return vocabularyServiceName;
255     }
256
257     @Override
258     public String getItemServiceName() {
259         return vocabularyItemServiceName;
260     }
261     
262         @Override
263         public Class<VocabulariesCommon> getCommonPartClass() {
264                 return VocabulariesCommon.class;
265         }
266
267     /**
268      * @return the name of the property used to specify references for items in this type of
269      * authority. For most authorities, it is ServiceBindingUtils.AUTH_REF_PROP ("authRef").
270      * Some types (like Vocabulary) use a separate property.
271      */
272         @Override
273     protected String getRefPropName() {
274         return ServiceBindingUtils.TERM_REF_PROP;
275     }
276         
277         @Override
278         protected String getOrderByField(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
279                 String result = null;
280
281                 result = authorityItemCommonSchemaName + ":" + VocabularyItemJAXBSchema.DISPLAY_NAME;
282
283                 return result;
284         }
285         
286         @Override
287         protected String getPartialTermMatchField(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {
288                 return getOrderByField(ctx);
289         }
290
291         /*
292          * The item schema for the Vocabulary service does not support a multi-valued term list.  Only authorities that support
293          * term lists need to implement this method.
294          */
295         @Override
296         public String getItemTermInfoGroupXPathBase() {
297                 return null;
298         }
299 }