mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Allow management of Alfresco Aspects through CMIS REST and SOAP APIs
- In CMIS methods that allow setting of node properties, the <cmis:properties> element may carry an <alf:setAspects> extension that lists - aspectsToRemove - aspectsToAdd - properties (properties to set belonging to aspects rather than the node type) - In CMIS methods that allow retrieval of node properties, the <cmis:properties> carries an <alf:getAspects> extension that lists - appliedAspects - properties (properties belonging to aspects rather than the node type) - Added extension types to Alfresco-Core.xsd and referenced in extended WSDL - Plumbed in to Web Service and REST APIs git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19037 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -23,6 +23,7 @@ import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -151,7 +152,7 @@ public interface CMISServices
|
||||
public AssociationRef[] getRelationships(NodeRef node, CMISTypeDefinition relDef, boolean includeSubTypes, CMISRelationshipDirectionEnum direction) throws CMISInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Get a single property for a node.
|
||||
* Get a single property belonging to the node's type.
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node
|
||||
@@ -163,6 +164,22 @@ public interface CMISServices
|
||||
*/
|
||||
public Serializable getProperty(NodeRef nodeRef, String propertyName) throws CMISInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Get a single property, optionally constrained to a given node type or aspect
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node
|
||||
* @param typeDef
|
||||
* the node type or aspect or <code>null</code> if any property can be returned
|
||||
* @param propertyName
|
||||
* the property name
|
||||
* @return value
|
||||
* @throws CMISInvalidArgumentException
|
||||
* if an argument is invalid
|
||||
*/
|
||||
public Serializable getProperty(NodeRef nodeRef, CMISTypeDefinition typeDef, String propertyName)
|
||||
throws CMISInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Get a single property for an association.
|
||||
*
|
||||
@@ -175,7 +192,7 @@ public interface CMISServices
|
||||
public Serializable getProperty(AssociationRef assocRef, String propertyName);
|
||||
|
||||
/**
|
||||
* Get all properties.
|
||||
* Get all properties of a node's type.
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node ref
|
||||
@@ -186,7 +203,32 @@ public interface CMISServices
|
||||
public Map<String, Serializable> getProperties(NodeRef nodeRef) throws CMISInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Set a single property.
|
||||
* Get all of a node's values for the properties in the given type or aspect.
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node ref
|
||||
* @param typeDef
|
||||
* the type or aspect definition
|
||||
* @return the properties
|
||||
* @throws CMISInvalidArgumentException
|
||||
* if an argument is invalid
|
||||
*/
|
||||
public Map<String, Serializable> getProperties(NodeRef nodeRef, CMISTypeDefinition typeDef)
|
||||
throws CMISInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Gets the aspects applied to a node.
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node ref
|
||||
* @return the aspect definitions
|
||||
* @throws CMISInvalidArgumentException
|
||||
* if an argument is invalid
|
||||
*/
|
||||
public Set<CMISTypeDefinition> getAspects(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* Set a single property belonging to the node's type.
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node ref
|
||||
@@ -196,9 +238,47 @@ public interface CMISServices
|
||||
* the value
|
||||
* @throws CMISInvalidArgumentException
|
||||
* if an argument is invalid
|
||||
* @throws CMISConstraintException
|
||||
* if the property cannot be set
|
||||
*/
|
||||
public void setProperty(NodeRef nodeRef, String propertyName, Serializable value) throws CMISInvalidArgumentException;
|
||||
|
||||
public void setProperty(NodeRef nodeRef, String propertyName, Serializable value)
|
||||
throws CMISInvalidArgumentException, CMISConstraintException;
|
||||
|
||||
/**
|
||||
* Set a single property, optionally constrained to a given node type or aspect
|
||||
*
|
||||
* @param nodeRef
|
||||
* the node ref
|
||||
* @param typeDef
|
||||
* the node type or aspect or <code>null</code> if any valid property should be set (corresponding aspect
|
||||
* added automatically).
|
||||
* @param propertyName
|
||||
* the property name
|
||||
* @param value
|
||||
* the value
|
||||
* @throws CMISInvalidArgumentException
|
||||
* if an argument is invalid
|
||||
* @throws CMISConstraintException
|
||||
* if the property cannot be set
|
||||
*/
|
||||
public void setProperty(NodeRef nodeRef, CMISTypeDefinition typeDef, String propertyName, Serializable value)
|
||||
throws CMISInvalidArgumentException, CMISConstraintException;
|
||||
|
||||
/**
|
||||
* Sets the aspects on a node (Alfresco extension).
|
||||
*
|
||||
* @param node
|
||||
* the node
|
||||
* @param aspectsToRemove
|
||||
* the aspects to remove
|
||||
* @param aspectsToAdd
|
||||
* the aspects to add
|
||||
* @throws CMISInvalidArgumentException
|
||||
* if an argument is invalid
|
||||
*/
|
||||
public void setAspects(NodeRef node, Iterable<String> aspectsToRemove, Iterable<String> aspectsToAdd)
|
||||
throws CMISInvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Applies a versioning state to a new node, potentially resulting in a new node.
|
||||
*
|
||||
|
@@ -26,9 +26,11 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -36,6 +38,7 @@ import java.util.regex.Pattern;
|
||||
import org.alfresco.cmis.CMISConstraintException;
|
||||
import org.alfresco.cmis.CMISContentAlreadyExistsException;
|
||||
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISFilterNotValidException;
|
||||
@@ -54,6 +57,7 @@ import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISStreamNotSupportedException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.cmis.CMISUpdatabilityEnum;
|
||||
import org.alfresco.cmis.CMISVersioningException;
|
||||
import org.alfresco.cmis.CMISVersioningStateEnum;
|
||||
import org.alfresco.cmis.dictionary.CMISFolderTypeDefinition;
|
||||
@@ -74,10 +78,12 @@ import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInServiceException;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
@@ -699,12 +705,24 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
|
||||
*/
|
||||
public Serializable getProperty(NodeRef nodeRef, String propertyName) throws CMISInvalidArgumentException
|
||||
{
|
||||
CMISTypeDefinition typeDef = getTypeDefinition(nodeRef);
|
||||
return getProperty(nodeRef, getTypeDefinition(nodeRef), propertyName);
|
||||
}
|
||||
|
||||
public Serializable getProperty(NodeRef nodeRef, CMISTypeDefinition typeDef, String propertyName)
|
||||
throws CMISInvalidArgumentException
|
||||
{
|
||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(propertyName, typeDef);
|
||||
if (propDef == null)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Property " + propertyName + " not found for type "
|
||||
+ typeDef.getTypeId() + " in CMIS Dictionary");
|
||||
if (typeDef == null)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Property " + propertyName + " not found in CMIS Dictionary");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Property " + propertyName + " not found for type "
|
||||
+ typeDef.getTypeId() + " in CMIS Dictionary");
|
||||
}
|
||||
}
|
||||
return propDef.getPropertyAccessor().getValue(nodeRef);
|
||||
}
|
||||
@@ -796,31 +814,143 @@ public class CMISServicesImpl implements CMISServices, ApplicationContextAware,
|
||||
*/
|
||||
public Map<String, Serializable> getProperties(NodeRef nodeRef) throws CMISInvalidArgumentException
|
||||
{
|
||||
CMISTypeDefinition typeDef = getTypeDefinition(nodeRef);
|
||||
return getProperties(nodeRef, getTypeDefinition(nodeRef));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISServices#getProperties(org.alfresco.service.cmr.repository.NodeRef,
|
||||
* org.alfresco.cmis.CMISTypeDefinition)
|
||||
*/
|
||||
public Map<String, Serializable> getProperties(NodeRef nodeRef, CMISTypeDefinition typeDef)
|
||||
throws CMISInvalidArgumentException
|
||||
{
|
||||
Map<String, CMISPropertyDefinition> propDefs = typeDef.getPropertyDefinitions();
|
||||
Map<String, Serializable> values = new HashMap<String, Serializable>(propDefs.size());
|
||||
Map<String, Serializable> values = new HashMap<String, Serializable>(propDefs.size() * 2);
|
||||
for (CMISPropertyDefinition propDef : propDefs.values())
|
||||
{
|
||||
values.put(propDef.getPropertyId().getId(), propDef.getPropertyAccessor().getValue(nodeRef));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISServices#getAspects(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public Set<CMISTypeDefinition> getAspects(NodeRef nodeRef)
|
||||
{
|
||||
Set<QName> aspects = nodeService.getAspects(nodeRef);
|
||||
Set<CMISTypeDefinition> result = new HashSet<CMISTypeDefinition>(aspects.size() * 2);
|
||||
for (QName aspect : aspects)
|
||||
{
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(aspect, CMISScope.POLICY);
|
||||
if (typeDef != null)
|
||||
{
|
||||
result.add(typeDef);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISServices#setProperty(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.io.Serializable)
|
||||
*/
|
||||
public void setProperty(NodeRef nodeRef, String propertyName, Serializable value)
|
||||
throws CMISInvalidArgumentException
|
||||
throws CMISInvalidArgumentException, CMISConstraintException
|
||||
{
|
||||
setProperty(nodeRef, getTypeDefinition(nodeRef), propertyName, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISServices#setProperty(org.alfresco.service.cmr.repository.NodeRef,
|
||||
* org.alfresco.cmis.CMISTypeDefinition, java.lang.String, java.io.Serializable)
|
||||
*/
|
||||
public void setProperty(NodeRef nodeRef, CMISTypeDefinition typeDef, String propertyName, Serializable value)
|
||||
throws CMISInvalidArgumentException, CMISConstraintException
|
||||
{
|
||||
CMISTypeDefinition typeDef = getTypeDefinition(nodeRef);
|
||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(propertyName, typeDef);
|
||||
if (propDef == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Property " + propertyName + " not found for type "
|
||||
+ typeDef.getTypeId() + " in CMIS Dictionary");
|
||||
if (typeDef == null)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Property " + propertyName + " not found in CMIS Dictionary");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Property " + propertyName + " not found for type "
|
||||
+ typeDef.getTypeId() + " in CMIS Dictionary");
|
||||
}
|
||||
}
|
||||
|
||||
CMISUpdatabilityEnum updatability = propDef.getUpdatability();
|
||||
if (updatability == CMISUpdatabilityEnum.READ_ONLY
|
||||
|| updatability == CMISUpdatabilityEnum.READ_AND_WRITE_WHEN_CHECKED_OUT
|
||||
&& !nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
throw new CMISConstraintException("Unable to update read-only property" + propertyName);
|
||||
}
|
||||
|
||||
if (propDef.isRequired() && value == null)
|
||||
{
|
||||
throw new CMISConstraintException("Property " + propertyName + " is required");
|
||||
}
|
||||
|
||||
if (propDef.getDataType() == CMISDataTypeEnum.STRING && propDef.getMaximumLength() > 0 && value != null
|
||||
&& value.toString().length() > propDef.getMaximumLength())
|
||||
{
|
||||
throw new CMISConstraintException("Value is too long for property " + propertyName);
|
||||
}
|
||||
|
||||
QName property = propDef.getPropertyAccessor().getMappedProperty();
|
||||
if (property == null)
|
||||
{
|
||||
throw new CMISConstraintException("Unable to set property " + propertyName);
|
||||
}
|
||||
nodeService.setProperty(nodeRef, property, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISServices#setAspects(org.alfresco.service.cmr.repository.NodeRef, java.lang.Iterable,
|
||||
* java.lang.Iterable)
|
||||
*/
|
||||
public void setAspects(NodeRef node, Iterable<String> aspectsToRemove, Iterable<String> aspectsToAdd)
|
||||
throws CMISInvalidArgumentException
|
||||
{
|
||||
for (String aspectType : aspectsToRemove)
|
||||
{
|
||||
try
|
||||
{
|
||||
nodeService.removeAspect(node, getTypeDefinition(aspectType).getTypeId().getQName());
|
||||
}
|
||||
catch (InvalidAspectException e)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Invalid aspect " + aspectType);
|
||||
}
|
||||
catch (InvalidNodeRefException e)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Invalid node " + node);
|
||||
}
|
||||
}
|
||||
for (String aspectType : aspectsToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
nodeService.addAspect(node, getTypeDefinition(aspectType).getTypeId().getQName(), Collections
|
||||
.<QName, Serializable> emptyMap());
|
||||
}
|
||||
catch (InvalidAspectException e)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Invalid aspect " + aspectType);
|
||||
}
|
||||
catch (InvalidNodeRefException e)
|
||||
{
|
||||
throw new CMISInvalidArgumentException("Invalid node " + node);
|
||||
}
|
||||
}
|
||||
propDef.getPropertyAccessor().setValue(nodeRef, value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user