]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a9475b49af41952eea418469f77f6a77857b2409
[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.blob.nuxeo;
25
26 import org.collectionspace.services.blob.BlobsCommon;
27 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
28 import org.collectionspace.services.client.BlobClient;
29 import org.collectionspace.services.client.PayloadOutputPart;
30 import org.collectionspace.services.client.PoxPayloadIn;
31 import org.collectionspace.services.client.PoxPayloadOut;
32 import org.collectionspace.services.common.blob.BlobInput;
33 import org.collectionspace.services.common.blob.BlobOutput;
34 import org.collectionspace.services.common.blob.BlobUtil;
35 import org.collectionspace.services.common.context.ServiceContext;
36 import org.collectionspace.services.common.document.DocumentUtils;
37 import org.collectionspace.services.common.document.DocumentWrapper;
38 import org.collectionspace.services.common.imaging.nuxeo.NuxeoBlobUtils;
39 import org.collectionspace.services.config.service.ListResultField;
40 import org.collectionspace.services.config.service.ObjectPartType;
41 import org.collectionspace.services.jaxb.BlobJAXBSchema;
42 import org.collectionspace.services.nuxeo.client.java.CommonList;
43 import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
44 import org.nuxeo.ecm.core.api.ClientException;
45 import org.nuxeo.ecm.core.api.DocumentModel;
46 import org.nuxeo.ecm.core.api.IdRef;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import java.util.List;
51 import java.util.Map;
52 import java.util.Set;
53
54 import javax.ws.rs.core.MultivaluedMap;
55
56 import org.dom4j.Element;
57
58 /**
59  * The Class BlobDocumentModelHandler.
60  */
61 public class BlobDocumentModelHandler
62 extends NuxeoDocumentModelHandler<BlobsCommon> {
63
64         /** The logger. */
65         private final Logger logger = LoggerFactory.getLogger(BlobDocumentModelHandler.class);
66
67     //==============================================================================
68
69         private String getDerivativePathBase(DocumentModel docModel) {
70                 return getServiceContextPath() + docModel.getName() + "/" +
71                         BlobInput.URI_DERIVATIVES_PATH + "/";
72         }
73
74         private BlobsCommon getCommonPartProperties(DocumentModel docModel) throws Exception {
75                 String label = getServiceContext().getCommonPartLabel();
76                 BlobsCommon result = new BlobsCommon();
77                 
78                 result.setData((String) 
79                                 docModel.getProperty(label, BlobJAXBSchema.data));
80                 result.setDigest((String)
81                                 docModel.getProperty(label, BlobJAXBSchema.digest));
82                 result.setEncoding((String)
83                                 docModel.getProperty(label, BlobJAXBSchema.encoding));
84                 result.setLength((String)
85                                 docModel.getProperty(label, BlobJAXBSchema.length));
86                 result.setMimeType((String)
87                                 docModel.getProperty(label, BlobJAXBSchema.mimeType));
88                 result.setName((String)
89                                 docModel.getProperty(label, BlobJAXBSchema.name));
90                 result.setRepositoryId((String)
91                                 docModel.getProperty(label, BlobJAXBSchema.repositoryId));
92                 result.setUri(getServiceContextPath() + docModel.getName() + "/" +
93                                 BlobInput.URI_CONTENT_PATH);
94                 
95                 return result;
96         }
97         
98         private void setCommonPartProperties(DocumentModel documentModel,
99                         BlobsCommon blobsCommon) throws ClientException {
100                 try {
101                         String schemaName = getServiceContext().getCommonPartLabel();
102                         PayloadOutputPart outputPart = new PayloadOutputPart(schemaName, blobsCommon);
103                         Element element = outputPart.asElement();
104                         Map<String, Object> propertyMap = DocumentUtils.parseProperties(schemaName, element, getServiceContext());
105                         documentModel.setProperties(schemaName, propertyMap);
106                 } catch (Exception e) {
107                         throw new ClientException(e);
108                 }               
109         }
110         
111         private void extractMetadata(String nuxeoImageID, String metadataLabel) {               
112         Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
113         ObjectPartType partMeta = partsMetaMap.get(metadataLabel);
114
115         if (partMeta != null) {
116                 CoreSessionInterface repoSession = this.getRepositorySession();
117                         if (nuxeoImageID != null && nuxeoImageID.isEmpty() == false) try {
118                                 IdRef documentRef = new IdRef(nuxeoImageID);
119                                 DocumentModel docModel = repoSession.getDocument(documentRef);
120                     Map<String, Object> unQObjectProperties = extractPart(docModel, metadataLabel);
121                     if (unQObjectProperties != null) {
122                         addOutputPart(unQObjectProperties, metadataLabel, partMeta);
123                     }
124                         } catch (Exception e) {
125                                 logger.warn("Metadata extraction failed: " + e.getMessage());
126                         }
127         } else {
128                 logger.warn("Metadata extraction failed: Could not find tenant binding for schema type = " + metadataLabel);
129         }
130         }
131
132         /* (non-Javadoc)
133          * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#extractAllParts(org.collectionspace.services.common.document.DocumentWrapper)
134          */
135         @Override
136         public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
137                         throws Exception {
138                 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
139                 BlobInput blobInput = BlobUtil.getBlobInput(ctx); // the blobInput was set by the Blob JAX-RS resource code and put into the service context
140                 CoreSessionInterface repoSession = this.getRepositorySession();
141                 DocumentModel docModel = wrapDoc.getWrappedObject();
142                 BlobsCommon blobsCommon = this.getCommonPartProperties(docModel);               
143                 String blobRepositoryId = blobsCommon.getRepositoryId(); //cache the value to pass to the blob retriever
144                 //
145                 // We're being asked for a list of blob derivatives, not the payload for a blob record.  FIXME: REM - This should be handled in a class called DerivativeDocumentHandler (need to create).
146                 //
147                 if (blobInput.isDerivativeListRequested() == true) {
148                 List<ListResultField> resultsFields = getListItemsArray();
149                         CommonList blobsCommonList = NuxeoBlobUtils.getBlobDerivatives( //FIXME: REM - Need to replace "NuxeoImageUtils" with something more general like "BlobUtils" since we may support other blob types.
150                                         repoSession, blobRepositoryId, resultsFields, getDerivativePathBase(docModel));
151 //                      ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, blobsCommonList);
152                         blobInput.setDerivativeList(blobsCommonList);
153                         return;  //FIXME: REM - Don't like this exit point.  Perhaps derivatives should be a sub-resource with its own DerivativeDocumentHandler doc handler?
154                 }               
155
156                 String derivativeTerm = blobInput.getDerivativeTerm();
157                 Boolean getContentFlag = blobInput.isContentRequested();
158                 //
159                 // If we're being asked for either the content of the blob, the content of a derivative, or the payload for a derivative then
160                 // fall into this block of code.  Otherwise, we'll just call our parent to deal with a plain-old-blob payload.
161                 //
162                 if (derivativeTerm != null || getContentFlag == true) {
163                         StringBuffer mimeTypeBuffer = new StringBuffer();
164                         BlobOutput blobOutput = NuxeoBlobUtils.getBlobOutput(ctx, repoSession,
165                                         blobRepositoryId, derivativeTerm, getContentFlag, mimeTypeBuffer);
166                         if (getContentFlag == true) {
167                                 if (blobOutput != null) {
168                                         blobInput.setContentStream(blobOutput.getBlobInputStream());
169                                 } else {
170                                         blobInput.setContentStream(null);
171                                 }
172                         }
173         
174                         if (derivativeTerm != null) {
175                                 // reset 'blobsCommon' if we have a derivative request
176                                 blobsCommon = blobOutput.getBlobsCommon();
177                                 blobsCommon.setUri(getDerivativePathBase(docModel) +
178                                                 derivativeTerm + "/" + BlobInput.URI_CONTENT_PATH);                             
179                         }
180                         
181                         String mimeType = mimeTypeBuffer.toString();
182                         if (mimeType != null && !mimeType.isEmpty()) { // MIME type for derivatives might be different from original
183                                 blobInput.setMimeType(mimeType);
184                                 blobsCommon.setMimeType(mimeType);
185                         } else {
186                                 blobInput.setMimeType(blobsCommon.getMimeType());  // Set the MIME type to the one in blobsCommon
187                         }
188                         
189                         blobsCommon.setRepositoryId(null); //hide the repository id from the GET results payload since it is private
190                         this.setCommonPartProperties(docModel, blobsCommon);
191                         // finish extracting the other parts by calling the parent
192                 } else {
193                         extractMetadata(blobRepositoryId, NuxeoBlobUtils.SCHEMA_IMAGE_METADATA);
194                         extractMetadata(blobRepositoryId, NuxeoBlobUtils.SCHEMA_IPTC);
195                 }
196                 
197                 //
198                 // Hide the Nuxeo repository ID of the Nuxeo blob since this is private
199                 //
200                 docModel.setProperty(ctx.getCommonPartLabel(), BlobJAXBSchema.repositoryId, null);      
201                 super.extractAllParts(wrapDoc);
202         }
203
204         @Override
205         public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
206                 ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
207                 BlobInput blobInput = BlobUtil.getBlobInput(ctx); // The blobInput should have been put into the context by the Blob or Media resource
208                 if (blobInput != null && blobInput.getBlobFile() != null) {             
209                         boolean purgeOriginal = false;
210                         MultivaluedMap<String, String> queryParams = ctx.getQueryParams();
211                         String purgeOriginalStr = queryParams.getFirst(BlobClient.BLOB_PURGE_ORIGINAL);
212                         if (purgeOriginalStr != null && purgeOriginalStr.isEmpty() == false) { // Find our if the caller wants us to purge/delete the original
213                                 purgeOriginal = true;
214                         }
215                         //
216                         // If blobInput has a file then we just received a multipart/form-data file post or a URI query parameter
217                         //
218                         DocumentModel documentModel = wrapDoc.getWrappedObject();
219                         CoreSessionInterface repoSession = this.getRepositorySession();
220                 
221                         BlobsCommon blobsCommon = NuxeoBlobUtils.createBlobInRepository(ctx, repoSession, blobInput, purgeOriginal, true);
222                         blobInput.setBlobCsid(documentModel.getName()); //Assumption here is that the documentModel "name" field is storing a CSID
223         
224                 PoxPayloadIn input = ctx.getInput();
225                 //
226                 // If the input payload is null, then we're creating a new blob from a post or a uri.  This means there
227                 // is no "input" payload for our framework to process.  Therefore we need to synthesize a payload from
228                 // the BlobsCommon instance we just filled out.
229                 //
230                 if (input == null) {
231                         PoxPayloadOut output = new PoxPayloadOut(BlobClient.SERVICE_PAYLOAD_NAME);
232                         PayloadOutputPart commonPart = new PayloadOutputPart(BlobClient.SERVICE_COMMON_PART_NAME, blobsCommon);
233                         output.addPart(commonPart);
234                         input = new PoxPayloadIn(output.toXML());
235                         ctx.setInput(input);
236                 } else {
237                         // At this point, we've created a blob document in the Nuxeo repository.  Usually, we use the blob to create and instance of BlobsCommon and use
238                         // that to populate the resource record.  However, since the "input" var is not null the requester provided their own resource record data
239                         // so we'll use it rather than deriving one from the blob.
240                         logger.warn("A resource record payload was provided along with the actually blob binary file.  This payload is usually derived from the blob binary.  Since a payload was provided, we're creating the resource record from the payload and not from the corresponding blob binary." +
241                                         " The data in blob resource record fields may not correspond completely with the persisted blob binary file.");
242                 }               
243                 }
244         
245                 super.fillAllParts(wrapDoc, action);
246         }    
247 }
248