]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
af09b24274e6e41a580d5d9ec52e439535f73448
[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 import javax.ws.rs.core.MediaType;
33 import org.collectionspace.services.common.context.RemoteServiceContext;
34 import org.collectionspace.services.common.context.ServiceContext;
35 import org.collectionspace.services.common.document.BadRequestException;
36 import org.collectionspace.services.common.document.DocumentUtils;
37 import org.collectionspace.services.common.document.DocumentWrapper;
38 import org.collectionspace.services.common.service.ObjectPartType;
39 import org.jboss.resteasy.plugins.providers.multipart.InputPart;
40 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
41 import org.nuxeo.ecm.core.api.DocumentModel;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.w3c.dom.Document;
45
46 /**
47  * RemoteDocumentModelHandler
48  *
49  * $LastChangedRevision: $
50  * $LastChangedDate: $
51  */
52 public abstract class RemoteDocumentModelHandler<T, TL>
53         extends DocumentModelHandler<T, TL> {
54
55     private final Logger logger = LoggerFactory.getLogger(RemoteDocumentModelHandler.class);
56
57     @Override
58     public void setServiceContext(ServiceContext ctx) {
59         if(ctx instanceof RemoteServiceContext){
60             super.setServiceContext(ctx);
61         }else{
62             throw new IllegalArgumentException("setServiceContext requires instance of " +
63                     RemoteServiceContext.class.getName());
64         }
65     }
66
67     @Override
68     public abstract String getDocumentType();
69
70     @Override
71     public void completeUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
72         DocumentModel docModel = wrapDoc.getWrappedObject();
73         //return at least those document part(s) that were received
74         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
75         RemoteServiceContext ctx = (RemoteServiceContext) getServiceContext();
76         List<InputPart> inputParts = ctx.getInput().getParts();
77         for(InputPart part : inputParts){
78             String partLabel = part.getHeaders().getFirst("label");
79             ObjectPartType partMeta = partsMetaMap.get(partLabel);
80             extractPart(docModel, partLabel, partMeta);
81         }
82     }
83
84     @Override
85     public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
86
87         DocumentModel docModel = wrapDoc.getWrappedObject();
88         String[] schemas = docModel.getDeclaredSchemas();
89         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
90         for(String schema : schemas){
91             ObjectPartType partMeta = partsMetaMap.get(schema);
92             if(partMeta == null){
93                 continue; //unknown part, ignore
94             }
95             extractPart(docModel, schema, partMeta);
96         }
97     }
98
99     @Override
100     public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
101
102         //TODO filling extension parts should be dynamic
103         //Nuxeo APIs lack to support stream/byte[] input, get/setting properties is
104         //not an ideal way of populating objects.
105         DocumentModel docModel = wrapDoc.getWrappedObject();
106         RemoteServiceContext ctx = (RemoteServiceContext) getServiceContext();
107         MultipartInput input = ctx.getInput();
108         if(input.getParts().isEmpty()){
109             String msg = "No payload found!";
110             logger.error(msg + "Ctx=" + getServiceContext().toString());
111             throw new BadRequestException(msg);
112         }
113
114         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
115
116         //iterate over parts received and fill those parts
117         List<InputPart> inputParts = input.getParts();
118         for(InputPart part : inputParts){
119
120             String partLabel = part.getHeaders().getFirst("label");
121             if (partLabel == null) {
122                 String msg = "Part label is missing or empty!";
123                 logger.error(msg + "Ctx=" + getServiceContext().toString());
124                 throw new BadRequestException(msg);
125             }
126             
127             //skip if the part is not in metadata
128             if(!partsMetaMap.containsKey(partLabel)){
129                 continue;
130             }
131             ObjectPartType partMeta = partsMetaMap.get(partLabel);
132             fillPart(part, docModel, partMeta);
133         }//rof
134
135     }
136
137     /**
138      * fillPart fills an XML part into given document model
139      * @param part to fill
140      * @param docModel for the given object
141      * @param partMeta metadata for the object to fill
142      * @throws Exception
143      */
144     protected void fillPart(InputPart part, DocumentModel docModel, ObjectPartType partMeta)
145             throws Exception {
146         InputStream payload = part.getBody(InputStream.class, null);
147
148         //check if this is an xml part
149         if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){
150             if(payload != null){
151                 Document document = DocumentUtils.parseDocument(payload);
152                 //TODO: callback to handler if registered to validate the
153                 //document
154                 Map<String, Object> objectProps = DocumentUtils.parseProperties(document);
155                 docModel.setProperties(partMeta.getLabel(), objectProps);
156             }
157         }
158     }
159
160     /**
161      * extractPart extracts an XML object from given DocumentModel
162      * @param docModel
163      * @param schema of the object to extract
164      * @param partMeta metadata for the object to extract
165      * @throws Exception
166      */
167     protected void extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
168             throws Exception {
169         MediaType mt = MediaType.valueOf(partMeta.getContent().getContentType());
170         if(mt.equals(MediaType.APPLICATION_XML_TYPE)){
171             Map<String, Object> objectProps = docModel.getProperties(schema);
172             //unqualify properties before sending the doc over the wire (to save bandwidh)
173             //FIXME: is there a better way to avoid duplication of a collection?
174             Map<String, Object> unQObjectProperties = new HashMap<String, Object>();
175             Set<Entry<String, Object>> qualifiedEntries = objectProps.entrySet();
176             for(Entry<String, Object> entry : qualifiedEntries){
177                 String unqProp = getUnQProperty(entry.getKey());
178                 unQObjectProperties.put(unqProp, entry.getValue());
179             }
180             Document doc = DocumentUtils.buildDocument(partMeta, schema, unQObjectProperties);
181             if(logger.isDebugEnabled()){
182                 DocumentUtils.writeDocument(doc, System.out);
183             }
184             RemoteServiceContext ctx = (RemoteServiceContext) getServiceContext();
185             ctx.addOutputPart(schema, doc, partMeta.getContent().getContentType());
186         } //TODO: handle other media types
187     }
188 }