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