import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
+
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.model.PropertyException;
+
+import org.nuxeo.ecm.core.schema.SchemaManager;
+import org.nuxeo.ecm.core.schema.TypeConstants;
+import org.nuxeo.ecm.core.schema.types.ComplexType;
+import org.nuxeo.ecm.core.schema.types.Field;
+import org.nuxeo.ecm.core.schema.types.ListType;
+import org.nuxeo.ecm.core.schema.types.Schema;
+import org.nuxeo.ecm.core.schema.types.Type;
+import org.nuxeo.ecm.core.schema.types.primitives.StringType;
+import org.nuxeo.ecm.core.schema.types.FieldImpl;
+import org.nuxeo.ecm.core.schema.types.QName;
+import org.nuxeo.runtime.api.Framework;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
*/
@Override
public void setServiceContext(ServiceContext ctx) { //FIXME: Apply proper generics to ServiceContext<MultipartInput, MultipartOutput>
- if(ctx instanceof MultipartServiceContext){
+ if (ctx instanceof MultipartServiceContext) {
super.setServiceContext(ctx);
- }else{
- throw new IllegalArgumentException("setServiceContext requires instance of " +
- MultipartServiceContext.class.getName());
+ } else {
+ throw new IllegalArgumentException("setServiceContext requires instance of "
+ + MultipartServiceContext.class.getName());
}
}
Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
List<InputPart> inputParts = ctx.getInput().getParts();
- for(InputPart part : inputParts){
+ for (InputPart part : inputParts) {
String partLabel = part.getHeaders().getFirst("label");
ObjectPartType partMeta = partsMetaMap.get(partLabel);
// extractPart(docModel, partLabel, partMeta);
- Map<String, Object> unQObjectProperties = extractPart(docModel, partLabel, partMeta);
- addOutputPart(unQObjectProperties, partLabel, partMeta);
+ Map<String, Object> unQObjectProperties = extractPart(docModel, partLabel, partMeta);
+ addOutputPart(unQObjectProperties, partLabel, partMeta);
}
}
* @throws Exception the exception
*/
private void addOutputPart(Map<String, Object> unQObjectProperties, String schema, ObjectPartType partMeta)
- throws Exception {
- Document doc = DocumentUtils.buildDocument(partMeta, schema,
- unQObjectProperties);
- if (logger.isDebugEnabled() == true) {
- logger.debug(DocumentUtils.xmlToString(doc));
- }
- MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
- ctx.addOutputPart(schema, doc, partMeta.getContent().getContentType());
- }
-
+ throws Exception {
+ Document doc = DocumentUtils.buildDocument(partMeta, schema,
+ unQObjectProperties);
+ if (logger.isDebugEnabled() == true) {
+ logger.debug(DocumentUtils.xmlToString(doc));
+ }
+ MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
+ ctx.addOutputPart(schema, doc, partMeta.getContent().getContentType());
+ }
+
/**
* Extract paging info.
*
* @throws Exception the exception
*/
protected TL extractPagingInfo(TL theCommonList, DocumentWrapper<DocumentModelList> wrapDoc)
- throws Exception {
- AbstractCommonList commonList = (AbstractCommonList)theCommonList;
-
- DocumentFilter docFilter = this.getDocumentFilter();
- long pageSize = docFilter.getPageSize();
- long pageNum = pageSize != 0 ? docFilter.getOffset() / pageSize : pageSize;
- // set the page size and page number
- commonList.setPageNum(pageNum);
- commonList.setPageSize(pageSize);
- DocumentModelList docList = wrapDoc.getWrappedObject();
- // Set num of items in list. this is useful to our testing framework.
- commonList.setItemsInPage(docList.size());
- // set the total result size
- commonList.setTotalItems(docList.totalSize());
-
- return (TL)commonList;
+ throws Exception {
+ AbstractCommonList commonList = (AbstractCommonList) theCommonList;
+
+ DocumentFilter docFilter = this.getDocumentFilter();
+ long pageSize = docFilter.getPageSize();
+ long pageNum = pageSize != 0 ? docFilter.getOffset() / pageSize : pageSize;
+ // set the page size and page number
+ commonList.setPageNum(pageNum);
+ commonList.setPageSize(pageSize);
+ DocumentModelList docList = wrapDoc.getWrappedObject();
+ // Set num of items in list. this is useful to our testing framework.
+ commonList.setItemsInPage(docList.size());
+ // set the total result size
+ commonList.setTotalItems(docList.totalSize());
+
+ return (TL) commonList;
+ }
+
+ /* (non-Javadoc)
+ * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#extractAllParts(org.collectionspace.services.common.document.DocumentWrapper)
+ */
+ @Override
+ public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
+ throws Exception {
+
+ DocumentModel docModel = wrapDoc.getWrappedObject();
+ String[] schemas = docModel.getDeclaredSchemas();
+ Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
+ for (String schema : schemas) {
+ ObjectPartType partMeta = partsMetaMap.get(schema);
+ if (partMeta == null) {
+ continue; // unknown part, ignore
+ }
+ Map<String, Object> unQObjectProperties = extractPart(docModel, schema, partMeta);
+ addOutputPart(unQObjectProperties, schema, partMeta);
+ }
}
-
-
- /* (non-Javadoc)
- * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#extractAllParts(org.collectionspace.services.common.document.DocumentWrapper)
- */
- @Override
- public void extractAllParts(DocumentWrapper<DocumentModel> wrapDoc)
- throws Exception {
-
- DocumentModel docModel = wrapDoc.getWrappedObject();
- String[] schemas = docModel.getDeclaredSchemas();
- Map<String, ObjectPartType> partsMetaMap = getServiceContext().getPartsMetadata();
- for (String schema : schemas) {
- ObjectPartType partMeta = partsMetaMap.get(schema);
- if (partMeta == null) {
- continue; // unknown part, ignore
- }
- Map<String, Object> unQObjectProperties = extractPart(docModel, schema, partMeta);
- addOutputPart(unQObjectProperties, schema, partMeta);
- }
- }
/* (non-Javadoc)
* @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#fillAllParts(org.collectionspace.services.common.document.DocumentWrapper)
DocumentModel docModel = wrapDoc.getWrappedObject();
MultipartServiceContext ctx = (MultipartServiceContext) getServiceContext();
MultipartInput input = ctx.getInput();
- if(input.getParts().isEmpty()){
+ if (input.getParts().isEmpty()) {
String msg = "No payload found!";
logger.error(msg + "Ctx=" + getServiceContext().toString());
throw new BadRequestException(msg);
//iterate over parts received and fill those parts
List<InputPart> inputParts = input.getParts();
- for(InputPart part : inputParts){
+ for (InputPart part : inputParts) {
String partLabel = part.getHeaders().getFirst("label");
if (partLabel == null) {
logger.error(msg + "Ctx=" + getServiceContext().toString());
throw new BadRequestException(msg);
}
-
+
//skip if the part is not in metadata
ObjectPartType partMeta = partsMetaMap.get(partLabel);
- if(partMeta==null){
+ if (partMeta == null) {
continue;
}
fillPart(part, docModel, partMeta, action);
protected void fillPart(InputPart part, DocumentModel docModel, ObjectPartType partMeta, Action action)
throws Exception {
InputStream payload = part.getBody(InputStream.class, null);
-
+
// TODO for sub-docs - after we parse the doc, we need to look for elements that are configured as
// subitem lists, for this part (schema), pull them out, and set them aside for later processing.
//check if this is an xml part
- if(part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)){
- if(payload != null){
+ if (part.getMediaType().equals(MediaType.APPLICATION_XML_TYPE)) {
+ if (payload != null) {
Document document = DocumentUtils.parseDocument(payload, partMeta,
- false /*don't validate*/);
+ false /*don't validate*/);
//TODO: callback to handler if registered to validate the
//document
Map<String, Object> objectProps = DocumentUtils.parseProperties(document.getFirstChild());
- if(action==Action.UPDATE) {
- this.filterReadOnlyPropertiesForPart(objectProps, partMeta);
+ if (action == Action.UPDATE) {
+ this.filterReadOnlyPropertiesForPart(objectProps, partMeta);
}
docModel.setProperties(partMeta.getLabel(), objectProps);
}
* @param partMeta metadata for the object to fill
*/
public void filterReadOnlyPropertiesForPart(
- Map<String, Object> objectProps, ObjectPartType partMeta) {
- // Currently a no-op, but can be overridden in Doc handlers.
+ Map<String, Object> objectProps, ObjectPartType partMeta) {
+ // Currently a no-op, but can be overridden in Doc handlers.
}
/**
*/
protected Map<String, Object> extractPart(DocumentModel docModel, String schema, ObjectPartType partMeta)
throws Exception {
- return extractPart( docModel, schema, partMeta, null );
+ return extractPart(docModel, schema, partMeta, null);
}
-
+
/**
* extractPart extracts an XML object from given DocumentModel
* @param docModel
* @throws Exception
*/
protected Map<String, Object> extractPart(
- DocumentModel docModel, String schema, ObjectPartType partMeta,
- Map<String, Object> addToMap)
+ DocumentModel docModel, String schema, ObjectPartType partMeta,
+ Map<String, Object> addToMap)
throws Exception {
- Map<String, Object> result = null;
-
+ Map<String, Object> result = null;
+
MediaType mt = MediaType.valueOf(partMeta.getContent().getContentType());
- if (mt.equals(MediaType.APPLICATION_XML_TYPE)){
+ if (mt.equals(MediaType.APPLICATION_XML_TYPE)) {
Map<String, Object> objectProps = docModel.getProperties(schema);
//unqualify properties before sending the doc over the wire (to save bandwidh)
//FIXME: is there a better way to avoid duplication of a collection?
- Map<String, Object> unQObjectProperties =
- (addToMap!=null)? addToMap:(new HashMap<String, Object>());
+ Map<String, Object> unQObjectProperties =
+ (addToMap != null) ? addToMap : (new HashMap<String, Object>());
Set<Entry<String, Object>> qualifiedEntries = objectProps.entrySet();
- for(Entry<String, Object> entry : qualifiedEntries){
+ for (Entry<String, Object> entry : qualifiedEntries) {
String unqProp = getUnQProperty(entry.getKey());
unQObjectProperties.put(unqProp, entry.getValue());
}
result = unQObjectProperties;
} //TODO: handle other media types
-
+
return result;
}
-
+
/* (non-Javadoc)
* @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getAuthorityRefs(org.collectionspace.services.common.document.DocumentWrapper, java.util.List)
*/
@Override
public AuthorityRefList getAuthorityRefs(
- DocumentWrapper<DocumentModel> docWrapper,
- List<String> authRefFields) throws PropertyException {
- final String FIELD_REFNAME_DELIMITER = "|";
- final String FIELD_REFNAME_DELIMITER_REGEX = "\\" + FIELD_REFNAME_DELIMITER;
- AuthorityRefList authRefList = new AuthorityRefList();
- try {
- DocumentModel docModel = docWrapper.getWrappedObject();
- List<AuthorityRefList.AuthorityRefItem> list = authRefList.getAuthorityRefItem();
-
- for (String field : authRefFields) {
- // FIXME If the code used below doesn't support
- // arbitrary levels of nesting; e.g. "get all authrefs
- // in any children of a parent," then we might use
- // docModel.getProperties() instead,
- List<String> refNames = new ArrayList<String>();
- Object val = docModel.getPropertyValue(field);
- if (val instanceof String)
- refNames.add((String) val);
- else if (val instanceof List) {
- refNames = (List<String>) val;
+ DocumentWrapper<DocumentModel> docWrapper,
+ List<String> authRefFieldNames) throws PropertyException {
+
+ final String SCHEMA_FIELD_DELIMITER = ":";
+ AuthorityRefList authRefList = new AuthorityRefList();
+ List<AuthorityRefList.AuthorityRefItem> list = authRefList.getAuthorityRefItem();
+ String refName = "";
+
+ try {
+ DocumentModel docModel = docWrapper.getWrappedObject();
+
+ for (String authRefFieldName : authRefFieldNames) {
+
+ String schemaName = "";
+ // FIXME: Replacing the following by an existing utility
+ // method or, if not already present, create a new utility
+ // method for this task in the common package.
+ if (authRefFieldName.indexOf(SCHEMA_FIELD_DELIMITER) > 0) {
+ String[] authRefFieldNameParts =
+ authRefFieldName.split(SCHEMA_FIELD_DELIMITER);
+ schemaName = authRefFieldNameParts[0];
+ authRefFieldName = authRefFieldNameParts[1];
+ }
+
+ Schema schema = DocumentUtils.getSchema(schemaName);
+ Field field = schema.getField(authRefFieldName);
+ Type type = field.getType();
+
+ if (type.isSimpleType()) {
+ Object obj = docModel.getPropertyValue(authRefFieldName);
+ if (obj != null) {
+ refName = (String) obj;
+ if (refName != null || ! refName.trim().isEmpty()) {
+ list.add(authorityRefListItem(authRefFieldName, refName));
}
- for (String refName : refNames) {
- if (refName == null || refName.trim().isEmpty())
- continue;
- try {
- // If the refName is prefixed by a field name
- // and a delimiter, this means that it was
- // found in a child of the specified authref field.
- //
- // Store the child field's name as the field name.
- // Then strip off the child's name and the delimiter
- // from the refName.
- //
- // FIXME: Move this 'split' code to its own utility method.
- // FIXME: Verify that the behavior description above
- // is accurate for arbitrary levels of nesting.
- if (refName.indexOf(FIELD_REFNAME_DELIMITER) > 0) {
- String[] refNameParts =
- refName.split(FIELD_REFNAME_DELIMITER_REGEX);
- field = refNameParts[0];
- refName = refNameParts[1];
- }
-
- RefNameUtils.AuthorityTermInfo termInfo = RefNameUtils
- .parseAuthorityTermInfo(refName);
- AuthorityRefList.AuthorityRefItem ilistItem = new AuthorityRefList.AuthorityRefItem();
- ilistItem.setRefName(refName);
- ilistItem.setAuthDisplayName(termInfo.inAuthority.displayName);
- ilistItem.setItemDisplayName(termInfo.displayName);
- ilistItem.setSourceField(field);
- ilistItem.setUri(termInfo.getRelativeUri());
- list.add(ilistItem);
- } catch (Exception e) {
- // FIXME: Do we need to throw this Exception here?
- if (logger.isDebugEnabled()) {
- logger.debug("Caught exception in getAuthorityRefs", e);
- }
+ }
+ // FIXME: The following assumes a very simple structure
+ // for repeatable single scalar fields: a parent (continer)
+ // element, containing 0-n child elements, each of the same
+ // name and type, with values capable of being meaningfully
+ // cast to String.
+ //
+ // Past release 1.0a, repeatability may consist
+ // of arbitrary nesting and complexity, rather than
+ // scalars and single-level lists. When needed, that
+ // might be implemented here via recursion through
+ // nested listTypes and/or complexTypes.
+ } else if (type.isListType()) {
+ // Get the name of the child field that comprises
+ // value instances of the parent (container) field.
+ ListType ltype = (ListType) type;
+ field = ltype.getField();
+ String childAuthRefFieldName = field.getName().getLocalName();
+ // For each value instance, add its refName to the authRefs list,
+ // with its source field name set to the child field's name.
+ List<Object> valuesList = (List<Object>) docModel.getPropertyValue(authRefFieldName);
+ for (Object obj : valuesList) {
+ if (obj != null) {
+ refName = (String) obj;
+ if (refName != null || ! refName.trim().isEmpty()) {
+ list.add(authorityRefListItem(childAuthRefFieldName, refName));
}
}
- }
- } catch (PropertyException pe) {
- String msg = "Attempted to retrieve value for invalid or missing authority field. "
- + "Check authority field properties in tenant bindings.";
- logger.warn(msg, pe);
- throw pe;
- } catch (Exception e) {
- if (logger.isDebugEnabled()) {
- logger.debug("Caught exception in getAuthorityRefs", e);
- }
- Response response = Response.status(
- Response.Status.INTERNAL_SERVER_ERROR).entity(
- "Failed to retrieve authority references").type(
- "text/plain").build();
- throw new WebApplicationException(response);
- }
- return authRefList;
+ }
+ }
+
+ }
+
+ } catch (PropertyException pe) {
+ String msg = "Attempted to retrieve value for invalid or missing authority field. "
+ + "Check authority field properties in tenant bindings.";
+ logger.warn(msg, pe);
+ throw pe;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception in getAuthorityRefs", e);
+ }
+ Response response = Response.status(
+ Response.Status.INTERNAL_SERVER_ERROR).entity(
+ "Failed to retrieve authority references").type(
+ "text/plain").build();
+ throw new WebApplicationException(response);
+ }
+ return authRefList;
}
+
+ public AuthorityRefList.AuthorityRefItem authorityRefListItem(String authRefFieldName, String refName) {
+
+ AuthorityRefList.AuthorityRefItem ilistItem = new AuthorityRefList.AuthorityRefItem();
+ try {
+ RefNameUtils.AuthorityTermInfo termInfo = RefNameUtils.parseAuthorityTermInfo(refName);
+ ilistItem.setRefName(refName);
+ ilistItem.setAuthDisplayName(termInfo.inAuthority.displayName);
+ ilistItem.setItemDisplayName(termInfo.displayName);
+ ilistItem.setSourceField(authRefFieldName);
+ ilistItem.setUri(termInfo.getRelativeUri());
+ } catch (Exception e) {
+ }
+ return ilistItem;
+ }
}