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