mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged DEV/SEAMIST4 to HEAD (part 1 of 2)
11607: Make the current CMIS Web Services compliant with the CMIS v0.5 spec 12369: Remove Unusing Imports 12375: Minor fixup for testing CMIS Web Services. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12661 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -30,7 +30,6 @@ import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.apache.ws.security.WSPasswordCallback;
|
||||
|
||||
/**
|
||||
@@ -38,14 +37,6 @@ import org.apache.ws.security.WSPasswordCallback;
|
||||
*/
|
||||
public class AuthenticationTokenCallbackHandler implements CallbackHandler
|
||||
{
|
||||
|
||||
private AuthenticationService authenticationService;
|
||||
|
||||
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
|
||||
{
|
||||
WSPasswordCallback wssPasswordCallback = (WSPasswordCallback) callbacks[0];
|
||||
|
@@ -34,7 +34,6 @@ import org.alfresco.service.cmr.repository.ContentReader;
|
||||
|
||||
/**
|
||||
* @author Dmitry Lazurkin
|
||||
*
|
||||
*/
|
||||
public class ContentReaderDataSource implements DataSource
|
||||
{
|
||||
|
@@ -28,6 +28,9 @@ import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.datatype.DatatypeConfigurationException;
|
||||
@@ -39,13 +42,19 @@ import org.alfresco.cmis.dictionary.CMISDictionaryService;
|
||||
import org.alfresco.cmis.dictionary.CMISMapping;
|
||||
import org.alfresco.cmis.property.CMISPropertyService;
|
||||
import org.alfresco.cmis.search.CMISQueryService;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.repo.web.util.paging.Page;
|
||||
import org.alfresco.repo.web.util.paging.Paging;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
@@ -58,9 +67,14 @@ import org.alfresco.service.namespace.QName;
|
||||
*
|
||||
* @author Michael Shavnev
|
||||
* @author Dmitry Lazurkin
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class DMAbstractServicePort
|
||||
{
|
||||
private static final String BASE_TYPE_PROPERTY_NAME = "BaseType";
|
||||
|
||||
protected static final String INITIAL_VERSION_DESCRIPTION = "Initial version";
|
||||
|
||||
private DatatypeFactory _datatypeFactory;
|
||||
private Paging paging = new Paging();
|
||||
|
||||
@@ -73,6 +87,10 @@ public class DMAbstractServicePort
|
||||
protected NodeService nodeService;
|
||||
protected VersionService versionService;
|
||||
protected FileFolderService fileFolderService;
|
||||
protected CheckOutCheckInService checkOutCheckInService;
|
||||
protected SearchService searchService;
|
||||
|
||||
protected CmisObjectsUtils cmisObjectsUtils;
|
||||
|
||||
private DatatypeFactory getDatatypeFactory()
|
||||
{
|
||||
@@ -90,6 +108,40 @@ public class DMAbstractServicePort
|
||||
return _datatypeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method converts Alfresco's <b>NodeRef</b>'s to CMIS objects those will be stored in <b>resultList</b>-parameter. Properties for returning filtering also performs
|
||||
*
|
||||
* @param filter properties filter value for filtering objects returning properties
|
||||
* @param sourceList the list that contains all returning Node References
|
||||
* @param resultList the list of <b>CmisObjectType</b> values for end response result collecting
|
||||
* @throws InvalidArgumentException
|
||||
* @throws FilterNotValidException
|
||||
*/
|
||||
protected void formatCommonResponse(PropertyFilter filter, List<NodeRef> sourceList, List<CmisObjectType> resultList) throws InvalidArgumentException, FilterNotValidException
|
||||
{
|
||||
|
||||
for (NodeRef objectNodeRef : sourceList)
|
||||
{
|
||||
resultList.add(convertAlfrescoObjectToCmisObject(objectNodeRef, filter));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef)
|
||||
*
|
||||
* @param objectNodeRef the Alfresco object against those conversion must to be done
|
||||
* @param filter accepted properties filter
|
||||
* @return converted to CMIS object Alfresco object
|
||||
*/
|
||||
protected CmisObjectType convertAlfrescoObjectToCmisObject(Object identifier, PropertyFilter filter)
|
||||
{
|
||||
|
||||
CmisObjectType result = new CmisObjectType();
|
||||
result.setProperties(getPropertiesType(identifier.toString(), filter));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts "Folder with folderNodeRef exists"
|
||||
*
|
||||
@@ -98,32 +150,30 @@ public class DMAbstractServicePort
|
||||
*/
|
||||
protected void assertExistFolder(NodeRef folderNodeRef) throws FolderNotValidException
|
||||
{
|
||||
CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping();
|
||||
if (folderNodeRef == null || nodeService.exists(folderNodeRef) == false || cmisMapping.isValidCmisFolder(cmisMapping.getCmisType(nodeService.getType(folderNodeRef))) == false)
|
||||
|
||||
if (!this.cmisObjectsUtils.isFolder(folderNodeRef))
|
||||
{
|
||||
throw new FolderNotValidException("OID for non-existent object or not folder object");
|
||||
}
|
||||
}
|
||||
|
||||
protected NodeRef getNodeRefFromOID(String oid) throws InvalidArgumentException
|
||||
/**
|
||||
* Checks specified in CMIS request parameters repository Id.
|
||||
*
|
||||
* @param repositoryId repository id
|
||||
* @throws InvalidArgumentException repository diesn't exist
|
||||
*/
|
||||
protected void checkRepositoryId(String repositoryId) throws InvalidArgumentException
|
||||
{
|
||||
NodeRef nodeRef;
|
||||
|
||||
try
|
||||
if (!this.descriptorService.getServerDescriptor().getId().equals(repositoryId))
|
||||
{
|
||||
nodeRef = new NodeRef(oid);
|
||||
throw new InvalidArgumentException("Invalid repository id");
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
{
|
||||
throw new InvalidArgumentException("Invalid OID value", e);
|
||||
}
|
||||
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
private void addBooleanProperty(CmisPropertiesType properties, PropertyFilter filter, String name, NodeRef nodeRef)
|
||||
private void addBooleanProperty(CmisPropertiesType properties, PropertyFilter filter, String name, Map<String, Serializable> alfrescoProperties)
|
||||
{
|
||||
Serializable value = cmisPropertyService.getProperty(nodeRef, name);
|
||||
Serializable value = alfrescoProperties.get(name);
|
||||
if (filter.allow(name) && value != null)
|
||||
{
|
||||
CmisPropertyBoolean propBoolean = new CmisPropertyBoolean ();
|
||||
@@ -133,9 +183,9 @@ public class DMAbstractServicePort
|
||||
}
|
||||
}
|
||||
|
||||
private void addDateTimeProperty(CmisPropertiesType properties, PropertyFilter filter, String name, NodeRef nodeRef)
|
||||
private void addDateTimeProperty(CmisPropertiesType properties, PropertyFilter filter, String name, Map<String, Serializable> alfrescoProperties)
|
||||
{
|
||||
Serializable value = cmisPropertyService.getProperty(nodeRef, name);
|
||||
Serializable value = alfrescoProperties.get(name);
|
||||
if (filter.allow(name) && value != null)
|
||||
{
|
||||
CmisPropertyDateTime propDateTime = new CmisPropertyDateTime();
|
||||
@@ -145,9 +195,9 @@ public class DMAbstractServicePort
|
||||
}
|
||||
}
|
||||
|
||||
private void addIDProperty(CmisPropertiesType properties, PropertyFilter filter, String name, NodeRef nodeRef)
|
||||
private void addIDProperty(CmisPropertiesType properties, PropertyFilter filter, String name, Map<String, Serializable> alfrescoProperties)
|
||||
{
|
||||
Serializable value = cmisPropertyService.getProperty(nodeRef, name);
|
||||
Serializable value = alfrescoProperties.get(name);
|
||||
if (filter.allow(name) && value != null)
|
||||
{
|
||||
CmisPropertyId propID = new CmisPropertyId();
|
||||
@@ -157,9 +207,9 @@ public class DMAbstractServicePort
|
||||
}
|
||||
}
|
||||
|
||||
private void addIntegerProperty(CmisPropertiesType properties, PropertyFilter filter, String name, NodeRef nodeRef)
|
||||
private void addIntegerProperty(CmisPropertiesType properties, PropertyFilter filter, String name, Map<String, Serializable> alfrescoProperties)
|
||||
{
|
||||
Serializable value = cmisPropertyService.getProperty(nodeRef, name);
|
||||
Serializable value = alfrescoProperties.get(name);
|
||||
if (filter.allow(name) && value != null)
|
||||
{
|
||||
CmisPropertyInteger propInteger = new CmisPropertyInteger();
|
||||
@@ -169,9 +219,9 @@ public class DMAbstractServicePort
|
||||
}
|
||||
}
|
||||
|
||||
private void addStringProperty(CmisPropertiesType properties, PropertyFilter filter, String name, NodeRef nodeRef)
|
||||
private void addStringProperty(CmisPropertiesType properties, PropertyFilter filter, String name, Map<String, Serializable> alfrescoProperties)
|
||||
{
|
||||
Serializable value = cmisPropertyService.getProperty(nodeRef, name);
|
||||
Serializable value = alfrescoProperties.get(name);
|
||||
if (filter.allow(name) && value != null)
|
||||
{
|
||||
CmisPropertyString propString = new CmisPropertyString();
|
||||
@@ -192,9 +242,9 @@ public class DMAbstractServicePort
|
||||
}
|
||||
}
|
||||
|
||||
private void addURIProperty(CmisPropertiesType properties, PropertyFilter filter, String name, NodeRef nodeRef)
|
||||
private void addURIProperty(CmisPropertiesType properties, PropertyFilter filter, String name, Map<String, Serializable> alfrescoProperties)
|
||||
{
|
||||
Serializable value = cmisPropertyService.getProperty(nodeRef, name);
|
||||
Serializable value = alfrescoProperties.get(name);
|
||||
if (filter.allow(name) && value != null)
|
||||
{
|
||||
CmisPropertyUri propString = new CmisPropertyUri();
|
||||
@@ -211,54 +261,91 @@ public class DMAbstractServicePort
|
||||
* @param filter property filter
|
||||
* @return properties
|
||||
*/
|
||||
public CmisPropertiesType getPropertiesType(NodeRef nodeRef, PropertyFilter filter)
|
||||
public CmisPropertiesType getPropertiesType(String identifier, PropertyFilter filter)
|
||||
{
|
||||
|
||||
Map<String, Serializable> properties = (NodeRef.isNodeRef(identifier)) ? (cmisPropertyService.getProperties(new NodeRef(identifier)))
|
||||
: (createBaseRelationshipProperties(new AssociationRef(identifier)));
|
||||
|
||||
return getPropertiesType(properties, filter);
|
||||
}
|
||||
|
||||
public CmisPropertiesType getPropertiesType(Map<String, Serializable> alfrescoProperties, PropertyFilter filter)
|
||||
{
|
||||
CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping();
|
||||
QName cmisType = cmisMapping.getCmisType(nodeService.getType(nodeRef));
|
||||
String objectTypeId = (String) alfrescoProperties.get(CMISMapping.PROP_OBJECT_TYPE_ID);
|
||||
QName cmisType = cmisMapping.getCmisTypeId(objectTypeId).getQName();
|
||||
|
||||
CmisPropertiesType properties = new CmisPropertiesType();
|
||||
|
||||
if (cmisMapping.isValidCmisDocument(cmisType))
|
||||
{
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_IMMUTABLE, nodeRef);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_LATEST_VERSION, nodeRef);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_MAJOR_VERSION, nodeRef);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_LATEST_MAJOR_VERSION, nodeRef);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT, nodeRef);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_CREATION_DATE, nodeRef);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_LAST_MODIFICATION_DATE, nodeRef);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_OBJECT_ID, nodeRef);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_VERSION_SERIES_ID, nodeRef);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID, nodeRef);
|
||||
addIntegerProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_LENGTH, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_NAME, nodeRef);
|
||||
addStringProperty(properties, filter, "BaseType", "document");
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_OBJECT_TYPE_ID, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CREATED_BY, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_LAST_MODIFIED_BY, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_FILENAME, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_VERSION_LABEL, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CHECKIN_COMMENT, nodeRef);
|
||||
addURIProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_URI, nodeRef);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_IMMUTABLE, alfrescoProperties);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_LATEST_VERSION, alfrescoProperties);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_MAJOR_VERSION, alfrescoProperties);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_LATEST_MAJOR_VERSION, alfrescoProperties);
|
||||
addBooleanProperty(properties, filter, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT, alfrescoProperties);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_CREATION_DATE, alfrescoProperties);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_LAST_MODIFICATION_DATE, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_OBJECT_ID, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_VERSION_SERIES_ID, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID, alfrescoProperties);
|
||||
addIntegerProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_LENGTH, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_NAME, alfrescoProperties);
|
||||
addStringProperty(properties, filter, BASE_TYPE_PROPERTY_NAME, "document");
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_OBJECT_TYPE_ID, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CREATED_BY, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_LAST_MODIFIED_BY, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_FILENAME, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_VERSION_LABEL, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CHECKIN_COMMENT, alfrescoProperties);
|
||||
addURIProperty(properties, filter, CMISMapping.PROP_CONTENT_STREAM_URI, alfrescoProperties);
|
||||
}
|
||||
else if (cmisMapping.isValidCmisFolder(cmisType))
|
||||
{
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_CREATION_DATE, nodeRef);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_LAST_MODIFICATION_DATE, nodeRef);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_OBJECT_ID, nodeRef);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_PARENT_ID, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_NAME, nodeRef);
|
||||
addStringProperty(properties, filter, "BaseType", "folder");
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_OBJECT_TYPE_ID, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CREATED_BY, nodeRef);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_LAST_MODIFIED_BY, nodeRef);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_CREATION_DATE, alfrescoProperties);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_LAST_MODIFICATION_DATE, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_OBJECT_ID, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_PARENT_ID, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_NAME, alfrescoProperties);
|
||||
addStringProperty(properties, filter, BASE_TYPE_PROPERTY_NAME, "folder");
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_OBJECT_TYPE_ID, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CREATED_BY, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_LAST_MODIFIED_BY, alfrescoProperties);
|
||||
}
|
||||
else if (cmisMapping.isValidCmisRelationship(cmisType))
|
||||
{
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_OBJECT_TYPE_ID, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_OBJECT_ID, alfrescoProperties);
|
||||
addStringProperty(properties, filter, BASE_TYPE_PROPERTY_NAME, alfrescoProperties);
|
||||
addStringProperty(properties, filter, CMISMapping.PROP_CREATED_BY, alfrescoProperties);
|
||||
addDateTimeProperty(properties, filter, CMISMapping.PROP_CREATION_DATE, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_SOURCE_ID, alfrescoProperties);
|
||||
addIDProperty(properties, filter, CMISMapping.PROP_TARGET_ID, alfrescoProperties);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all <i>properties</i>' fields for specified node
|
||||
*
|
||||
* @param nodeRef the <b>NodeRef</b> for node for those properties must be setted
|
||||
* @param properties all necessary properties fields
|
||||
*/
|
||||
protected void setProperties(NodeRef nodeRef, CmisPropertiesType properties)
|
||||
{
|
||||
// TODO: properties setting
|
||||
|
||||
String name = (String) PropertyUtil.getProperty(properties, CMISMapping.PROP_NAME);
|
||||
if (name != null)
|
||||
{
|
||||
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns latest minor or major version of document
|
||||
*
|
||||
@@ -286,8 +373,7 @@ public class DMAbstractServicePort
|
||||
do
|
||||
{
|
||||
latestVersion = versionHistory.getPredecessor(latestVersion);
|
||||
}
|
||||
while (latestVersion.getVersionType().equals(VersionType.MAJOR) == false);
|
||||
} while (latestVersion.getVersionType().equals(VersionType.MAJOR) == false);
|
||||
|
||||
latestVersionNodeRef = latestVersion.getFrozenStateNodeRef();
|
||||
}
|
||||
@@ -297,9 +383,19 @@ public class DMAbstractServicePort
|
||||
return latestVersionNodeRef;
|
||||
}
|
||||
|
||||
public static PropertyFilter createPropertyFilter(JAXBElement<String> filterElt) throws FilterNotValidException
|
||||
public static PropertyFilter createPropertyFilter(String filter) throws FilterNotValidException
|
||||
{
|
||||
return (filterElt == null) ? (new PropertyFilter()) : (new PropertyFilter(filterElt.getValue()));
|
||||
return (filter == null) ? (new PropertyFilter()) : (new PropertyFilter(filter));
|
||||
}
|
||||
|
||||
public static PropertyFilter createPropertyFilter(JAXBElement<String> element) throws FilterNotValidException
|
||||
{
|
||||
String filter = null;
|
||||
if (element != null)
|
||||
{
|
||||
filter = element.getValue();
|
||||
}
|
||||
return createPropertyFilter(filter);
|
||||
}
|
||||
|
||||
public Cursor createCursor(int totalRows, BigInteger skipCount, BigInteger maxItems)
|
||||
@@ -361,4 +457,58 @@ public class DMAbstractServicePort
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
||||
{
|
||||
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
}
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
public void setSearchService(SearchService searchService)
|
||||
{
|
||||
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
private Map<String, Serializable> createBaseRelationshipProperties(AssociationRef association)
|
||||
{
|
||||
|
||||
Map<String, Serializable> result = new HashMap<String, Serializable>();
|
||||
|
||||
result.put(CMISMapping.PROP_OBJECT_TYPE_ID, cmisDictionaryService.getCMISMapping().getCmisType(association.getTypeQName()));
|
||||
result.put(CMISMapping.PROP_OBJECT_ID, association.toString());
|
||||
result.put(BASE_TYPE_PROPERTY_NAME, CMISMapping.RELATIONSHIP_TYPE_ID.getTypeId());
|
||||
result.put(CMISMapping.PROP_CREATED_BY, AuthenticationUtil.getFullyAuthenticatedUser());
|
||||
result.put(CMISMapping.PROP_CREATION_DATE, new Date());
|
||||
result.put(CMISMapping.PROP_SOURCE_ID, association.getSourceRef());
|
||||
result.put(CMISMapping.PROP_TARGET_ID, association.getTargetRef());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Map<String, Serializable> createVersionProperties(String versionDescription, VersionType versionType)
|
||||
{
|
||||
|
||||
Map<String, Serializable> result = new HashMap<String, Serializable>();
|
||||
result.put(Version.PROP_DESCRIPTION, versionDescription);
|
||||
result.put(VersionModel.PROP_VERSION_TYPE, versionType);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected NodeRef performCheckouting(NodeRef documentNodeReference)
|
||||
{
|
||||
|
||||
if (!this.nodeService.hasAspect(documentNodeReference, ContentModel.ASPECT_VERSIONABLE))
|
||||
{
|
||||
this.versionService.createVersion(documentNodeReference, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MAJOR));
|
||||
}
|
||||
|
||||
return checkOutCheckInService.checkout(documentNodeReference);
|
||||
}
|
||||
}
|
||||
|
84
source/java/org/alfresco/repo/cmis/ws/DMDiscoveryServicePort.java
Executable file
84
source/java/org/alfresco/repo/cmis/ws/DMDiscoveryServicePort.java
Executable file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import org.alfresco.cmis.search.CMISQueryOptions;
|
||||
import org.alfresco.cmis.search.CMISResultSet;
|
||||
import org.alfresco.cmis.search.CMISResultSetRow;
|
||||
|
||||
/**
|
||||
* Port for Discovery service.
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
*/
|
||||
@javax.jws.WebService(name = "DiscoveryServicePort", serviceName = "DiscoveryService", portName = "DiscoveryServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.DiscoveryServicePort")
|
||||
public class DMDiscoveryServicePort extends DMAbstractServicePort implements DiscoveryServicePort
|
||||
{
|
||||
|
||||
/**
|
||||
* Queries the repository for queryable object based on properties or an optional full-text string. Relationship objects are not queryable. Content-streams are not returned as
|
||||
* part of query
|
||||
*
|
||||
* @param parameters query parameters
|
||||
* @return collection of CmisObjectType and boolean hasMoreItems
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public QueryResponse query(CmisQueryType parameters) throws PermissionDeniedException, UpdateConflictException, OperationNotSupportedException, InvalidArgumentException,
|
||||
RuntimeException, ConstraintViolationException
|
||||
{
|
||||
// TODO: searchAllVersions, returnAllowableActions, includeRelationships
|
||||
CMISQueryOptions options = new CMISQueryOptions(parameters.getStatement(), cmisService.getDefaultRootStoreRef());
|
||||
|
||||
if (parameters.getSkipCount() != null)
|
||||
{
|
||||
options.setSkipCount(parameters.getSkipCount().intValue());
|
||||
}
|
||||
|
||||
if (parameters.getPageSize() != null)
|
||||
{
|
||||
options.setMaxItems(parameters.getPageSize().intValue());
|
||||
}
|
||||
|
||||
CMISResultSet resultSet = cmisQueryService.query(options);
|
||||
|
||||
QueryResponse response = new QueryResponse();
|
||||
response.setHasMoreItems(resultSet.hasMore());
|
||||
|
||||
for (CMISResultSetRow row : resultSet)
|
||||
{
|
||||
CmisObjectType object = new CmisObjectType();
|
||||
object.setProperties(getPropertiesType(row.getValues(), new PropertyFilter()));
|
||||
response.getObject().add(object);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
122
source/java/org/alfresco/repo/cmis/ws/DMMultiFilingServicePort.java
Executable file
122
source/java/org/alfresco/repo/cmis/ws/DMMultiFilingServicePort.java
Executable file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* Port for Multi-Filing service.
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
@javax.jws.WebService(name = "MultiFilingServicePort", serviceName = "MultiFilingService", portName = "MultiFilingServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.MultiFilingServicePort")
|
||||
public class DMMultiFilingServicePort extends DMAbstractServicePort implements MultiFilingServicePort
|
||||
{
|
||||
/**
|
||||
* Adds an existing non-folder, fileable object to a folder.
|
||||
*
|
||||
* @param repositoryId Repository Id
|
||||
* @param objectId object Id to be added to a folder
|
||||
* @param folderId folder Id to which the object is added
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws FolderNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void addObjectToFolder(String repositoryId, String objectId, String folderId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
FolderNotValidException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = this.cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT).getConvertedIdentifier();
|
||||
NodeRef parentFolderNodeRef = this.cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier();
|
||||
|
||||
// TODO: check for allowed child object types
|
||||
|
||||
this.cmisObjectsUtils.addObjectToFolder(objectNodeRef, parentFolderNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a non-folder child object from a folder or from all folders. This does not delete the object and does not change the ID of the object.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param objectId The object to be removed from a folder
|
||||
* @param folderId The folder to be removed from.
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws FolderNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws NotInFolderException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void removeObjectFromFolder(String repositoryId, String objectId, String folderId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
FolderNotValidException, OperationNotSupportedException, NotInFolderException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
NodeRef objectNodeReference = this.cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT).getConvertedIdentifier();
|
||||
NodeRef folderNodeReference = checkAndReceiveFolderIdentifier(folderId);
|
||||
|
||||
assertExistFolder(folderNodeReference);
|
||||
|
||||
checkObjectChildParentRelationships(objectNodeReference, folderNodeReference);
|
||||
|
||||
if (!this.cmisObjectsUtils.removeObject(objectNodeReference, folderNodeReference))
|
||||
{
|
||||
throw new NotInFolderException("The specified Object is not child of the specified Folder Object");
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef checkAndReceiveFolderIdentifier(String folderIdentifier) throws OperationNotSupportedException
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
return this.cmisObjectsUtils.getIdentifierInstance(folderIdentifier, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new OperationNotSupportedException("Unfiling is not supported. Any Object can't be deleted from all Folders");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkObjectChildParentRelationships(NodeRef objectNodeReference, NodeRef folderNodeReference) throws OperationNotSupportedException
|
||||
{
|
||||
|
||||
if (this.cmisObjectsUtils.isPrimaryObjectParent(folderNodeReference, objectNodeReference))
|
||||
{
|
||||
throw new OperationNotSupportedException("Unfiling is not supported. User deleteObjectService instead");
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,35 +24,103 @@
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* Port for navigation service
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
|
||||
@javax.jws.WebService(name = "NavigationServicePort", serviceName = "NavigationService", portName = "NavigationServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.NavigationServicePort")
|
||||
public class DMNavigationServicePort extends DMAbstractServicePort implements NavigationServicePort
|
||||
{
|
||||
private static final String POLICIES_LISTING_UNSUPPORTED_EXCEPTION_MESSAGE = "Policies listing isn't supported";
|
||||
|
||||
private static final int EQUALS_CONDITION_VALUE = 0;
|
||||
|
||||
private static final BigInteger FULL_DESCENDANTS_HIERARCHY_CONDITION = BigInteger.valueOf(-1l);
|
||||
|
||||
/**
|
||||
* Gets the private working copies of checked-out objects that the user is allowed to update.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; folderID: folder Id; filter: property filter; includeAllowableActions; includeRelationships; maxItems: 0 = Unlimited;
|
||||
* skipCount: 0 = start at beginning
|
||||
* @return collection of CmisObjectType and boolean hasMoreItems
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws ConstraintViolationException
|
||||
* @throws FilterNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FolderNotValidException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public GetCheckedoutDocsResponse getCheckedoutDocs(GetCheckedoutDocs parameters) throws RuntimeException, InvalidArgumentException, ObjectNotFoundException,
|
||||
ConstraintViolationException, FilterNotValidException, OperationNotSupportedException, UpdateConflictException, FolderNotValidException, PermissionDeniedException
|
||||
{
|
||||
return null;
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
|
||||
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
|
||||
|
||||
NodeRef folderId = (NodeRef) (((parameters.getFolderID() != null) && (parameters.getFolderID().getValue() != null)) ? (this.cmisObjectsUtils.getIdentifierInstance(
|
||||
parameters.getFolderID().getValue(), AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier()) : (null));
|
||||
|
||||
NodeRef[] nodeRefs = this.cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderId, (folderId == null));
|
||||
|
||||
Cursor cursor = createCursor(nodeRefs.length, parameters.getSkipCount() != null ? parameters.getSkipCount().getValue() : null,
|
||||
parameters.getMaxItems() != null ? parameters.getMaxItems().getValue() : null);
|
||||
|
||||
GetCheckedoutDocsResponse response = new GetCheckedoutDocsResponse();
|
||||
List<CmisObjectType> resultListing = response.getObject();
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
resultListing.add(convertAlfrescoObjectToCmisObject(nodeRefs[index].toString(), propertyFilter));
|
||||
}
|
||||
|
||||
response.setHasMoreItems(cursor.getEndRow() < (nodeRefs.length - 1));
|
||||
|
||||
// TODO: includeAllowableActions, includeRelationships
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of child objects contained in the specified folder. Only the filter-selected properties associated with each object are returned. The content-streams of
|
||||
* documents are not returned.For returning a tree of objects of a certain depth, use {@link #getDescendants(GetDescendants parameters)}.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; folderId: folder Id; type: DOCUMENTS, FOLDERS, POLICIES, ANY; filter: property filter; includeAllowableActions;
|
||||
* includeRelationships; maxItems: 0 = Unlimited; skipCount: 0 = start at beginning
|
||||
* @return collection of CmisObjectType and boolean hasMoreItems
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws ConstraintViolationException
|
||||
* @throws FilterNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FolderNotValidException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public GetChildrenResponse getChildren(GetChildren parameters) throws RuntimeException, InvalidArgumentException, ObjectNotFoundException, ConstraintViolationException,
|
||||
FilterNotValidException, OperationNotSupportedException, UpdateConflictException, FolderNotValidException, PermissionDeniedException
|
||||
{
|
||||
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
|
||||
|
||||
NodeRef folderNodeRef = getNodeRefFromOID(parameters.getFolderId());
|
||||
assertExistFolder(folderNodeRef);
|
||||
NodeRef folderNodeRef = this.cmisObjectsUtils.getIdentifierInstance(parameters.getFolderId(), AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier();
|
||||
|
||||
NodeRef[] listing = null;
|
||||
|
||||
@@ -72,50 +140,327 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.FOLDERS);
|
||||
break;
|
||||
case POLICIES:
|
||||
throw new OperationNotSupportedException("Policies listing isn't supported");
|
||||
throw new OperationNotSupportedException(POLICIES_LISTING_UNSUPPORTED_EXCEPTION_MESSAGE);
|
||||
case ANY:
|
||||
listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY);
|
||||
break;
|
||||
}
|
||||
|
||||
Cursor cursor = createCursor(listing.length, parameters.getSkipCount() != null ? parameters.getSkipCount().getValue() : null, parameters.getMaxItems() != null ? parameters
|
||||
.getMaxItems().getValue() : null);
|
||||
Cursor cursor = createCursor(listing.length, (parameters.getSkipCount() != null ? parameters.getSkipCount().getValue() : null),
|
||||
(parameters.getMaxItems() != null ? parameters.getMaxItems().getValue() : null));
|
||||
|
||||
GetChildrenResponse response = new GetChildrenResponse();
|
||||
List<CmisObjectType> resultListing = response.getObject();
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
NodeRef currentNodeRef = listing[index];
|
||||
CmisObjectType cmisObject = new CmisObjectType();
|
||||
cmisObject.setProperties(getPropertiesType(currentNodeRef, propertyFilter));
|
||||
resultListing.add(cmisObject);
|
||||
resultListing.add(convertAlfrescoObjectToCmisObject(listing[index].toString(), propertyFilter));
|
||||
}
|
||||
|
||||
if (parameters.getMaxItems() != null && cursor.getRowCount() > 0)
|
||||
{
|
||||
response.setHasMoreItems(cursor.getRowCount() < listing.length);
|
||||
}
|
||||
response.setHasMoreItems(cursor.getEndRow() < (listing.length - 1));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of descendant objects contained at one or more levels in the tree rooted at the specified folder. Only the filter-selected properties associated with each
|
||||
* object are returned. The content-stream is not returned. For paging through the children (depth of 1) only use {@link #getChildren(GetChildren parameters)}.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; folderId: folder Id; depth: 1 this folder only (Default), <20> N folders deep, -1 for all levels; filter: property filter;
|
||||
* includeAllowableActions; includeRelationships;
|
||||
* @return collection of CmisObjectType
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws ConstraintViolationException
|
||||
* @throws FilterNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FolderNotValidException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public GetDescendantsResponse getDescendants(GetDescendants parameters) throws RuntimeException, InvalidArgumentException, ObjectNotFoundException,
|
||||
ConstraintViolationException, FilterNotValidException, OperationNotSupportedException, UpdateConflictException, FolderNotValidException, PermissionDeniedException
|
||||
{
|
||||
return null;
|
||||
|
||||
BigInteger depth = ((parameters.getDepth() != null) && (parameters.getDepth().getValue() != null)) ? (parameters.getDepth().getValue()) : (BigInteger.ONE);
|
||||
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
checkDepthParameter(depth);
|
||||
|
||||
GetDescendantsResponse response = new GetDescendantsResponse();
|
||||
|
||||
formatCommonResponse(createPropertyFilter(parameters.getFilter()), createHierarchyReceiver(
|
||||
(parameters.getType() != null) ? (parameters.getType()) : (EnumTypesOfFileableObjects.ANY), depth).receiveHierarchy(parameters.getFolderId()), response.getObject());
|
||||
|
||||
// TODO: includeAllowableActions, includeRelationships
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent folder object, and optionally all ancestor folder objects, above a specified folder object.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; folderId: folder Id; filter: property filter; includeAllowableActions; includeRelationships; returnToRoot: If false, return
|
||||
* only the immediate parent of the folder. If true, return an ordered list of all ancestor folders from the specified folder to the root folder
|
||||
* @return collection of CmisObjectType
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws ConstraintViolationException
|
||||
* @throws FilterNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FolderNotValidException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public GetFolderParentResponse getFolderParent(GetFolderParent parameters) throws RuntimeException, InvalidArgumentException, ObjectNotFoundException,
|
||||
ConstraintViolationException, FilterNotValidException, OperationNotSupportedException, UpdateConflictException, FolderNotValidException, PermissionDeniedException
|
||||
{
|
||||
return null;
|
||||
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
|
||||
GetFolderParentResponse response = new GetFolderParentResponse();
|
||||
|
||||
formatCommonResponse(createPropertyFilter(parameters.getFilter()), receiveParentList(parameters.getFolderId(), (((parameters.getReturnToRoot() != null) && (parameters
|
||||
.getReturnToRoot().getValue() != null)) ? (parameters.getReturnToRoot().getValue()) : (false))), response.getObject());
|
||||
|
||||
// TODO: includeAllowableActions, includeRelationships
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent folders for the specified non-folder, fileable object.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; objectId: object Id; filter: property filter; includeAllowableActions; includeRelationships;
|
||||
* @return collection of CmisObjectType
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws ConstraintViolationException
|
||||
* @throws FilterNotValidException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FolderNotValidException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public GetObjectParentsResponse getObjectParents(GetObjectParents parameters) throws RuntimeException, InvalidArgumentException, ObjectNotFoundException,
|
||||
ConstraintViolationException, FilterNotValidException, OperationNotSupportedException, UpdateConflictException, FolderNotValidException, PermissionDeniedException
|
||||
{
|
||||
return null;
|
||||
// TODO: Policy
|
||||
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
|
||||
GetObjectParentsResponse response = new GetObjectParentsResponse();
|
||||
|
||||
formatCommonResponse(createPropertyFilter(parameters.getFilter()), receiveObjectParents((NodeRef) this.cmisObjectsUtils.getIdentifierInstance(parameters.getObjectId(),
|
||||
AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier()), response.getObject());
|
||||
|
||||
// TODO: includeAllowableActions, includeRelationships
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private void checkDepthParameter(BigInteger depth) throws InvalidArgumentException
|
||||
{
|
||||
|
||||
if (depth.equals(BigInteger.ZERO) || (depth.compareTo(FULL_DESCENDANTS_HIERARCHY_CONDITION) < EQUALS_CONDITION_VALUE))
|
||||
{
|
||||
throw new InvalidArgumentException("The specified descendants retriving depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0");
|
||||
}
|
||||
}
|
||||
|
||||
private List<NodeRef> receiveParentList(String targetChildIdentifier, boolean fullParentsHierarchy) throws InvalidNodeRefException, InvalidArgumentException,
|
||||
ObjectNotFoundException
|
||||
{
|
||||
|
||||
List<NodeRef> result = new LinkedList<NodeRef>();
|
||||
|
||||
if (targetChildIdentifier.equals(this.cmisService.getDefaultRootNodeRef().toString()))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
NodeRef currentParent = receiveNextParentNodeReference((NodeRef) this.cmisObjectsUtils.getIdentifierInstance(targetChildIdentifier, AlfrescoObjectType.FOLDER_OBJECT)
|
||||
.getConvertedIdentifier(), result);
|
||||
|
||||
return (fullParentsHierarchy) ? (receiveFullAncestorsHierachy(currentParent, result)) : (result);
|
||||
}
|
||||
|
||||
private List<NodeRef> receiveFullAncestorsHierachy(NodeRef currentParent, List<NodeRef> parents)
|
||||
{
|
||||
|
||||
String lastAncestorIdentifier = this.cmisService.getDefaultRootNodeRef().toString();
|
||||
|
||||
while ((currentParent != null) && !currentParent.toString().equals(lastAncestorIdentifier))
|
||||
{
|
||||
currentParent = receiveNextParentNodeReference(currentParent, parents);
|
||||
}
|
||||
|
||||
return parents;
|
||||
}
|
||||
|
||||
private NodeRef receiveNextParentNodeReference(NodeRef currentParent, List<NodeRef> parents)
|
||||
{
|
||||
|
||||
currentParent = this.nodeService.getPrimaryParent(currentParent).getParentRef();
|
||||
|
||||
if (currentParent != null)
|
||||
{
|
||||
parents.add(currentParent);
|
||||
}
|
||||
|
||||
return currentParent;
|
||||
}
|
||||
|
||||
private List<NodeRef> receiveObjectParents(NodeRef objectId) throws InvalidArgumentException
|
||||
{
|
||||
|
||||
List<NodeRef> parents = new LinkedList<NodeRef>();
|
||||
|
||||
for (ChildAssociationRef childParentAssociation : this.nodeService.getParentAssocs(objectId))
|
||||
{
|
||||
parents.add(childParentAssociation.getParentRef());
|
||||
}
|
||||
|
||||
return parents;
|
||||
}
|
||||
|
||||
private HierarchyReceiverStrategy createHierarchyReceiver(EnumTypesOfFileableObjects returnObjectsType, BigInteger finalDepth)
|
||||
{
|
||||
|
||||
return (finalDepth.equals(FULL_DESCENDANTS_HIERARCHY_CONDITION)) ? (new FullHierarchyReceiver(returnObjectsType)) : (new LayerConstrainedHierarchyReceiver(
|
||||
returnObjectsType, finalDepth));
|
||||
}
|
||||
|
||||
private void separateDescendantsObjects(EnumTypesOfFileableObjects returnObjectsType, List<NodeRef> descendantsFolders, List<NodeRef> currentLayerFolders,
|
||||
List<NodeRef> currentLayerDocuments)
|
||||
{
|
||||
|
||||
for (NodeRef element : descendantsFolders)
|
||||
{
|
||||
// TODO: OrderBy functionality processing. Instead Arrays.asList() it is necessary to add ordering processing method to store each new element where it should go
|
||||
currentLayerFolders.addAll(Arrays.asList(this.cmisService.getChildren(element, CMISTypesFilterEnum.FOLDERS)));
|
||||
|
||||
// TODO: OrderBy functionality processing. Instead Arrays.asList() it is necessary to add ordering processing method to store each new element where it should go
|
||||
if ((returnObjectsType == EnumTypesOfFileableObjects.ANY) || (returnObjectsType == EnumTypesOfFileableObjects.DOCUMENTS))
|
||||
{
|
||||
currentLayerDocuments.addAll(Arrays.asList(this.cmisService.getChildren(element, CMISTypesFilterEnum.DOCUMENTS)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<NodeRef> performDescendantsResultObjectsStoring(EnumTypesOfFileableObjects returnObjectsType, List<NodeRef> resultList, List<NodeRef> descendantsFolders,
|
||||
List<NodeRef> currentLayerFolders, List<NodeRef> currentLayerDocuments)
|
||||
{
|
||||
|
||||
separateDescendantsObjects(returnObjectsType, descendantsFolders, currentLayerFolders, currentLayerDocuments);
|
||||
|
||||
if ((returnObjectsType == EnumTypesOfFileableObjects.ANY) || (returnObjectsType == EnumTypesOfFileableObjects.FOLDERS))
|
||||
{
|
||||
resultList.addAll(currentLayerFolders);
|
||||
}
|
||||
|
||||
resultList.addAll(currentLayerDocuments);
|
||||
|
||||
return currentLayerFolders;
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface introduce common type for Alfresco objects hierarchy receiving
|
||||
*/
|
||||
private interface HierarchyReceiverStrategy
|
||||
{
|
||||
/**
|
||||
* @param rootFolderIdentifier the source folder Id from whose hierarchy bypassing will be started
|
||||
* @return <b>List</b> that contains all appropriates layers of Alfresco objects
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public List<NodeRef> receiveHierarchy(String rootFolderIdentifier) throws InvalidArgumentException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HierarchyReceiverStrategy
|
||||
*/
|
||||
private class LayerConstrainedHierarchyReceiver implements HierarchyReceiverStrategy
|
||||
{
|
||||
private List<NodeRef> descendantsFolders = new LinkedList<NodeRef>();
|
||||
|
||||
private EnumTypesOfFileableObjects returnObjectsType;
|
||||
|
||||
private BigInteger finalDepth;
|
||||
|
||||
private BigInteger currentDepth = BigInteger.ZERO;
|
||||
|
||||
private List<NodeRef> resultList = new LinkedList<NodeRef>();
|
||||
|
||||
/**
|
||||
* @param returnObjectsType flag that specifies objects of which type are need to be returned
|
||||
* @param finalDepth the number of final Alfresco hierarchy layer: 1 - only children of specified folder; -1 - full descendants hierarchy
|
||||
*/
|
||||
public LayerConstrainedHierarchyReceiver(EnumTypesOfFileableObjects returnObjectsType, BigInteger finalDepth)
|
||||
{
|
||||
|
||||
this.returnObjectsType = returnObjectsType;
|
||||
this.finalDepth = finalDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method of this class receives Alfresco objects hierarchy until specified layer number
|
||||
*/
|
||||
public List<NodeRef> receiveHierarchy(String rootFolderIdentifier) throws InvalidArgumentException
|
||||
{
|
||||
|
||||
this.descendantsFolders.add((NodeRef) cmisObjectsUtils.getIdentifierInstance(rootFolderIdentifier, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier());
|
||||
|
||||
do
|
||||
{
|
||||
this.descendantsFolders = performDescendantsResultObjectsStoring(this.returnObjectsType, this.resultList, this.descendantsFolders, new LinkedList<NodeRef>(),
|
||||
new LinkedList<NodeRef>());
|
||||
|
||||
this.currentDepth = this.currentDepth.add(BigInteger.ONE);
|
||||
} while (!this.descendantsFolders.isEmpty() && (this.currentDepth.compareTo(this.finalDepth) < EQUALS_CONDITION_VALUE));
|
||||
|
||||
return this.resultList;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see HierarchyReceiverStrategy
|
||||
*/
|
||||
private class FullHierarchyReceiver implements HierarchyReceiverStrategy
|
||||
{
|
||||
private EnumTypesOfFileableObjects returnObjectsType;
|
||||
|
||||
private List<NodeRef> descendantsFolders = new LinkedList<NodeRef>();
|
||||
|
||||
private List<NodeRef> resultList = new LinkedList<NodeRef>();
|
||||
|
||||
/**
|
||||
* @param returnObjectsType flag that specifies objects of which type are need to be returned
|
||||
*/
|
||||
public FullHierarchyReceiver(EnumTypesOfFileableObjects returnObjectsType)
|
||||
{
|
||||
|
||||
this.returnObjectsType = returnObjectsType;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method of this class bypass Alfresco objects hierarchy until there is some Folder-objects can be found
|
||||
*/
|
||||
public List<NodeRef> receiveHierarchy(String rootFolderIdentifier) throws InvalidArgumentException
|
||||
{
|
||||
|
||||
this.descendantsFolders.add((NodeRef) cmisObjectsUtils.getIdentifierInstance(rootFolderIdentifier, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier());
|
||||
|
||||
while (!this.descendantsFolders.isEmpty())
|
||||
{
|
||||
this.descendantsFolders = performDescendantsResultObjectsStoring(this.returnObjectsType, this.resultList, this.descendantsFolders, new LinkedList<NodeRef>(),
|
||||
new LinkedList<NodeRef>());
|
||||
}
|
||||
|
||||
return this.resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
93
source/java/org/alfresco/repo/cmis/ws/DMPolicyServicePort.java
Executable file
93
source/java/org/alfresco/repo/cmis/ws/DMPolicyServicePort.java
Executable file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
@javax.jws.WebService(name = "PolicyServicePort", serviceName = "PolicyServicePort", portName = "PolicyServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.PolicyServicePort")
|
||||
public class DMPolicyServicePort extends DMAbstractServicePort implements PolicyServicePort
|
||||
{
|
||||
|
||||
/**
|
||||
* Applies a policy object to a target object.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param policyId policy Id
|
||||
* @param objectId target object Id
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void applyPolicy(String repositoryId, String policyId, String objectId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of policy objects currently applied to a target object.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; objectId: target object Id; filter: filter specifying which properties to return
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FilterNotValidException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public GetAppliedPoliciesResponse getAppliedPolicies(GetAppliedPolicies parameters) throws PermissionDeniedException, UpdateConflictException, FilterNotValidException,
|
||||
ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a previously applied policy from a target object. The policy object is not deleted, and may still be applied to other objects.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param policyId policy Id
|
||||
* @param objectId target object Id.
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void removePolicy(String repositoryId, String policyId, String objectId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
151
source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java
Executable file
151
source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java
Executable file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
|
||||
/**
|
||||
* Port for relationship service
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
@javax.jws.WebService(name = "RelationshipServicePort", serviceName = "RelationshipService", portName = "RelationshipServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.RelationshipServicePort")
|
||||
public class DMRelationshipServicePort extends DMAbstractServicePort implements RelationshipServicePort
|
||||
{
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
/**
|
||||
* Gets a list of relationships associated with the object, optionally of a specified relationship type, and optionally in a specified direction.
|
||||
*
|
||||
* @param parameters repositoryId: Repository Id, objectId: The object with which relationships are associated with; direction: source (Default), target, both; typeId:
|
||||
* Relationship Type; includeSubRelationshipTypes: false (Default); filter: property filter; includeAllowableActions: false (default); maxItems: 0 = Unlimited;
|
||||
* skipCount: 0 = start at beginning
|
||||
* @return collection of CmisObjectType and boolean hasMoreItems
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FilterNotValidException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws TypeNotFoundException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public GetRelationshipsResponse getRelationships(GetRelationships parameters) throws PermissionDeniedException, UpdateConflictException, FilterNotValidException,
|
||||
ObjectNotFoundException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
|
||||
EnumRelationshipDirection direction = ((parameters.getDirection() != null) && (parameters.getDirection().getValue() != null)) ? (parameters.getDirection().getValue())
|
||||
: (EnumRelationshipDirection.SOURCE);
|
||||
Boolean includingSubtypes = ((parameters.getIncludeSubRelationshipTypes() != null) && (parameters.getIncludeSubRelationshipTypes().getValue() != null)) ? (parameters
|
||||
.getIncludeSubRelationshipTypes().getValue()) : (false);
|
||||
String typeId = ((parameters.getTypeId() != null) && (parameters.getTypeId().getValue() != null)) ? (parameters.getTypeId().getValue()) : (null);
|
||||
BigInteger skipCount = ((parameters.getSkipCount() != null) && (parameters.getSkipCount().getValue() != null)) ? (parameters.getSkipCount().getValue()) : (BigInteger.ZERO);
|
||||
BigInteger maxItems = ((parameters.getMaxItems() != null) && (parameters.getMaxItems().getValue() != null)) ? (parameters.getMaxItems().getValue()) : (BigInteger.ZERO);
|
||||
|
||||
QName associationType = cmisDictionaryService.getCMISMapping().getAlfrescoType(cmisDictionaryService.getCMISMapping().getCmisTypeId(typeId).getQName());
|
||||
|
||||
return formatResponse(createPropertyFilter(parameters.getFilter()), receiveAssociations(
|
||||
(NodeRef) this.cmisObjectsUtils.getIdentifierInstance(parameters.getObjectId(), AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT).getConvertedIdentifier(),
|
||||
associationType, direction, includingSubtypes).toArray(), new GetRelationshipsResponse(), skipCount, maxItems);
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
private GetRelationshipsResponse formatResponse(PropertyFilter filter, Object[] sourceArray, GetRelationshipsResponse result, BigInteger skipCount, BigInteger maxItems)
|
||||
throws InvalidArgumentException, FilterNotValidException
|
||||
{
|
||||
|
||||
Cursor cursor = createCursor(sourceArray.length, skipCount, maxItems);
|
||||
|
||||
for (int i = cursor.getStartRow(); i < cursor.getEndRow(); i++)
|
||||
{
|
||||
result.getObject().add(convertAlfrescoObjectToCmisObject(sourceArray[i].toString(), filter));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<AssociationRef> receiveAssociations(NodeRef objectNodeReference, QName necessaryRelationshipType, EnumRelationshipDirection direction, boolean includingSubtypes)
|
||||
{
|
||||
|
||||
List<AssociationRef> result = new LinkedList<AssociationRef>();
|
||||
|
||||
QNamePattern matcher = new RelationshipByTypeFilter(necessaryRelationshipType, includingSubtypes);
|
||||
|
||||
if ((direction == EnumRelationshipDirection.BOTH) || (direction == EnumRelationshipDirection.TARGET))
|
||||
{
|
||||
result.addAll(this.nodeService.getSourceAssocs(objectNodeReference, matcher));
|
||||
}
|
||||
|
||||
if ((direction == EnumRelationshipDirection.BOTH) || (direction == EnumRelationshipDirection.SOURCE))
|
||||
{
|
||||
result.addAll(this.nodeService.getTargetAssocs(objectNodeReference, matcher));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private class RelationshipByTypeFilter implements QNamePattern
|
||||
{
|
||||
private boolean includingSubtypes;
|
||||
private QName necessaryGeneralType;
|
||||
|
||||
public RelationshipByTypeFilter(QName necessaryGeneralType, boolean includingSubtypes)
|
||||
{
|
||||
|
||||
this.includingSubtypes = includingSubtypes;
|
||||
this.necessaryGeneralType = necessaryGeneralType;
|
||||
}
|
||||
|
||||
public boolean isMatch(QName qname)
|
||||
{
|
||||
|
||||
if (this.necessaryGeneralType == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return ((this.includingSubtypes) ? (dictionaryService.getAssociation(qname) != null)
|
||||
: (cmisDictionaryService.getCMISMapping().isValidCmisRelationship(qname) && this.necessaryGeneralType.equals(qname)));
|
||||
}
|
||||
}
|
||||
}
|
@@ -43,6 +43,7 @@ import org.alfresco.cmis.CMISJoinEnum;
|
||||
import org.alfresco.cmis.CMISPropertyTypeEnum;
|
||||
import org.alfresco.cmis.CMISUpdatabilityEnum;
|
||||
import org.alfresco.cmis.dictionary.CMISChoice;
|
||||
import org.alfresco.cmis.dictionary.CMISMapping;
|
||||
import org.alfresco.cmis.dictionary.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.dictionary.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.dictionary.CMISTypeId;
|
||||
@@ -50,11 +51,10 @@ import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.descriptor.Descriptor;
|
||||
|
||||
/**
|
||||
* Port for repository service
|
||||
* Port for repository service.
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
*/
|
||||
|
||||
@javax.jws.WebService(name = "RepositoryServicePort", serviceName = "RepositoryService", portName = "RepositoryServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.RepositoryServicePort")
|
||||
public class DMRepositoryServicePort extends DMAbstractServicePort implements RepositoryServicePort
|
||||
{
|
||||
@@ -103,6 +103,16 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
propertyTypeEnumMapping.put(CMISPropertyTypeEnum.XML, EnumPropertyType.XML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of available repositories for this CMIS service endpoint.
|
||||
*
|
||||
* @return collection of CmisRepositoryEntryType (repositoryId - repository Id, repositoryName: repository name, repositoryURI: Repository URI)
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public List<CmisRepositoryEntryType> getRepositories() throws RuntimeException, InvalidArgumentException, OperationNotSupportedException, UpdateConflictException,
|
||||
PermissionDeniedException
|
||||
{
|
||||
@@ -113,6 +123,19 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
return Collections.singletonList(repositoryEntryType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the CMIS repository and the capabilities it supports.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id
|
||||
* @return CMIS repository Info
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public CmisRepositoryInfoType getRepositoryInfo(GetRepositoryInfo parameters) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
@@ -128,7 +151,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
repositoryInfoType.setRepositoryName(serverDescriptor.getName());
|
||||
repositoryInfoType.setRepositoryRelationship("self");
|
||||
repositoryInfoType.setRepositoryDescription("");
|
||||
repositoryInfoType.setRootFolderId(cmisService.getDefaultRootNodeRef().toString());
|
||||
repositoryInfoType.setRootFolderId((String) cmisPropertyService.getProperty(cmisService.getDefaultRootNodeRef(), CMISMapping.PROP_OBJECT_ID));
|
||||
repositoryInfoType.setVendorName("Alfresco");
|
||||
repositoryInfoType.setProductName("Alfresco Repository (" + serverDescriptor.getEdition() + ")");
|
||||
repositoryInfoType.setProductVersion(serverDescriptor.getVersion());
|
||||
@@ -370,6 +393,20 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of all types in the repository.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; typeId: type Id; returnPropertyDefinitions: false (default); maxItems: 0 = Repository-default number of items(Default);
|
||||
* skipCount: 0 = start;
|
||||
* @return collection of CmisTypeDefinitionType and boolean hasMoreItems
|
||||
* @throws RuntimeException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws ConstraintViolationException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
public GetTypesResponse getTypes(GetTypes parameters) throws RuntimeException, InvalidArgumentException, ObjectNotFoundException, ConstraintViolationException,
|
||||
OperationNotSupportedException, UpdateConflictException, PermissionDeniedException
|
||||
{
|
||||
@@ -413,6 +450,20 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition for specified object type
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; typeId: type Id;
|
||||
* @return CMIS type definition
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws TypeNotFoundException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public GetTypeDefinitionResponse getTypeDefinition(GetTypeDefinition parameters) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
|
@@ -31,7 +31,7 @@ import org.springframework.aop.ThrowsAdvice;
|
||||
|
||||
/**
|
||||
* @author Dmitry Lazurkin
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
{
|
||||
@@ -44,7 +44,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
log.info(e);
|
||||
}
|
||||
|
||||
throw new PermissionDeniedException("Access denied", e);
|
||||
throw new PermissionDeniedException("Access denied. Message: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
public void afterThrowing(java.lang.RuntimeException e) throws RuntimeException
|
||||
@@ -54,7 +54,6 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
log.error(e);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Runtime error", e);
|
||||
throw new RuntimeException("Runtime error. Message: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
281
source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java
Executable file
281
source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java
Executable file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.dictionary.CMISMapping;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
|
||||
/**
|
||||
* Port for versioning service.
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
@javax.jws.WebService(name = "VersioningServicePort", serviceName = "VersioningService", portName = "VersioningServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.VersioningServicePort")
|
||||
public class DMVersioningServicePort extends DMAbstractServicePort implements VersioningServicePort
|
||||
{
|
||||
private LockService lockService;
|
||||
|
||||
/**
|
||||
* Reverses the effect of a check-out. Removes the private working copy of the checked-out document object, allowing other documents in the version series to be checked out
|
||||
* again.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param documentId document Id
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public void cancelCheckOut(String repositoryId, String documentId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
OperationNotSupportedException, InvalidArgumentException, RuntimeException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef workingCopyNodeRef = this.cmisObjectsUtils.getIdentifierInstance(documentId, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier();
|
||||
assertWorkingCopy(workingCopyNodeRef);
|
||||
checkOutCheckInService.cancelCheckout(workingCopyNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the private working copy the current version of the document.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param documentId document Id
|
||||
* @param major is major True (Default)
|
||||
* @param properties CMIS properties
|
||||
* @param contentStream content stream
|
||||
* @param checkinComment check in comment
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws StorageException
|
||||
* @throws StreamNotSupportedException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void checkIn(String repositoryId, Holder<String> documentId, Boolean major, CmisPropertiesType properties, CmisContentStreamType contentStream, String checkinComment)
|
||||
throws PermissionDeniedException, UpdateConflictException, StorageException, StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException,
|
||||
InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef workingCopyNodeRef = this.cmisObjectsUtils.getIdentifierInstance(documentId.value, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier();
|
||||
assertWorkingCopy(workingCopyNodeRef);
|
||||
|
||||
if (contentStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ContentWriter writer = fileFolderService.getWriter(workingCopyNodeRef);
|
||||
writer.setMimetype(contentStream.getMimeType());
|
||||
writer.putContent(contentStream.getStream().getInputStream());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Exception while updating content stream");
|
||||
}
|
||||
}
|
||||
|
||||
if (properties != null)
|
||||
{
|
||||
setProperties(workingCopyNodeRef, properties);
|
||||
}
|
||||
|
||||
NodeRef nodeRef = checkOutCheckInService.checkin(workingCopyNodeRef, createVersionProperties(checkinComment, ((major != null) && (major)) ? (VersionType.MAJOR)
|
||||
: (VersionType.MINOR)));
|
||||
|
||||
documentId.value = (String) cmisPropertyService.getProperty(nodeRef, CMISMapping.PROP_OBJECT_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a private working copy of the object, copies the metadata and optionally content.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param documentId ObjectID of document version to checkout
|
||||
* @param contentCopied
|
||||
* @return ObjectID of private working copy as documentId; True if succeed, False otherwise as contentCopied
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void checkOut(String repositoryId, Holder<String> documentId, Holder<Boolean> contentCopied) throws PermissionDeniedException, UpdateConflictException,
|
||||
ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
|
||||
NodeRef documentNodeRef = this.cmisObjectsUtils.getIdentifierInstance(documentId.value, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier();
|
||||
|
||||
LockStatus lockStatus = lockService.getLockStatus(documentNodeRef);
|
||||
|
||||
if (lockStatus.equals(LockStatus.LOCKED) || lockStatus.equals(LockStatus.LOCK_OWNER) || nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
throw new OperationNotSupportedException("Object is already checked out");
|
||||
}
|
||||
|
||||
NodeRef pwcNodeRef = performCheckouting(documentNodeRef);
|
||||
|
||||
documentId.value = (String) cmisPropertyService.getProperty(pwcNodeRef, CMISMapping.PROP_OBJECT_ID);
|
||||
contentCopied.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all document versions in the specified version series.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param versionSeriesId version series Id
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public void deleteAllVersions(String repositoryId, String versionSeriesId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException,
|
||||
OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = this.cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier();
|
||||
|
||||
versionService.deleteVersionHistory(documentNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of all document versions for the specified version series.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; versionSeriesId: version series Id; filter: property filter; includeAllowableActions; includeRelationships;
|
||||
* @return list of CmisObjectType
|
||||
* @throws PermissionDeniedException
|
||||
* @throws UpdateConflictException
|
||||
* @throws FilterNotValidException
|
||||
* @throws ObjectNotFoundException
|
||||
* @throws OperationNotSupportedException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws RuntimeException
|
||||
* @throws ConstraintViolationException
|
||||
*/
|
||||
public GetAllVersionsResponse getAllVersions(GetAllVersions parameters) throws PermissionDeniedException, UpdateConflictException, FilterNotValidException,
|
||||
ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException
|
||||
{
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
|
||||
NodeRef documentNodeRef = this.cmisObjectsUtils.getIdentifierInstance(parameters.getVersionSeriesId(), AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier();
|
||||
documentNodeRef = getLatestVersionNodeRef(documentNodeRef, false);
|
||||
|
||||
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
|
||||
|
||||
GetAllVersionsResponse response = new GetAllVersionsResponse();
|
||||
List<CmisObjectType> objects = response.getObject();
|
||||
|
||||
searchWorkingCopy(documentNodeRef, propertyFilter, objects);
|
||||
objects.add(convertAlfrescoObjectToCmisObject(documentNodeRef, propertyFilter));
|
||||
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(documentNodeRef);
|
||||
|
||||
if (versionHistory == null)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
Version version = this.versionService.getCurrentVersion(documentNodeRef);
|
||||
|
||||
while (version != null)
|
||||
{
|
||||
objects.add(convertAlfrescoObjectToCmisObject(version.getFrozenStateNodeRef(), propertyFilter));
|
||||
|
||||
version = versionHistory.getPredecessor(version);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of the latest version, or the latest major version, of the specified version series.
|
||||
*
|
||||
* @param parameters repositoryId: repository Id; versionSeriesId: version series Id; majorVersion: whether or not to return the latest major version. Default=FALSE; filter:
|
||||
* property filter
|
||||
* @return CmisObjectType with properties
|
||||
*/
|
||||
public GetPropertiesOfLatestVersionResponse getPropertiesOfLatestVersion(GetPropertiesOfLatestVersion parameters) throws PermissionDeniedException, UpdateConflictException,
|
||||
FilterNotValidException, ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException
|
||||
{
|
||||
checkRepositoryId(parameters.getRepositoryId());
|
||||
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
|
||||
|
||||
NodeRef documentNodeRef = this.cmisObjectsUtils.getIdentifierInstance(parameters.getVersionSeriesId(), AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier();
|
||||
|
||||
NodeRef latestVersionNodeRef = getLatestVersionNodeRef(documentNodeRef, parameters.isMajorVersion());
|
||||
|
||||
GetPropertiesOfLatestVersionResponse response = new GetPropertiesOfLatestVersionResponse();
|
||||
response.setObject(new CmisObjectType());
|
||||
CmisObjectType object = response.getObject();
|
||||
object.setProperties(getPropertiesType(latestVersionNodeRef.toString(), propertyFilter));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
private void searchWorkingCopy(NodeRef documentNodeRef, PropertyFilter propertyFilter, List<CmisObjectType> resultList)
|
||||
{
|
||||
|
||||
NodeRef workingCopyNodeReference = (this.cmisObjectsUtils.isWorkingCopy(documentNodeRef)) ? (documentNodeRef) : (checkOutCheckInService.getWorkingCopy(documentNodeRef));
|
||||
|
||||
if (workingCopyNodeReference instanceof NodeRef)
|
||||
{
|
||||
resultList.add(convertAlfrescoObjectToCmisObject(workingCopyNodeReference, propertyFilter));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertWorkingCopy(NodeRef nodeRef) throws OperationNotSupportedException
|
||||
{
|
||||
if (!this.cmisObjectsUtils.isWorkingCopy(nodeRef))
|
||||
{
|
||||
throw new OperationNotSupportedException("Object isn't checked out");
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -33,55 +32,56 @@ import java.util.regex.Pattern;
|
||||
* Property filter class
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class PropertyFilter
|
||||
{
|
||||
private static final Pattern PROPERTY_FILTER_REGEX = Pattern.compile("^(\\*)|([\\p{Upper}\\p{Digit}_]+(,[\\p{Upper}\\p{Digit}_]+)*)$");
|
||||
private static final int MINIMAL_ALLOWED_STRUCTURE_SIZE = 1;
|
||||
|
||||
private static final String MATCH_ALL_FILTER = "*";
|
||||
|
||||
private static final Pattern PROPERTY_FILTER_REGEX = Pattern.compile("^(\\*)|([\\p{Alpha}\\p{Digit}_]+((,){1}( )*[\\p{Alpha}\\p{Digit}_]+)*)$");
|
||||
|
||||
private Set<String> properties;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public PropertyFilter()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param filter filter string
|
||||
* @param filter filter value (case insensitive)
|
||||
* @throws FilterNotValidException if filter string isn't valid
|
||||
*/
|
||||
public PropertyFilter(String filter) throws FilterNotValidException
|
||||
{
|
||||
if (filter == null)
|
||||
if ((filter == null) || ((filter.length() < MINIMAL_ALLOWED_STRUCTURE_SIZE) ? (false) : (!PROPERTY_FILTER_REGEX.matcher(filter).matches())))
|
||||
{
|
||||
throw new FilterNotValidException(filter + " isn't valid");
|
||||
throw new FilterNotValidException("\"" + filter + "\" filter value is invalid");
|
||||
}
|
||||
|
||||
if (filter.equals("") == false)
|
||||
if (!filter.equals(MATCH_ALL_FILTER) && (filter.length() >= MINIMAL_ALLOWED_STRUCTURE_SIZE))
|
||||
{
|
||||
if (PROPERTY_FILTER_REGEX.matcher(filter).matches() == false)
|
||||
{
|
||||
throw new FilterNotValidException(filter + " isn't valid");
|
||||
}
|
||||
|
||||
if (filter.equals("*") == false)
|
||||
{
|
||||
properties = new HashSet<String>(Arrays.asList(filter.split(",")));
|
||||
}
|
||||
splitFilterOnTokens(filter.split(","));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param property property
|
||||
* @return if property is allow by filter then returns true else false
|
||||
* @param property property token name (e.g.: name (or Name), ObjectId (or: objectid, Objectid etc))
|
||||
* @return <b>true</b> returns if property is allowed by filter. In other case returns <b>false</b>
|
||||
*/
|
||||
public boolean allow(String property)
|
||||
{
|
||||
return properties == null || properties.contains(property);
|
||||
return (properties == null) || properties.contains(property.toLowerCase());
|
||||
}
|
||||
|
||||
private void splitFilterOnTokens(String[] tokens)
|
||||
{
|
||||
|
||||
properties = new HashSet<String>();
|
||||
|
||||
for (String token : tokens)
|
||||
{
|
||||
properties.add(token.trim().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
@@ -29,46 +29,48 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.dictionary.CMISMapping;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
* Class for accessing CMIS properties
|
||||
*
|
||||
* @author Dmitry Lazurkin
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class PropertyUtil
|
||||
{
|
||||
private static Map<String, String> cmisToRepoPropertiesNamesMapping = new HashMap<String, String>();
|
||||
private static Map<String, String> repoToCmisPropertiesNamesMapping = new HashMap<String, String>();
|
||||
private static Map<String, Pair<String, Boolean>> cmisToRepoPropertiesNamesMapping = new HashMap<String, Pair<String, Boolean>>();
|
||||
private static Map<String, Pair<String, Boolean>> repoToCmisPropertiesNamesMapping = new HashMap<String, Pair<String, Boolean>>();
|
||||
|
||||
static
|
||||
{
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_IMMUTABLE, "IsImmutable");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_LATEST_VERSION, "IsLatestVersion");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_MAJOR_VERSION, "IsMajorVersion");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_LATEST_MAJOR_VERSION, "IsLatestMajorVersion");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT, "IsVersionSeriesCheckedOut");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CREATION_DATE, "CreationDate");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_LAST_MODIFICATION_DATE, "LastModificationDate");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_OBJECT_ID, "ObjectId");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_ID, "VersionSeriesId");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID, "VersionSeriesCheckedOutId");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_LENGTH, "ContentStreamLength");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_NAME, "Name");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_OBJECT_TYPE_ID, "ObjectTypeId");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CREATED_BY, "CreatedBy");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_LAST_MODIFIED_BY, "LastModifiedBy");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE, "ContentStreamMimeType");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_FILENAME, "ContentStreamFilename");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_LABEL, "VersionLabel");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CHECKIN_COMMENT, "checkinComment");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_URI, "contentStreamURI");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY, "VersionSeriesCheckedOutBy");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_PARENT_ID, "ParentId");
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_IMMUTABLE, new Pair<String, Boolean>("IsImmutable", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_LATEST_VERSION, new Pair<String, Boolean>("IsLatestVersion", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_MAJOR_VERSION, new Pair<String, Boolean>("IsMajorVersion", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_LATEST_MAJOR_VERSION, new Pair<String, Boolean>("IsLatestMajorVersion", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT, new Pair<String, Boolean>("IsVersionSeriesCheckedOut", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CREATION_DATE, new Pair<String, Boolean>("CreationDate", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_LAST_MODIFICATION_DATE, new Pair<String, Boolean>("LastModificationDate", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_OBJECT_ID, new Pair<String, Boolean>("ObjectId", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_ID, new Pair<String, Boolean>("VersionSeriesId", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID, new Pair<String, Boolean>("VersionSeriesCheckedOutId", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_LENGTH, new Pair<String, Boolean>("ContentStreamLength", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_NAME, new Pair<String, Boolean>("Name", false));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_OBJECT_TYPE_ID, new Pair<String, Boolean>("ObjectTypeId", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CREATED_BY, new Pair<String, Boolean>("CreatedBy", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_LAST_MODIFIED_BY, new Pair<String, Boolean>("LastModifiedBy", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE, new Pair<String, Boolean>("ContentStreamMimeType", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_FILENAME, new Pair<String, Boolean>("ContentStreamFilename", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_LABEL, new Pair<String, Boolean>("VersionLabel", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CHECKIN_COMMENT, new Pair<String, Boolean>("checkinComment", false));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_URI, new Pair<String, Boolean>("contentStreamURI", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY, new Pair<String, Boolean>("VersionSeriesCheckedOutBy", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_PARENT_ID, new Pair<String, Boolean>("ParentId", true));
|
||||
cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_ALLOWED, new Pair<String, Boolean>("ContentStreamAllowed", true));
|
||||
|
||||
for (Map.Entry<String, String> entry : cmisToRepoPropertiesNamesMapping.entrySet())
|
||||
for (Map.Entry<String, Pair<String, Boolean>> entry : cmisToRepoPropertiesNamesMapping.entrySet())
|
||||
{
|
||||
repoToCmisPropertiesNamesMapping.put(entry.getValue(), entry.getKey());
|
||||
repoToCmisPropertiesNamesMapping.put(entry.getValue().getFirst(), new Pair<String, Boolean>(entry.getKey(), entry.getValue().getSecond()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +82,7 @@ public class PropertyUtil
|
||||
*/
|
||||
public static String getCMISPropertyName(String internalName)
|
||||
{
|
||||
return cmisToRepoPropertiesNamesMapping.get(internalName);
|
||||
return cmisToRepoPropertiesNamesMapping.get(internalName).getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +93,19 @@ public class PropertyUtil
|
||||
*/
|
||||
public static String getRepositoryPropertyName(String cmisName)
|
||||
{
|
||||
return repoToCmisPropertiesNamesMapping.get(cmisName);
|
||||
return repoToCmisPropertiesNamesMapping.get(cmisName).getFirst();
|
||||
}
|
||||
|
||||
public static boolean isReadOnlyCmisProperty(String internalPropertyName)
|
||||
{
|
||||
|
||||
return repoToCmisPropertiesNamesMapping.get(internalPropertyName).getSecond();
|
||||
}
|
||||
|
||||
public static boolean isReadOnlyRepositoryProperty(String cmisPropertyName)
|
||||
{
|
||||
|
||||
return repoToCmisPropertiesNamesMapping.get(cmisPropertyName).getSecond();
|
||||
}
|
||||
|
||||
public static Serializable getProperty(CmisPropertiesType cmisProperties, String property)
|
||||
@@ -149,5 +163,4 @@ public class PropertyUtil
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
75
source/java/org/alfresco/repo/cmis/ws/utils/AlfrescoObjectType.java
Executable file
75
source/java/org/alfresco/repo/cmis/ws/utils/AlfrescoObjectType.java
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.dictionary.CMISMapping;
|
||||
import org.alfresco.model.ContentModel;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public enum AlfrescoObjectType
|
||||
{
|
||||
DOCUMENT_OBJECT(ContentModel.TYPE_CONTENT.toString()), FOLDER_OBJECT(ContentModel.TYPE_FOLDER.toString()), DOCUMENT_OR_FOLDER_OBJECT("DOCUMENT_OR_FOLDER"), RELATIONSHIP_OBJECT(
|
||||
CMISMapping.RELATIONSHIP_QNAME.toString()), ANY_OBJECT("ANY");
|
||||
|
||||
String value;
|
||||
|
||||
final static Map<String, AlfrescoObjectType> VALUES;
|
||||
static
|
||||
{
|
||||
VALUES = new HashMap<String, AlfrescoObjectType>();
|
||||
VALUES.put(DOCUMENT_OBJECT.getValue(), DOCUMENT_OBJECT);
|
||||
VALUES.put(FOLDER_OBJECT.getValue(), FOLDER_OBJECT);
|
||||
}
|
||||
|
||||
AlfrescoObjectType(String value)
|
||||
{
|
||||
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static AlfrescoObjectType fromValue(String valueName)
|
||||
{
|
||||
|
||||
AlfrescoObjectType result = VALUES.get(valueName);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
result = ANY_OBJECT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
473
source/java/org/alfresco/repo/cmis/ws/utils/CmisObjectsUtils.java
Executable file
473
source/java/org/alfresco/repo/cmis/ws/utils/CmisObjectsUtils.java
Executable file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.dictionary.CMISDictionaryService;
|
||||
import org.alfresco.cmis.dictionary.CMISMapping;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.EnumObjectType;
|
||||
import org.alfresco.repo.cmis.ws.InvalidArgumentException;
|
||||
import org.alfresco.repo.cmis.ws.ObjectNotFoundException;
|
||||
import org.alfresco.repo.cmis.ws.OperationNotSupportedException;
|
||||
import org.alfresco.repo.cmis.ws.utils.DescendantsQueueManager.DescendantElement;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class CmisObjectsUtils
|
||||
{
|
||||
private static final int NODE_REFERENCE_WITH_SUFFIX_DELIMETERS_COUNT = 5;
|
||||
|
||||
public static final String NODE_REFERENCE_ID_DELIMETER = "/";
|
||||
|
||||
private static final String DOUBLE_NODE_REFERENCE_ID_DELIMETER = NODE_REFERENCE_ID_DELIMETER + NODE_REFERENCE_ID_DELIMETER;
|
||||
|
||||
private static final List<QName> DOCUMENT_AND_FOLDER_TYPES;
|
||||
static
|
||||
{
|
||||
DOCUMENT_AND_FOLDER_TYPES = new LinkedList<QName>();
|
||||
DOCUMENT_AND_FOLDER_TYPES.add(ContentModel.TYPE_CONTENT);
|
||||
DOCUMENT_AND_FOLDER_TYPES.add(ContentModel.TYPE_FOLDER);
|
||||
}
|
||||
|
||||
private CheckOutCheckInService checkOutCheckInService;
|
||||
private CMISDictionaryService cmisDictionaryService;
|
||||
private FileFolderService fileFolderService;
|
||||
private AuthorityService authorityService;
|
||||
private NodeService nodeService;
|
||||
private LockService lockService;
|
||||
private CMISMapping cmisMapping;
|
||||
|
||||
private Throwable lastOperationException;
|
||||
|
||||
public IdentifierConversionResults getIdentifierInstance(String identifier, AlfrescoObjectType expectedType) throws InvalidArgumentException
|
||||
{
|
||||
|
||||
if (!(identifier instanceof String))
|
||||
{
|
||||
throw new InvalidArgumentException("Invalid Object Identifier was specified");
|
||||
}
|
||||
|
||||
IdentifierConversionResults result;
|
||||
AlfrescoObjectType actualObjectType;
|
||||
|
||||
if (isRelationship(identifier))
|
||||
{
|
||||
result = createAssociationIdentifierResult(identifier);
|
||||
|
||||
actualObjectType = AlfrescoObjectType.RELATIONSHIP_OBJECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef nodeReference = receiveNodeReferenceOfExistenceObject(cutNodeVersionIfNecessary(identifier, identifier.split(NODE_REFERENCE_ID_DELIMETER), 1));
|
||||
|
||||
result = createNodeReferenceIdentifierResult(nodeReference);
|
||||
|
||||
actualObjectType = determineActualObjectType(expectedType, this.nodeService.getType(nodeReference));
|
||||
}
|
||||
|
||||
if ((expectedType == AlfrescoObjectType.ANY_OBJECT) || (actualObjectType == expectedType))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unexpected object type of the specified Object Identifier");
|
||||
}
|
||||
|
||||
public void deleteFolder(NodeRef folderNodeReference, boolean continueOnFailure, boolean totalDeletion, List<String> resultList) throws OperationNotSupportedException
|
||||
{
|
||||
|
||||
DescendantsQueueManager queueManager = new DescendantsQueueManager(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, null, null, folderNodeReference));
|
||||
|
||||
do
|
||||
{
|
||||
DescendantElement currentElement = queueManager.receiveNextElement();
|
||||
|
||||
if (!this.nodeService.exists(currentElement.getNodesAssociation().getChildRef()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UnlinkOperationStatus unlinkingStatus = unlinkObject(currentElement.getNodesAssociation().getChildRef(), currentElement.getNodesAssociation().getParentRef(),
|
||||
totalDeletion);
|
||||
|
||||
if (!unlinkingStatus.isObjectUnlinked())
|
||||
{
|
||||
processNotUnlinkedObjectResults(currentElement, unlinkingStatus, queueManager, resultList, continueOnFailure);
|
||||
}
|
||||
} while (!queueManager.isDepleted() && (continueOnFailure || resultList.isEmpty()));
|
||||
}
|
||||
|
||||
public boolean deleteObject(NodeRef objectNodeReference)
|
||||
{
|
||||
|
||||
return isObjectLockIsNotATrouble(objectNodeReference) && performNodeDeletion(objectNodeReference);
|
||||
}
|
||||
|
||||
public boolean removeObject(NodeRef objectNodeReference, NodeRef folderNodeReference)
|
||||
{
|
||||
|
||||
if (isChildOfThisFolder(objectNodeReference, folderNodeReference))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.nodeService.removeChild(folderNodeReference, objectNodeReference);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
this.lastOperationException = e;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addObjectToFolder(NodeRef objectNodeRef, NodeRef parentFolderNodeRef)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
this.nodeService.addChild(parentFolderNodeRef, objectNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName
|
||||
.createValidLocalName((String) this.nodeService.getProperty(objectNodeRef, ContentModel.PROP_NAME))));
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
this.lastOperationException = e;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFolder(NodeRef folderNodeRef)
|
||||
{
|
||||
|
||||
return (folderNodeRef != null) && this.cmisMapping.isValidCmisFolder(this.cmisMapping.getCmisType(this.nodeService.getType(folderNodeRef)));
|
||||
}
|
||||
|
||||
public boolean isDocument(NodeRef documentNodeRef)
|
||||
{
|
||||
|
||||
return (documentNodeRef != null) && this.cmisMapping.isValidCmisDocument(this.cmisMapping.getCmisType(this.nodeService.getType(documentNodeRef)));
|
||||
}
|
||||
|
||||
public boolean isRelationship(String identifier)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
new AssociationRef(identifier);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPolicy(NodeRef policyNodeRef)
|
||||
{
|
||||
|
||||
// TODO: Policy
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public EnumObjectType determineObjectType(String identifier)
|
||||
{
|
||||
|
||||
if (isRelationship(identifier))
|
||||
{
|
||||
return EnumObjectType.RELATIONSHIP;
|
||||
}
|
||||
|
||||
NodeRef objectNodeReference = new NodeRef(identifier);
|
||||
|
||||
if (isFolder(objectNodeReference))
|
||||
{
|
||||
return EnumObjectType.FOLDER;
|
||||
}
|
||||
|
||||
if (isDocument(objectNodeReference))
|
||||
{
|
||||
return EnumObjectType.DOCUMENT;
|
||||
}
|
||||
|
||||
return EnumObjectType.POLICY;
|
||||
}
|
||||
|
||||
public boolean isChildOfThisFolder(NodeRef objectNodeReference, NodeRef folderNodeReference)
|
||||
{
|
||||
|
||||
NodeRef searchedObjectNodeReference = this.fileFolderService.searchSimple(folderNodeReference, (String) this.nodeService.getProperty(objectNodeReference,
|
||||
ContentModel.PROP_NAME));
|
||||
|
||||
return (searchedObjectNodeReference != null) && searchedObjectNodeReference.equals(objectNodeReference);
|
||||
}
|
||||
|
||||
public boolean isPrimaryObjectParent(NodeRef folderNodeReference, NodeRef objectNodeReference)
|
||||
{
|
||||
|
||||
NodeRef searchedParentObject = this.nodeService.getPrimaryParent(objectNodeReference).getParentRef();
|
||||
|
||||
return (searchedParentObject != null) && searchedParentObject.equals(folderNodeReference);
|
||||
}
|
||||
|
||||
public boolean isWorkingCopy(NodeRef objectIdentifier)
|
||||
{
|
||||
|
||||
return nodeService.hasAspect(objectIdentifier, ContentModel.ASPECT_WORKING_COPY);
|
||||
}
|
||||
|
||||
public void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
|
||||
this.cmisMapping = this.cmisDictionaryService.getCMISMapping();
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
||||
{
|
||||
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
}
|
||||
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
public Throwable getLastOperationException()
|
||||
{
|
||||
|
||||
return lastOperationException;
|
||||
}
|
||||
|
||||
private boolean performNodeDeletion(NodeRef objectNodeReference)
|
||||
{
|
||||
|
||||
if (this.nodeService.hasAspect(objectNodeReference, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
this.checkOutCheckInService.cancelCheckout(objectNodeReference);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.nodeService.deleteNode(objectNodeReference);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isObjectLockIsNotATrouble(NodeRef objectNodeReference)
|
||||
{
|
||||
|
||||
String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
|
||||
return (this.lockService.getLockStatus(objectNodeReference, currentUserName) != LockStatus.LOCKED) || this.authorityService.isAdminAuthority(currentUserName);
|
||||
}
|
||||
|
||||
private UnlinkOperationStatus unlinkObject(NodeRef objectNodeReference, NodeRef parentFolderNodeReference, boolean totalDeletion)
|
||||
{
|
||||
|
||||
if (isFolder(objectNodeReference))
|
||||
{
|
||||
List<ChildAssociationRef> children = this.nodeService.getChildAssocs(objectNodeReference);
|
||||
|
||||
return new UnlinkOperationStatus(((children == null) || children.isEmpty()) && deleteObject(objectNodeReference), (children != null) ? (children)
|
||||
: (new LinkedList<ChildAssociationRef>()));
|
||||
}
|
||||
|
||||
return new UnlinkOperationStatus((totalDeletion) ? (deleteObject(objectNodeReference))
|
||||
: (!isPrimaryObjectParent(parentFolderNodeReference, objectNodeReference) && removeObject(objectNodeReference, parentFolderNodeReference)),
|
||||
new LinkedList<ChildAssociationRef>());
|
||||
}
|
||||
|
||||
private void processNotUnlinkedObjectResults(DescendantElement currentElement, UnlinkOperationStatus unlinkingStatus, DescendantsQueueManager queueManager,
|
||||
List<String> resultList, boolean addAllFailedToDelete)
|
||||
{
|
||||
|
||||
if (!unlinkingStatus.getChildren().isEmpty())
|
||||
{
|
||||
queueManager.addElementToQueueEnd(currentElement);
|
||||
|
||||
queueManager.addChildren(unlinkingStatus.getChildren(), currentElement);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
resultList.add(currentElement.getNodesAssociation().getChildRef().toString());
|
||||
|
||||
if (addAllFailedToDelete)
|
||||
{
|
||||
queueManager.removeParents(currentElement, resultList);
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef receiveNodeReferenceOfExistenceObject(String clearNodeIdentifier) throws InvalidArgumentException
|
||||
{
|
||||
|
||||
if (NodeRef.isNodeRef(clearNodeIdentifier))
|
||||
{
|
||||
NodeRef result = new NodeRef(clearNodeIdentifier);
|
||||
|
||||
if (this.nodeService.exists(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Invalid Object Identifier was specified: Identifier is incorrect or Object with the specified Identifier is not exists",
|
||||
new ObjectNotFoundException());
|
||||
}
|
||||
|
||||
private String cutNodeVersionIfNecessary(String identifier, String[] splitedNodeIdentifier, int startIndex)
|
||||
{
|
||||
|
||||
String withoutVersionSuffix = identifier;
|
||||
|
||||
if (splitedNodeIdentifier.length == NODE_REFERENCE_WITH_SUFFIX_DELIMETERS_COUNT)
|
||||
{
|
||||
withoutVersionSuffix = splitedNodeIdentifier[startIndex++ - 1] + DOUBLE_NODE_REFERENCE_ID_DELIMETER + splitedNodeIdentifier[startIndex++] + NODE_REFERENCE_ID_DELIMETER
|
||||
+ splitedNodeIdentifier[startIndex];
|
||||
}
|
||||
|
||||
return withoutVersionSuffix;
|
||||
}
|
||||
|
||||
private AlfrescoObjectType determineActualObjectType(AlfrescoObjectType expectedType, QName objectType)
|
||||
{
|
||||
|
||||
return (expectedType != AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT) ? (AlfrescoObjectType.fromValue(objectType.toString())) : ((DOCUMENT_AND_FOLDER_TYPES
|
||||
.contains(objectType)) ? (AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT) : (AlfrescoObjectType.ANY_OBJECT));
|
||||
}
|
||||
|
||||
private IdentifierConversionResults createAssociationIdentifierResult(final String identifier)
|
||||
{
|
||||
|
||||
return new IdentifierConversionResults()
|
||||
{
|
||||
public AssociationRef getConvertedIdentifier()
|
||||
{
|
||||
|
||||
return new AssociationRef(identifier);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IdentifierConversionResults createNodeReferenceIdentifierResult(final NodeRef identifier)
|
||||
{
|
||||
|
||||
return new IdentifierConversionResults()
|
||||
{
|
||||
public NodeRef getConvertedIdentifier()
|
||||
{
|
||||
|
||||
return identifier;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public interface IdentifierConversionResults
|
||||
{
|
||||
public <I> I getConvertedIdentifier();
|
||||
}
|
||||
|
||||
private class UnlinkOperationStatus
|
||||
{
|
||||
private boolean objectUnlinked;
|
||||
private List<ChildAssociationRef> children;
|
||||
|
||||
public UnlinkOperationStatus(boolean objectUnlinked, List<ChildAssociationRef> children)
|
||||
{
|
||||
|
||||
this.objectUnlinked = objectUnlinked;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public boolean isObjectUnlinked()
|
||||
{
|
||||
|
||||
return this.objectUnlinked;
|
||||
}
|
||||
|
||||
public List<ChildAssociationRef> getChildren()
|
||||
{
|
||||
|
||||
return this.children;
|
||||
}
|
||||
|
||||
protected UnlinkOperationStatus()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
156
source/java/org/alfresco/repo/cmis/ws/utils/DescendantsQueueManager.java
Executable file
156
source/java/org/alfresco/repo/cmis/ws/utils/DescendantsQueueManager.java
Executable file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class DescendantsQueueManager
|
||||
{
|
||||
private LinkedList<DescendantElement> queue;
|
||||
|
||||
public DescendantsQueueManager(ChildAssociationRef headAssociation)
|
||||
{
|
||||
|
||||
this.queue = new LinkedList<DescendantElement>();
|
||||
this.queue.addFirst(createElement(headAssociation, null));
|
||||
}
|
||||
|
||||
public DescendantElement createElement(ChildAssociationRef data, DescendantElement parent)
|
||||
{
|
||||
|
||||
return new DescendantElement(parent, data);
|
||||
}
|
||||
|
||||
public void removeParents(DescendantElement source, List<String> undeletedNodes)
|
||||
{
|
||||
|
||||
while (source.getParentElement() != null)
|
||||
{
|
||||
source = source.getParentElement();
|
||||
|
||||
determineUndeletedObjectToPut(source.getNodesAssociation().getChildRef().toString(), undeletedNodes);
|
||||
|
||||
this.queue.remove(source);
|
||||
}
|
||||
}
|
||||
|
||||
public void addChildren(List<ChildAssociationRef> children, DescendantElement parent)
|
||||
{
|
||||
|
||||
for (ChildAssociationRef child : children)
|
||||
{
|
||||
this.queue.addFirst(createElement(child, parent));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method receives and immediately removes next element from the queue
|
||||
*
|
||||
* @return next <b>DescendantElement</b> (in this case - first element) in the queue if queue still contain any element or <b>null</b> if queue is empty
|
||||
*/
|
||||
public DescendantElement receiveNextElement()
|
||||
{
|
||||
|
||||
DescendantElement result = (this.queue.isEmpty()) ? (null) : (this.queue.getFirst());
|
||||
|
||||
this.queue.remove(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addElementToQueueEnd(DescendantElement element)
|
||||
{
|
||||
|
||||
this.queue.addLast(element);
|
||||
}
|
||||
|
||||
public boolean isDepleted()
|
||||
{
|
||||
|
||||
return this.queue.isEmpty();
|
||||
}
|
||||
|
||||
protected DescendantsQueueManager()
|
||||
{
|
||||
}
|
||||
|
||||
private void determineUndeletedObjectToPut(String undeletedObjectIdentifier, List<String> undeletedNodes)
|
||||
{
|
||||
|
||||
if (!undeletedNodes.contains(undeletedObjectIdentifier))
|
||||
{
|
||||
undeletedNodes.add(undeletedObjectIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
public class DescendantElement
|
||||
{
|
||||
private DescendantElement parentElement;
|
||||
private ChildAssociationRef nodesAssociation;
|
||||
|
||||
public DescendantElement(DescendantElement parentElement, ChildAssociationRef nodesAssociation)
|
||||
{
|
||||
|
||||
this.parentElement = parentElement;
|
||||
this.nodesAssociation = nodesAssociation;
|
||||
}
|
||||
|
||||
public DescendantElement getParentElement()
|
||||
{
|
||||
|
||||
return parentElement;
|
||||
}
|
||||
|
||||
public ChildAssociationRef getNodesAssociation()
|
||||
{
|
||||
|
||||
return nodesAssociation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
|
||||
if (!(obj instanceof DescendantElement))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DescendantElement currentElement = (DescendantElement) obj;
|
||||
|
||||
return (this.nodesAssociation != null) ? (this.nodesAssociation.equals(currentElement.getNodesAssociation())) : (currentElement.getNodesAssociation() == null);
|
||||
}
|
||||
|
||||
protected DescendantElement()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user