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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.blob.nuxeo;
26 import org.collectionspace.services.blob.BlobsCommon;
27 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
28 import org.collectionspace.services.client.BlobClient;
29 import org.collectionspace.services.client.PayloadInputPart;
30 import org.collectionspace.services.client.PayloadOutputPart;
31 import org.collectionspace.services.client.PoxPayloadIn;
32 import org.collectionspace.services.client.PoxPayloadOut;
33 import org.collectionspace.services.common.blob.BlobInput;
34 import org.collectionspace.services.common.blob.BlobOutput;
35 import org.collectionspace.services.common.blob.BlobUtil;
36 import org.collectionspace.services.common.context.ServiceContext;
37 import org.collectionspace.services.common.document.DocumentUtils;
38 import org.collectionspace.services.common.document.DocumentWrapper;
39 import org.collectionspace.services.common.imaging.nuxeo.NuxeoImageUtils;
40 import org.collectionspace.services.common.service.ListResultField;
41 import org.collectionspace.services.common.service.ObjectPartType;
42 import org.collectionspace.services.jaxb.AbstractCommonList;
43 import org.collectionspace.services.jaxb.BlobJAXBSchema;
44 import org.collectionspace.services.jaxb.AbstractCommonList;
45 import org.collectionspace.services.nuxeo.client.java.CommonList;
47 import org.nuxeo.ecm.core.api.ClientException;
48 import org.nuxeo.ecm.core.api.DocumentModel;
49 import org.nuxeo.ecm.core.api.IdRef;
50 import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
51 import org.nuxeo.ecm.core.schema.types.Schema;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 import java.util.ArrayList;
57 import java.util.List;
60 import org.dom4j.Element;
63 * The Class BlobDocumentModelHandler.
65 public class BlobDocumentModelHandler
66 extends DocHandlerBase<BlobsCommon> {
69 private final Logger logger = LoggerFactory.getLogger(BlobDocumentModelHandler.class);
71 //==============================================================================
73 private String getDerivativePathBase(DocumentModel docModel) {
74 return getServiceContextPath() + docModel.getName() + "/" +
75 BlobInput.URI_DERIVATIVES_PATH + "/";
78 private BlobsCommon getCommonPartProperties(DocumentModel docModel) throws Exception {
79 String label = getServiceContext().getCommonPartLabel();
80 BlobsCommon result = new BlobsCommon();
82 result.setData((String)
83 docModel.getProperty(label, BlobJAXBSchema.data));
84 result.setDigest((String)
85 docModel.getProperty(label, BlobJAXBSchema.digest));
86 result.setEncoding((String)
87 docModel.getProperty(label, BlobJAXBSchema.encoding));
88 result.setLength((String)
89 docModel.getProperty(label, BlobJAXBSchema.length));
90 result.setMimeType((String)
91 docModel.getProperty(label, BlobJAXBSchema.mimeType));
92 result.setName((String)
93 docModel.getProperty(label, BlobJAXBSchema.name));
94 result.setRepositoryId((String)
95 docModel.getProperty(label, BlobJAXBSchema.repositoryId));
96 result.setUri(getServiceContextPath() + docModel.getName() + "/" +
97 BlobInput.URI_CONTENT_PATH);
102 private void setCommonPartProperties(DocumentModel documentModel,
103 BlobsCommon blobsCommon) throws ClientException {
105 String schemaName = getServiceContext().getCommonPartLabel();
106 PayloadOutputPart outputPart = new PayloadOutputPart(schemaName, blobsCommon);
107 Element element = outputPart.asElement();
108 Map<String, Object> propertyMap = DocumentUtils.parseProperties(schemaName, element, getServiceContext());
109 documentModel.setProperties(schemaName, propertyMap);
110 } catch (Exception e) {
111 throw new ClientException(e);
115 private void extractMetadata(String nuxeoImageID, String metadataLabel) {
116 PayloadOutputPart result = null;
117 Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
118 ObjectPartType partMeta = partsMetaMap.get(metadataLabel);
120 if (partMeta != null) {
121 RepositoryInstance repoSession = this.getRepositorySession();
122 if (nuxeoImageID != null && nuxeoImageID.isEmpty() == false) try {
123 IdRef documentRef = new IdRef(nuxeoImageID);
124 DocumentModel docModel = repoSession.getDocument(documentRef);
125 Map<String, Object> unQObjectProperties = extractPart(docModel, metadataLabel);
126 if (unQObjectProperties != null) {
127 addOutputPart(unQObjectProperties, metadataLabel, partMeta);
129 } catch (Exception e) {
130 logger.warn("Metadata extraction failed: " + e.getMessage());
133 logger.warn("Metadata extraction failed: Could not find tenant binding for schema type = " + metadataLabel);
138 * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#extractAllParts(org.collectionspace.services.common.document.DocumentWrapper)
141 public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
143 ServiceContext ctx = this.getServiceContext();
144 BlobInput blobInput = BlobUtil.getBlobInput(ctx);
145 RepositoryInstance repoSession = this.getRepositorySession();
146 DocumentModel docModel = wrapDoc.getWrappedObject();
147 BlobsCommon blobsCommon = this.getCommonPartProperties(docModel);
148 String blobRepositoryId = blobsCommon.getRepositoryId(); //cache the value to pass to the blob retriever
150 // 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).
152 if (blobInput.isDerivativeListRequested() == true) {
153 List<ListResultField> resultsFields = getListItemsArray();
154 CommonList blobsCommonList = NuxeoImageUtils.getBlobDerivatives( //FIXME: REM - Need to replace "NuxeoImageUtils" with something more general like "BlobUtils" since we may support other blob types.
155 repoSession, blobRepositoryId, resultsFields, getDerivativePathBase(docModel));
156 // ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, blobsCommonList);
157 blobInput.setDerivativeList(blobsCommonList);
158 return; //FIXME: REM - Don't like this exit point. Perhaps derivatives should be a sub-resource with its own DerivativeDocumentHandler doc handler?
161 String derivativeTerm = blobInput.getDerivativeTerm();
162 Boolean getContentFlag = blobInput.isContentRequested();
164 // If we're being asked for either the content of the blob, the content of a derivative, or the payload for a derivative then
165 // fall into this block of code. Otherwise, we'll just call our parent to deal with a plain-old-blob payload.
167 if (derivativeTerm != null || getContentFlag == true) {
168 BlobOutput blobOutput = NuxeoImageUtils.getBlobOutput(ctx, repoSession, //FIXME: REM - If the blob's binary has been removed from the file system, then this call will return null. We need to at least spit out a meaningful error/warning message
169 blobRepositoryId, derivativeTerm, getContentFlag);
170 if (getContentFlag == true) {
171 blobInput.setContentStream(blobOutput.getBlobInputStream());
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);
181 blobsCommon.setRepositoryId(null); //hide the repository id from the GET results payload since it is private
182 this.setCommonPartProperties(docModel, blobsCommon);
183 // finish extracting the other parts by calling the parent
185 extractMetadata(blobRepositoryId, NuxeoImageUtils.SCHEMA_IMAGE_METADATA);
186 extractMetadata(blobRepositoryId, NuxeoImageUtils.SCHEMA_IPTC);
190 // Hide the Nuxeo repository ID of the Nuxeo blob since this is private
192 docModel.setProperty(ctx.getCommonPartLabel(), BlobJAXBSchema.repositoryId, null);
193 super.extractAllParts(wrapDoc);
197 public void fillAllParts(DocumentWrapper<DocumentModel> wrapDoc, Action action) throws Exception {
198 ServiceContext ctx = this.getServiceContext();
199 BlobInput blobInput = BlobUtil.getBlobInput(ctx);
200 if (blobInput.getBlobFile() != null) {
202 // If blobInput has a file then we just received a multipart/form-data file post or a URI query parameter
204 DocumentModel documentModel = wrapDoc.getWrappedObject();
205 RepositoryInstance repoSession = this.getRepositorySession();
206 BlobsCommon blobsCommon = NuxeoImageUtils.createPicture(ctx, repoSession, blobInput);
207 PoxPayloadIn input = (PoxPayloadIn)ctx.getInput();
209 // If the input payload is null, then we're creating a new blob from a post or a uri. This means there
210 // is no "input" payload for our framework to process. Therefore we need to synthesize a payload from
211 // the BlobsCommon instance we just filled out.
214 PoxPayloadOut output = new PoxPayloadOut(BlobClient.SERVICE_PAYLOAD_NAME);
215 PayloadOutputPart commonPart = new PayloadOutputPart(BlobClient.SERVICE_COMMON_PART_NAME, blobsCommon);
216 output.addPart(commonPart);
217 input = new PoxPayloadIn(output.toXML());
220 // this.setCommonPartProperties(documentModel, blobsCommon);
221 blobInput.setBlobCsid(documentModel.getName()); //Assumption here is that the documentModel "name" field is storing a CSID
224 super.fillAllParts(wrapDoc, action);