<xs:element name="name" type="xs:string" />\r
<xs:element name="length" type="xs:string" />\r
<xs:element name="digest" type="xs:string" />\r
+ <xs:element name="dimensionGroupList" type="dimensionGroupList"/>\r
<xs:element name="uri" type="xs:string" />\r
<xs:element name="repositoryId" type="xs:string" />\r
+ \r
+ <xs:complexType name="dimensionGroupList">\r
+ <xs:sequence>\r
+ <xs:element name="dimensionGroup" type="dimensionGroup" minOccurs="0"\r
+ maxOccurs="unbounded"/>\r
+ </xs:sequence>\r
+ </xs:complexType>\r
+ <xs:complexType name="dimensionGroup"> <!-- //FIXME: The "dimensionGroup" type should be declared in one place since other services use it -->\r
+ <xs:sequence>\r
+ <xs:element name="measuredPart" type="xs:string"/>\r
+ <xs:element name="dimension" type="xs:string"/>\r
+ <xs:element name="measuredBy" type="xs:string"/>\r
+ <xs:element name="measurementUnit" type="xs:string"/>\r
+ <xs:element name="measurementMethod" type="xs:string"/>\r
+ <xs:element name="value" type="xs:string"/>\r
+ <xs:element name="valueDate" type="xs:string"/>\r
+ <xs:element name="valueQualifier" type="xs:string"/>\r
+ </xs:sequence>\r
+ </xs:complexType>\r
+ \r
</xs:schema>\r
public static final String SERVICE_PATH_COMPONENT = SERVICE_NAME;
public static final String SERVICE_PATH = "/" + SERVICE_PATH_COMPONENT;
public static final String SERVICE_PAYLOAD_NAME = SERVICE_NAME;
+ public static final String SERVICE_COMMON_PART_NAME = SERVICE_NAME + PART_LABEL_SEPARATOR + PART_COMMON_LABEL;
//HTTP query param string for specifying a URI source to blob bits.
public static final String BLOB_URI_PARAM = "blobUri";
blobInput.setDerivativeListRequested(true);
BlobUtil.setBlobInput(ctx, blobInput);
- PoxPayloadOut response = this.get(csid, ctx);
+ PoxPayloadOut response = this.get(csid, ctx); //FIXME: Derivatives should get their own document handler -something like DerivativeDocumentModelHandler.
if (logger.isDebugEnabled() == true) {
logger.debug(response.toString());
}
import org.collectionspace.services.blob.BlobsCommon;
import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.client.BlobClient;
+import org.collectionspace.services.client.PayloadInputPart;
+import org.collectionspace.services.client.PayloadOutputPart;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.common.blob.BlobInput;
import org.collectionspace.services.common.blob.BlobOutput;
import org.collectionspace.services.common.blob.BlobUtil;
import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.DocumentUtils;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.imaging.nuxeo.NuxeoImageUtils;
import org.collectionspace.services.common.service.ListResultField;
import org.collectionspace.services.jaxb.BlobJAXBSchema;
import org.collectionspace.services.jaxb.AbstractCommonList;
import org.collectionspace.services.nuxeo.client.java.CommonList;
+
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.nuxeo.ecm.core.schema.types.Schema;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Element;
/**
* The Class BlobDocumentModelHandler.
private void setCommonPartProperties(DocumentModel documentModel,
BlobsCommon blobsCommon) throws ClientException {
- String label = getServiceContext().getCommonPartLabel();
- documentModel.setProperty(label, BlobJAXBSchema.data, blobsCommon.getData());
- documentModel.setProperty(label, BlobJAXBSchema.digest, blobsCommon.getDigest());
- documentModel.setProperty(label, BlobJAXBSchema.encoding, blobsCommon.getEncoding());
- documentModel.setProperty(label, BlobJAXBSchema.length, blobsCommon.getLength());
- documentModel.setProperty(label, BlobJAXBSchema.mimeType, blobsCommon.getMimeType());
- documentModel.setProperty(label, BlobJAXBSchema.name, blobsCommon.getName());
- documentModel.setProperty(label, BlobJAXBSchema.uri, blobsCommon.getUri());
- documentModel.setProperty(label, BlobJAXBSchema.repositoryId, blobsCommon.getRepositoryId());
+ try {
+ String schemaName = getServiceContext().getCommonPartLabel();
+ PayloadOutputPart outputPart = new PayloadOutputPart(schemaName, blobsCommon);
+ Element element = outputPart.asElement();
+ Map<String, Object> propertyMap = DocumentUtils.parseProperties(schemaName, element, getServiceContext());
+ documentModel.setProperties(schemaName, propertyMap);
+ } catch (Exception e) {
+ throw new ClientException(e);
+ }
}
/* (non-Javadoc)
DocumentModel docModel = wrapDoc.getWrappedObject();
BlobsCommon blobsCommon = this.getCommonPartProperties(docModel);
String blobRepositoryId = blobsCommon.getRepositoryId(); //cache the value to pass to the blob retriever
-
+ //
+ // 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).
+ //
if (blobInput.isDerivativeListRequested() == true) {
List<ListResultField> resultsFields = getListItemsArray();
- CommonList blobsCommonList = NuxeoImageUtils.getBlobDerivatives(
+ CommonList blobsCommonList = NuxeoImageUtils.getBlobDerivatives( //FIXME: REM - Need to replace "NuxeoImageUtils" with something more general like "BlobUtils" since we may support other blob types.
repoSession, blobRepositoryId, resultsFields, getDerivativePathBase(docModel));
// ctx.setProperty(BlobInput.BLOB_DERIVATIVE_LIST_KEY, blobsCommonList);
blobInput.setDerivativeList(blobsCommonList);
- return; //FIXME: Don't like this exit point. Perhaps derivatives should be a sub-resource?
+ return; //FIXME: REM - Don't like this exit point. Perhaps derivatives should be a sub-resource with its own DerivativeDocumentHandler doc handler?
}
String derivativeTerm = blobInput.getDerivativeTerm();
Boolean getContentFlag = blobInput.isContentRequested();
- BlobOutput blobOutput = NuxeoImageUtils.getBlobOutput(ctx, repoSession,
- blobRepositoryId, derivativeTerm, getContentFlag);
- if (getContentFlag == true) {
- blobInput.setContentStream(blobOutput.getBlobInputStream());
-// ctx.setProperty(BlobInput.BLOB_CONTENT_KEY, blobOutput.getBlobInputStream());
- }
-
- if (derivativeTerm != null) {
- // reset 'blobsCommon' if we have a derivative request
- blobsCommon = blobOutput.getBlobsCommon();
- blobsCommon.setUri(getDerivativePathBase(docModel) +
- derivativeTerm + "/" + BlobInput.URI_CONTENT_PATH);
+ //
+ // If we're being asked for either the content of the blob, the content of a derivative, or the payload for a derivative then
+ // fall into this block of code. Otherwise, we'll just call our parent to deal with a plain-old-blob payload.
+ //
+ if (derivativeTerm != null || getContentFlag == true) {
+ BlobOutput blobOutput = NuxeoImageUtils.getBlobOutput(ctx, repoSession,
+ blobRepositoryId, derivativeTerm, getContentFlag);
+ if (getContentFlag == true) {
+ blobInput.setContentStream(blobOutput.getBlobInputStream());
+ }
+
+ if (derivativeTerm != null) {
+ // reset 'blobsCommon' if we have a derivative request
+ blobsCommon = blobOutput.getBlobsCommon();
+ blobsCommon.setUri(getDerivativePathBase(docModel) +
+ derivativeTerm + "/" + BlobInput.URI_CONTENT_PATH);
+ }
+
+ blobsCommon.setRepositoryId(null); //hide the repository id from the GET results payload since it is private
+ this.setCommonPartProperties(docModel, blobsCommon);
+ // finish extracting the other parts by calling the parent
}
- blobsCommon.setRepositoryId(null); //hide the repository id from the GET results payload since it is private
- this.setCommonPartProperties(docModel, blobsCommon);
- // finish extracting the other parts by calling the parent
+ //
+ // Hide the Nuxeo repository ID of the Nuxeo blob since this is private
+ //
+ docModel.setProperty(ctx.getCommonPartLabel(), BlobJAXBSchema.repositoryId, null);
super.extractAllParts(wrapDoc);
}
DocumentModel documentModel = wrapDoc.getWrappedObject();
RepositoryInstance repoSession = this.getRepositorySession();
BlobsCommon blobsCommon = NuxeoImageUtils.createPicture(ctx, repoSession, blobInput);
- this.setCommonPartProperties(documentModel, blobsCommon);
+ PoxPayloadIn input = (PoxPayloadIn)ctx.getInput();
+ //
+ // If the input payload is null, then we're creating a new blob from a post or a uri. This means there
+ // is no "input" payload for our framework to process. Therefore we need to synthesize a payload from
+ // the BlobsCommon instance we just filled out.
+ //
+ if (input == null) {
+ PoxPayloadOut output = new PoxPayloadOut(BlobClient.SERVICE_PAYLOAD_NAME);
+ PayloadOutputPart commonPart = new PayloadOutputPart(BlobClient.SERVICE_COMMON_PART_NAME, blobsCommon);
+ output.addPart(commonPart);
+ input = new PoxPayloadIn(output.toXML());
+ ctx.setInput(input);
+ }
+// this.setCommonPartProperties(documentModel, blobsCommon);
blobInput.setBlobCsid(documentModel.getName());
- } else {
- super.fillAllParts(wrapDoc, action);
}
+
+ super.fillAllParts(wrapDoc, action);
}
}
return result;
}
+ public static Map<String, Object> parseProperties(String schemaName, org.dom4j.Element element, ServiceContext ctx) throws Exception {
+ Map<String, Object> result = null;
+ Schema schema = getSchemaFromName(schemaName);
+ result = DocumentUtils.loadSchema(schema, element, ctx);
+ return result;
+ }
+
/**
* Load schema.
*
\r
import org.nuxeo.ecm.platform.picture.api.adapters.MultiviewPictureAdapter;\r
import org.nuxeo.ecm.platform.picture.api.adapters.MultiviewPictureAdapterFactory; \r
+import org.nuxeo.ecm.platform.picture.api.ImageInfo;\r
+import org.nuxeo.ecm.platform.picture.api.ImagingService;\r
import org.nuxeo.ecm.platform.picture.api.PictureView;\r
\r
import org.nuxeo.ecm.platform.picture.api.adapters.PictureResourceAdapter;\r
import org.collectionspace.services.common.service.ListResultField;\r
import org.collectionspace.services.common.FileUtils;\r
import org.collectionspace.services.blob.BlobsCommon;\r
+import org.collectionspace.services.blob.DimensionGroup;\r
+import org.collectionspace.services.blob.DimensionGroupList;\r
//import org.collectionspace.services.blob.BlobsCommonList;\r
//import org.collectionspace.services.blob.BlobsCommonList.BlobListItem;\r
import org.collectionspace.services.jaxb.AbstractCommonList;\r
public static final String DERIVATIVE_THUMBNAIL_TAG = DERIVATIVE_THUMBNAIL + "_";\r
\r
public static final String DERIVATIVE_UNKNOWN = "_UNKNOWN_DERIVATIVE_NAME_";\r
+ \r
+ //\r
+ // Image Dimension fields\r
+ //\r
+ public static final String PART_IMAGE = "digitalImage";\r
+ public static final String WIDTH = "width";\r
+ public static final String HEIGHT = "height";\r
+ public static final String DEPTH = "depth";\r
+ public static final String UNIT_PIXELS = "pixels";\r
+ public static final String UNIT_BITS = "bits";\r
\r
// static DefaultBinaryManager binaryManager = new DefaultBinaryManager(); //can we get this from Nuxeo? i.e., Framework.getService(BinaryManger.class)\r
\r
\r
return commonList;\r
}\r
+ \r
+ static private DimensionGroupList getDimensions(DocumentModel documentModel, Blob nuxeoBlob) {\r
+ DimensionGroupList result = null;\r
+ try {\r
+ ImagingService service = Framework.getService(ImagingService.class); \r
+ ImageInfo imageInfo = service.getImageInfo(nuxeoBlob);\r
+ \r
+ if (imageInfo != null) {\r
+ DimensionGroupList dimensionGroupList = new DimensionGroupList();\r
+ List<DimensionGroup> dgList = dimensionGroupList.getDimensionGroup();\r
+ //\r
+ // Set the width\r
+ //\r
+ DimensionGroup widthDimension = new DimensionGroup();\r
+ widthDimension.setMeasuredPart(PART_IMAGE);\r
+ widthDimension.setDimension(WIDTH);\r
+ widthDimension.setMeasurementUnit(UNIT_PIXELS);\r
+ widthDimension.setValue(Integer.toString(imageInfo.getWidth()));\r
+ dgList.add(widthDimension);\r
+ //\r
+ // Set the height\r
+ //\r
+ DimensionGroup heightDimension = new DimensionGroup();\r
+ heightDimension.setMeasuredPart(PART_IMAGE);\r
+ heightDimension.setDimension(HEIGHT);\r
+ heightDimension.setMeasurementUnit(UNIT_PIXELS);\r
+ heightDimension.setValue(Integer.toString(imageInfo.getHeight()));\r
+ dgList.add(heightDimension);\r
+ //\r
+ // Set the depth\r
+ //\r
+ DimensionGroup depthDimension = new DimensionGroup();\r
+ depthDimension.setMeasuredPart(PART_IMAGE);\r
+ depthDimension.setDimension(DEPTH);\r
+ depthDimension.setMeasurementUnit(UNIT_BITS);\r
+ depthDimension.setValue(Integer.toString(imageInfo.getDepth()));\r
+ dgList.add(depthDimension);\r
+ //\r
+ // Now set out result\r
+ //\r
+ result = dimensionGroupList;\r
+ } else {\r
+ if (logger.isWarnEnabled() == true) {\r
+ logger.warn("Could not synthesize a dimension list of the blob: " + documentModel.getName());\r
+ }\r
+ } \r
+ } catch (Exception e) {\r
+ logger.warn("Could not extract image information for blob: " + documentModel.getName());\r
+ }\r
+ \r
+ return result;\r
+ }\r
\r
static private BlobsCommon createBlobsCommon(DocumentModel documentModel, Blob nuxeoBlob) {\r
BlobsCommon result = new BlobsCommon();\r
+\r
if (documentModel != null) {\r
result.setMimeType(nuxeoBlob.getMimeType());\r
result.setName(nuxeoBlob.getFilename());\r
result.setLength(Long.toString(nuxeoBlob.getLength()));\r
result.setRepositoryId(documentModel.getId());\r
+ DimensionGroupList dimensionGroupList = getDimensions(documentModel, nuxeoBlob);\r
+ if (dimensionGroupList != null) {\r
+ result.setDimensionGroupList(dimensionGroupList);\r
+ }\r
}\r
+ \r
return result;\r
}\r
\r
return result;\r
}\r
\r
+// /*\r
+// * This is an alternate approach to getting information about an image\r
+// * and its corresponding derivatives.\r
+// */\r
+// // MultiviewPictureAdapter multiviewPictureAdapter = documentModel.getAdapter(MultiviewPictureAdapter.class);\r
+// MultiviewPictureAdapterFactory multiviewPictureAdapterFactory = new MultiviewPictureAdapterFactory();\r
+// MultiviewPictureAdapter multiviewPictureAdapter =\r
+// (MultiviewPictureAdapter)multiviewPictureAdapterFactory.getAdapter(documentModel, null);\r
+// if (multiviewPictureAdapter != null) {\r
+// PictureView[] pictureViewArray = multiviewPictureAdapter.getViews();\r
+// for (PictureView pictureView : pictureViewArray) {\r
+// if (logger.isDebugEnabled() == true) {\r
+// logger.debug("-------------------------------------");\r
+// logger.debug(toStringPictureView(pictureView));\r
+// }\r
+// }\r
+// }\r
+ \r
/**\r
* Gets the image.\r
*\r
Boolean getContentFlag) {\r
BlobOutput result = new BlobOutput();\r
\r
- try {\r
+ if (repositoryId != null && repositoryId.isEmpty() == false) try {\r
IdRef documentRef = new IdRef(repositoryId);\r
DocumentModel documentModel = repoSession.getDocument(documentRef);\r
-\r
- /*\r
- * This is a second, and better, approach to getting information about an image\r
- * and its corresponding derivatives.\r
- */\r
- // MultiviewPictureAdapter multiviewPictureAdapter = documentModel.getAdapter(MultiviewPictureAdapter.class);\r
- MultiviewPictureAdapterFactory multiviewPictureAdapterFactory = new MultiviewPictureAdapterFactory();\r
- MultiviewPictureAdapter multiviewPictureAdapter =\r
- (MultiviewPictureAdapter)multiviewPictureAdapterFactory.getAdapter(documentModel, null);\r
- if (multiviewPictureAdapter != null) {\r
- PictureView[] pictureViewArray = multiviewPictureAdapter.getViews();\r
- for (PictureView pictureView : pictureViewArray) {\r
- if (logger.isDebugEnabled() == true) {\r
- logger.debug("-------------------------------------");\r
- logger.debug(toStringPictureView(pictureView));\r
- }\r
- }\r
- }\r
-\r
+ \r
Blob docBlob = null;\r
DocumentBlobHolder docBlobHolder = (DocumentBlobHolder)documentModel.getAdapter(BlobHolder.class);\r
if (docBlobHolder instanceof PictureBlobHolder) { // if it is a PictureDocument then it has these Nuxeo schemas: [dublincore, uid, picture, iptc, common, image_metadata]\r
} else {\r
docBlob = docBlobHolder.getBlob();\r
}\r
-\r
+ \r
//\r
// Create the result instance that will contain the blob metadata\r
// and an InputStream with the bits if the 'getContentFlag' is set\r
result.setBlobsCommon(blobsCommon);\r
if (getContentFlag == true) {\r
InputStream remoteStream = docBlob.getStream();\r
- BufferedInputStream bufferedInputStream = new BufferedInputStream(remoteStream);\r
+ BufferedInputStream bufferedInputStream = new BufferedInputStream(remoteStream); //FIXME: REM - To improve performance, try BufferedInputStream(InputStream in, int size) \r
result.setBlobInputStream(bufferedInputStream); // the input stream of blob bits\r
}\r
\r
final static String length = "length";
final static String digest = "digest";
final static String uri = "uri";
+ final static String dimensionGroupList = "dimensionGroupList";
final static String repositoryId = "repositoryId";
}
<xs:element name="name" type="xs:string" />
<xs:element name="length" type="xs:string" />
<xs:element name="digest" type="xs:string" />
+ <xs:element name="dimensionGroupList" type="dimensionGroupList"/>
<xs:element name="uri" type="xs:string" />
<xs:element name="repositoryId" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
+ <xs:complexType name="dimensionGroupList">
+ <xs:sequence>
+ <xs:element name="dimensionGroup" type="dimensionGroup" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="dimensionGroup"> <!-- //FIXME: The "dimensionGroup" type should be declared in one place since other services use it -->
+ <xs:sequence>
+ <xs:element name="measuredPart" type="xs:string"/>
+ <xs:element name="dimension" type="xs:string"/>
+ <xs:element name="measuredBy" type="xs:string"/>
+ <xs:element name="measurementUnit" type="xs:string"/>
+ <xs:element name="measurementMethod" type="xs:string"/>
+ <xs:element name="value" type="xs:string"/>
+ <xs:element name="valueDate" type="xs:string"/>
+ <xs:element name="valueQualifier" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+
</xs:schema>
</xs:element>\r
<xs:element name="rightsHolder" type="xs:string"/>\r
<xs:element name="source" type="xs:string"/>\r
+ <xs:element name="sourceUrl" type="xs:string"/>\r
<xs:element name="subjectList">\r
<xs:complexType>\r
<xs:sequence>\r
<xs:element name="publisher" type="xs:string"/>
<xs:element name="relationList" type="relationList"/>
<xs:element name="rightsHolder" type="xs:string"/>
- <xs:element name="source" type="xs:string"/>
+ <xs:element name="source" type="xs:string"/>
+ <xs:element name="sourceUrl" type="xs:string"/>
<xs:element name="subjectList" type="subjectList"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="typeList" type="typeList"/>
<dependency>\r
<groupId>org.collectionspace.services</groupId>\r
<artifactId>org.collectionspace.services.authority</artifactId>\r
- <optional>true</optional>\r
<version>${project.version}</version>\r
</dependency> \r
<dependency>\r
</dependency>\r
<dependency>\r
<groupId>org.collectionspace.services</groupId>\r
- <artifactId>org.collectionspace.services.contact.client</artifactId>\r
- \r
+ <artifactId>org.collectionspace.services.contact.client</artifactId> \r
<version>${project.version}</version>\r
</dependency>\r
<dependency>\r