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