]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
4ea6e9309204242703d49b64458d00141d1c7802
[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.nuxeo.client.java;
25
26 import java.io.InputStream;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Set;
32
33 import javax.ws.rs.WebApplicationException;
34 import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.Response;
36
37 import org.collectionspace.services.common.authorityref.AuthorityRefList;
38 import org.collectionspace.services.common.context.MultipartServiceContext;
39 import org.collectionspace.services.common.context.ServiceContext;
40 import org.collectionspace.services.common.document.BadRequestException;
41 import org.collectionspace.services.common.document.DocumentUtils;
42 import org.collectionspace.services.common.document.DocumentWrapper;
43 import org.collectionspace.services.common.service.ObjectPartType;
44 import org.collectionspace.services.common.vocabulary.RefNameUtils;
45 import org.jboss.resteasy.plugins.providers.multipart.InputPart;
46 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
47 import org.nuxeo.ecm.core.api.DocumentModel;
48 import org.nuxeo.ecm.core.api.model.PropertyException;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.w3c.dom.Document;
52
53 /**
54  * RemoteDocumentModelHandler
55  *
56  * $LastChangedRevision: $
57  * $LastChangedDate: $
58  */
59 public abstract class RemoteDocumentModelHandlerImpl<T, TL>
60         extends DocumentModelHandler<T, TL> {
61
62     private final Logger logger = LoggerFactory.getLogger(RemoteDocumentModelHandlerImpl.class);
63
64     @Override
65     public void setServiceContext(ServiceContext ctx) {
66         if(ctx instanceof MultipartServiceContext){
67             super.setServiceContext(ctx);
68         }else{
69             throw new IllegalArgumentException("setServiceContext requires instance of " +
70                     MultipartServiceContext.class.getName());
71         }
72     }
73
74     @Override
75     public void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
76         DocumentModel docModel = wrapDoc.getWrappedObject();
77         //return at least those document part(s) that were received
78         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
79         MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
80         List<InputPart> inputParts = ctx.getInput().getParts();
81         for(InputPart part : inputParts){
82             String partLabel = part.getHeaders().getFirst("label");
83             ObjectPartType partMeta = partsMetaMap.get(partLabel);
84 //            extractPart(docModel, partLabel, partMeta);
85                         Map<String, Object> unQObjectProperties = extractPart(docModel, partLabel, partMeta);
86                         addOutputPart(unQObjectProperties, partLabel, partMeta);
87         }
88     }
89
90     private void addOutputPart(Map<String, Object> unQObjectProperties, String schema, ObjectPartType partMeta)
91                 throws Exception {
92                 Document doc = DocumentUtils.buildDocument(partMeta, schema,
93                                 unQObjectProperties);
94                 if (logger.isDebugEnabled()) {
95                         DocumentUtils.writeDocument(doc, System.out);
96                 }
97                 MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
98                 ctx.addOutputPart(schema, doc, partMeta.getContent().getContentType());
99     }
100     
101         @Override
102         public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
103                         throws Exception {
104
105                 DocumentModel docModel = wrapDoc.getWrappedObject();
106                 String[] schemas = docModel.getDeclaredSchemas();
107                 Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
108                 for (String schema : schemas) {
109                         ObjectPartType partMeta = partsMetaMap.get(schema);
110                         if (partMeta == null) {
111                                 continue; // unknown part, ignore
112                         }
113                         Map<String, Object> unQObjectProperties = extractPart(docModel, schema, partMeta);
114                         addOutputPart(unQObjectProperties, schema, partMeta);
115                 }
116         }
117
118     @Override
119     public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
120
121         //TODO filling extension parts should be dynamic
122         //Nuxeo APIs lack to support stream/byte[] input, get/setting properties is
123         //not an ideal way of populating objects.
124         DocumentModel docModel = wrapDoc.getWrappedObject();
125         MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
126         MultipartInput input = ctx.getInput();
127         if(input.getParts().isEmpty()){
128             String msg = "No payload found!";
129             logger.error(msg + "Ctx=" + getServiceContext().toString());
130             throw new BadRequestException(msg);
131         }
132
133         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
134
135         //iterate over parts received and fill those parts
136         List<InputPart> inputParts = input.getParts();
137         for(InputPart part : inputParts){
138
139             String partLabel = part.getHeaders().getFirst("label");
140             if (partLabel == null) {
141                 String msg = "Part label is missing or empty!";
142                 logger.error(msg + "Ctx=" + getServiceContext().toString());
143                 throw new BadRequestException(msg);
144             }
145             
146             //skip if the part is not in metadata
147             if(!partsMetaMap.containsKey(partLabel)){
148                 continue;
149             }
150             ObjectPartType partMeta = partsMetaMap.get(partLabel);
151             fillPart(part, docModel, partMeta);
152         }//rof
153
154     }
155
156     /**
157      * fillPart fills an XML part into given document model
158      * @param part to fill
159      * @param docModel for the given object
160      * @param partMeta metadata for the object to fill
161      * @throws Exception
162      */
163     protected void fillPart(InputPart part, DocumentModel docModel, ObjectPartType partMeta)
164             throws Exception {
165         InputStream payload = part.getBody(InputStream.class, null);
166
167         //check if this is an xml part
168         if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){
169             if(payload != null){
170                 Document document = DocumentUtils.parseDocument(payload);
171                 //TODO: callback to handler if registered to validate the
172                 //document
173                 Map<String, Object> objectProps = DocumentUtils.parseProperties(document);
174                 docModel.setProperties(partMeta.getLabel(), objectProps);
175             }
176         }
177     }
178
179     /**
180      * extractPart extracts an XML object from given DocumentModel
181      * @param docModel
182      * @param schema of the object to extract
183      * @param partMeta metadata for the object to extract
184      * @throws Exception
185      */
186     protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
187             throws Exception {
188         Map<String, Object> result = null;
189         
190         MediaType mt = MediaType.valueOf(partMeta.getContent().getContentType());
191         if (mt.equals(MediaType.APPLICATION_XML_TYPE)){
192             Map<String, Object> objectProps = docModel.getProperties(schema);
193             //unqualify properties before sending the doc over the wire (to save bandwidh)
194             //FIXME: is there a better way to avoid duplication of a collection?
195             Map<String, Object> unQObjectProperties = new HashMap<String, Object>();
196             Set<Entry<String, Object>> qualifiedEntries = objectProps.entrySet();
197             for(Entry<String, Object> entry : qualifiedEntries){
198                 String unqProp = getUnQProperty(entry.getKey());
199                 unQObjectProperties.put(unqProp, entry.getValue());
200             }
201             result = unQObjectProperties;
202         } //TODO: handle other media types
203         
204         return result;
205     }
206     
207     /* (non-Javadoc)
208      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getAuthorityRefs(org.collectionspace.services.common.document.DocumentWrapper, java.util.List)
209      */
210     @Override
211     public AuthorityRefList getAuthorityRefs(
212                 DocumentWrapper<DocumentModel> docWrapper,
213                 List<String> authRefFields) throws PropertyException {
214         AuthorityRefList authRefList = new AuthorityRefList();
215         try {
216                 DocumentModel docModel = docWrapper.getWrappedObject();
217                 List<AuthorityRefList.AuthorityRefItem> list = authRefList.getAuthorityRefItem();
218
219                 for (String field : authRefFields) {
220                         String refName = (String) docModel.getPropertyValue(field);
221                         if (refName == null)
222                                 continue;
223                         try {
224                                 RefNameUtils.AuthorityTermInfo termInfo = RefNameUtils
225                                 .parseAuthorityTermInfo(refName);
226                                 AuthorityRefList.AuthorityRefItem ilistItem = new AuthorityRefList.AuthorityRefItem();
227                                 ilistItem.setRefName(refName);
228                                 ilistItem.setAuthDisplayName(termInfo.inAuthority.displayName);
229                                 ilistItem.setItemDisplayName(termInfo.displayName);
230                                 ilistItem.setSourceField(field);
231                                 ilistItem.setUri(termInfo.getRelativeUri());
232                                 list.add(ilistItem);
233                         } catch (Exception e) {
234                                 // FIXME: Do we need to throw this Exception here?
235                                 if (logger.isDebugEnabled()) {
236                                         logger.debug("Caught exception in getAuthorityRefs", e);
237                                 }
238                         }
239                 }
240         } catch (PropertyException pe) {
241                 String msg = "Attempted to retrieve value for invalid or missing authority field. "
242                         + "Check authority field properties in tenant bindings.";
243                 logger.warn(msg, pe);
244                 throw pe;
245         } catch (Exception e) {
246                 if (logger.isDebugEnabled()) {
247                         logger.debug("Caught exception in getAuthorityRefs", e);
248                 }
249                 Response response = Response.status(
250                                 Response.Status.INTERNAL_SERVER_ERROR).entity(
251                                 "Failed to retrieve authority references").type(
252                                 "text/plain").build();
253                 throw new WebApplicationException(response);
254         }
255         return authRefList;
256     }
257 }