diff --git a/config/alfresco/cmis-ws-context.xml b/config/alfresco/cmis-ws-context.xml index 05b81d59ad..136e6c972e 100644 --- a/config/alfresco/cmis-ws-context.xml +++ b/config/alfresco/cmis-ws-context.xml @@ -9,22 +9,20 @@ - + - - - @@ -32,24 +30,26 @@ + + + + - + - - - @@ -57,24 +57,25 @@ + + + + - - - @@ -82,51 +83,160 @@ + + + + + - - - - org.alfresco.repo.cmis.ws.RepositoryServicePort - - - - - - - - - - - - + + + + + + - - - - org.alfresco.repo.cmis.ws.NavigationServicePort - - - - - - - - - - - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - org.alfresco.repo.cmis.ws.ObjectServicePort + dmRepositoryService + dmNavigationService + dmObjectService + dmMultiFilingService + dmVersioningService + dmDiscoveryService + dmRelationshipService + dmPolicyService - - - @@ -142,16 +252,49 @@ ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} ${server.transaction.mode.default} - + + + + + - + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + @@ -162,20 +305,14 @@ - + + - - - - + - - - - @@ -214,9 +351,7 @@ - - - + diff --git a/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java b/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java index 2b0ef7f2d0..1e9c98fb17 100644 --- a/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java +++ b/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java @@ -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]; diff --git a/source/java/org/alfresco/repo/cmis/ws/ContentReaderDataSource.java b/source/java/org/alfresco/repo/cmis/ws/ContentReaderDataSource.java index 4f6f716040..1999d944d2 100755 --- a/source/java/org/alfresco/repo/cmis/ws/ContentReaderDataSource.java +++ b/source/java/org/alfresco/repo/cmis/ws/ContentReaderDataSource.java @@ -34,7 +34,6 @@ import org.alfresco.service.cmr.repository.ContentReader; /** * @author Dmitry Lazurkin - * */ public class ContentReaderDataSource implements DataSource { diff --git a/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java index dd61819cb6..af454565c8 100644 --- a/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java +++ b/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java @@ -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 NodeRef's to CMIS objects those will be stored in resultList-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 CmisObjectType values for end response result collecting + * @throws InvalidArgumentException + * @throws FilterNotValidException + */ + protected void formatCommonResponse(PropertyFilter filter, List sourceList, List 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 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 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 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 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 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 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 properties = (NodeRef.isNodeRef(identifier)) ? (cmisPropertyService.getProperties(new NodeRef(identifier))) + : (createBaseRelationshipProperties(new AssociationRef(identifier))); + + return getPropertiesType(properties, filter); + } + + public CmisPropertiesType getPropertiesType(Map 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 properties' fields for specified node + * + * @param nodeRef the NodeRef 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 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 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 createBaseRelationshipProperties(AssociationRef association) + { + + Map result = new HashMap(); + + 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 createVersionProperties(String versionDescription, VersionType versionType) + { + + Map result = new HashMap(); + 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); + } } diff --git a/source/java/org/alfresco/repo/cmis/ws/DMDiscoveryServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMDiscoveryServicePort.java new file mode 100755 index 0000000000..1c429634f7 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/DMDiscoveryServicePort.java @@ -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; + } + +} diff --git a/source/java/org/alfresco/repo/cmis/ws/DMMultiFilingServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMMultiFilingServicePort.java new file mode 100755 index 0000000000..fed86a286d --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/DMMultiFilingServicePort.java @@ -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"); + } + } +} diff --git a/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java index 7c4cff704a..fcabc20cd4 100644 --- a/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java +++ b/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java @@ -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 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 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), � 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 receiveParentList(String targetChildIdentifier, boolean fullParentsHierarchy) throws InvalidNodeRefException, InvalidArgumentException, + ObjectNotFoundException + { + + List result = new LinkedList(); + + 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 receiveFullAncestorsHierachy(NodeRef currentParent, List 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 parents) + { + + currentParent = this.nodeService.getPrimaryParent(currentParent).getParentRef(); + + if (currentParent != null) + { + parents.add(currentParent); + } + + return currentParent; + } + + private List receiveObjectParents(NodeRef objectId) throws InvalidArgumentException + { + + List parents = new LinkedList(); + + 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 descendantsFolders, List currentLayerFolders, + List 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 performDescendantsResultObjectsStoring(EnumTypesOfFileableObjects returnObjectsType, List resultList, List descendantsFolders, + List currentLayerFolders, List 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 List that contains all appropriates layers of Alfresco objects + * @throws InvalidArgumentException + */ + public List receiveHierarchy(String rootFolderIdentifier) throws InvalidArgumentException; + } + + /** + * @see HierarchyReceiverStrategy + */ + private class LayerConstrainedHierarchyReceiver implements HierarchyReceiverStrategy + { + private List descendantsFolders = new LinkedList(); + + private EnumTypesOfFileableObjects returnObjectsType; + + private BigInteger finalDepth; + + private BigInteger currentDepth = BigInteger.ZERO; + + private List resultList = new LinkedList(); + + /** + * @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 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(), + new LinkedList()); + + 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 descendantsFolders = new LinkedList(); + + private List resultList = new LinkedList(); + + /** + * @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 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(), + new LinkedList()); + } + + return this.resultList; + } + } } diff --git a/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java index 80c80d67e4..6a8c0953be 100644 --- a/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java +++ b/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java @@ -34,24 +34,612 @@ import java.util.Map; import javax.activation.DataHandler; import javax.xml.ws.Holder; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.cmis.dictionary.CMISMapping; import org.alfresco.cmis.dictionary.CMISTypeId; +import org.alfresco.model.ContentModel; import org.alfresco.repo.cmis.ws.DeleteTreeResponse.FailedToDelete; +import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType; +import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils; +import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils.IdentifierConversionResults; +import org.alfresco.service.cmr.dictionary.AssociationDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.lock.NodeLockedException; import org.alfresco.service.cmr.model.FileExistsException; +import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.version.VersionType; import org.alfresco.service.namespace.QName; /** * Port for object service - * + * * @author Dmitry Lazurkin + * @author Dmitry Velichkevich */ - @javax.jws.WebService(name = "ObjectServicePort", serviceName = "ObjectService", portName = "ObjectServicePort", targetNamespace = "http://www.cmis.org/ns/1.0", endpointInterface = "org.alfresco.repo.cmis.ws.ObjectServicePort") public class DMObjectServicePort extends DMAbstractServicePort implements ObjectServicePort { + private static final int SINGLE_PARENT_CONDITION = 1; + + private static final String VERSION_DELIMETER = "."; + + private PermissionService permissionService; + private DictionaryService dictionaryService; + + /** + * Creates a document object of the specified type, and optionally adds the document to a folder + * + * @param repositoryId repository Id + * @param typeId document type + * @param properties CMIS properties + * @param folderId parent folder for this new document + * @param contentStream content stream + * @param versioningState versioning state (checkedout, minor, major) + * @return Id of the created document object + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws StorageException + * @throws StreamNotSupportedException + * @throws FolderNotValidException + * @throws OperationNotSupportedException + * @throws TypeNotFoundException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public String createDocument(String repositoryId, String typeId, CmisPropertiesType properties, String folderId, CmisContentStreamType contentStream, + EnumVersioningState versioningState) throws PermissionDeniedException, UpdateConflictException, StorageException, StreamNotSupportedException, FolderNotValidException, + OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException + { + checkRepositoryId(repositoryId); + + Map propertiesMap = getPropertiesMap(properties); + CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping(); + CMISTypeId cmisTypeId = cmisMapping.getCmisTypeId(typeId); + + if (cmisMapping.getCmisTypeId(typeId).equals(CMISMapping.DOCUMENT_TYPE_ID) == false) + { + throw new ConstraintViolationException("Invalid document type " + typeId); + } + + NodeRef parentNodeRef = receiveMandatoryFolderNodeReference(folderId); + + String documentName = (String) propertiesMap.get(CMISMapping.PROP_NAME); + if (documentName == null) + { + throw new InvalidArgumentException("Name property not found"); + } + + NodeRef newDocumentNodeRef = fileFolderService.create(parentNodeRef, documentName, cmisMapping.getAlfrescoType(cmisTypeId.getQName())).getNodeRef(); + ContentWriter writer = fileFolderService.getWriter(newDocumentNodeRef); + String mimeType = (String) propertiesMap.get(CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE); + if (mimeType != null) + { + writer.setMimetype(mimeType); + } + InputStream inputstream = null; + try + { + inputstream = contentStream.getStream().getInputStream(); + } + catch (IOException e) + { + throw new ConstraintViolationException("", e.getCause()); + } + writer.putContent(inputstream); + + if (versioningState == null) + { + versioningState = EnumVersioningState.MAJOR; + } + + // TODO: + // cmisPropertyService.setProperties(newDocumentNodeRef, propertiesMap); + + switch (versioningState) + { + case CHECKEDOUT: + newDocumentNodeRef = performCheckouting(newDocumentNodeRef); + + break; + case MAJOR: + this.versionService.createVersion(newDocumentNodeRef, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MAJOR)); + + break; + case MINOR: + this.versionService.createVersion(newDocumentNodeRef, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MINOR)); + + break; + } + + String versionLabel = (String) cmisPropertyService.getProperty(newDocumentNodeRef, CMISMapping.PROP_VERSION_LABEL); + + return ((versionLabel instanceof String) && versionLabel.contains(VERSION_DELIMETER)) ? (newDocumentNodeRef.toString() + CmisObjectsUtils.NODE_REFERENCE_ID_DELIMETER + versionLabel) + : (newDocumentNodeRef.toString()); + } + + /** + * Creates a folder object of the specified type. + * + * @param repositoryId repository Id + * @param typeId document type + * @param properties CMIS properties + * @param folderId parent folder for this new folder + * @return Id of the created folder object + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws FolderNotValidException + * @throws OperationNotSupportedException + * @throws TypeNotFoundException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public String createFolder(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) throws PermissionDeniedException, UpdateConflictException, + FolderNotValidException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException + { + checkRepositoryId(repositoryId); + + NodeRef folderNodeRef = this.cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier(); + + CMISTypeId cmisTypeId = getCmisTypeId(typeId); + assertExistType(cmisTypeId); + + CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping(); + + if (cmisMapping.isValidCmisFolder(cmisTypeId.getQName()) == false) + { + throw new InvalidArgumentException(typeId + " isn't folder type"); + } + + Map propertiesMap = getPropertiesMap(properties); + + String name = (String) propertiesMap.get(CMISMapping.PROP_NAME); + if (name == null) + { + throw new InvalidArgumentException("Name property not found"); + } + + assertExistFolder(folderNodeRef); + + try + { + NodeRef newFolderNodeRef = fileFolderService.create(folderNodeRef, name, cmisMapping.getAlfrescoType(cmisTypeId.getQName())).getNodeRef(); + // TODO: + // cmisPropertyService.setProperties(newFolderNodeRef, propertiesMap); + return (String) cmisPropertyService.getProperty(newFolderNodeRef, CMISMapping.PROP_OBJECT_ID); + } + catch (FileExistsException e) + { + throw new UpdateConflictException("Folder already exists"); + } + } + + /** + * Creates a policy object of the specified type, and optionally adds the policy to a folder. + * + * @param repositoryId repository Id + * @param typeId policy type + * @param properties CMIS properties + * @param folderId parent folder for this new policy + * @return Id of the created policy object + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws FolderNotValidException + * @throws OperationNotSupportedException + * @throws TypeNotFoundException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public String createPolicy(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) throws PermissionDeniedException, UpdateConflictException, + FolderNotValidException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException + { + + // TODO: + + return null; + } + + /** + * Creates a relationship object of the specified type. + * + * @param repositoryId repository Id + * @param typeId relationship type + * @param properties CMIS properties + * @param sourceObjectId source object Id + * @param targetObjectId target object Id + * @return Id of the created relationship object + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws TypeNotFoundException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public String createRelationship(String repositoryId, String typeId, CmisPropertiesType properties, String sourceObjectId, String targetObjectId) + throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, + RuntimeException, ConstraintViolationException + { + checkRepositoryId(repositoryId); + + NodeRef sourceNodeRef; + NodeRef targetNodeRef; + + try + { + sourceNodeRef = this.cmisObjectsUtils.getIdentifierInstance(sourceObjectId, AlfrescoObjectType.ANY_OBJECT).getConvertedIdentifier(); + targetNodeRef = this.cmisObjectsUtils.getIdentifierInstance(targetObjectId, AlfrescoObjectType.ANY_OBJECT).getConvertedIdentifier(); + } + catch (InvalidArgumentException e) + { + if (e.getCause() instanceof ObjectNotFoundException) + { + throw new ObjectNotFoundException(e.getMessage()); + } + + throw e; + } + + CMISTypeId relationshipTypeId; + + try + { + relationshipTypeId = cmisDictionaryService.getCMISMapping().getCmisTypeId(typeId); + } + catch (Exception e) + { + throw new InvalidArgumentException("Invalid typeId format: " + typeId); + } + + QName relationshipTypeQName = cmisDictionaryService.getCMISMapping().getAlfrescoType(relationshipTypeId.getQName()); + + AssociationDefinition associationDef = dictionaryService.getAssociation(relationshipTypeQName); + if (associationDef != null) + { + if (!dictionaryService.isSubClass(nodeService.getType(sourceNodeRef), associationDef.getSourceClass().getName())) + { + throw new ConstraintViolationException("Source object type isn't allowed as source type"); + } + + if (!dictionaryService.isSubClass(nodeService.getType(targetNodeRef), associationDef.getTargetClass().getName())) + { + throw new ConstraintViolationException("Target object type isn't allowed as target type"); + } + + return nodeService.createAssociation(sourceNodeRef, targetNodeRef, relationshipTypeQName).toString(); + } + else + { + throw new TypeNotFoundException(relationshipTypeId.getQName() + " Relationship type not found"); + } + } + + /** + * Deletes the content-stream of the specified document. This does not delete properties. If there are other versions this does not affect them, their properties or content. + * This does not change the ID of the document. + * + * @param repositoryId repository Id + * @param documentId document Id + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws StorageException + * @throws StreamNotSupportedException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws VersioningException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public void deleteContentStream(String repositoryId, String documentId) throws PermissionDeniedException, UpdateConflictException, StorageException, + StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException, VersioningException, InvalidArgumentException, RuntimeException, + ConstraintViolationException + { + + checkRepositoryId(repositoryId); + + performContentStreamDeletion((NodeRef) this.cmisObjectsUtils.getIdentifierInstance(documentId, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier()); + } + + /** + * Deletes specified object. + * + * @param repositoryId repository Id + * @param objectId object Id + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public void deleteObject(String repositoryId, String objectId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException, + OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException + { + + checkRepositoryId(repositoryId); + + NodeRef objectNodeReference = this.cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT).getConvertedIdentifier(); + + checkForRootObject(repositoryId, objectId); + checkObjectTypeAndAppropriateStates(objectNodeReference, this.cmisDictionaryService.getCMISMapping().getCmisType(this.nodeService.getType(objectNodeReference))); + + if (!this.cmisObjectsUtils.deleteObject(objectNodeReference)) + { + throw new PermissionDeniedException("Currently authenticated User has no appropriate Permissions to delete specified Object"); + } + } + + /** + * Deletes the tree rooted at specified folder (including that folder) + * + * @param repositoryId repository Id + * @param folderId folder Id + * @param unfileNonfolderObjects unfile : unfile all non-folder objects from folders in this tree. They may remain filed in other folders, or may become unfiled, + * deletesinglefiled : delete non-folder objects filed only in this tree, and unfile the others so they remain filed in other folders, delete : delete all non-folder + * objects in this tree (Default) + * @param continueOnFailure flag + * @return collection of object IDs that failed to delete (if continueOnFailure is FALSE, then single object ID) + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws FolderNotValidException + * @throws OperationNotSupportedException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public FailedToDelete deleteTree(String repositoryId, String folderId, EnumUnfileNonfolderObjects unfileNonfolderObjects, Boolean continueOnFailure) + throws PermissionDeniedException, UpdateConflictException, FolderNotValidException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, + ConstraintViolationException + { + + checkRepositoryId(repositoryId); + checkUnfilingIsNotRequested(unfileNonfolderObjects); + checkForRootObject(repositoryId, folderId); + + NodeRef folderNodeReference = this.cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier(); + + FailedToDelete responce = new FailedToDelete(); + + this.cmisObjectsUtils.deleteFolder(folderNodeReference, continueOnFailure, (unfileNonfolderObjects == EnumUnfileNonfolderObjects.DELETE), responce.getObjectId()); + + return responce; + } + + /** + * Gets the list of allowable actions (CMIS service calls) for an object based on the current user�s context, subject to any access constraints that are currently imposed by + * the repository. + * + * @param repositoryId repository Id + * @param objectId object Id + * @return list of allowable actions + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws InvalidArgumentException + * @throws RuntimeException + */ + public CmisAllowableActionsType getAllowableActions(String repositoryId, String objectId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException, + OperationNotSupportedException, InvalidArgumentException, RuntimeException + { + + checkRepositoryId(repositoryId); + + return determineObjectAllowableActions(this.cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT)); + } + + /** + * Gets the content-stream for a document. + * + * @param repositoryId repository Id + * @param documentId document to return the content-stream + * @return content stream + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws StorageException + * @throws StreamNotSupportedException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws OffsetException + */ + public CmisContentStreamType getContentStream(String repositoryId, String documentId) throws PermissionDeniedException, UpdateConflictException, StorageException, + StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, OffsetException + { + NodeRef nodeRef = this.cmisObjectsUtils.getIdentifierInstance(documentId, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier(); + + CmisContentStreamType response = new CmisContentStreamType(); + + ContentReader reader = safelyReceiveContentReader(nodeRef); + + response.setLength(BigInteger.valueOf(reader.getSize())); + response.setMimeType(reader.getMimetype()); + String filename = (String) cmisPropertyService.getProperty(nodeRef, CMISMapping.PROP_NAME); + response.setFilename(filename); + response.setStream(new DataHandler(new ContentReaderDataSource(reader, filename))); + + return response; + } + + /** + * Moves the specified filed object from one folder to another + * + * @param repositoryId repository Id + * @param objectId object Id + * @param targetFolderId the target folder to be moved into + * @param sourceFolderId the source folder to be moved out of + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws ObjectNotFoundException + * @throws FolderNotValidException + * @throws OperationNotSupportedException + * @throws NotInFolderException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public void moveObject(String repositoryId, String objectId, String targetFolderId, String sourceFolderId) throws PermissionDeniedException, UpdateConflictException, + ObjectNotFoundException, FolderNotValidException, OperationNotSupportedException, NotInFolderException, InvalidArgumentException, RuntimeException, + ConstraintViolationException + { + checkRepositoryId(repositoryId); + + NodeRef objectNodeRef = this.cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT).getConvertedIdentifier(); + NodeRef targetFolderNodeRef = this.cmisObjectsUtils.getIdentifierInstance(targetFolderId, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier(); + + // TODO: Allowed_Child_Object_Types + + if ((this.nodeService.getParentAssocs(objectNodeRef).size() == SINGLE_PARENT_CONDITION) + || !changeObjectParentAssociation(objectNodeRef, targetFolderNodeRef, (NodeRef) this.cmisObjectsUtils.getIdentifierInstance(sourceFolderId, + AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier())) + { + moveObjectToFolder(objectNodeRef, targetFolderNodeRef); + } + } + + /** + * Sets (creates or replaces) the content-stream for the specified document object. + * + * @param repositoryId repository Id + * @param documentId document Id + * @param overwriteFlag flag + * @param contentStream content stream + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws StorageException + * @throws StreamNotSupportedException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws ContentAlreadyExistsException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public void setContentStream(String repositoryId, Holder documentId, Boolean overwriteFlag, CmisContentStreamType contentStream) throws PermissionDeniedException, + UpdateConflictException, StorageException, StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException, ContentAlreadyExistsException, + InvalidArgumentException, RuntimeException, ConstraintViolationException + { + checkRepositoryId(repositoryId); + + NodeRef nodeRef = this.cmisObjectsUtils.getIdentifierInstance(documentId.value, AlfrescoObjectType.DOCUMENT_OBJECT).getConvertedIdentifier(); + + if (contentStream.getStream() == null) + { + throw new InvalidArgumentException("New Content Stream was not provided"); + } + + if ((nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT) != null) && !overwriteFlag) + { + throw new ContentAlreadyExistsException(); + } + + ContentWriter writer = fileFolderService.getWriter(nodeRef); + InputStream inputstream = null; + try + { + inputstream = contentStream.getStream().getInputStream(); + } + catch (IOException e) + { + throw new ConstraintViolationException("", e.getCause()); + } + + writer.setMimetype(contentStream.getMimeType()); + writer.putContent(inputstream); + } + + /** + * Updates properties of the specified object. As per the data model, content-streams are not properties. + * + * @param repositoryId repository Id + * @param objectId object Id + * @param changeToken change token + * @param properties list of properties to update + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws ObjectNotFoundException + * @throws InvalidArgumentException + * @throws RuntimeException + * @throws ConstraintViolationException + */ + public void updateProperties(String repositoryId, Holder objectId, String changeToken, CmisPropertiesType properties) throws PermissionDeniedException, + UpdateConflictException, ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException + { + checkRepositoryId(repositoryId); + checkForReadOnlyProperties(properties); + + NodeRef objectNodeRef = this.cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT).getConvertedIdentifier(); + + setProperties(objectNodeRef, properties); + + // TODO: change token + + // no new version + objectId.value = (String) cmisPropertyService.getProperty(objectNodeRef, CMISMapping.PROP_OBJECT_ID); + } + + /** + * Gets the properties of an object, and optionally the operations that the user is allowed to perform on the object. + * + * @param parameters + * @return collection collection of CmisObjectType + * @throws PermissionDeniedException + * @throws UpdateConflictException + * @throws FilterNotValidException + * @throws ObjectNotFoundException + * @throws OperationNotSupportedException + * @throws InvalidArgumentException + * @throws RuntimeException + */ + public GetPropertiesResponse getProperties(GetProperties parameters) throws PermissionDeniedException, UpdateConflictException, FilterNotValidException, + ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException + { + checkRepositoryId(parameters.getRepositoryId()); + + PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter()); + + String identifier = ((NodeRef) this.cmisObjectsUtils.getIdentifierInstance(parameters.getObjectId(), AlfrescoObjectType.ANY_OBJECT).getConvertedIdentifier()).toString(); + + if ((this.cmisObjectsUtils.determineObjectType(identifier) == EnumObjectType.DOCUMENT) && (parameters.getReturnVersion() != null) + && (parameters.getReturnVersion().getValue() != null)) + { + identifier = getLatestVersionNodeRef(new NodeRef(identifier), (parameters.getReturnVersion().getValue() != EnumReturnVersion.LATEST)).toString(); + } + + GetPropertiesResponse response = new GetPropertiesResponse(); + response.setObject(new CmisObjectType()); + CmisObjectType object = response.getObject(); + object.setProperties(getPropertiesType(identifier, propertyFilter)); + + if (parameters.getIncludeAllowableActions() != null && parameters.getIncludeAllowableActions().getValue()) + { + // TODO: allowable actions + } + + if (parameters.getIncludeRelationships() != null && parameters.getIncludeAllowableActions().getValue()) + { + // TODO: relationships + } + + return response; + } + + public void setPermissionService(PermissionService permissionService) + { + + this.permissionService = permissionService; + } private Map getPropertiesMap(CmisPropertiesType cmisProperties) throws InvalidArgumentException { @@ -72,254 +660,248 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object return properties; } - public String createDocument(String repositoryId, String typeId, CmisPropertiesType properties, String folderId, CmisContentStreamType contentStream, - EnumVersioningState versioningState) throws PermissionDeniedException, UpdateConflictException, StorageException, StreamNotSupportedException, FolderNotValidException, - OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException + private void assertExistType(CMISTypeId cmisTypeId) throws TypeNotFoundException { - - if (descriptorService.getServerDescriptor().getId().equals(repositoryId) == false) + if (cmisDictionaryService.getCMISMapping().isValidCmisType(cmisTypeId.getQName()) == false) { - throw new InvalidArgumentException("Invalid repository id"); + throw new TypeNotFoundException(cmisTypeId.toString()); } - - Map propertiesMap = getPropertiesMap(properties); - CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping(); - CMISTypeId cmisTypeId = cmisMapping.getCmisTypeId(typeId); - - if (cmisMapping.getCmisTypeId(typeId).equals(CMISMapping.DOCUMENT_TYPE_ID) == false) - { - throw new ConstraintViolationException("Invalid document type"); - } - - NodeRef parentNodeRef = getNodeRefFromOID(folderId); - - if (!nodeService.exists(parentNodeRef)) - { - throw new FolderNotValidException("Invalid parent OID"); - } - - String documentName = (String) propertiesMap.get(CMISMapping.PROP_NAME); - if (documentName == null) - { - throw new InvalidArgumentException("Name property not found"); - } - - NodeRef newDocumentNodeRef = fileFolderService.create(parentNodeRef, documentName, cmisTypeId.getQName()).getNodeRef(); - ContentWriter writer = fileFolderService.getWriter(newDocumentNodeRef); - String mimeType = (String) propertiesMap.get(CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE); - if (mimeType != null) - { - writer.setMimetype(mimeType); - } - InputStream inputstream = null; - try - { - inputstream = contentStream.getStream().getInputStream(); - } - catch (IOException e) - { - e.printStackTrace(); - throw new ConstraintViolationException("", e.getCause()); - } - writer.putContent(inputstream); - - if (versioningState == null) - { - versioningState = EnumVersioningState.MAJOR; - } - - cmisPropertyService.setProperties(newDocumentNodeRef, propertiesMap); - - switch (versioningState) - { - case CHECKEDOUT: - //TODO: maybe this must be done by VersioningService - cmisPropertyService.setProperty(newDocumentNodeRef, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT, Boolean.TRUE); - break; - case MAJOR: - cmisPropertyService.setProperty(newDocumentNodeRef, CMISMapping.PROP_IS_MAJOR_VERSION, Boolean.FALSE); - break; - case MINOR: - cmisPropertyService.setProperty(newDocumentNodeRef, CMISMapping.PROP_IS_MAJOR_VERSION, Boolean.TRUE); - break; - - } - - return newDocumentNodeRef.toString(); } - public String createFolder(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) throws PermissionDeniedException, UpdateConflictException, - FolderNotValidException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException + private CMISTypeId getCmisTypeId(String typeId) throws InvalidArgumentException { - if (descriptorService.getServerDescriptor().getId().equals(repositoryId) == false) + try { - throw new InvalidArgumentException("Invalid repository id"); + return cmisDictionaryService.getCMISMapping().getCmisTypeId(typeId); } - - NodeRef folderNodeRef = getNodeRefFromOID(folderId); - assertExistFolder(folderNodeRef); - - CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping(); - - CMISTypeId cmisTypeId = cmisMapping.getCmisTypeId(typeId); - - Map propertiesMap = getPropertiesMap(properties); - - String name = (String) propertiesMap.get(CMISMapping.PROP_NAME); - if (name == null) + catch (Exception e) { - throw new InvalidArgumentException("Name property not found"); + throw new InvalidArgumentException("Invalid typeId " + typeId); } + } + + private void moveObjectToFolder(NodeRef objectNodeRef, NodeRef targetFolderNodeRef) throws PermissionDeniedException, UpdateConflictException + { try { - NodeRef newFolderNodeRef = fileFolderService.create(folderNodeRef, name, cmisTypeId.getQName()).getNodeRef(); - cmisPropertyService.setProperties(newFolderNodeRef, propertiesMap); - return newFolderNodeRef.toString(); + fileFolderService.move(objectNodeRef, targetFolderNodeRef, null); } - catch (FileExistsException e) + catch (Exception e) { - throw new UpdateConflictException("Folder already exists"); + determineException(e); } } - public String createPolicy(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) throws PermissionDeniedException, UpdateConflictException, - FolderNotValidException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, RuntimeException, ConstraintViolationException + private boolean changeObjectParentAssociation(NodeRef objectNodeRef, NodeRef targetFolderNodeRef, NodeRef sourceFolderNodeReference) throws UpdateConflictException, + PermissionDeniedException { - return null; - } - public String createRelationship(String repositoryId, String typeId, CmisPropertiesType properties, String sourceObjectId, String targetObjectId) - throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException, OperationNotSupportedException, TypeNotFoundException, InvalidArgumentException, - RuntimeException, ConstraintViolationException - { - return null; - } - - public void deleteContentStream(String repositoryId, String documentId) throws PermissionDeniedException, UpdateConflictException, StorageException, - StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException, VersioningException, InvalidArgumentException, RuntimeException, - ConstraintViolationException - { - } - - public void deleteObject(String repositoryId, String objectId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException, - OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException - { - } - - public FailedToDelete deleteTree(String repositoryId, String folderId, EnumUnfileNonfolderObjects unfileNonfolderObjects, Boolean continueOnFailure) - throws PermissionDeniedException, UpdateConflictException, FolderNotValidException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, - ConstraintViolationException - { - return null; - } - - public CmisAllowableActionsType getAllowableActions(String repositoryId, String objectId) throws PermissionDeniedException, UpdateConflictException, ObjectNotFoundException, - OperationNotSupportedException, InvalidArgumentException, RuntimeException - { - return null; - } - - public CmisContentStreamType getContentStream(String repositoryId, String documentId) throws PermissionDeniedException, UpdateConflictException, StorageException, - StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, OffsetException - { - NodeRef nodeRef = getNodeRefFromOID(documentId); - - if (!nodeService.exists(nodeRef)) + if (this.cmisObjectsUtils.isPrimaryObjectParent(sourceFolderNodeReference, objectNodeRef)) { - throw new ObjectNotFoundException("Invalid document OID"); + return false; } - CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping(); - - if (cmisMapping.isValidCmisDocument(cmisMapping.getCmisType(nodeService.getType(nodeRef))) == false) + if (!this.cmisObjectsUtils.removeObject(objectNodeRef, sourceFolderNodeReference) && this.cmisObjectsUtils.addObjectToFolder(objectNodeRef, targetFolderNodeRef)) { - throw new StreamNotSupportedException("Stream not supported for this type of node"); + determineException(this.cmisObjectsUtils.getLastOperationException()); } - ContentReader reader = fileFolderService.getReader(nodeRef); - - CmisContentStreamType response = new CmisContentStreamType(); - response.setLength(BigInteger.valueOf(reader.getSize())); - response.setMimeType(reader.getMimetype()); - String filename = (String) cmisPropertyService.getProperty(nodeRef, CMISMapping.PROP_NAME); - response.setFilename(filename); - response.setStream(new DataHandler(new ContentReaderDataSource(reader, filename))); - - return response; + return true; } - public void moveObject(String repositoryId, String objectId, String targetFolderId, String sourceFolderId) throws PermissionDeniedException, UpdateConflictException, - ObjectNotFoundException, FolderNotValidException, OperationNotSupportedException, NotInFolderException, InvalidArgumentException, RuntimeException, - ConstraintViolationException + private void determineException(Throwable lastException) throws PermissionDeniedException, UpdateConflictException { - } - public void setContentStream(String repositoryId, Holder documentId, Boolean overwriteFlag, CmisContentStreamType contentStream) throws PermissionDeniedException, - UpdateConflictException, StorageException, StreamNotSupportedException, ObjectNotFoundException, OperationNotSupportedException, ContentAlreadyExistsException, - InvalidArgumentException, RuntimeException, ConstraintViolationException - { - } - - public void updateProperties(String repositoryId, Holder objectId, String changeToken, CmisPropertiesType properties) throws PermissionDeniedException, - UpdateConflictException, ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException, ConstraintViolationException - { - } - - public GetPropertiesResponse getProperties(GetProperties parameters) throws PermissionDeniedException, UpdateConflictException, FilterNotValidException, - ObjectNotFoundException, OperationNotSupportedException, InvalidArgumentException, RuntimeException - { - if (descriptorService.getServerDescriptor().getId().equals(parameters.getRepositoryId()) == false) + if (lastException instanceof AccessDeniedException) { - throw new InvalidArgumentException("Invalid repository id"); + throw new PermissionDeniedException(lastException.getMessage()); } - PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter()); + throw new UpdateConflictException("Couldn't to relocate multi-filed Object"); + } - NodeRef nodeRef = getNodeRefFromOID(parameters.getObjectId()); + private void performContentStreamDeletion(NodeRef documentNodeReference) throws ConstraintViolationException + { - if (nodeService.exists(nodeRef) == false) + try { - throw new ObjectNotFoundException("Object not found"); + this.nodeService.setProperty(documentNodeReference, ContentModel.PROP_CONTENT, null); + } + catch (NodeLockedException e) + { + throw new ConstraintViolationException("Content Stream Deletion is not allowed for specified Document", e); + } + } + + private void checkObjectTypeAndAppropriateStates(NodeRef objectNodeReference, QName objectType) throws InvalidArgumentException, ConstraintViolationException + { + + if (objectType == null) + { + throw new InvalidArgumentException("Specified Object has invalid Object Type"); } - QName typeQName = nodeService.getType(nodeRef); - - CMISMapping cmisMapping = cmisDictionaryService.getCMISMapping(); - - if (cmisMapping.isValidCmisDocument((cmisMapping.getCmisType(typeQName)))) + if (objectType.equals(CMISMapping.FOLDER_QNAME) && (this.nodeService.getChildAssocs(objectNodeReference).size() > 0)) { - if (parameters.getReturnVersion() != null) + throw new ConstraintViolationException("Could not delete folder with at least one Child"); + } + } + + private void checkUnfilingIsNotRequested(EnumUnfileNonfolderObjects unfileNonfolderObjects) throws OperationNotSupportedException + { + + if (unfileNonfolderObjects == EnumUnfileNonfolderObjects.UNFILE) + { + throw new OperationNotSupportedException("Unfiling is not supported"); + } + } + + private void checkForRootObject(String repositoryId, String objectId) throws OperationNotSupportedException + { + + if (this.cmisService.getDefaultRootNodeRef().toString().equals(objectId) || repositoryId.equals(objectId)) + { + throw new OperationNotSupportedException("Could not delete Repository object or Root Folder object - operation is not allowed or not supported"); + } + } + + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + private ContentReader safelyReceiveContentReader(NodeRef objectNodeReference) throws StorageException + { + + ContentReader reader = fileFolderService.getReader(objectNodeReference); + + if (reader == null) + { + throw new StorageException("The specified Document has no Content Stream"); + } + + return reader; + } + + private void checkForReadOnlyProperties(CmisPropertiesType properties) throws ConstraintViolationException + { + + for (CmisProperty property : properties.getProperty()) + { + if (PropertyUtil.isReadOnlyRepositoryProperty(property.getName())) { - EnumReturnVersion neededVersion = parameters.getReturnVersion().getValue(); - - if (neededVersion.equals(EnumReturnVersion.LATEST)) - { - nodeRef = getLatestVersionNodeRef(nodeRef, false); - } - else if (neededVersion.equals(EnumReturnVersion.LATESTMAJOR)) - { - nodeRef = getLatestVersionNodeRef(nodeRef, true); - } + throw new ConstraintViolationException("The property " + property.getName() + " is Read Only and couldn't be updated"); } } - - GetPropertiesResponse response = new GetPropertiesResponse(); - response.setObject(new CmisObjectType()); - CmisObjectType object = response.getObject(); - object.setProperties(getPropertiesType(nodeRef, propertyFilter)); - - if (parameters.getIncludeAllowableActions() != null && parameters.getIncludeAllowableActions().getValue()) - { - // TODO: allowable actions - } - - if (parameters.getIncludeRelationships() != null && parameters.getIncludeAllowableActions().getValue()) - { - // TODO: relationships - } - - return response; } + private CmisAllowableActionsType determineObjectAllowableActions(IdentifierConversionResults objectIdentifierContainer) throws OperationNotSupportedException + { + Object objectNodeReference = objectIdentifierContainer.getConvertedIdentifier(); + + if (objectNodeReference instanceof AssociationRef) + { + return determineRelationshipAllowableActions((AssociationRef) objectIdentifierContainer.getConvertedIdentifier()); + } + + switch (this.cmisObjectsUtils.determineObjectType(objectNodeReference.toString())) + { + case DOCUMENT: + { + return determineDocumentAllowableActions((NodeRef) objectNodeReference); + } + case FOLDER: + { + return determineFolderAllowableActions((NodeRef) objectNodeReference); + } + } + + // TODO: determinePolicyAllowableActions() when Policy functionality is ready + throw new OperationNotSupportedException("It is impossible to get Allowable actions for the specified Object"); + } + + private CmisAllowableActionsType determineRelationshipAllowableActions(AssociationRef association) + { + + CmisAllowableActionsType result = new CmisAllowableActionsType(); + + result.setCanDelete(this.permissionService.hasPermission(association.getSourceRef(), PermissionService.DELETE_ASSOCIATIONS) == AccessStatus.ALLOWED); + result.setCanGetRelationships(this.permissionService.hasPermission(association.getSourceRef(), PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED); + + return result; + } + + private CmisAllowableActionsType determineBaseAllowableActions(NodeRef objectNodeReference) + { + + CmisAllowableActionsType result = new CmisAllowableActionsType(); + + result.setCanGetProperties(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_PROPERTIES) == AccessStatus.ALLOWED); + result.setCanUpdateProperties(this.permissionService.hasPermission(objectNodeReference, PermissionService.WRITE_PROPERTIES) == AccessStatus.ALLOWED); + result.setCanDelete(this.permissionService.hasPermission(objectNodeReference, PermissionService.DELETE) == AccessStatus.ALLOWED); + + // TODO: response.setCanAddPolicy(value); + // TODO: response.setCanRemovePolicy(value); + // TODO: response.setCanGetAppliedPolicies(value); + + return result; + } + + private void determineCommonFolderDocumentAllowableActions(NodeRef objectNodeReference, CmisAllowableActionsType allowableActions) + { + + allowableActions.setCanAddToFolder(this.permissionService.hasPermission(objectNodeReference, PermissionService.CREATE_ASSOCIATIONS) == AccessStatus.ALLOWED); + allowableActions.setCanGetRelationships(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED); + allowableActions.setCanMove(allowableActions.isCanUpdateProperties() && allowableActions.isCanAddToFolder()); + allowableActions.setCanRemoveFromFolder(allowableActions.isCanUpdateProperties()); + allowableActions.setCanCreateRelationship(allowableActions.isCanAddToFolder()); + } + + private CmisAllowableActionsType determineDocumentAllowableActions(NodeRef objectNodeReference) + { + + CmisAllowableActionsType result = determineBaseAllowableActions(objectNodeReference); + determineCommonFolderDocumentAllowableActions(objectNodeReference, result); + + result.setCanGetParents(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED); + result.setCanViewContent(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_CONTENT) == AccessStatus.ALLOWED); + result.setCanSetContent(this.permissionService.hasPermission(objectNodeReference, PermissionService.WRITE_CONTENT) == AccessStatus.ALLOWED); + result.setCanCheckout(this.permissionService.hasPermission(objectNodeReference, PermissionService.CHECK_OUT) == AccessStatus.ALLOWED); + result.setCanCheckin(this.permissionService.hasPermission(objectNodeReference, PermissionService.CHECK_IN) == AccessStatus.ALLOWED); + result.setCanCancelCheckout(this.permissionService.hasPermission(objectNodeReference, PermissionService.CANCEL_CHECK_OUT) == AccessStatus.ALLOWED); + result.setCanDeleteContent(result.isCanUpdateProperties() && result.isCanSetContent()); + + return result; + } + + private CmisAllowableActionsType determineFolderAllowableActions(NodeRef objectNodeReference) + { + + CmisAllowableActionsType result = determineBaseAllowableActions(objectNodeReference); + determineCommonFolderDocumentAllowableActions(objectNodeReference, result); + + result.setCanGetChildren(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_CHILDREN) == AccessStatus.ALLOWED); + result.setCanCreateDocument(this.permissionService.hasPermission(objectNodeReference, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED); + result.setCanGetDescendants(result.isCanGetChildren() && (this.permissionService.hasPermission(objectNodeReference, PermissionService.READ) == AccessStatus.ALLOWED)); + result.setCanDeleteTree(result.isCanDelete() && (this.permissionService.hasPermission(objectNodeReference, PermissionService.DELETE_CHILDREN) == AccessStatus.ALLOWED)); + result.setCanGetFolderParent(result.isCanGetRelationships()); + result.setCanCreateFolder(result.isCanCreateDocument()); + // TODO: response.setCanCreatePolicy(value); + + return result; + } + + private NodeRef receiveMandatoryFolderNodeReference(String folderId) throws FolderNotValidException + { + + try + { + return this.cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT).getConvertedIdentifier(); + } + catch (InvalidArgumentException e) + { + throw new FolderNotValidException("Unfiling is not suppoerted. Each Document must have existent parent Folder"); + } + } } diff --git a/source/java/org/alfresco/repo/cmis/ws/DMPolicyServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMPolicyServicePort.java new file mode 100755 index 0000000000..a75f9a1817 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/DMPolicyServicePort.java @@ -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 + + } + +} diff --git a/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java new file mode 100755 index 0000000000..0a90dd0af5 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java @@ -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 receiveAssociations(NodeRef objectNodeReference, QName necessaryRelationshipType, EnumRelationshipDirection direction, boolean includingSubtypes) + { + + List result = new LinkedList(); + + 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))); + } + } +} diff --git a/source/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePort.java index 4f7cdb89c1..a07abc2ec5 100644 --- a/source/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePort.java +++ b/source/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePort.java @@ -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 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 { diff --git a/source/java/org/alfresco/repo/cmis/ws/DMServicePortThrowsAdvice.java b/source/java/org/alfresco/repo/cmis/ws/DMServicePortThrowsAdvice.java index d999ff8e54..25d65f2291 100644 --- a/source/java/org/alfresco/repo/cmis/ws/DMServicePortThrowsAdvice.java +++ b/source/java/org/alfresco/repo/cmis/ws/DMServicePortThrowsAdvice.java @@ -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); } - } diff --git a/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java new file mode 100755 index 0000000000..e811c46dee --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java @@ -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 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 documentId, Holder 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 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 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"); + } + } +} diff --git a/source/java/org/alfresco/repo/cmis/ws/PropertyFilter.java b/source/java/org/alfresco/repo/cmis/ws/PropertyFilter.java index 1249a931e0..0a8082e515 100644 --- a/source/java/org/alfresco/repo/cmis/ws/PropertyFilter.java +++ b/source/java/org/alfresco/repo/cmis/ws/PropertyFilter.java @@ -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 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(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 true returns if property is allowed by filter. In other case returns false */ 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(); + + for (String token : tokens) + { + properties.add(token.trim().toLowerCase()); + } + } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/cmis/ws/PropertyUtil.java b/source/java/org/alfresco/repo/cmis/ws/PropertyUtil.java index 7f246683a6..bed39dbcf7 100755 --- a/source/java/org/alfresco/repo/cmis/ws/PropertyUtil.java +++ b/source/java/org/alfresco/repo/cmis/ws/PropertyUtil.java @@ -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 cmisToRepoPropertiesNamesMapping = new HashMap(); - private static Map repoToCmisPropertiesNamesMapping = new HashMap(); + private static Map> cmisToRepoPropertiesNamesMapping = new HashMap>(); + private static Map> repoToCmisPropertiesNamesMapping = new HashMap>(); 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("IsImmutable", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_LATEST_VERSION, new Pair("IsLatestVersion", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_MAJOR_VERSION, new Pair("IsMajorVersion", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_LATEST_MAJOR_VERSION, new Pair("IsLatestMajorVersion", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT, new Pair("IsVersionSeriesCheckedOut", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CREATION_DATE, new Pair("CreationDate", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_LAST_MODIFICATION_DATE, new Pair("LastModificationDate", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_OBJECT_ID, new Pair("ObjectId", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_ID, new Pair("VersionSeriesId", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID, new Pair("VersionSeriesCheckedOutId", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_LENGTH, new Pair("ContentStreamLength", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_NAME, new Pair("Name", false)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_OBJECT_TYPE_ID, new Pair("ObjectTypeId", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CREATED_BY, new Pair("CreatedBy", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_LAST_MODIFIED_BY, new Pair("LastModifiedBy", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE, new Pair("ContentStreamMimeType", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_FILENAME, new Pair("ContentStreamFilename", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_LABEL, new Pair("VersionLabel", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CHECKIN_COMMENT, new Pair("checkinComment", false)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_URI, new Pair("contentStreamURI", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY, new Pair("VersionSeriesCheckedOutBy", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_PARENT_ID, new Pair("ParentId", true)); + cmisToRepoPropertiesNamesMapping.put(CMISMapping.PROP_CONTENT_STREAM_ALLOWED, new Pair("ContentStreamAllowed", true)); - for (Map.Entry entry : cmisToRepoPropertiesNamesMapping.entrySet()) + for (Map.Entry> entry : cmisToRepoPropertiesNamesMapping.entrySet()) { - repoToCmisPropertiesNamesMapping.put(entry.getValue(), entry.getKey()); + repoToCmisPropertiesNamesMapping.put(entry.getValue().getFirst(), new Pair(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; } - } diff --git a/source/java/org/alfresco/repo/cmis/ws/utils/AlfrescoObjectType.java b/source/java/org/alfresco/repo/cmis/ws/utils/AlfrescoObjectType.java new file mode 100755 index 0000000000..5e385763f9 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/utils/AlfrescoObjectType.java @@ -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 VALUES; + static + { + VALUES = new HashMap(); + 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; + } +} diff --git a/source/java/org/alfresco/repo/cmis/ws/utils/CmisObjectsUtils.java b/source/java/org/alfresco/repo/cmis/ws/utils/CmisObjectsUtils.java new file mode 100755 index 0000000000..95cc7130a7 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/utils/CmisObjectsUtils.java @@ -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 DOCUMENT_AND_FOLDER_TYPES; + static + { + DOCUMENT_AND_FOLDER_TYPES = new LinkedList(); + 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 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 children = this.nodeService.getChildAssocs(objectNodeReference); + + return new UnlinkOperationStatus(((children == null) || children.isEmpty()) && deleteObject(objectNodeReference), (children != null) ? (children) + : (new LinkedList())); + } + + return new UnlinkOperationStatus((totalDeletion) ? (deleteObject(objectNodeReference)) + : (!isPrimaryObjectParent(parentFolderNodeReference, objectNodeReference) && removeObject(objectNodeReference, parentFolderNodeReference)), + new LinkedList()); + } + + private void processNotUnlinkedObjectResults(DescendantElement currentElement, UnlinkOperationStatus unlinkingStatus, DescendantsQueueManager queueManager, + List 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 getConvertedIdentifier(); + } + + private class UnlinkOperationStatus + { + private boolean objectUnlinked; + private List children; + + public UnlinkOperationStatus(boolean objectUnlinked, List children) + { + + this.objectUnlinked = objectUnlinked; + this.children = children; + } + + public boolean isObjectUnlinked() + { + + return this.objectUnlinked; + } + + public List getChildren() + { + + return this.children; + } + + protected UnlinkOperationStatus() + { + } + } +} diff --git a/source/java/org/alfresco/repo/cmis/ws/utils/DescendantsQueueManager.java b/source/java/org/alfresco/repo/cmis/ws/utils/DescendantsQueueManager.java new file mode 100755 index 0000000000..89aab0e3e1 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/utils/DescendantsQueueManager.java @@ -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 queue; + + public DescendantsQueueManager(ChildAssociationRef headAssociation) + { + + this.queue = new LinkedList(); + this.queue.addFirst(createElement(headAssociation, null)); + } + + public DescendantElement createElement(ChildAssociationRef data, DescendantElement parent) + { + + return new DescendantElement(parent, data); + } + + public void removeParents(DescendantElement source, List undeletedNodes) + { + + while (source.getParentElement() != null) + { + source = source.getParentElement(); + + determineUndeletedObjectToPut(source.getNodesAssociation().getChildRef().toString(), undeletedNodes); + + this.queue.remove(source); + } + } + + public void addChildren(List 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 DescendantElement (in this case - first element) in the queue if queue still contain any element or null 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 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() + { + } + } +} diff --git a/source/test-resources/import-for-cmis-ws-test.acp b/source/test-resources/import-for-cmis-ws-test.acp deleted file mode 100644 index fef83b5125..0000000000 Binary files a/source/test-resources/import-for-cmis-ws-test.acp and /dev/null differ diff --git a/source/test-resources/test-cmis-context.xml b/source/test-resources/test-cmis-context.xml deleted file mode 100644 index 7b718ad7dc..0000000000 --- a/source/test-resources/test-cmis-context.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - org.alfresco.repo.cmis.ws.RepositoryServicePort - - - - - - - - - - - - - - - - - org.alfresco.repo.cmis.ws.NavigationServicePort - - - - - - - - - - - - - - - - - org.alfresco.repo.cmis.ws.ObjectServicePort - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/test-resources/test.jpg b/source/test-resources/test.jpg new file mode 100755 index 0000000000..fb1b25168f Binary files /dev/null and b/source/test-resources/test.jpg differ diff --git a/source/test/java/org/alfresco/repo/cmis/ws/AbstractServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/AbstractServiceTest.java index 25805576dc..110b533019 100644 --- a/source/test/java/org/alfresco/repo/cmis/ws/AbstractServiceTest.java +++ b/source/test/java/org/alfresco/repo/cmis/ws/AbstractServiceTest.java @@ -24,102 +24,210 @@ */ package org.alfresco.repo.cmis.ws; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; +import java.util.List; import junit.framework.TestCase; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.ResultSet; -import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; -import org.apache.cxf.endpoint.Client; -import org.apache.cxf.frontend.ClientProxy; -import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; -import org.apache.ws.security.WSConstants; -import org.apache.ws.security.WSPasswordCallback; -import org.apache.ws.security.handler.WSHandlerConstants; -import org.springframework.context.support.FileSystemXmlApplicationContext; +import org.alfresco.cmis.dictionary.CMISMapping; /** * @author Michael Shavnev + * @author Alexander Tsvetkov + * */ + public abstract class AbstractServiceTest extends TestCase { - protected ServiceRegistry serviceRegistry; - protected static NodeRef ALFRESCO_TUTORIAL_NODE_REF = null; - protected static NodeRef COMPANY_HOME_NODE_REF = null; + // protected ServiceRegistry serviceRegistry; - protected static FileSystemXmlApplicationContext fContext = null; + public String companyHomeId; + public String repositoryId; + + protected String documentId; + protected String folderId; + protected String documentName; + protected String folderName; + + protected ObjectFactory cmisObjectFactory = new ObjectFactory(); protected Object servicePort = null; + protected CmisServiceTestHelper helper; + + private static boolean testAsUser = false; + + protected abstract Object getServicePort(); @Override protected void setUp() throws Exception { super.setUp(); - if (fContext == null) - { - fContext = new FileSystemXmlApplicationContext("classpath:alfresco/application-context.xml"); - - AuthenticationComponent authenticationComponent = (AuthenticationComponent) fContext.getBean("authenticationComponent"); - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - serviceRegistry = (ServiceRegistry) fContext.getBean(ServiceRegistry.SERVICE_REGISTRY); - ResultSet resultSet = serviceRegistry.getSearchService().query(new StoreRef("workspace://SpacesStore"), "lucene", "@cm\\:name:Alfresco-Tutorial.pdf"); - ALFRESCO_TUTORIAL_NODE_REF = resultSet.getNodeRef(0); - - resultSet = serviceRegistry.getSearchService().query(new StoreRef("workspace://SpacesStore"), "lucene", "@cm\\:name:Company Home"); - COMPANY_HOME_NODE_REF = resultSet.getNodeRef(0); - - authenticationComponent.clearCurrentSecurityContext(); - } } - public AbstractServiceTest() { - servicePort = getServicePort(); - - Map wss4jOutInterceptorProp = new HashMap(); - wss4jOutInterceptorProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP); - - wss4jOutInterceptorProp.put(WSHandlerConstants.USER, getUserName()); - wss4jOutInterceptorProp.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); - - wss4jOutInterceptorProp.put(WSHandlerConstants.PW_CALLBACK_REF, new CallbackHandler() + super(); + if (testAsUser) { - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + helper = CmisServiceTestHelper.getInstance(CmisServiceTestHelper.USERNAME_USER1, CmisServiceTestHelper.PASSWORD_USER1); + servicePort = getServicePort(); + helper.authenticateServicePort(servicePort, CmisServiceTestHelper.USERNAME_USER1, CmisServiceTestHelper.PASSWORD_USER1); + + repositoryId = helper.getRepositoryId(); + companyHomeId = helper.getCompanyHomeId(repositoryId); + // Users could not create any content in Company Home, they should create test content in Users Hone folder + companyHomeId = helper.getUserHomeId(repositoryId, companyHomeId); + } + else + { + helper = CmisServiceTestHelper.getInstance(); + servicePort = getServicePort(); + helper.authenticateServicePort(servicePort, CmisServiceTestHelper.USERNAME_ADMIN, CmisServiceTestHelper.PASSWORD_ADMIN); + + repositoryId = helper.getRepositoryId(); + companyHomeId = helper.getCompanyHomeId(repositoryId); + } + } + + public AbstractServiceTest(String testCase, String userName, String password) + { + super(testCase); + helper = CmisServiceTestHelper.getInstance(userName, password); + servicePort = getServicePort(); + helper.authenticateServicePort(servicePort, userName, password); + repositoryId = helper.getRepositoryId(); + companyHomeId = helper.getCompanyHomeId(repositoryId); + // Users could not create any content in Company Home, they should create test content in Users Home folder + companyHomeId = helper.getUserHomeId(repositoryId, companyHomeId); + + } + + public String getObjectName(GetPropertiesResponse response) + { + String property = null; + + if (response != null && response.getObject() != null) + { + CmisObjectType object = response.getObject(); + CmisPropertiesType properties = object.getProperties(); + property = (String) PropertyUtil.getProperty(properties, CMISMapping.PROP_NAME); + } + else + { + fail("Response has no results."); + } + return property; + } + + public String getPropertyValue(GetPropertiesResponse response, String propertyName) + { + String property = null; + + if (response != null && response.getObject() != null) + { + CmisObjectType object = response.getObject(); + CmisPropertiesType properties = object.getProperties(); + if (PropertyUtil.getProperty(properties, propertyName) != null) { - WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; - pc.setPassword(getPassword()); + property = (String) PropertyUtil.getProperty(properties, propertyName); } - }); - - WSS4JOutInterceptor wss4jOutInterceptor = new WSS4JOutInterceptor(wss4jOutInterceptorProp); - - Client client = ClientProxy.getClient(servicePort); - client.getEndpoint().getOutInterceptors().add(new SAAJOutInterceptor()); - client.getEndpoint().getOutInterceptors().add(wss4jOutInterceptor); + } + else + { + fail("Response has no results."); + } + return property; } - protected abstract Object getServicePort(); - - protected String getUserName() + public Boolean getPropertyBooleanValue(GetPropertiesResponse response, String propertyName) { - return "admin"; + Boolean property = null; + + if (response != null && response.getObject() != null) + { + CmisObjectType object = response.getObject(); + CmisPropertiesType properties = object.getProperties(); + if (PropertyUtil.getProperty(properties, propertyName) != null) + { + property = (Boolean) PropertyUtil.getProperty(properties, propertyName); + } + } + else + { + fail("Response has no results."); + } + return property; } - protected String getPassword() + public String getObjectId(GetPropertiesResponse response) { - return "admin"; + String property = null; + + if (response != null && response.getObject() != null) + { + CmisObjectType object = response.getObject(); + CmisPropertiesType properties = object.getProperties(); + property = (String) PropertyUtil.getProperty(properties, CMISMapping.PROP_OBJECT_ID); + } + else + { + fail("Response has no results."); + } + return property; + } + + public void validateResponse(List objects) + { + for (CmisObjectType object : objects) + { + CmisPropertiesType properties = object.getProperties(); + String name = (String) PropertyUtil.getProperty(properties, CMISMapping.PROP_NAME); + assertNotNull(name); + } + + } + + public boolean isExistItemWithProperty(List objects, String propertyName, String propertyValue) + { + boolean isFound = false; + for (CmisObjectType object : objects) + { + CmisPropertiesType properties = object.getProperties(); + String property = (String) PropertyUtil.getProperty(properties, propertyName); + if (property.equals(propertyValue)) + { + isFound = true; + } + } + return isFound; + } + + public void createInitialContent() throws Exception + { + // create initial content + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId = helper.createDocument(documentName, companyHomeId); + + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId = helper.createFolder(folderName, companyHomeId); + } + + public void deleteInitialContent() + { + try + { + helper.deleteFolder(folderId); + } + catch (Exception e) + { + } + + try + { + helper.deleteDocument(documentId); + } + catch (Exception e) + { + } } } diff --git a/source/test/java/org/alfresco/repo/cmis/ws/BaseServicePortContentTest.java b/source/test/java/org/alfresco/repo/cmis/ws/BaseServicePortContentTest.java deleted file mode 100644 index ef836f9481..0000000000 --- a/source/test/java/org/alfresco/repo/cmis/ws/BaseServicePortContentTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.io.InputStream; -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.action.executer.ImporterActionExecuter; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.version.VersionModel; -import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.coci.CheckOutCheckInService; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.repository.ContentService; -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.VersionService; -import org.alfresco.service.cmr.version.VersionType; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; - -/** - * Base class for all CMIS content tests - * - * @author Dmitry Lazurkin - * - */ -public class BaseServicePortContentTest extends BaseServicePortTest -{ - protected CheckOutCheckInService checkOutCheckInService; - - private static final String IMPORT = "import-for-cmis-ws-test.acp"; - - protected static final String L0_FILE_0 = "L0-File-0"; - protected static final String L0_FILE_1 = "L0-File-1"; - protected static final String L0_FILE_2 = "L0-File-2"; - protected static final String L1_FILE_0 = "L1-File-0"; - protected static final String L1_FILE_1 = "L1-File-1"; - protected static final String L1_FILE_VERSIONABLE = "L1-File-Versionable"; - protected static final String L0_FOLDER_0 = "L0-Folder-0"; - protected static final String L0_FOLDER_1 = "L0-Folder-1"; - protected static final String L0_FOLDER_2 = "L0-Folder-2"; - protected static final String L1_FOLDER_0 = "L1-Folder-0"; - protected static final String L1_FOLDER_1 = "L1-Folder-1"; - - protected NodeRef L0_FILE_0_NODEREF; - protected NodeRef L0_FILE_1_NODEREF; - protected NodeRef L0_FILE_2_NODEREF; - protected NodeRef L1_FILE_0_NODEREF; - protected NodeRef L1_FILE_1_NODEREF; - protected NodeRef L0_FOLDER_0_NODEREF; - protected NodeRef L0_FOLDER_1_NODEREF; - protected NodeRef L0_FOLDER_2_NODEREF; - protected NodeRef L1_FOLDER_0_NODEREF; - protected NodeRef L1_FOLDER_1_NODEREF; - protected NodeRef L0_NONEXISTENT_NODEREF; - - protected NodeRef L1_FILE_VERSION_2_1_NODEREF; - protected NodeRef L1_FILE_VERSION_2_0_NODEREF; - protected NodeRef L1_FILE_VERSION_1_0_NODEREF; - - @Override - protected void onSetUp() throws Exception - { - super.onSetUp(); - - checkOutCheckInService = serviceRegistry.getCheckOutCheckInService(); - - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - InputStream is = getClass().getClassLoader().getResourceAsStream(IMPORT); - if (is == null) - { - throw new NullPointerException("Test resource not found: " + IMPORT); - } - - NodeRef importForTest = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "import-for-test.acp"), ContentModel.TYPE_CONTENT).getChildRef(); - ContentService contentService = serviceRegistry.getContentService(); - ContentWriter writer = contentService.getWriter(importForTest, ContentModel.PROP_CONTENT, true); - writer.setMimetype(MimetypeMap.MIMETYPE_ACP); - writer.setEncoding("UTF-8"); - writer.putContent(is); - - Map params = new HashMap(2, 1.0f); - params.put(ImporterActionExecuter.PARAM_DESTINATION_FOLDER, rootNodeRef); - params.put(ImporterActionExecuter.PARAM_ENCODING, "UTF-8"); - - ActionService actionService = serviceRegistry.getActionService(); - Action action = actionService.createAction(ImporterActionExecuter.NAME, params); - action.setExecuteAsynchronously(false); - - actionService.executeAction(action, importForTest); - - nodeService.deleteNode(importForTest); - - FileFolderService fileFolderService = serviceRegistry.getFileFolderService(); - VersionService versionService = serviceRegistry.getVersionService(); - - L0_FILE_0_NODEREF = fileFolderService.resolveNamePath(rootNodeRef, Collections.singletonList(L0_FILE_0)).getNodeRef(); - L0_FILE_1_NODEREF = fileFolderService.resolveNamePath(rootNodeRef, Collections.singletonList(L0_FILE_1)).getNodeRef(); - L0_FILE_2_NODEREF = fileFolderService.resolveNamePath(rootNodeRef, Collections.singletonList(L0_FILE_2)).getNodeRef(); - L0_FOLDER_0_NODEREF = fileFolderService.resolveNamePath(rootNodeRef, Collections.singletonList(L0_FOLDER_0)).getNodeRef(); - L0_FOLDER_1_NODEREF = fileFolderService.resolveNamePath(rootNodeRef, Collections.singletonList(L0_FOLDER_1)).getNodeRef(); - L0_FOLDER_2_NODEREF = fileFolderService.resolveNamePath(rootNodeRef, Collections.singletonList(L0_FOLDER_2)).getNodeRef(); - L1_FILE_0_NODEREF = fileFolderService.resolveNamePath(L0_FOLDER_0_NODEREF, Collections.singletonList(L1_FILE_0)).getNodeRef(); - L1_FILE_1_NODEREF = fileFolderService.resolveNamePath(L0_FOLDER_1_NODEREF, Collections.singletonList(L1_FILE_1)).getNodeRef(); - - L1_FILE_VERSION_2_1_NODEREF = fileFolderService.resolveNamePath(L0_FOLDER_2_NODEREF, Collections.singletonList(L1_FILE_VERSIONABLE)).getNodeRef(); - nodeService.addAspect(L1_FILE_VERSION_2_1_NODEREF, ContentModel.ASPECT_VERSIONABLE, Collections.singletonMap(ContentModel.PROP_AUTO_VERSION, (Serializable) Boolean.FALSE)); - contentService.getWriter(L1_FILE_VERSION_2_1_NODEREF, ContentModel.PROP_CONTENT, true).putContent("1.0"); - L1_FILE_VERSION_1_0_NODEREF = versionService.createVersion(L1_FILE_VERSION_2_1_NODEREF, createVersionProps("1.0", VersionType.MAJOR)).getFrozenStateNodeRef(); - contentService.getWriter(L1_FILE_VERSION_2_1_NODEREF, ContentModel.PROP_CONTENT, true).putContent("2.0"); - L1_FILE_VERSION_2_0_NODEREF = versionService.createVersion(L1_FILE_VERSION_2_1_NODEREF, createVersionProps("2.0", VersionType.MAJOR)).getFrozenStateNodeRef(); - contentService.getWriter(L1_FILE_VERSION_2_1_NODEREF, ContentModel.PROP_CONTENT, true).putContent("2.1"); - versionService.createVersion(L1_FILE_VERSION_2_1_NODEREF, createVersionProps("2.1", VersionType.MINOR)); - - L1_FOLDER_0_NODEREF = fileFolderService.resolveNamePath(L0_FOLDER_0_NODEREF, Collections.singletonList(L1_FOLDER_0)).getNodeRef(); - L1_FOLDER_1_NODEREF = fileFolderService.resolveNamePath(L0_FOLDER_0_NODEREF, Collections.singletonList(L1_FOLDER_1)).getNodeRef(); - L0_NONEXISTENT_NODEREF = importForTest; - - authenticationComponent.clearCurrentSecurityContext(); - } - - private Map createVersionProps(String comment, VersionType versionType) - { - Map props = new HashMap(1, 1.0f); - props.put(Version.PROP_DESCRIPTION, comment); - props.put(VersionModel.PROP_VERSION_TYPE, versionType); - return props; - } - -} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/BaseServicePortTest.java b/source/test/java/org/alfresco/repo/cmis/ws/BaseServicePortTest.java deleted file mode 100644 index 7274be00e0..0000000000 --- a/source/test/java/org/alfresco/repo/cmis/ws/BaseServicePortTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 javax.transaction.UserTransaction; - -import org.alfresco.cmis.CMISService; -import org.alfresco.cmis.dictionary.CMISMapping; -import org.alfresco.model.ContentModel; -import org.alfresco.repo.node.integrity.IntegrityChecker; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.security.AuthenticationService; -import org.alfresco.service.descriptor.DescriptorService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.springframework.test.AbstractDependencyInjectionSpringContextTests; - -/** - * Base class for all CMIS tests - * - * @author Dmitry Lazurkin - * - */ -public class BaseServicePortTest extends AbstractDependencyInjectionSpringContextTests -{ - protected AuthenticationService authenticationService; - protected TransactionService transactionService; - protected NodeService nodeService; - protected ServiceRegistry serviceRegistry; - protected DictionaryService dictionaryService; - protected DescriptorService descriptorService; - protected CMISMapping cmisMapping; - protected CMISService cmisService; - - protected AuthenticationComponent authenticationComponent; - - private UserTransaction txn; - - protected NodeRef rootNodeRef; - - protected ObjectFactory cmisObjectFactory = new ObjectFactory(); - - protected String repositoryId; - - @Override - protected void onSetUp() throws Exception - { - super.onSetUp(); - - serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY); - - authenticationService = serviceRegistry.getAuthenticationService(); - transactionService = serviceRegistry.getTransactionService(); - nodeService = serviceRegistry.getNodeService(); - dictionaryService = serviceRegistry.getDictionaryService(); - descriptorService = serviceRegistry.getDescriptorService(); - - repositoryId = descriptorService.getServerDescriptor().getId(); - - authenticationComponent = (AuthenticationComponent) applicationContext.getBean("authenticationComponent"); - - cmisService = (CMISService) applicationContext.getBean("CMISService"); - cmisMapping = (CMISMapping) applicationContext.getBean("CMISMapping"); - - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - // start the transaction - txn = transactionService.getUserTransaction(); - txn.begin(); - - IntegrityChecker.setWarnInTransaction(); - - // authenticate - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - // create a test store if need - rootNodeRef = nodeService.createNode(cmisService.getDefaultRootNodeRef(), ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.ALFRESCO_URI, "cmis_test_folder"), - ContentModel.TYPE_FOLDER).getChildRef(); - - authenticationComponent.clearCurrentSecurityContext(); - } - - @Override - protected void onTearDown() throws Exception - { - try - { - txn.rollback(); - } - catch (Throwable e) - { - e.printStackTrace(); - } - } - - @Override - protected String[] getConfigLocations() - { - return new String[] { "classpath:alfresco/application-context.xml", "classpath:test-cmis-context.xml" }; - } - -} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java b/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java new file mode 100755 index 0000000000..50e90569cd --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java @@ -0,0 +1,753 @@ +/* + * 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.io.IOException; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.URLDataSource; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.xml.namespace.QName; +import javax.xml.ws.Holder; +import javax.xml.ws.Service; + +import junit.framework.TestCase; + +import org.alfresco.cmis.dictionary.CMISMapping; +import org.alfresco.cmis.dictionary.CMISTypeId; +import org.alfresco.repo.content.MimetypeMap; +import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; +import org.apache.cxf.endpoint.Client; +import org.apache.cxf.frontend.ClientProxy; +import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; +import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSPasswordCallback; +import org.apache.ws.security.handler.WSHandlerConstants; + +public class CmisServiceTestHelper extends TestCase +{ + public final static String ALFRESCO_URL = "http://localhost:8080/alfresco"; + + public static final String USERNAME_ADMIN = "admin"; + public static final String PASSWORD_ADMIN = "admin"; + + public static final String USERNAME_GUEST = "guest"; + public static final String PASSWORD_GUEST = "guest"; + + public static final String USERNAME_USER1 = "user1"; + public static final String PASSWORD_USER1 = "user1"; + + public String companyHomeId; + public String repositoryId; + + protected ObjectFactory cmisObjectFactory = new ObjectFactory(); + + protected String documentId; + protected String folderId; + protected String documentName; + protected String folderName; + + protected RepositoryServicePort repositoryServicePort = null; + protected VersioningServicePort versioningServicePort = null; + protected ObjectServicePort objectServicePort = null; + protected MultiFilingServicePort multiFilingServicePort = null; + protected NavigationServicePort navigationServicePort = null; + + private static CmisServiceTestHelper helperInstance; + private static String previousUserName = null; + + private CmisServiceTestHelper() + { + repositoryServicePort = getRepositoryServicePort(); + authenticateServicePort(repositoryServicePort, USERNAME_ADMIN, PASSWORD_ADMIN); + + objectServicePort = getObjectServicePort(); + authenticateServicePort(objectServicePort, USERNAME_ADMIN, PASSWORD_ADMIN); + + versioningServicePort = getVersioningServicePort(); + authenticateServicePort(versioningServicePort, USERNAME_ADMIN, PASSWORD_ADMIN); + + multiFilingServicePort = getMultiFilingServicePort(); + authenticateServicePort(multiFilingServicePort, USERNAME_ADMIN, PASSWORD_ADMIN); + + navigationServicePort = getNavigationServicePort(); + authenticateServicePort(navigationServicePort, USERNAME_ADMIN, PASSWORD_ADMIN); + + repositoryId = getRepositoryId(); + companyHomeId = getCompanyHomeId(repositoryId); + } + + private CmisServiceTestHelper(String username, String password) + { + repositoryServicePort = getRepositoryServicePort(); + authenticateServicePort(repositoryServicePort, username, password); + + objectServicePort = getObjectServicePort(); + authenticateServicePort(objectServicePort, username, password); + + versioningServicePort = getVersioningServicePort(); + authenticateServicePort(versioningServicePort, username, password); + + multiFilingServicePort = getMultiFilingServicePort(); + authenticateServicePort(multiFilingServicePort, username, password); + + navigationServicePort = getNavigationServicePort(); + authenticateServicePort(navigationServicePort, username, password); + + repositoryId = getRepositoryId(); + companyHomeId = getCompanyHomeId(repositoryId); + // Users could not create any content in Company Home, they should create test content in Users Hone folder + companyHomeId = getUserHomeId(repositoryId, companyHomeId); + } + + public static CmisServiceTestHelper getInstance() + { + if (previousUserName != null && !previousUserName.equals(USERNAME_ADMIN)) + { + helperInstance = null; + } + + if (helperInstance == null) + { + helperInstance = new CmisServiceTestHelper(); + previousUserName = USERNAME_ADMIN; + } + return helperInstance; + } + + public static CmisServiceTestHelper getInstance(String userName, String password) + { + if (previousUserName != null && !previousUserName.equals(userName)) + { + helperInstance = null; + } + + if (helperInstance == null) + { + helperInstance = new CmisServiceTestHelper(userName, password); + previousUserName = userName; + } + return helperInstance; + } + + public void authenticateServicePort(Object servicePort, String username, String passwordValue) + { + final String password = passwordValue; + + Map wss4jOutInterceptorProp = new HashMap(); + wss4jOutInterceptorProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP); + + wss4jOutInterceptorProp.put(WSHandlerConstants.USER, username); + wss4jOutInterceptorProp.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); + + wss4jOutInterceptorProp.put(WSHandlerConstants.PW_CALLBACK_REF, new CallbackHandler() + { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; + pc.setPassword(password); + } + }); + + WSS4JOutInterceptor wss4jOutInterceptor = new WSS4JOutInterceptor(wss4jOutInterceptorProp); + + Client client = ClientProxy.getClient(servicePort); + client.getEndpoint().getOutInterceptors().add(new SAAJOutInterceptor()); + client.getEndpoint().getOutInterceptors().add(wss4jOutInterceptor); + } + + public String createDocument(String name, String parentFolderId) throws Exception + { + String content = "This is a test content"; + // Cmis Properties + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setValue(name); + propertiesList.add(cmisProperty); + + CmisContentStreamType cmisStream = new CmisContentStreamType(); + cmisStream.setFilename(name); + cmisStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + + DataHandler dataHandler = new DataHandler(content, MimetypeMap.MIMETYPE_TEXT_PLAIN); + cmisStream.setStream(dataHandler); + + // public String createDocument(String repositoryId, String typeId, CmisPropertiesType properties, String folderId, CmisContentStreamType contentStream, + // EnumVersioningState versioningState) + String objectId = objectServicePort.createDocument(repositoryId, CMISMapping.DOCUMENT_TYPE_ID.getTypeId(), properties, parentFolderId, cmisStream, + EnumVersioningState.MAJOR); + // assertNotNull(objectId); + return objectId; + } + + public String createDocument(String name, String parentFolderId, CMISTypeId typeId, EnumVersioningState enumVersioningState) throws Exception + { + String content = "This is a test content"; + // Cmis Properties + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setValue(name); + propertiesList.add(cmisProperty); + + CmisContentStreamType cmisStream = new CmisContentStreamType(); + cmisStream.setFilename(name); + cmisStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + + DataHandler dataHandler = new DataHandler(content, MimetypeMap.MIMETYPE_TEXT_PLAIN); + cmisStream.setStream(dataHandler); + + // public String createDocument(String repositoryId, String typeId, CmisPropertiesType properties, String folderId, CmisContentStreamType contentStream, + // EnumVersioningState versioningState) + String objectId = objectServicePort.createDocument(repositoryId, typeId.getTypeId(), properties, parentFolderId, cmisStream, enumVersioningState); + // assertNotNull(objectId); + return objectId; + } + + public String createDocumentImage(String name, String parentFolderId) throws Exception + { + DataSource dataSource = new URLDataSource(getClass().getResource("test.jpg")); + DataHandler dataHandler = new DataHandler(dataSource); + + CmisContentStreamType cmisStream = new CmisContentStreamType(); + cmisStream.setFilename(name + dataSource.getName()); + cmisStream.setMimeType(MimetypeMap.MIMETYPE_BINARY); + cmisStream.setStream(dataHandler); + + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setValue(name + dataSource.getName()); + propertiesList.add(cmisProperty); + + // public String createDocument(String repositoryId, String typeId, CmisPropertiesType properties, String folderId, CmisContentStreamType contentStream, + // EnumVersioningState versioningState) + String objectId = objectServicePort.createDocument(repositoryId, CMISMapping.DOCUMENT_TYPE_ID.getTypeId(), properties, parentFolderId, cmisStream, + EnumVersioningState.MAJOR); + // assertNotNull(objectId); + return objectId; + + } + + public String createFolder(String name, String parentFolderId) throws Exception + { + // CreateFolder request = cmisObjectFactory.createCreateFolder(); + // request.setRepositoryId(repositoryId); + // request.setFolderId(CompanyHomeId); + // request.setTypeId(CMISMapping.FOLDER_TYPE_ID.getTypeId()); + // request.setProperties(properties); + + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setPropertyType(EnumPropertyType.STRING); + cmisProperty.setIndex(BigInteger.valueOf(1)); + cmisProperty.setValue(name); + propertiesList.add(cmisProperty); + + // public String createFolder(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) + String objectId = objectServicePort.createFolder(repositoryId, CMISMapping.FOLDER_TYPE_ID.getTypeId(), properties, parentFolderId); + // assertNotNull(objectId); + return objectId; + } + + public String createFolder(String name, String parentFolderId, CMISTypeId cmisTypeId) throws Exception + { + + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setPropertyType(EnumPropertyType.STRING); + cmisProperty.setIndex(BigInteger.valueOf(1)); + cmisProperty.setValue(name); + propertiesList.add(cmisProperty); + + // public String createFolder(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) + String objectId = objectServicePort.createFolder(repositoryId, cmisTypeId.getTypeId(), properties, parentFolderId); + // assertNotNull(objectId); + return objectId; + } + + public void deleteDocument(String documentId) throws Exception + { + objectServicePort.deleteObject(repositoryId, documentId); + assertNull("Document has not been deleted", getObjectProperties(documentId)); + } + + public void deleteFolder(String folderId) throws Exception + { + objectServicePort.deleteTree(repositoryId, folderId, EnumUnfileNonfolderObjects.DELETE, true); + assertNull("Folder has not been deleted", getObjectProperties(folderId)); + } + + public GetPropertiesResponse getObjectProperties(String objectId) + { + GetProperties request = new GetProperties(); + request.setRepositoryId(repositoryId); + + request.setObjectId(objectId); + request.setReturnVersion(cmisObjectFactory.createGetPropertiesReturnVersion(EnumReturnVersion.LATEST)); + request.setFilter(cmisObjectFactory.createGetPropertiesFilter("*")); + + request.setIncludeAllowableActions(cmisObjectFactory.createGetPropertiesIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetPropertiesIncludeRelationships(true)); + + GetPropertiesResponse response = null; + try + { + response = objectServicePort.getProperties(request); + } + + catch (InvalidArgumentException e) + { + // e.printStackTrace(); + } + catch (ObjectNotFoundException e) + { + + } + catch (Exception e) + { + e.printStackTrace(); + } + return response; + } + + public GetPropertiesResponse getObjectProperties(String objectId, String filter) + { + GetProperties request = new GetProperties(); + request.setRepositoryId(repositoryId); + + request.setObjectId(objectId); + request.setReturnVersion(cmisObjectFactory.createGetPropertiesReturnVersion(EnumReturnVersion.LATEST)); + request.setFilter(cmisObjectFactory.createGetPropertiesFilter(filter)); + + request.setIncludeAllowableActions(cmisObjectFactory.createGetPropertiesIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetPropertiesIncludeRelationships(true)); + + GetPropertiesResponse response = null; + try + { + response = objectServicePort.getProperties(request); + } + + catch (FilterNotValidException e) + { + fail("FilterNotValidException"); + } + catch (ObjectNotFoundException e) + { + + } + catch (Exception e) + { + e.printStackTrace(); + } + return response; + } + + /** + * This method simplify receiving of Object Identificator for Company Home Root Folder + * + * @param servicesPort - RepositoryServicePort instance that configured with WSS4J Client + * @return String representation of Object Identificator + * @throws Exception This exception throws when any CMIS Services operations was failed + */ + public String getCompanyHomeId(String repositoryId) + { + String rootFolder = null; + GetRepositoryInfo parameters = new GetRepositoryInfo(); + try + { + parameters.setRepositoryId(repositoryId); + rootFolder = repositoryServicePort.getRepositoryInfo(parameters).getRootFolderId(); + } + catch (Exception e) + { + e.printStackTrace(); + } + return rootFolder; + } + + public String getUserHomeId(String repositoryId, String companyHomeId) + { + String userHomeFolder = null; + GetRepositoryInfo parameters = new GetRepositoryInfo(); + try + { + parameters.setRepositoryId(repositoryId); + GetChildrenResponse response = getChildren(companyHomeId, EnumTypesOfFileableObjects.FOLDERS, 0, "*"); + for (CmisObjectType object : response.getObject()) + { + if (PropertyUtil.getProperty(object.getProperties(), CMISMapping.PROP_NAME).equals("User Homes")) + { + return (String) PropertyUtil.getProperty(object.getProperties(), CMISMapping.PROP_OBJECT_ID); + } + } + + userHomeFolder = repositoryServicePort.getRepositoryInfo(parameters).getRootFolderId(); + } + catch (Exception e) + { + e.printStackTrace(); + } + return userHomeFolder; + } + + public final static String REPOSITORY_SERVICE_WSDL_LOCATION = ALFRESCO_URL + "/cmis/RepositoryService?wsdl"; + public final static QName REPOSITORY_SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "RepositoryService"); + + protected RepositoryServicePort getRepositoryServicePort() + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(REPOSITORY_SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, REPOSITORY_SERVICE_NAME); + + return (RepositoryServicePort) service.getPort(RepositoryServicePort.class); + + } + + public final static String OBJECT_SERVICE_WSDL_LOCATION = ALFRESCO_URL + "/cmis/ObjectService?wsdl"; + public final static QName OBJECT_SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "ObjectService"); + + protected ObjectServicePort getObjectServicePort() + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(OBJECT_SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, OBJECT_SERVICE_NAME); + + return (ObjectServicePort) service.getPort(ObjectServicePort.class); + + } + + public final static String VERSIONING_SERVICE_WSDL_LOCATION = ALFRESCO_URL + "/cmis/VersioningService?wsdl"; + public final static QName VERSIONING_SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "VersioningService"); + + protected VersioningServicePort getVersioningServicePort() + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(VERSIONING_SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, VERSIONING_SERVICE_NAME); + return service.getPort(VersioningServicePort.class); + } + + public final static String MULTIFILING_SERVICE_WSDL_LOCATION = ALFRESCO_URL + "/cmis/MultiFilingService?wsdl"; + public final static QName MULTIFILING_SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "MultiFilingService"); + + protected MultiFilingServicePort getMultiFilingServicePort() + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(MULTIFILING_SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, MULTIFILING_SERVICE_NAME); + return service.getPort(MultiFilingServicePort.class); + } + + public final static String NAVIGATION_SERVICE_WSDL_LOCATION = ALFRESCO_URL + "/cmis/NavigationService?wsdl"; + public final static QName NAVIGATION_SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "NavigationService"); + + protected NavigationServicePort getNavigationServicePort() + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(NAVIGATION_SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, NAVIGATION_SERVICE_NAME); + + NavigationServicePort servicePort = service.getPort(NavigationServicePort.class); + + return servicePort; + } + + public String getRepositoryId() + { + try + { + return repositoryServicePort.getRepositories().get(0).getRepositoryID(); + } + catch (Exception e) + { + return null; + } + } + + public void checkIn(Holder documentId, String checkinComment, Boolean isMajor) + { + try + { + CmisPropertiesType properties = new CmisPropertiesType(); + CmisContentStreamType contentStream = new CmisContentStreamType(); + contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + DataHandler dataHandler = new DataHandler("Test content string :" + System.currentTimeMillis(), MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentStream.setStream(dataHandler); + versioningServicePort.checkIn(repositoryId, documentId, isMajor, properties, contentStream, checkinComment); + } + catch (Throwable e) + { + e.printStackTrace(); + fail(); + } + } + + public void checkOut(Holder documentId, Holder contentCopied) + { + try + { + versioningServicePort.checkOut(repositoryId, documentId, contentCopied); + } + catch (Throwable e) + { + e.printStackTrace(); + fail(); + } + } + + public GetAllVersionsResponse getAllVersions(String documentId) + { + GetAllVersionsResponse response = null; + try + { + GetAllVersions request = new GetAllVersions(); + request.setRepositoryId(repositoryId); + request.setVersionSeriesId(documentId); + request.setFilter(cmisObjectFactory.createGetAllVersionsFilter("*")); + request.setIncludeAllowableActions(cmisObjectFactory.createGetAllVersionsIncludeAllowableActions(Boolean.FALSE)); + request.setIncludeRelationships(cmisObjectFactory.createGetAllVersionsIncludeRelationships(Boolean.FALSE)); + + response = versioningServicePort.getAllVersions(request); + assertNotNull(response.getObject()); + } + catch (Throwable e) + { + e.printStackTrace(); + fail(); + } + return response; + } + + public String createRelationship(String name, String folderId, String documentId) throws Exception + { + String objectId = null; + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setPropertyType(EnumPropertyType.STRING); + cmisProperty.setIndex(BigInteger.valueOf(1)); + cmisProperty.setValue(name); + propertiesList.add(cmisProperty); + + // createRelationship(String repositoryId, String typeId, CmisPropertiesType properties, String sourceObjectId, String targetObjectId) + objectId = objectServicePort.createRelationship(repositoryId, CMISMapping.RELATIONSHIP_TYPE_ID.getTypeId(), properties, documentId, folderId); + assertNotNull(objectId); + + return objectId; + + } + + public String updateProperty(String documentId, String propName, String propValue) throws Exception + { + + // Cmis Properties + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(propName); + cmisProperty.setValue(propValue); + propertiesList.add(cmisProperty); + + Holder documentIdHolder = new Holder(documentId); + // public void updateProperties(String repositoryId, Holder objectId, String changeToken, CmisPropertiesType properties) + objectServicePort.updateProperties(repositoryId, documentIdHolder, new String(""), properties); + assertEquals(documentId, documentIdHolder.value); + + return documentIdHolder.value; + } + + public void addObjectToFolder(String documentId, String anotherFolderId) + { + try + { + multiFilingServicePort.addObjectToFolder(repositoryId, documentId, anotherFolderId); + } + catch (Throwable e) + { + fail(e.getMessage()); + } + } + + public void removeObjectFromFolder(String documentId, String folderId) + { + try + { + multiFilingServicePort.removeObjectFromFolder(repositoryId, documentId, folderId); + } + catch (Exception e) + { + fail(e.getMessage()); + } + } + + public GetObjectParentsResponse getObjectParents(String objectId, String filter) throws Exception + { + + GetObjectParents request = cmisObjectFactory.createGetObjectParents(); + request.setRepositoryId(repositoryId); + request.setObjectId(objectId); + request.setFilter("*"); + request.setIncludeAllowableActions(cmisObjectFactory.createGetObjectParentsIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetObjectParentsIncludeRelationships(true)); + + GetObjectParentsResponse response = null; + + try + { + response = navigationServicePort.getObjectParents(request); + } + catch (FilterNotValidException e) + { + fail(e.getMessage()); + } + return response; + } + + public GetObjectParentsResponse getObjectParents(String objectId) throws Exception + { + + GetObjectParents request = cmisObjectFactory.createGetObjectParents(); + + request.setRepositoryId(repositoryId); + request.setObjectId(objectId); + + GetObjectParentsResponse response = navigationServicePort.getObjectParents(request); + + return response; + } + + public void setTextContentStream(String documentId, String newContent) throws Exception + { + String newFileName = "New file name (" + System.currentTimeMillis() + ")"; + + CmisContentStreamType contentStream = new CmisContentStreamType(); + contentStream.setFilename(newFileName); + contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + DataHandler dataHandler = new DataHandler(newContent, MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentStream.setStream(dataHandler); + + Holder documentIdHolder = new Holder(documentId); + // public void setContentStream(String repositoryId, Holder documentId, Boolean overwriteFlag, CmisContentStreamType contentStream) + objectServicePort.setContentStream(repositoryId, documentIdHolder, true, contentStream); + } + + public CmisContentStreamType getContentStream(String documentId) throws Exception + { + CmisContentStreamType result = null; + result = objectServicePort.getContentStream(repositoryId, documentId); + return result; + } + + public GetChildrenResponse getChildren(String folderId, EnumTypesOfFileableObjects type, long maxItems, String filter) throws Exception + { + GetChildren request = cmisObjectFactory.createGetChildren(); + + request.setRepositoryId(repositoryId); + request.setFolderId(folderId); + + request.setFilter(cmisObjectFactory.createGetChildrenFilter(filter)); + request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(maxItems))); + request.setSkipCount(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(0))); + request.setType(cmisObjectFactory.createGetChildrenType(type)); + + GetChildrenResponse response = null; + + try + { + response = navigationServicePort.getChildren(request); + } + catch (FilterNotValidException e) + { + fail(e.getMessage()); + } + + return response; + + } + +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/CmisWebServiceSuiteSystemTest.java b/source/test/java/org/alfresco/repo/cmis/ws/CmisWebServiceSuiteSystemTest.java new file mode 100755 index 0000000000..0c324ecab6 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/CmisWebServiceSuiteSystemTest.java @@ -0,0 +1,52 @@ +/* + * 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 junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Cmis Web service system tests suite + * + * @author Alexander Tsvetkov + */ +public class CmisWebServiceSuiteSystemTest extends TestSuite +{ + public static Test suite() + { + TestSuite suite = new TestSuite(); + suite.addTestSuite(DMDiscoveryServiceTest.class); + suite.addTestSuite(DMMultiFilingServiceTest.class); + suite.addTestSuite(DMNavigationServiceTest.class); + suite.addTestSuite(DMObjectServiceTest.class); + suite.addTestSuite(DMPolicyServiceTest.class); + suite.addTestSuite(DMRelationshipServiceTest.class); + suite.addTestSuite(DMRepositoryServiceTest.class); + suite.addTestSuite(DMVersioningServiceTest.class); + suite.addTestSuite(MultiThreadsServiceTest.class); + + return suite; + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMDiscoveryServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMDiscoveryServiceTest.java new file mode 100755 index 0000000000..79dab002b4 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMDiscoveryServiceTest.java @@ -0,0 +1,88 @@ +/* + * 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.net.MalformedURLException; +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.ws.Service; + +public class DMDiscoveryServiceTest extends AbstractServiceTest +{ + + public final static String SERVICE_WSDL_LOCATION = CmisServiceTestHelper.ALFRESCO_URL + "/cmis/DiscoveryService?wsdl"; + public final static QName SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "DiscoveryService"); + public final static String STATEMENT = "SELECT * FROM DOCUMENT"; + + public DMDiscoveryServiceTest() + { + super(); + } + + public DMDiscoveryServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + protected Object getServicePort() + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, SERVICE_NAME); + return service.getPort(DiscoveryServicePort.class); + } + + public void testQuery() throws Exception + { + CmisQueryType request = new CmisQueryType(); + request.setStatement(STATEMENT); + QueryResponse response = ((DiscoveryServicePort) servicePort).query(request); + assertNotNull(response); + + assertNotNull(response.getObject()); + + if (!response.getObject().isEmpty()) + { + for (CmisObjectType object : response.getObject()) + { + assertNotNull(object.getProperties()); + } + + } + else + { + fail("The query returned no results"); + } + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMMultiFilingServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMMultiFilingServiceTest.java new file mode 100755 index 0000000000..1246cf4e20 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMMultiFilingServiceTest.java @@ -0,0 +1,124 @@ +/* + * 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 javax.xml.namespace.QName; + +import org.alfresco.cmis.dictionary.CMISMapping; + +public class DMMultiFilingServiceTest extends AbstractServiceTest +{ + + public final static String SERVICE_WSDL_LOCATION = CmisServiceTestHelper.ALFRESCO_URL + "/cmis/MultiFilingService?wsdl"; + public final static QName SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "MultiFilingService"); + private String anotherFolderId; + + public DMMultiFilingServiceTest() + { + super(); + } + + public DMMultiFilingServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + createInitialContent(); + anotherFolderId = helper.createFolder("Test Cmis Folder (" + System.currentTimeMillis() + ")", companyHomeId); + + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + deleteInitialContent(); + helper.deleteFolder(anotherFolderId); + } + + protected Object getServicePort() + { + return helper.multiFilingServicePort; + } + + public void testAddObjectToFolder() throws Exception + { + ((MultiFilingServicePort) servicePort).addObjectToFolder(repositoryId, documentId, anotherFolderId); + boolean found = false; + for (CmisObjectType cmisObjectType : helper.getChildren(anotherFolderId, EnumTypesOfFileableObjects.DOCUMENTS, 0, CMISMapping.PROP_OBJECT_ID).getObject()) + { + if ((found = PropertyUtil.getProperty(cmisObjectType.getProperties(), CMISMapping.PROP_OBJECT_ID).equals(documentId))) + { + break; + } + } + assertTrue("Document was not added to folder", found); + } + + public void testRemoveObjectFromFolder() throws Exception + { + + helper.addObjectToFolder(documentId, anotherFolderId); + + try + { + // remove object from all folders expects Exception + ((MultiFilingServicePort) servicePort).removeObjectFromFolder(repositoryId, documentId, null); + fail("Expects exception"); + } + catch (Exception e) + { + assertTrue(e instanceof OperationNotSupportedException); + } + + helper.removeObjectFromFolder(documentId, anotherFolderId); + + try + { + // remove object from folder where it is not situated expects Exception + ((MultiFilingServicePort) servicePort).removeObjectFromFolder(repositoryId, documentId, folderId); + fail("Expected exception"); + } + catch (Exception e) + { + assertTrue(e instanceof NotInFolderException); + } + + try + { + // remove object from last folder expects Exception + ((MultiFilingServicePort) servicePort).removeObjectFromFolder(repositoryId, documentId, companyHomeId); + fail("Expected exception"); + } + catch (Exception e) + { + assertTrue(e instanceof OperationNotSupportedException); + } + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMNavigationServicePortTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMNavigationServicePortTest.java deleted file mode 100644 index 0a6593cf67..0000000000 --- a/source/test/java/org/alfresco/repo/cmis/ws/DMNavigationServicePortTest.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * 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.ArrayList; -import java.util.List; - -import org.alfresco.cmis.dictionary.CMISMapping; -import org.alfresco.service.cmr.repository.NodeRef; - -/** - * @see org.alfresco.repo.cmis.ws.NavigationServicePortDM - * - * @author Dmitry Lazurkin - * - */ -public class DMNavigationServicePortTest extends BaseServicePortContentTest -{ - private NavigationServicePort navigationServicePort; - - @Override - protected void onSetUp() throws Exception - { - super.onSetUp(); - - navigationServicePort = (NavigationServicePort) applicationContext.getBean("dmNavigationService"); - } - - public void testGetChildrenFolders() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(3))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.FOLDERS)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF }; - checkListExact(listing, 0, 3, expectedNodeRefs); - } - - public void testGetChildrenDocuments() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.DOCUMENTS)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkListExact(listing, 3, 0, expectedNodeRefs); - } - - public void testGetChildrenSkipCount() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setSkipCount(cmisObjectFactory.createGetChildrenSkipCount(BigInteger.valueOf(1))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF, L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkList(listing, 5, 3, 3, expectedNodeRefs); - } - - public void testGetChildrenMaxItems() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(3))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF, L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkList(listing, 3, 3, 3, expectedNodeRefs); - } - - public void testGetChildrenMaxItemsMore() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(10))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF, L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkList(listing, 6, 3, 3, expectedNodeRefs); - } - - public void testGetChildrenSkipCountMore() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setSkipCount(cmisObjectFactory.createGetChildrenSkipCount(BigInteger.valueOf(10))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF, L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkList(listing, 0, 3, 3, expectedNodeRefs); - } - - public void testGetChildrenMaxItemsSkipCount() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setSkipCount(cmisObjectFactory.createGetChildrenSkipCount(BigInteger.valueOf(5))); - request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(4))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF, L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkList(listing, 1, 3, 3, expectedNodeRefs); - } - - public void testGetChildrenMaxItemsZero() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(0))); - request.setFolderId(rootNodeRef.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - GetChildrenResponse response = navigationServicePort.getChildren(request); - List listing = response.getObject(); - NodeRef[] expectedNodeRefs = new NodeRef[] { L0_FOLDER_0_NODEREF, L0_FOLDER_1_NODEREF, L0_FOLDER_2_NODEREF, L0_FILE_0_NODEREF, L0_FILE_1_NODEREF, L0_FILE_2_NODEREF }; - checkListExact(listing, 3, 3, expectedNodeRefs); - } - - public void testGetChildrenForDocument() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetChildren request = new GetChildren(); - request.setRepositoryId(repositoryId); - request.setFolderId(L0_FILE_0_NODEREF.toString()); - request.setType(cmisObjectFactory.createGetChildrenType(EnumTypesOfFileableObjects.ANY)); - - try - { - navigationServicePort.getChildren(request); - } - catch (FolderNotValidException e) - { - return; - } - - fail("Expects exception"); - } - - private void checkListExact(List objects, int expectedFileCount, int expectedFolderCount, NodeRef[] expectedNodeRefs) - { - int fileCount = 0; - int folderCount = 0; - List check = new ArrayList(8); - - for (NodeRef nodeRef : expectedNodeRefs) - { - check.add(nodeRef); - } - - for (CmisObjectType object : objects) - { - NodeRef nodeRef = new NodeRef((String) PropertyUtil.getProperty(object.getProperties(), CMISMapping.PROP_OBJECT_ID)); - - if (cmisMapping.isValidCmisFolder(cmisMapping.getCmisType(nodeService.getType(nodeRef)))) - { - folderCount++; - } - else - { - fileCount++; - } - - assertTrue(check.remove(nodeRef)); - } - - assertTrue("Name list was not exact - remaining: " + check, check.size() == 0); - assertEquals("Incorrect number of files", expectedFileCount, fileCount); - assertEquals("Incorrect number of folders", expectedFolderCount, folderCount); - } - - private void checkList(List objects, int expectedCount, int expectedMaxFileCount, int expectedMaxFolderCount, NodeRef[] expectedNodeRefs) - { - int fileCount = 0; - int folderCount = 0; - List check = new ArrayList(8); - - for (NodeRef nodeRef : expectedNodeRefs) - { - check.add(nodeRef); - } - - for (CmisObjectType object : objects) - { - NodeRef nodeRef = new NodeRef((String) PropertyUtil.getProperty(object.getProperties(), CMISMapping.PROP_OBJECT_ID)); - - if (cmisMapping.isValidCmisFolder(cmisMapping.getCmisType(nodeService.getType(nodeRef)))) - { - folderCount++; - } - else - { - fileCount++; - } - - assertTrue(check.remove(nodeRef)); - } - - assertTrue((fileCount + folderCount) == expectedCount); - assertTrue(fileCount <= expectedMaxFileCount); - assertTrue(folderCount <= expectedMaxFolderCount); - } - -} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMNavigationServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMNavigationServiceTest.java new file mode 100755 index 0000000000..6845b1fed5 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMNavigationServiceTest.java @@ -0,0 +1,423 @@ +/* + * 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 javax.xml.ws.Holder; + +import org.alfresco.cmis.dictionary.CMISMapping; + +/** + * @author Alexander Tsvetkov + * + */ + +public class DMNavigationServiceTest extends AbstractServiceTest +{ + public DMNavigationServiceTest() + { + super(); + } + + public DMNavigationServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + createInitialContent(); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + deleteInitialContent(); + } + + protected Object getServicePort() + { + return helper.navigationServicePort; + } + + public void testGetCheckedoutDocs() throws Exception + { + // check out + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + helper.versioningServicePort.checkOut(repositoryId, documentIdHolder, contentCopied); + assertTrue(contentCopied.value); + + String documentName1 = "Test cmis document (" + System.currentTimeMillis() + ")"; + String documentId1 = helper.createDocument(documentName1, folderId); + Holder documentIdHolder1 = new Holder(documentId1); + contentCopied = new Holder(); + helper.versioningServicePort.checkOut(repositoryId, documentIdHolder1, contentCopied); + assertTrue(contentCopied.value); + + GetCheckedoutDocsResponse response; + response = getCheckedoutDocs(null, 0, 0); + + if (response.getObject().size() < 2) + { + // check in + helper.versioningServicePort.checkIn(repositoryId, documentIdHolder, null, null, null, null); + fail("Not all checkout docs have been found"); + } + validateResponse(response.getObject()); + + // assertTrue("Checked out document has not been found ", isExistItemWithProperty(response.getObject(), CMISMapping.PROP_OBJECT_ID, documentId)); + // assertTrue("Checked out document has not been found ", isExistItemWithProperty(response.getObject(), CMISMapping.PROP_OBJECT_ID, documentId1)); + + response = getCheckedoutDocs(null, 1, 0); + assertTrue(response.getObject().size() == 1); + assertTrue(response.hasMoreItems); + + // check in + helper.versioningServicePort.checkIn(repositoryId, documentIdHolder, null, null, null, null); + + response = getCheckedoutDocs(companyHomeId, 0, 0); + assertFalse("Wrong results", isExistItemWithProperty(response.getObject(), CMISMapping.PROP_NAME, documentName)); + + } + + public void testGetChildren() throws Exception + { + GetChildrenResponse response; + response = getChildren(companyHomeId, EnumTypesOfFileableObjects.ANY, 0); + + if ((response != null) && (response.getObject() != null)) + { + validateResponse(response.getObject()); + } + else + { + fail("response is null"); + } + + String folderName1 = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + String folderId1 = helper.createFolder(folderName1, folderId); + String documentName1 = "Test cmis document (" + System.currentTimeMillis() + ")"; + String documentId1 = helper.createDocument(documentName1, folderId, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.MAJOR); + + response = getChildren(folderId, EnumTypesOfFileableObjects.ANY, 0); + assertEquals(2, response.getObject().size()); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName1)); + assertTrue(PropertyUtil.getProperty(response.getObject().get(1).getProperties(), CMISMapping.PROP_NAME).equals(documentName1)); + + response = getChildren(folderId, EnumTypesOfFileableObjects.FOLDERS, 0); + assertTrue(response.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName1)); + + response = getChildren(folderId, EnumTypesOfFileableObjects.DOCUMENTS, 0); + assertTrue(response.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(documentName1)); + + // FIXME: bug • If maxItems > 0, Bool hasMoreItems + // Should return 1 item + response = getChildren(folderId, EnumTypesOfFileableObjects.ANY, 1); + assertTrue("Actual size is: " + response.getObject().size(), response.getObject().size() == 1); + assertTrue(response.hasMoreItems); + + // • If “includeAllowableActions” is TRUE, the repository will return the allowable actions for the current user for each child object as part of the output. + // • "IncludeRelationships" indicates whether relationships are also returned for each returned object. If it is set to "source" or "target", relationships for which the + // returned object is a source, or respectively a target, will also be returned. If it is set to "both", relationships for which the returned object is either a source or a + // target will be returned. If it is set to "none", relationships are not returned. + + // TODO: not implemented + // assertNotNull(response.getObject().get(0).getAllowableActions()); + // assertNotNull(response.getObject().get(0).getRelationship()); + + // filters + // response = getChildren(folderId, EnumTypesOfFileableObjects.DOCUMENTS, 0, CMISMapping.PROP_NAME); + // assertNotNull(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME)); + + response = getChildren(folderId); + assertTrue(response.getObject().size() == 2); + + } + + public void testGetDescendants() throws Exception + { + + GetDescendantsResponse response = getDescendants(companyHomeId, EnumTypesOfFileableObjects.DOCUMENTS, 10); + + if ((response != null) && (response.getObject() != null)) + { + validateResponse(response.getObject()); + } + else + { + fail("response is null"); + } + + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + String folderId1 = helper.createFolder(folderName, folderId); + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + String documentId1 = helper.createDocument(documentName, folderId1, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.MAJOR); + + response = getDescendants(folderId, EnumTypesOfFileableObjects.FOLDERS, 1); + assertTrue(response.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName)); + + response = getDescendants(folderId, EnumTypesOfFileableObjects.DOCUMENTS, 2); + assertTrue(response.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(documentName)); + + response = getDescendants(folderId, EnumTypesOfFileableObjects.ANY, 2); + assertTrue(response.getObject().size() == 2); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName)); + assertTrue(PropertyUtil.getProperty(response.getObject().get(1).getProperties(), CMISMapping.PROP_NAME).equals(documentName)); + + response = getDescendants(folderId, EnumTypesOfFileableObjects.ANY, -1); + assertTrue(response.getObject().size() == 2); + + // test with out option parameters + response = getDescendants(folderId); + assertTrue(response.getObject().size() == 1); + + response = getDescendants(folderId, EnumTypesOfFileableObjects.DOCUMENTS, 2); + // TODO: not implemented + // assertNotNull(response.getObject().get(0).getAllowableActions()); + // assertNotNull(response.getObject().get(0).getRelationship()); + + // Filter test + // response = getDescendants(folderId, EnumTypesOfFileableObjects.DOCUMENTS, 2, CMISMapping.PROP_NAME); + // assertTrue(response.getObject().size() == 1); + // assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(documentName)); + + helper.deleteFolder(folderId1); + + } + + public void testGetFolderParent() throws Exception + { + GetFolderParentResponse response; + response = getFolderParent(folderId, false); + + if ((response != null) && (response.getObject() != null)) + { + validateResponse(response.getObject()); + } + else + { + fail("response is null"); + } + + String folderId1; + + String folderName1 = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId1 = helper.createFolder(folderName1, folderId); + + response = getFolderParent(folderId1, false); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName)); + + String folderName2 = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + String folderId2 = helper.createFolder(folderName2, folderId1); + + response = getFolderParent(folderId2, true); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName1)); + assertTrue(PropertyUtil.getProperty(response.getObject().get(1).getProperties(), CMISMapping.PROP_NAME).equals(folderName)); + assertTrue(response.getObject().size() >= 3); + + } + + public void testGetObjectParents() throws Exception + { + GetObjectParentsResponse response = helper.getObjectParents(documentId, "*"); + + if ((response != null) && (response.getObject() != null)) + { + validateResponse(response.getObject()); + } + else + { + fail("response is null"); + } + + String folderId1; + String documentId1; + + String folderName1 = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId1 = helper.createFolder(folderName1, folderId); + String documentName1 = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId1 = helper.createDocument(documentName1, folderId1, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.MAJOR); + + response = helper.getObjectParents(documentId1, "*"); + assertTrue(response.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName1)); + + // TODO: not implemented + // assertNotNull(response.getObject().get(0).getAllowableActions()); + // assertNotNull(response.getObject().get(0).getRelationship()); + + // filters + // response = getObjectParents(documentId1, CMISMapping.PROP_NAME); + // assertTrue(response.getObject().size() >= 2); + // assertNotNull(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME)); + + response = helper.getObjectParents(documentId1); + assertTrue(response.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName1)); + // assertTrue(PropertyUtil.getProperty(response.getObject().get(1).getProperties(), CMISMapping.PROP_NAME).equals(folderName)); + + } + + private GetDescendantsResponse getDescendants(String folderId, EnumTypesOfFileableObjects type, long depth) throws Exception + { + GetDescendants request = cmisObjectFactory.createGetDescendants(); + + request.setRepositoryId(repositoryId); + request.setFolderId(folderId); + request.setType(type); + request.setDepth(cmisObjectFactory.createGetDescendantsDepth(BigInteger.valueOf(depth))); + request.setFilter(cmisObjectFactory.createGetPropertiesFilter("*")); + request.setIncludeAllowableActions(cmisObjectFactory.createGetDescendantsIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetDescendantsIncludeRelationships(true)); + + GetDescendantsResponse response = ((NavigationServicePort) servicePort).getDescendants(request); + return response; + } + + private GetDescendantsResponse getDescendants(String folderId) throws Exception + { + GetDescendants request = cmisObjectFactory.createGetDescendants(); + + request.setRepositoryId(repositoryId); + request.setFolderId(folderId); + + GetDescendantsResponse response = ((NavigationServicePort) servicePort).getDescendants(request); + return response; + } + + private GetChildrenResponse getChildren(String folderId, EnumTypesOfFileableObjects type, long maxItems) throws Exception + { + + GetChildren request = cmisObjectFactory.createGetChildren(); + + request.setRepositoryId(repositoryId); + request.setFolderId(folderId); + + request.setFilter(cmisObjectFactory.createGetChildrenFilter("*")); + request.setMaxItems(cmisObjectFactory.createGetChildrenMaxItems(BigInteger.valueOf(maxItems))); + request.setSkipCount(cmisObjectFactory.createGetChildrenSkipCount(BigInteger.valueOf(0))); + request.setType(cmisObjectFactory.createGetChildrenType(type)); + + GetChildrenResponse response = ((NavigationServicePort) servicePort).getChildren(request); + + return response; + } + + private GetChildrenResponse getChildren(String folderId) throws Exception + { + + GetChildren request = cmisObjectFactory.createGetChildren(); + + request.setRepositoryId(repositoryId); + request.setFolderId(folderId); + + GetChildrenResponse response = ((NavigationServicePort) servicePort).getChildren(request); + + return response; + } + + public GetFolderParentResponse getFolderParent(String folderId, boolean setReturnToRoot) throws Exception + { + GetFolderParent request = cmisObjectFactory.createGetFolderParent(); + + request.setRepositoryId(repositoryId); + + request.setFolderId(folderId); + + request.setFilter("*"); + request.setReturnToRoot(cmisObjectFactory.createGetFolderParentReturnToRoot(setReturnToRoot)); + + request.setIncludeAllowableActions(cmisObjectFactory.createGetFolderParentIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetFolderParentIncludeRelationships(true)); + + GetFolderParentResponse response = ((NavigationServicePort) servicePort).getFolderParent(request); + return response; + } + + public GetFolderParentResponse getFolderParent(String folderId, String filter) throws Exception + { + GetFolderParent request = cmisObjectFactory.createGetFolderParent(); + + request.setRepositoryId(repositoryId); + + request.setFolderId(folderId); + + request.setFilter(filter); + + request.setIncludeAllowableActions(cmisObjectFactory.createGetFolderParentIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetFolderParentIncludeRelationships(true)); + + GetFolderParentResponse response = null; + try + { + response = ((NavigationServicePort) servicePort).getFolderParent(request); + } + catch (FilterNotValidException e) + { + fail(e.getMessage()); + } + return response; + } + + public GetFolderParentResponse getFolderParent(String folderId) throws Exception + { + GetFolderParent request = cmisObjectFactory.createGetFolderParent(); + + request.setRepositoryId(repositoryId); + request.setFolderId(folderId); + + GetFolderParentResponse response = ((NavigationServicePort) servicePort).getFolderParent(request); + + return response; + } + + private GetCheckedoutDocsResponse getCheckedoutDocs(String folderId, long maxItems, long skipCount) throws Exception + { + GetCheckedoutDocs request = cmisObjectFactory.createGetCheckedoutDocs(); + + request.setRepositoryId(repositoryId); + + request.setFolderID(cmisObjectFactory.createGetCheckedoutDocsFolderID(folderId)); + request.setFilter(cmisObjectFactory.createGetCheckedoutDocsFilter("*")); + request.setMaxItems(cmisObjectFactory.createGetCheckedoutDocsMaxItems(BigInteger.valueOf(maxItems))); + request.setSkipCount(cmisObjectFactory.createGetCheckedoutDocsSkipCount(BigInteger.valueOf(skipCount))); + + request.setIncludeAllowableActions(cmisObjectFactory.createGetCheckedoutDocsIncludeAllowableActions(true)); + request.setIncludeRelationships(cmisObjectFactory.createGetCheckedoutDocsIncludeRelationships(true)); + + GetCheckedoutDocsResponse response = ((NavigationServicePort) servicePort).getCheckedoutDocs(request); + + return response; + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServicePortTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServicePortTest.java deleted file mode 100644 index b17612007e..0000000000 --- a/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServicePortTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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 org.alfresco.cmis.dictionary.CMISMapping; -import org.alfresco.service.cmr.repository.NodeRef; - -/** - * @see org.alfresco.repo.cmis.ws.ObjectServicePortDM - * - * @author Dmitry Lazurkin - */ -public class DMObjectServicePortTest extends BaseServicePortContentTest -{ - private ObjectServicePort objectServicePort; - private RepositoryServicePort repositoryServicePort; - - @Override - protected void onSetUp() throws Exception - { - super.onSetUp(); - - repositoryServicePort = (RepositoryServicePort) applicationContext.getBean("dmRepositoryService"); - objectServicePort = (ObjectServicePort) applicationContext.getBean("dmObjectService"); - } - - public void testGetExistentFolderProperties() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setObjectId(L0_FOLDER_0_NODEREF.toString()); - - GetPropertiesResponse response = objectServicePort.getProperties(request); - assertNotNull(response); - assertEquals(rootNodeRef.toString(), PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_PARENT_ID)); - assertEquals(L0_FOLDER_0, PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_NAME)); - } - - public void testGetExistentDocumentPropertiesThis() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setObjectId(L1_FILE_VERSION_1_0_NODEREF.toString()); - - GetPropertiesResponse response = objectServicePort.getProperties(request); - assertNotNull(response); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_CHECKIN_COMMENT), "1.0"); - assertTrue((Boolean) PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_IS_MAJOR_VERSION)); - } - - public void testGetExistentDocumentPropertiesLatestMajor() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setReturnVersion(cmisObjectFactory.createGetPropertiesReturnVersion(EnumReturnVersion.LATESTMAJOR)); - request.setObjectId(L1_FILE_VERSION_1_0_NODEREF.toString()); - - GetPropertiesResponse response = objectServicePort.getProperties(request); - assertNotNull(response); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_CHECKIN_COMMENT), "2.0"); - assertTrue((Boolean) PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_IS_MAJOR_VERSION)); - } - - public void testGetExistentDocumentPropertiesLatest() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setReturnVersion(cmisObjectFactory.createGetPropertiesReturnVersion(EnumReturnVersion.LATEST)); - request.setObjectId(L1_FILE_VERSION_2_0_NODEREF.toString()); - - GetPropertiesResponse response = objectServicePort.getProperties(request); - assertNotNull(response); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_CHECKIN_COMMENT), "2.1"); - assertFalse((Boolean) PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_IS_MAJOR_VERSION)); - } - - public void testGetNonExistentObjectProperties() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setObjectId(L0_NONEXISTENT_NODEREF.toString()); - try - { - objectServicePort.getProperties(request); - } - catch (ObjectNotFoundException e) - { - return; - } - - fail("Expects exception"); - } - - public void testGetPropertiesForInvalidOID() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setObjectId("invalid OID"); - - try - { - objectServicePort.getProperties(request); - } - catch (InvalidArgumentException e) - { - return; - } - - fail("Expects exception"); - } - - public void testGetPropertiesCheckedout() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - NodeRef workingCopyNodeRef = checkOutCheckInService.checkout(L0_FILE_0_NODEREF); - - GetProperties request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setObjectId(L0_FILE_0_NODEREF.toString()); - - GetPropertiesResponse response = objectServicePort.getProperties(request); - assertNotNull(response); - - assertNull(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_CHECKIN_COMMENT)); - assertTrue((Boolean) PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY), authenticationComponent.getSystemUserName()); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID), workingCopyNodeRef.toString()); - - request = new GetProperties(); - request.setRepositoryId(repositoryId); - request.setObjectId(workingCopyNodeRef.toString()); - - response = objectServicePort.getProperties(request); - assertNotNull(response); - assertNull(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_CHECKIN_COMMENT)); - assertTrue((Boolean) PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY), authenticationComponent.getSystemUserName()); - assertEquals(PropertyUtil.getProperty(response.getObject().getProperties(), CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID), workingCopyNodeRef.toString()); - } - - public void testGetContentStream() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - List repositories = repositoryServicePort.getRepositories(); - String documentId = L0_FILE_0_NODEREF.toString(); - CmisContentStreamType result = objectServicePort.getContentStream(repositories.get(0).getRepositoryID(), documentId); - assertNotNull(result); - if (result.getLength().intValue() != 9) - { - fail(); - } - - try - { - result = objectServicePort.getContentStream(repositories.get(0).getRepositoryID(), documentId + "s"); - } - catch (ObjectNotFoundException e) - { - } - catch (Throwable e) - { - fail(); - } - } - -} \ No newline at end of file diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServiceTest.java index a3e50298ef..342c0762bb 100644 --- a/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServiceTest.java +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMObjectServiceTest.java @@ -15,68 +15,233 @@ * 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: + * 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.net.MalformedURLException; -import java.net.URL; +import java.math.BigInteger; +import java.util.List; -import javax.xml.namespace.QName; -import javax.xml.ws.Service; +import javax.activation.DataHandler; +import javax.xml.ws.Holder; + +import org.alfresco.cmis.dictionary.CMISMapping; +import org.alfresco.repo.content.MimetypeMap; + +/** + * @author Alexander Tsvetkov + * + */ public class DMObjectServiceTest extends AbstractServiceTest { + GetPropertiesResponse propertiesResponse; - public final static String SERVICE_WSDL_LOCATION = "http://localhost:8080/alfresco/cmis/ObjectService?wsdl"; - public final static QName SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "ObjectService"); - - - private RepositoryServicePort repositoryServicePort; + public DMObjectServiceTest() + { + super(); + } + + public DMObjectServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } @Override protected void setUp() throws Exception { super.setUp(); - - repositoryServicePort = (RepositoryServicePort) fContext.getBean("dmRepositoryService"); - } - - protected Object getServicePort() - { - URL serviceWsdlURL; - try - { - serviceWsdlURL = new URL(SERVICE_WSDL_LOCATION); - } - catch (MalformedURLException e) - { - throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); - } - Service service = Service.create(serviceWsdlURL, SERVICE_NAME); - - return service.getPort(ObjectServicePort.class); + createInitialContent(); } + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + deleteInitialContent(); + } + + protected Object getServicePort() + { + return helper.objectServicePort; + } + + public void testCreateDocument() throws Exception + { + + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + + String content = "This is a test content"; + // Cmis Properties + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setValue(documentName); + propertiesList.add(cmisProperty); + + CmisContentStreamType cmisStream = new CmisContentStreamType(); + cmisStream.setFilename(documentName); + cmisStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + + DataHandler dataHandler = new DataHandler(content, MimetypeMap.MIMETYPE_TEXT_PLAIN); + cmisStream.setStream(dataHandler); + + // public String helper.createDocument(String repositoryId, String typeId, CmisPropertiesType properties, String folderId, CmisContentStreamType contentStream, + // EnumVersioningState versioningState) + + String documentId; + // MAJOR + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId = helper.createDocument(documentName, folderId, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.MAJOR); + propertiesResponse = helper.getObjectProperties(documentId); + // assertTrue(getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_IS_MAJOR_VERSION)); + assertFalse(getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); + helper.deleteDocument(documentId); + + // MINOR + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId = helper.createDocument(documentName, folderId, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.MINOR); + propertiesResponse = helper.getObjectProperties(documentId); + assertFalse(getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); + // assertTrue(getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_IS_MAJOR_VERSION)); + helper.deleteDocument(documentId); + + } + + public void testCreateDocument_Versioning() throws Exception + { + // CHECKEDOUT + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + String documentId = helper.createDocument(documentName, folderId, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.CHECKEDOUT); + propertiesResponse = helper.getObjectProperties(documentId); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_VERSION_SERIES_ID)); + // Bug + assertTrue(getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY)); + assertTrue(getPropertyValue(propertiesResponse, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_ID).equals(documentId)); + + Holder documentIdHolder = new Holder(documentId); + helper.checkIn(documentIdHolder, "checkin Comment", true); + assertTrue(getPropertyValue(propertiesResponse, CMISMapping.PROP_VERSION_LABEL).equals("1.0")); + + // documentId = (String) PropertyUtil.getProperty(response.getObject().iterator().next().getProperties(), CMISMapping.PROP_OBJECT_ID); + // deleteDocument(documentId); + } + + public void testCreateDocument_Exceptions() throws Exception + { + // • If unfiling is not supported and a Folder is not specified, throw FolderNotValidException. + try + { + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId = helper.createDocument(documentName, null, CMISMapping.DOCUMENT_TYPE_ID, EnumVersioningState.MAJOR); + fail(); + } + catch (FolderNotValidException e) + { + + } + catch (Exception e) + { // Bug + e.printStackTrace(); // org.alfresco.repo.cmis.ws.RuntimeException: Runtime error. Message: null + fail(e.getMessage()); + } + } + + public void testCreateFolder() throws Exception + { + String folderId1; + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")" + "testCreateFolder"; + folderId1 = helper.createFolder(folderName, folderId, CMISMapping.FOLDER_TYPE_ID); + + propertiesResponse = helper.getObjectProperties(folderId1); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_NAME)); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_PARENT_ID)); + + helper.deleteFolder(folderId1); + } public void testGetDocumentProperties() throws Exception { - GetProperties request = new GetProperties(); - request.setObjectId(ALFRESCO_TUTORIAL_NODE_REF.toString()); - request.setRepositoryId(repositoryServicePort.getRepositories().get(0).getRepositoryID()); - - GetPropertiesResponse response = ((ObjectServicePort) servicePort).getProperties(request); - assertNotNull(response); + String filter; + filter = "*"; + propertiesResponse = helper.getObjectProperties(documentId, filter); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_NAME)); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_CONTENT_STREAM_FILENAME)); + assertNotNull(getPropertyValue(propertiesResponse, CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE)); + assertTrue(getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_IS_LATEST_VERSION)); + + // A property filter is a string that contains either ‘*’ (to return all properties) or a comma-separated list of property names (to return selected properties). An + // arbitrary number of spaces are allowed before or after each comma. + + // filter = "*Stream*"; + // propertiesResponse = helper.getObjectProperties(documentId, filter); + // assertNotNull("filter test", getPropertyValue(propertiesResponse, CMISMapping.PROP_NAME)); + // assertNotNull("filter test", getPropertyValue(propertiesResponse, CMISMapping.PROP_CONTENT_STREAM_LENGTH)); + + } + + public void testGetDocumentProperties_Versioning() throws Exception + { + GetPropertiesResponse response = helper.getObjectProperties(documentId); + + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + String checkinComment = "Test checkin" + System.currentTimeMillis(); + + helper.checkOut(documentIdHolder, contentCopied); + // new version of doc + response = helper.getObjectProperties(documentIdHolder.value); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_NAME)); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_CONTENT_STREAM_FILENAME)); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE)); + assertTrue(getPropertyBooleanValue(response, CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_VERSION_SERIES_CHECKED_OUT_BY)); + + helper.checkIn(documentIdHolder, checkinComment, true); + + response = helper.getObjectProperties(documentId); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_NAME)); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_CONTENT_STREAM_FILENAME)); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_CONTENT_STREAM_MIME_TYPE)); + assertTrue(getPropertyBooleanValue(response, CMISMapping.PROP_IS_LATEST_VERSION)); + assertTrue(getPropertyBooleanValue(response, CMISMapping.PROP_IS_LATEST_MAJOR_VERSION)); + assertTrue(getPropertyBooleanValue(response, CMISMapping.PROP_IS_MAJOR_VERSION)); + + // Returns the list of all document versions for the specified version series, sorted by CREATION_DATE descending. + GetAllVersionsResponse responseVersions = helper.getAllVersions(documentId); + + // Last version + + assertEquals(3, responseVersions.getObject().size()); + assertTrue("Initial version was not returned", isExistItemWithProperty(responseVersions.getObject(), CMISMapping.PROP_VERSION_LABEL, "1.0")); + assertTrue("Invalid response ordering: First object is not latest version", (Boolean) PropertyUtil.getProperty(responseVersions.getObject().get(0).getProperties(), CMISMapping.PROP_IS_LATEST_VERSION)); + assertTrue("Invalid response ordering: Second object is not head version", (Boolean) PropertyUtil.getProperty(responseVersions.getObject().get(1).getProperties(), CMISMapping.PROP_IS_LATEST_VERSION)); + } + + // This test don't asserts until CMIS setProperty()/setProperties() logic is unimplemented + public void testGetDocumentProperties_Other() throws Exception + { + // • If “includeAllowableActions” is TRUE, the repository will return the allowable actions for the current user for the object as part of the output. + // • "IncludeRelationships" indicates whether relationships are also returned for the object. If it is set to "source" or "target", relationships for which the returned + // object is a source, or respectively a target, will also be returned. If it is set to "both", relationships for which the returned object is either a source or a target + // will be returned. If it is set to "none", relationships are not returned. + + GetPropertiesResponse response = helper.getObjectProperties(documentId); + CmisObjectType object = response.getObject(); + // TODO: not implemented + // assertNotNull(object.getAllowableActions()); + // assertNotNull(object.getRelationship()); } public void testGetPropertiesForInvalidOID() throws Exception { - GetProperties request = new GetProperties(); request.setObjectId("invalid OID"); request.setRepositoryId("invalid OID"); @@ -92,36 +257,462 @@ public class DMObjectServiceTest extends AbstractServiceTest fail("Expects exception"); } - - public void testGetContentStream() throws Exception { - String documentId = ALFRESCO_TUTORIAL_NODE_REF.toString(); - String repoId = repositoryServicePort.getRepositories().get(0).getRepositoryID(); - GetContentStream contStream = new GetContentStream(); contStream.setDocumentId(documentId); - contStream.setRepositoryId(repoId); - - CmisContentStreamType result = ((ObjectServicePort) servicePort).getContentStream(repoId, documentId); - if (result.length.intValue() == 0) + contStream.setRepositoryId(repositoryId); + + CmisContentStreamType result = ((ObjectServicePort) servicePort).getContentStream(repositoryId, documentId); + if (result.getLength().intValue() == 0) { fail(); } - try { contStream.setDocumentId(documentId + "s"); { - result = ((ObjectServicePort) servicePort).getContentStream(repoId, documentId); + result = ((ObjectServicePort) servicePort).getContentStream(repositoryId, documentId); } } - catch (ObjectNotFoundException e) + catch (InvalidArgumentException e) { } catch (Throwable e) { + e.printStackTrace(); fail(); } + + // Content Stream of checked out doc + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + String checkinComment = "Test checkin" + System.currentTimeMillis(); + + helper.checkOut(documentIdHolder, contentCopied); + + result = ((ObjectServicePort) servicePort).getContentStream(repositoryId, documentIdHolder.value); + if (result.getLength().intValue() == 0) + { + fail(); + } + + helper.checkIn(documentIdHolder, checkinComment, true); + } -} + + // this method is not implemented yet + public void testCreatePolicy() throws Exception + { + CreatePolicy request = cmisObjectFactory.createCreatePolicy(); + + request.setRepositoryId(repositoryId); + request.setFolderId(cmisObjectFactory.createCreatePolicyFolderId(companyHomeId)); + // there is no CMISMapping.POLICY_TYPE_ID + request.setTypeId("policy"); + + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setPropertyType(EnumPropertyType.STRING); + cmisProperty.setIndex(BigInteger.valueOf(1)); + cmisProperty.setValue("Cmis Test Policy"); + propertiesList.add(cmisProperty); + request.setProperties(properties); + + // TODO: not implemented + // String createPolicy(String repositoryId, String typeId, CmisPropertiesType properties, String folderId) + String response = ((ObjectServicePort) servicePort).createPolicy(repositoryId, request.getTypeId(), request.getProperties(), companyHomeId); + + // assertNotNull(response); + } + + public void testCreateRelationship() throws Exception + { + // TODO: uncomment + // String name = "Cmis Test Relationship"; + // String objectId = null; + // try + // { + // objectId = helper.createRelationship(name, folderId, documentId); + // } + // catch (Exception e) + // { + // fail(e.getMessage()); + // } + // + // GetPropertiesResponse response = helper.getObjectProperties(objectId); + // assertEquals(name, getPropertyValue(response, CMISMapping.PROP_NAME)); + // + // helper.deleteFolder(folderId); + // + // response = helper.getObjectProperties(documentId); + // assertNull(response); + } + + public void testDeleteContentStream() throws Exception + { + // public void deleteContentStream(String repositoryId, String documentId) + ((ObjectServicePort) servicePort).deleteContentStream(repositoryId, documentId); + + try + { + CmisContentStreamType result = ((ObjectServicePort) servicePort).getContentStream(repositoryId, documentId); + } + catch (StorageException e) + { + } + catch (Exception e) + { + e.printStackTrace(); // org.alfresco.repo.cmis.ws.StorageException: The specified Document has no Content Stream + fail(e.getMessage()); + } + + // on content update and on content delete new version should be created + GetAllVersionsResponse responseVersions = helper.getAllVersions(documentId); + assertTrue("new version of document should be created", responseVersions.getObject().size() > 1); + + } + + public void testDeleteObject() throws Exception + { + // public void deleteObject(String repositoryId, String objectId) + ((ObjectServicePort) servicePort).deleteObject(repositoryId, documentId); + assertNull(helper.getObjectProperties(documentId)); + } + + public void testDeleteObject_Exceptions() throws Exception + { + // • If the object is a Folder with at least one child, throw ConstraintViolationException. + // • If the object is the Root Folder, throw OperationNotSupportedException. + + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + String documentId = helper.createDocument(documentName, folderId); + + // Try to delere folder with child + try + { + ((ObjectServicePort) servicePort).deleteObject(repositoryId, folderId); + fail("Try to delere folder with child"); + } + catch (ConstraintViolationException e) + { + } + catch (Exception e) + { + e.printStackTrace(); + fail(e.getClass().getName() + ": " + e.getMessage()); + } + + // Try to delere root folder + try + { + ((ObjectServicePort) servicePort).deleteObject(repositoryId, helper.getCompanyHomeId(repositoryId)); + fail("Try to delere root folder"); + } + catch (OperationNotSupportedException e) + { + } + catch (Exception e) + { + e.printStackTrace();// org.alfresco.repo.cmis.ws.ConstraintViolationException: Could not delete folder with at least one Child + fail(e.getClass().getName() + ": " + e.getMessage()); + } + + } + + public void testDeleteTree() throws Exception + { + String folderName; + String folderId1; + String folderId2; + String documentId2; + + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId1 = helper.createFolder(folderName, folderId); + + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId2 = helper.createFolder(folderName, folderId1); + + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId2 = helper.createDocument(documentName, folderId2); + + // public FailedToDelete deleteTree(String repositoryId, String folderId, EnumUnfileNonfolderObjects unfileNonfolderObjects, Boolean continueOnFailure) + DeleteTreeResponse.FailedToDelete response = ((ObjectServicePort) servicePort).deleteTree(repositoryId, folderId1, EnumUnfileNonfolderObjects.DELETE, true); + assertTrue("All objects should be deleted", response.getObjectId().size() == 0); + + assertNull("DELETE", helper.getObjectProperties(folderId1)); + assertNull("DELETE", helper.getObjectProperties(folderId2)); + assertNull("DELETE", helper.getObjectProperties(documentId2)); + + // Check DELETESINGLEFILED + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId1 = helper.createFolder(folderName, folderId); + + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId2 = helper.createFolder(folderName, folderId1); + + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId2 = helper.createDocument(documentName, folderId2); + + response = ((ObjectServicePort) servicePort).deleteTree(repositoryId, folderId1, EnumUnfileNonfolderObjects.DELETESINGLEFILED, true); + // assertNotNull("DELETESINGLEFILED", response); + assertTrue("All objects should not be deleted", response.getObjectId().size() != 0); + assertNotNull("DELETESINGLEFILED", helper.getObjectProperties(folderId1)); + assertNotNull("DELETESINGLEFILED", helper.getObjectProperties(folderId2)); + assertNotNull("DELETESINGLEFILED", helper.getObjectProperties(documentId2)); + + helper.deleteFolder(folderId1); + + /* + // on DELETESINGLEFILED deletes only relationships and folder. Primary parent folder and contend should not be deleted + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId1 = helper.createFolder(folderName, folderId); + + folderName = "Test Cmis Folder (" + System.currentTimeMillis() + ")"; + folderId2 = helper.createFolder(folderName, companyHomeId); + + documentName = "Test cmis document (" + System.currentTimeMillis() + ")"; + documentId2 = helper.createDocument(documentName, folderId2); + + String relationshipId = createRelationship("test relashionship", folderId1, documentId2); + + response = ((ObjectServicePort) servicePort).deleteTree(repositoryId, folderId1, EnumUnfileNonfolderObjects.DELETESINGLEFILED, true); + assertNotNull("DELETESINGLEFILED", response); + + assertNull("DELETESINGLEFILED", helper.getObjectProperties(folderId1)); + assertNull("DELETESINGLEFILED", helper.getObjectProperties(relationshipId)); + + assertNotNull("DELETESINGLEFILED", helper.getObjectProperties(folderId2)); + assertNotNull("DELETESINGLEFILED", helper.getObjectProperties(documentId2)); + + deleteFolder(folderId2); + + // response = ((ObjectServicePort) servicePort).deleteTree(repositoryId, folderId, EnumUnfileNonfolderObjects.UNFILE, true); + // assertNotNull("UNFILE", response); + // + // assertNull(getObjectProperties(folderId)); + + // deleteFolder(folderId); + * + */ + } + + public void testDeleteTree_Exceptions() throws Exception + { + // Try to delere root folder + try + { + DeleteTreeResponse.FailedToDelete response = ((ObjectServicePort) servicePort).deleteTree(repositoryId, helper.getCompanyHomeId(repositoryId), + EnumUnfileNonfolderObjects.DELETE, true); + fail("Try to delere root folder"); + } + catch (OperationNotSupportedException e) + { + } + catch (Exception e) + { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + public void testGetAllowableActions() throws Exception + { + CmisAllowableActionsType response; + // CmisAllowableActionsType getAllowableActions(String repositoryId, String objectId) + response = ((ObjectServicePort) servicePort).getAllowableActions(repositoryId, documentId); + assertNotNull(response); + assertTrue(response.canGetProperties); + assertTrue(response.canCheckout); + + response = ((ObjectServicePort) servicePort).getAllowableActions(repositoryId, folderId); + assertNotNull(response); + assertTrue(response.canGetProperties); + assertNull(response.canCheckout); + } + + public void testMoveObject() throws Exception + { + // public void moveObject(String repositoryId, String objectId, String targetFolderId, String sourceFolderId) + ((ObjectServicePort) servicePort).moveObject(repositoryId, documentId, folderId, companyHomeId); + + GetPropertiesResponse response = helper.getObjectProperties(documentId); + + CmisObjectType objectType = response.getObject(); + + assertNotNull(objectType); + assertNotNull(getPropertyValue(response, CMISMapping.PROP_NAME)); + + GetObjectParentsResponse parentsResponse = helper.getObjectParents(documentId, "*"); + assertTrue(parentsResponse.getObject().size() == 1); + assertTrue(PropertyUtil.getProperty(parentsResponse.getObject().get(0).getProperties(), CMISMapping.PROP_NAME).equals(folderName)); + + } + + // The moveObject() method must throw InvalidArgumentException for null SourceFolderId only if specified Object (Folder or Document) has SEVERAL parents. + // In other case this parameter may be null. + public void testMoveObject_Exceptions() throws Exception + { + // sourceFolderId is not specified - throw InvalidArgumentException + // • If Object is multi-filed and source folder is not specified, throw InvalidArgumentException. + + helper.addObjectToFolder(documentId, folderId); + + try + { + ((ObjectServicePort) servicePort).moveObject(repositoryId, documentId, folderId, null); + fail("sourceFolderId is not specified - should throw InvalidArgumentException"); + } + catch (InvalidArgumentException e) + { + + } + catch (Exception e) + { + e.printStackTrace(); + fail(e.getClass().getName() + ": " + e.getMessage()); + } + } + + public void testSetContentStream() throws Exception + { + String newFileName = "New file name (" + System.currentTimeMillis() + ")"; + String newContent = "New content test"; + + CmisContentStreamType contentStream = new CmisContentStreamType(); + contentStream.setFilename(newFileName); + contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + // contentStream.setLength(BigInteger.valueOf(256)); + // contentStream.setUri("test uri"); + // DataHandler dataHandler = new DataHandler(new FileDataSource("D:/test.txt")); + DataHandler dataHandler = new DataHandler(newContent, MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentStream.setStream(dataHandler); + + Holder documentIdHolder = new Holder(documentId); + // public void setContentStream(String repositoryId, Holder documentId, Boolean overwriteFlag, CmisContentStreamType contentStream) + ((ObjectServicePort) servicePort).setContentStream(repositoryId, documentIdHolder, true, contentStream); + + CmisContentStreamType result = ((ObjectServicePort) servicePort).getContentStream(repositoryId, documentId); + if (result.getLength().intValue() == 0) + { + fail("Content Stream is empty"); + } + assertEquals(newContent, result.getStream().getContent()); + + // Alfresco create new version of document + propertiesResponse = helper.getObjectProperties(documentIdHolder.value); + assertFalse("new version of document should be created", getPropertyValue(propertiesResponse, CMISMapping.PROP_OBJECT_ID).equals(documentId)); + GetAllVersionsResponse responseVersions = helper.getAllVersions(documentId); + assertTrue("new version of document should be created", responseVersions.getObject().size() > 1); + + // assertEquals(newFileName, result.getFilename()); + + // GetPropertiesResponse response = helper.getObjectProperties(documentId); + // assertNotNull(getObjectName(response)); + // assertEquals(newFileName, getContentStreamFilename(response)); + } + + public void testSetContentStream_Exceptions() throws Exception + { + String newFileName = "New file name (" + System.currentTimeMillis() + ")"; + String newContent = "New content test"; + + CmisContentStreamType contentStream = new CmisContentStreamType(); + contentStream.setFilename(newFileName); + contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + DataHandler dataHandler = new DataHandler(newContent, MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentStream.setStream(dataHandler); + + try + { + // public void setContentStream(String repositoryId, Holder documentId, Boolean overwriteFlag, CmisContentStreamType contentStream) + ((ObjectServicePort) servicePort).setContentStream(repositoryId, new Holder(documentId), false, contentStream); + fail("ContentAlreadyExists should be thrown"); + } + catch (ContentAlreadyExistsException e) + { + + } + catch (Exception e) + { + e.printStackTrace(); + fail(e.getMessage()); + } + + // now we can not set any property (beside name) when we create new document - so this case not working + propertiesResponse = helper.getObjectProperties(documentId); + Boolean contentStreamAllowed = getPropertyBooleanValue(propertiesResponse, CMISMapping.PROP_CONTENT_STREAM_ALLOWED); + if (contentStreamAllowed != null && contentStreamAllowed == false) + { + try + { + // public void setContentStream(String repositoryId, Holder documentId, Boolean overwriteFlag, CmisContentStreamType contentStream) + ((ObjectServicePort) servicePort).setContentStream(repositoryId, new Holder(documentId), true, contentStream); + fail("ConstraintViolationException should be thrown"); + } + catch (ConstraintViolationException e) + { + + } + catch (Exception e) + { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + } + + public void testUpdateProperties() throws Exception + { + + String newName = "New Cmis Test Node Name (" + System.currentTimeMillis() + ")"; + + // Cmis Properties + CmisPropertiesType properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_NAME); + cmisProperty.setValue(newName); + propertiesList.add(cmisProperty); + + // public void updateProperties(String repositoryId, Holder objectId, String changeToken, CmisPropertiesType properties) + ((ObjectServicePort) servicePort).updateProperties(repositoryId, new Holder(documentId), new String(""), properties); + + GetPropertiesResponse response = helper.getObjectProperties(documentId); + assertEquals(newName, getObjectName(response)); + } + + public void testUpdateProperties_Exceptions() throws Exception + { + // Now we can set up only name propery + + // try to update read only property + CmisPropertiesType properties = new CmisPropertiesType(); + properties = new CmisPropertiesType(); + List propertiesList = properties.getProperty(); + CmisPropertyString cmisProperty = new CmisPropertyString(); + cmisProperty.setName(CMISMapping.PROP_OBJECT_ID); + cmisProperty.setValue("new id value"); + propertiesList.add(cmisProperty); + + try + { + // public void updateProperties(String repositoryId, Holder objectId, String changeToken, CmisPropertiesType properties) + ((ObjectServicePort) servicePort).updateProperties(repositoryId, new Holder(documentId), new String(""), properties); + fail("should not update read only propery"); + } + catch (ConstraintViolationException e) + { + + } + catch (Exception e) + { + e.printStackTrace(); + fail(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMPolicyServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMPolicyServiceTest.java new file mode 100755 index 0000000000..230646684b --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMPolicyServiceTest.java @@ -0,0 +1,109 @@ +/* + * 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.net.MalformedURLException; +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.ws.Service; + +public class DMPolicyServiceTest extends AbstractServiceTest +{ + + public final static String SERVICE_WSDL_LOCATION = CmisServiceTestHelper.ALFRESCO_URL + "/cmis/PolicyService?wsdl"; + public final static QName SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "PolicyServicePort"); + + public DMPolicyServiceTest() + { + super(); + } + + public DMPolicyServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + protected Object getServicePort() + { + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, SERVICE_NAME); + return service.getPort(PolicyServicePort.class); + } + } + + public void testApplyPolicy() throws Exception + { + String documentId = helper.createDocument("Test cmis document (" + System.currentTimeMillis() + ")", companyHomeId); + assertNotNull(documentId); + ((PolicyServicePort) servicePort).applyPolicy(repositoryId, "policyId", documentId); // TODO policyId + helper.deleteDocument(documentId); + } + + public void testGetAppliedPolicies() throws Exception + { + String documentId = helper.createDocument("Test cmis document (" + System.currentTimeMillis() + ")", companyHomeId); + assertNotNull(documentId); + + GetAppliedPolicies request = new GetAppliedPolicies(); + request.setRepositoryId(repositoryId); + request.setObjectId(documentId); + request.setFilter(cmisObjectFactory.createGetAppliedPoliciesFilter("")); // TODO + GetAppliedPoliciesResponse response = ((PolicyServicePort) servicePort).getAppliedPolicies(request); + + // TODO: Uncomment + // assertNotNull(response); + // assertNotNull(response.getObject()); + // if (!response.getObject().isEmpty()) + // { + // for (CmisObjectType object : response.getObject()) + // { + // assertNotNull(object.getProperties()); + // } + // } + + helper.deleteDocument(documentId); + } + + public void testRemovePolicy() throws Exception + { + String documentId = helper.createDocument("Test cmis document (" + System.currentTimeMillis() + ")", companyHomeId); + assertNotNull(documentId); + + ((PolicyServicePort) servicePort).removePolicy(repositoryId, "policyId", documentId); // TODO policyId + + helper.deleteDocument(documentId); + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMRelationshipServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMRelationshipServiceTest.java new file mode 100755 index 0000000000..1844250023 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMRelationshipServiceTest.java @@ -0,0 +1,141 @@ +/* + * 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.net.MalformedURLException; +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.ws.Service; + +import org.alfresco.cmis.dictionary.CMISMapping; + +public class DMRelationshipServiceTest extends AbstractServiceTest +{ + + public final static String SERVICE_WSDL_LOCATION = CmisServiceTestHelper.ALFRESCO_URL + "/cmis/RelationshipService?wsdl"; + public final static QName SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "RelationshipService"); + + private String relationshipId; + private String document2Id; + + public DMRelationshipServiceTest() + { + super(); + } + + public DMRelationshipServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + documentId = helper.createDocument("Test cmis document (" + System.currentTimeMillis() + ")", companyHomeId); + document2Id = helper.createDocument("Test cmis document (" + System.currentTimeMillis() + ")", companyHomeId); + // TODO: uncomment + // try + // { + // relationshipId = helper.createRelationship("Test cmis relationship (" + System.currentTimeMillis() + ")", documentId, document2Id); + // } + // catch (Exception e) + // { + // if(documentId != null ){ + // helper.deleteDocument(documentId); + // } + // if(document2Id != null ){ + // helper.deleteDocument(document2Id); + // } + // throw e; + // } + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + helper.deleteDocument(documentId); + helper.deleteDocument(document2Id); + } + + protected Object getServicePort() + { + { + URL serviceWsdlURL; + try + { + serviceWsdlURL = new URL(SERVICE_WSDL_LOCATION); + } + catch (MalformedURLException e) + { + throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); + } + + Service service = Service.create(serviceWsdlURL, SERVICE_NAME); + return service.getPort(RelationshipServicePort.class); + } + } + + public void testGetRelationships() throws Exception + { + // TODO: uncomment +// GetRelationships request = cmisObjectFactory.createGetRelationships(); +// request.setRepositoryId(repositoryId); +// request.setObjectId(documentId); +// request.setFilter(cmisObjectFactory.createGetRelationshipsFilter("*")); +// request.setTypeId(cmisObjectFactory.createGetRelationshipsTypeId(CMISMapping.RELATIONSHIP_TYPE_ID.getTypeId())); +// request.setIncludeAllowableActions(cmisObjectFactory.createGetRelationshipsIncludeAllowableActions(true)); +// request.setIncludeSubRelationshipTypes(cmisObjectFactory.createGetRelationshipsIncludeSubRelationshipTypes(true)); +// request.setMaxItems(cmisObjectFactory.createGetRelationshipsMaxItems(BigInteger.valueOf(0))); +// request.setSkipCount(cmisObjectFactory.createGetRelationshipsSkipCount(BigInteger.valueOf(0))); +// request.setDirection(cmisObjectFactory.createGetRelationshipsDirection(EnumRelationshipDirection.SOURCE)); +// +// // public GetRelationshipsResponse getRelationships(GetRelationships parameters) +// GetRelationshipsResponse responce = ((RelationshipServicePort) servicePort).getRelationships(request); +// assertNotNull(responce.getObject()); + } + + public void testGetRelationshipObjectProperties() throws Exception + { + + // TODO: uncomment + + // GetPropertiesResponse response = helper.getObjectProperties(relationshipId); + // + // assertNotNull(response); + // assertNotNull(response.getObject()); + // assertNotNull(response.getObject().getProperties()); + // assertNotNull(response.getObject().getProperties().getProperty()); + // + // assertTrue(response.getObject().getProperties().getProperty().size() > 3); + // + // assertEquals(relationshipId.toString(), PropertyUtil.getValue((CmisProperty) PropertyUtil.getProperty(response.getObject().getProperties(), + // CMISMapping.PROP_OBJECT_ID))); + } +} + diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePortTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePortTest.java deleted file mode 100644 index 13e9dbad8c..0000000000 --- a/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServicePortTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 org.alfresco.repo.cmis.ws.RepositoryServicePort; - -/** - * @see org.alfresco.repo.cmis.ws.RepositoryServicePortDM - * - * @author Dmitry Lazurkin - * - */ -public class DMRepositoryServicePortTest extends BaseServicePortTest -{ - private RepositoryServicePort repositoryServicePort; - - @Override - protected void onSetUp() throws Exception - { - super.onSetUp(); - - repositoryServicePort = (RepositoryServicePort) applicationContext.getBean("dmRepositoryService"); - } - - public void testGetRepositoryServicePort() throws Exception - { - authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); - - List repositories = repositoryServicePort.getRepositories(); - assertTrue(repositories.size() == 1); - assertFalse(repositories.get(0).getRepositoryID() == null); - assertFalse(repositories.get(0).getRepositoryName() == null); - } - - public void testGetRepositoryInfo() throws Exception - { - List repositories = repositoryServicePort.getRepositories(); - GetRepositoryInfo response = new GetRepositoryInfo(); - response.setRepositoryId(repositories.get(0).getRepositoryID()); - CmisRepositoryInfoType repositoryInfo = repositoryServicePort.getRepositoryInfo(response); - - assertTrue(repositoryInfo.getRepositoryId().equals(repositories.get(0).getRepositoryID())); - assertTrue(repositoryInfo.getRepositoryName().equals(repositories.get(0).getRepositoryName())); - assertTrue("Alfresco".equals(repositoryInfo.getVendorName())); - CmisRepositoryCapabilitiesType capabilities = repositoryInfo.getCapabilities(); - assertTrue(capabilities.isCapabilityMultifiling() && capabilities.isCapabilityPWCUpdateable()); - assertFalse(capabilities.isCapabilityUnfiling() && capabilities.isCapabilityVersionSpecificFiling()); - } -} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServiceTest.java index 032f2c0b34..5756449f8b 100644 --- a/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServiceTest.java +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMRepositoryServiceTest.java @@ -24,79 +24,73 @@ */ package org.alfresco.repo.cmis.ws; -import java.net.MalformedURLException; -import java.net.URL; +import java.math.BigInteger; import java.util.List; -import javax.xml.namespace.QName; -import javax.xml.ws.Service; - -import org.alfresco.repo.cmis.ws.RepositoryServicePort; - -/** - * @author Michael Shavnev - */ public class DMRepositoryServiceTest extends AbstractServiceTest { + public final static String TYPE_ID = "D/wcm_avmlayeredcontent"; - public final static String SERVICE_WSDL_LOCATION = "http://localhost:8080/alfresco/cmis/RepositoryService?wsdl"; - public final static QName SERVICE_NAME = new QName("http://www.cmis.org/ns/1.0", "RepositoryService"); + public DMRepositoryServiceTest() + { + super(); + } + + public DMRepositoryServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } protected Object getServicePort() { - URL serviceWsdlURL; - try - { - serviceWsdlURL = new URL(SERVICE_WSDL_LOCATION); - } - catch (MalformedURLException e) - { - throw new java.lang.RuntimeException("Cannot get service Wsdl URL", e); - } - Service service = Service.create(serviceWsdlURL, SERVICE_NAME); - return service.getPort(RepositoryServicePort.class); + return helper.repositoryServicePort; } - public void testGetRepositories() + public void testGetRepositories() throws Exception { - try - { - List repositories = ((RepositoryServicePort) servicePort).getRepositories(); - assertTrue(repositories.size() == 1); - assertFalse(repositories.get(0).getRepositoryID() == null); - assertFalse(repositories.get(0).getRepositoryName() == null); - } - catch (Throwable e) - { - e.printStackTrace(); - fail(); - } - + List repositories = ((RepositoryServicePort) servicePort).getRepositories(); + assertTrue(repositories.size() == 1); + assertFalse(repositories.get(0).getRepositoryID() == null); + assertFalse(repositories.get(0).getRepositoryName() == null); } - public void testGetRepositoryInfo() + public void testGetRepositoryInfo() throws Exception { - try - { - List repositories = ((RepositoryServicePort) servicePort).getRepositories(); - GetRepositoryInfo parameters = new GetRepositoryInfo(); - parameters.setRepositoryId(repositories.get(0).getRepositoryID()); - CmisRepositoryInfoType cmisRepositoryInfoType = ((RepositoryServicePort) servicePort).getRepositoryInfo(parameters); - - assertTrue(cmisRepositoryInfoType.getRepositoryId().equals(repositories.get(0).getRepositoryID())); - assertTrue(cmisRepositoryInfoType.getRepositoryName().equals(repositories.get(0).getRepositoryName())); - assertTrue("Alfresco".equals(cmisRepositoryInfoType.getVendorName())); - assertTrue(cmisRepositoryInfoType.getVendorName().indexOf("Alfresco Repository (") > -1 ); - CmisRepositoryCapabilitiesType capabilities = cmisRepositoryInfoType.getCapabilities(); - assertTrue(capabilities.isCapabilityMultifiling() && capabilities.isCapabilityPWCUpdateable()); - assertFalse(capabilities.isCapabilityUnfiling() && capabilities.isCapabilityVersionSpecificFiling()); + List repositories = ((RepositoryServicePort) servicePort).getRepositories(); + GetRepositoryInfo parameters = new GetRepositoryInfo(); + parameters.setRepositoryId(repositories.get(0).getRepositoryID()); + CmisRepositoryInfoType cmisRepositoryInfoType = ((RepositoryServicePort) servicePort).getRepositoryInfo(parameters); - } - catch (Throwable e) - { - e.printStackTrace(); - fail(); - } + assertTrue(cmisRepositoryInfoType.getRepositoryId().equals(repositories.get(0).getRepositoryID())); + assertTrue(cmisRepositoryInfoType.getRepositoryName().equals(repositories.get(0).getRepositoryName())); + CmisRepositoryCapabilitiesType capabilities = cmisRepositoryInfoType.getCapabilities(); + assertTrue(capabilities.isCapabilityMultifiling() && capabilities.isCapabilityPWCUpdateable()); + assertFalse(capabilities.isCapabilityUnfiling() && capabilities.isCapabilityVersionSpecificFiling()); + } + public void testGetTypes() throws Exception + { + GetTypes request = new GetTypes(); + request.setMaxItems(cmisObjectFactory.createGetTypesMaxItems(BigInteger.valueOf(0))); + request.setSkipCount(cmisObjectFactory.createGetTypesMaxItems(BigInteger.valueOf(0))); + request.setRepositoryId(repositoryId); + request.setReturnPropertyDefinitions(cmisObjectFactory.createGetTypesReturnPropertyDefinitions(Boolean.FALSE)); + GetTypesResponse response = ((RepositoryServicePort) servicePort).getTypes(request); + assertNotNull(response.getType()); + assertFalse(response.getType().isEmpty()); + CmisTypeDefinitionType element = response.getType().get(0).getValue(); + assertNotNull(element); + } + + public void testGetTypeDefinition() throws Exception + { + GetTypeDefinition request = new GetTypeDefinition(); + request.setRepositoryId(repositoryId); + request.setTypeId(TYPE_ID); + GetTypeDefinitionResponse response = ((RepositoryServicePort) servicePort).getTypeDefinition(request); + assertNotNull(response); + assertNotNull(response.getType()); + CmisTypeDefinitionType element = response.getType().getValue(); + assertNotNull(element); } } diff --git a/source/test/java/org/alfresco/repo/cmis/ws/DMVersioningServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/DMVersioningServiceTest.java new file mode 100755 index 0000000000..cb85451b7d --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/DMVersioningServiceTest.java @@ -0,0 +1,279 @@ +/* + * 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 javax.activation.DataHandler; +import javax.xml.ws.Holder; + +import org.alfresco.cmis.dictionary.CMISMapping; +import org.alfresco.repo.content.MimetypeMap; + +public class DMVersioningServiceTest extends AbstractServiceTest +{ + private String documentId; + + public DMVersioningServiceTest() + { + super(); + } + + public DMVersioningServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + protected Object getServicePort() + { + return helper.versioningServicePort; + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + documentId = helper.createDocument("Test cmis document (" + System.currentTimeMillis() + ")", companyHomeId); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + helper.deleteDocument(documentId); + } + + public void testCheckOutCheckIn() throws Exception + { + // check out + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + ((VersioningServicePort) servicePort).checkOut(repositoryId, documentIdHolder, contentCopied); + assertTrue(contentCopied.value); + assertFalse(documentId.equals(documentIdHolder.value)); + + // check in + CmisPropertiesType properties = new CmisPropertiesType();// TODO + CmisContentStreamType contentStream = new CmisContentStreamType(); + contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + DataHandler dataHandler = new DataHandler("Test content string: " + System.currentTimeMillis(), MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentStream.setStream(dataHandler); + String checkinComment = "Test checkin" + System.currentTimeMillis(); + ((VersioningServicePort) servicePort).checkIn(repositoryId, documentIdHolder, Boolean.TRUE, properties, contentStream, checkinComment); + + assertEquals(checkinComment, PropertyUtil.getProperty(helper.getObjectProperties(documentId).getObject().getProperties(), CMISMapping.PROP_CHECKIN_COMMENT)); + } + + public void testCheckOutCheckInDefault() throws Exception + { + // check out + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + ((VersioningServicePort) servicePort).checkOut(repositoryId, documentIdHolder, contentCopied); + assertTrue(contentCopied.value); + assertFalse(documentId.equals(documentIdHolder.value)); + + // check in + ((VersioningServicePort) servicePort).checkIn(repositoryId, documentIdHolder, null, null, null, null); + } + + public void testCheckOutCancelCheckOut() throws Exception + { + // check out + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + ((VersioningServicePort) servicePort).checkOut(repositoryId, documentIdHolder, contentCopied); + assertTrue(contentCopied.value); + assertFalse(documentId.equals(documentIdHolder.value)); + + // Cancel check out + ((VersioningServicePort) servicePort).cancelCheckOut(repositoryId, documentIdHolder.value); + assertFalse((Boolean) PropertyUtil.getProperty(helper.getObjectProperties(documentId).getObject().getProperties(), CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT)); + } + + public void testCheckinNoExistsCheckOut() throws Exception + { + try + { + Holder documentIdHolder = new Holder(documentId); + CmisPropertiesType properties = new CmisPropertiesType(); + CmisContentStreamType contentStream = new CmisContentStreamType(); + contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); + DataHandler dataHandler = new DataHandler("Test content string: " + System.currentTimeMillis(), MimetypeMap.MIMETYPE_TEXT_PLAIN); + contentStream.setStream(dataHandler); + String checkinComment = "Test checkin"; + ((VersioningServicePort) servicePort).checkIn(repositoryId, documentIdHolder, Boolean.TRUE, properties, contentStream, checkinComment); + fail("Expects exception"); + + } + catch (Throwable e) + { + assertTrue(e instanceof OperationNotSupportedException); + } + } + + public void testCancelNotExistsCheckOut() throws Exception + { + try + { + Holder documentIdHolder = new Holder(documentId); + ((VersioningServicePort) servicePort).cancelCheckOut(repositoryId, documentIdHolder.value); + fail("Expects exception"); + + } + catch (Throwable e) + { + assertTrue(e instanceof OperationNotSupportedException); + } + } + + public void testGetPropertiesOfLatestVersion() throws Exception + { + GetPropertiesOfLatestVersion request = new GetPropertiesOfLatestVersion(); + request.setRepositoryId(repositoryId); + request.setFilter(cmisObjectFactory.createGetPropertiesOfLatestVersionFilter("*")); + request.setMajorVersion(Boolean.TRUE); + request.setVersionSeriesId(documentId); + GetPropertiesOfLatestVersionResponse response = ((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(request); + assertNotNull(response); + assertNotNull(response.getObject()); + CmisObjectType objectType = response.getObject(); + assertNotNull(objectType.getProperties()); + assertTrue((Boolean) PropertyUtil.getProperty(objectType.getProperties(), CMISMapping.PROP_IS_LATEST_VERSION)); + } + + public void testGetPropertiesOfLatestVersionDefault() throws Exception + { + GetPropertiesOfLatestVersion request = new GetPropertiesOfLatestVersion(); + request.setRepositoryId(repositoryId); + request.setVersionSeriesId(documentId); + GetPropertiesOfLatestVersionResponse response = ((VersioningServicePort) servicePort).getPropertiesOfLatestVersion(request); + assertNotNull(response); + assertNotNull(response.getObject()); + CmisObjectType objectType = response.getObject(); + assertNotNull(objectType.getProperties()); + assertTrue((Boolean) PropertyUtil.getProperty(objectType.getProperties(), CMISMapping.PROP_IS_LATEST_VERSION)); + } + + public void testGetAllVersionsDefault() throws Exception + { + GetAllVersions request = new GetAllVersions(); + + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + String checkinComment = "Test checkin" + System.currentTimeMillis(); + + helper.checkOut(documentIdHolder, contentCopied); + helper.checkIn(documentIdHolder, checkinComment, true); + + request.setRepositoryId(repositoryId); + request.setVersionSeriesId(documentId); + + GetAllVersionsResponse response = ((VersioningServicePort) servicePort).getAllVersions(request); + assertNotNull(response); + assertNotNull(response.getObject()); + assertEquals(checkinComment, PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_CHECKIN_COMMENT)); + } + + public void testGetAllVersions() throws Exception + { + GetAllVersions request = new GetAllVersions(); + + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + String checkinComment = "Test checkin" + System.currentTimeMillis(); + + helper.checkOut(documentIdHolder, contentCopied); + helper.checkIn(documentIdHolder, checkinComment, true); + + request.setRepositoryId(repositoryId); + request.setVersionSeriesId(documentId); + request.setFilter(cmisObjectFactory.createGetAllVersionsFilter("*")); + request.setIncludeAllowableActions(cmisObjectFactory.createGetAllVersionsIncludeAllowableActions(Boolean.FALSE)); + request.setIncludeRelationships(cmisObjectFactory.createGetAllVersionsIncludeRelationships(Boolean.FALSE)); + + GetAllVersionsResponse response = ((VersioningServicePort) servicePort).getAllVersions(request); + assertNotNull(response); + assertNotNull(response.getObject()); + assertEquals(checkinComment, PropertyUtil.getProperty(response.getObject().get(0).getProperties(), CMISMapping.PROP_CHECKIN_COMMENT)); + } + + public void testGetAllVersionsForNoVersionHistory() throws Exception + { + GetAllVersions request = new GetAllVersions(); + + request.setRepositoryId(repositoryId); + request.setVersionSeriesId(documentId); + request.setFilter(cmisObjectFactory.createGetAllVersionsFilter("*")); + request.setIncludeAllowableActions(cmisObjectFactory.createGetAllVersionsIncludeAllowableActions(Boolean.FALSE)); + request.setIncludeRelationships(cmisObjectFactory.createGetAllVersionsIncludeRelationships(Boolean.FALSE)); + + GetAllVersionsResponse response = ((VersioningServicePort) servicePort).getAllVersions(request); + assertNotNull(response); + assertNotNull(response.getObject()); + } + + public void testGetAllVersionsCheckedOutAndPWC() throws Exception + { + GetAllVersions request = new GetAllVersions(); + Holder documentIdHolder = new Holder(documentId); + Holder contentCopied = new Holder(); + boolean checkedOutfound = false; + boolean pwcFound = false; + try + { + helper.checkOut(documentIdHolder, contentCopied); + request.setRepositoryId(repositoryId); + request.setVersionSeriesId(documentId); + request.setFilter(cmisObjectFactory.createGetAllVersionsFilter("*")); + request.setIncludeAllowableActions(cmisObjectFactory.createGetAllVersionsIncludeAllowableActions(Boolean.FALSE)); + request.setIncludeRelationships(cmisObjectFactory.createGetAllVersionsIncludeRelationships(Boolean.FALSE)); + + GetAllVersionsResponse response = ((VersioningServicePort) servicePort).getAllVersions(request); + assertNotNull(response); + assertNotNull(response.getObject()); + for (CmisObjectType cmisObjectType : response.getObject()) + { + if (!checkedOutfound) + { + checkedOutfound = (Boolean) PropertyUtil.getProperty(cmisObjectType.getProperties(), CMISMapping.PROP_IS_VERSION_SERIES_CHECKED_OUT); + } + if (!pwcFound) + { + pwcFound = ((String) PropertyUtil.getProperty(cmisObjectType.getProperties(), CMISMapping.PROP_OBJECT_ID)).startsWith(documentIdHolder.value); + } + } + assertTrue("No checked out version found", checkedOutfound); + assertTrue("No private working copy version found", pwcFound); + } + finally + { + helper.checkIn(documentIdHolder, "Hello", true); + } + } + + public void testDeleteAllVersions() throws Exception + { + ((VersioningServicePort) servicePort).deleteAllVersions(repositoryId, documentId); + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/MultiThreadsServiceTest.java b/source/test/java/org/alfresco/repo/cmis/ws/MultiThreadsServiceTest.java new file mode 100755 index 0000000000..6361edb3d2 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/MultiThreadsServiceTest.java @@ -0,0 +1,202 @@ +/* + * 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.LinkedList; +import java.util.List; +import java.util.Random; + +import org.alfresco.cmis.dictionary.CMISMapping; + +public class MultiThreadsServiceTest extends AbstractServiceTest +{ + private String lastName; + private String lastContent; + private Random generator = new Random(); + private boolean isRunning; + private Thread thread; + + public MultiThreadsServiceTest(String testCase, String username, String password) + { + super(testCase, username, password); + } + + public MultiThreadsServiceTest() + { + super(); + } + + @Override + protected Object getServicePort() + { + return helper.navigationServicePort; + } + + @Override + protected void setUp() throws Exception + { + super.setUp(); + + createInitialContent(); + + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + + deleteInitialContent(); + } + + public void testUpdateDocumentMultiThreaded() throws Exception + { + ThreadGroup threadGroup = new ThreadGroup("testUpdateDocumentMultiThreaded"); + List threads = new LinkedList(); + for (int i = 0; i < 5; i++) + { + AbstractBaseRunner updater = new DocumentUpdater(); + + Thread updateDocumentTread = new Thread(threadGroup, updater, "updateDocument " + i); + + threads.add(updater); + + updateDocumentTread.start(); + } + + isRunning = true; + while (isRunning) + { + isRunning = threadGroup.activeCount() != 0; + } + if (isRunning == false) + { + assertTrue("All threads done their work normally", anyFailed(threads)); + + GetPropertiesResponse propertiesResponse; + propertiesResponse = helper.getObjectProperties(documentId); + assertEquals(lastName, getPropertyValue(propertiesResponse, CMISMapping.PROP_NAME)); + } + } + + public void testSetTextContentStreamMultiThreaded() throws Exception + { + ThreadGroup threadGroup = new ThreadGroup("testSetContentStreamMultiThreaded"); + List threads = new LinkedList(); + for (int i = 0; i < 5; i++) + { + // thread = new Thread(threadGroup, updateDocument, "updateDocument again " + i); + // thread.start(); + + AbstractBaseRunner runner = new TextContentStreamSetter(); + + thread = new Thread(threadGroup, runner, "setTextContentStream" + i); + + threads.add(runner); + + thread.start(); + } + + isRunning = true; + while (isRunning) + { + isRunning = threadGroup.activeCount() != 0; + } + if (isRunning == false) + { + CmisContentStreamType result; + result = helper.getContentStream(documentId); + if (result.getLength().intValue() == 0) + { + fail("Content Stream is empty"); + } + + assertTrue("All threads done their work normally", anyFailed(threads)); + + assertEquals(lastContent, result.getStream().getContent()); + } + } + + private boolean anyFailed(List threads) + { + + for (AbstractBaseRunner runner : threads) + { + if (runner.isExecutionFailed()) + { + return true; + } + } + + return false; + } + + private abstract class AbstractBaseRunner implements Runnable + { + protected boolean executionFailed; + + public boolean isExecutionFailed() + { + + return executionFailed; + } + } + + private class DocumentUpdater extends AbstractBaseRunner + { + public void run() + { + try + { + String newName = "New Name" + System.currentTimeMillis() + generator.nextDouble(); + helper.updateProperty(documentId, CMISMapping.PROP_NAME, newName); + lastName = newName; + } + catch (Exception e) + { + // this fail() does not fail the test, just print exception message to the console + executionFailed = true; + } + } + } + + private class TextContentStreamSetter extends AbstractBaseRunner + { + public void run() + { + try + { + String newContent = "New text content for testing." + generator.nextDouble(); + helper.setTextContentStream(documentId, newContent); + lastContent = newContent; + } + catch (Exception e) + { + // this fail() does not fail the test, just print exception message to the console + executionFailed = true; + } + } + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/WebServiceMultipleUsersSuiteTest.java b/source/test/java/org/alfresco/repo/cmis/ws/WebServiceMultipleUsersSuiteTest.java new file mode 100755 index 0000000000..96f547de06 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/WebServiceMultipleUsersSuiteTest.java @@ -0,0 +1,128 @@ +/* + * 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 junit.framework.Test; +import junit.framework.TestSuite; +import static org.alfresco.repo.cmis.ws.CmisServiceTestHelper.*; + +public class WebServiceMultipleUsersSuiteTest extends TestSuite +{ + public static Test suite() + { + TestSuite suite = new TestSuite(); + + // Discovery Service tests + // suite.addTest(new DMDiscoveryServiceTest("testQuery", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMDiscoveryServiceTest("testQuery", USERNAME_USER1, PASSWORD_USER1)); + + // MultiFiling Service tests + // suite.addTest(new DMMultiFilingServiceTest("testAddObjectToFolder", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMMultiFilingServiceTest("testAddObjectToFolder", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMMultiFilingServiceTest("testRemoveObjectFromFolder", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMMultiFilingServiceTest("testRemoveObjectFromFolder", USERNAME_USER1, PASSWORD_USER1)); + + // Navigation Service tests + + // suite.addTest(new DMNavigationServiceTest("testGetChildren", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMNavigationServiceTest("testGetChildren", USERNAME_USER1, PASSWORD_USER1)); + + // suite.addTest(new DMNavigationServiceTest("testGetCheckedoutDocs", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMNavigationServiceTest("testGetCheckedoutDocs", USERNAME_USER1, PASSWORD_USER1)); + + // suite.addTest(new DMNavigationServiceTest("testGetDescendants", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMNavigationServiceTest("testGetDescendants", USERNAME_USER1, PASSWORD_USER1)); + + // suite.addTest(new DMNavigationServiceTest("testGetFolderParent", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMNavigationServiceTest("testGetFolderParent", USERNAME_USER1, PASSWORD_USER1)); + + // suite.addTest(new DMNavigationServiceTest("testGetObjectParents", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMNavigationServiceTest("testGetObjectParents", USERNAME_USER1, PASSWORD_USER1)); + + // Object Service tests + // suite.addTest(new DMObjectServiceTest("testCreateDocument", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testCreateDocument", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testCreateFolder", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testCreateFolder", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testGetDocumentProperties", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testGetDocumentProperties", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testGetContentStream", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testGetContentStream", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testCreatePolicy", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testCreatePolicy", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testCreateRelationship", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testCreateRelationship", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testDeleteContentStream", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testDeleteContentStream", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testDeleteObject", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testDeleteObject", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testDeleteTree", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testDeleteTree", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testGetAllowableActions", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testGetAllowableActions", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testMoveObject", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testMoveObject", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testSetContentStream", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testSetContentStream", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMObjectServiceTest("testUpdateProperties", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMObjectServiceTest("testUpdateProperties", USERNAME_USER1, PASSWORD_USER1)); + + // MultiThreadsServiceTest + // suite.addTest(new MultiThreadsServiceTest("testUpdateDocumentMultiThreaded", USERNAME_USER1, PASSWORD_USER1)); + suite.addTest(new MultiThreadsServiceTest("testSetTextContentStreamMultiThreaded", USERNAME_USER1, PASSWORD_USER1)); + + // //Policy Service tests + // suite.addTest(new DMPolicyServiceTest("testApplyPolicy", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMPolicyServiceTest("testApplyPolicy", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMPolicyServiceTest("testGetAppliedPolicies", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMPolicyServiceTest("testGetAppliedPolicies", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMPolicyServiceTest("testRemovePolicy", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMPolicyServiceTest("testRemovePolicy", USERNAME_USER1, PASSWORD_USER1)); + + // Repository Service tests + // suite.addTest(new DMRepositoryServiceTest("testGetRepositories", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMRepositoryServiceTest("testGetRepositories", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMRepositoryServiceTest("testGetRepositoryInfo", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMRepositoryServiceTest("testGetRepositoryInfo", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMRepositoryServiceTest("testGetTypes", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMRepositoryServiceTest("testGetTypes", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMRepositoryServiceTest("testGetTypeDefinition", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMRepositoryServiceTest("testGetTypeDefinition", USERNAME_USER1, PASSWORD_USER1)); + + // Versioning Service tests + // suite.addTest(new DMVersioningServiceTest("testCheckOutCheckIn", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMVersioningServiceTest("testCheckOutCheckIn", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMVersioningServiceTest("testCheckOutCancelCheckOut", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMVersioningServiceTest("testCheckOutCancelCheckOut", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMVersioningServiceTest("testGetPropertiesOfLatestVersion", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMVersioningServiceTest("testGetPropertiesOfLatestVersion", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMVersioningServiceTest("testGetAllVersions", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMVersioningServiceTest("testGetAllVersions", USERNAME_USER1, PASSWORD_USER1)); + // suite.addTest(new DMVersioningServiceTest("testDeleteAllVersions", USERNAME_ADMIN, PASSWORD_ADMIN)); + suite.addTest(new DMVersioningServiceTest("testDeleteAllVersions", USERNAME_USER1, PASSWORD_USER1)); + return suite; + + } +} diff --git a/source/test/java/org/alfresco/repo/cmis/ws/filtering/PropertyFilterTest.java b/source/test/java/org/alfresco/repo/cmis/ws/filtering/PropertyFilterTest.java new file mode 100755 index 0000000000..ee789c5b04 --- /dev/null +++ b/source/test/java/org/alfresco/repo/cmis/ws/filtering/PropertyFilterTest.java @@ -0,0 +1,159 @@ +/* + * 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.filtering; + +import org.alfresco.repo.cmis.ws.FilterNotValidException; +import org.alfresco.repo.cmis.ws.PropertyFilter; + +import junit.framework.TestCase; + +/** + * @author Dmitry Velichkevich + */ +public class PropertyFilterTest extends TestCase +{ + private static final String NAME_TOKEN = "name"; + + private static final String[] FILTER_TOKENS = new String[] { "Name", NAME_TOKEN, "nAmE", "ObjectId", "ObjectID", "objectId" }; + private static final String[] TOKENS_THAT_ARE_NOT_ALLOWED = new String[] { "ParentId", "parentId", "ParEnTiD", "IsMajorVersion", "iSmAJORvERSION" }; + + private static final String VALID_MATCHE_ALL_FILTER = "*"; + private static final String VALID_MATCHE_ALL_EMPTY_FILTER = ""; + private static final String VALID_FILTER_WITH_NAME = NAME_TOKEN; + private static final String VALID_FILTER_WITH_SEVERAL_TOKENS = "name, ObjectId"; + private static final String LONG_VALID_FILTER_WITH_SEVERAL_TOKENS = "ObjectId, name, CreationDate, CreatedBy"; + private static final String VALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS = "name,Objectid,CreationDate"; + private static final String VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES = "name, Objectid,CreationDate,CreatedBy, ModifiedBy, LastModifiedBy"; + private static final String VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_SEVERAL_BREAKS_IN_SOME_PLACES = "name, Objectid, CreationDate,CreatedBy, ModifiedBy, LastModifiedBy"; + + private static final String INVALID_MATCHE_ALL_FILTER = "*,"; + private static final String INVALID_FILTER_WITH_NAME = "*name,"; + private static final String INVALID_FILTER_WITH_SEVERAL_TOKENS = "name ,ObjectId"; + private static final String LONG_INVALID_FILTER_WITH_SEVERAL_TOKENS = "ObjectId, name CreationDate, CreatedBy*"; + private static final String INVALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS = ",name,Objectid,CreationDate"; + private static final String INVALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES = " name, Objectid,CreationDate CreatedBy ModifiedBy, LastModifiedBy"; + private static final String INVALID_FILTER_WITH_FIRST_BREAK_SYMBOL = " name, Objectid,CreationDate, CreatedBy, ModifiedBy, LastModifiedBy"; + private static final String INVALID_FILTER_WITH_DENIED_SYMBOL = "ObjectId; name"; + private static final String INVALID_FILTER_WITH_LAST_INVALID_SYMBOL = "ObjectId, name*"; + + public void testValidFilters() throws Exception + { + + try + { + allTokensValidAssertion(new PropertyFilter()); + allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_EMPTY_FILTER)); + allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_FILTER)); + + onlyNameTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_NAME)); + + nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS)); + nameAndObjectIdTokensAssertionValid(new PropertyFilter(LONG_VALID_FILTER_WITH_SEVERAL_TOKENS)); + nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS)); + nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES)); + nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_SEVERAL_BREAKS_IN_SOME_PLACES)); + } + catch (Throwable e) + { + fail(e.getMessage()); + } + } + + public void testInvalidFilters() throws Exception + { + + invalidFilterAssertion(INVALID_MATCHE_ALL_FILTER); + invalidFilterAssertion(INVALID_FILTER_WITH_NAME); + invalidFilterAssertion(INVALID_FILTER_WITH_SEVERAL_TOKENS); + invalidFilterAssertion(LONG_INVALID_FILTER_WITH_SEVERAL_TOKENS); + invalidFilterAssertion(INVALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS); + invalidFilterAssertion(INVALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES); + invalidFilterAssertion(INVALID_FILTER_WITH_FIRST_BREAK_SYMBOL); + invalidFilterAssertion(INVALID_FILTER_WITH_DENIED_SYMBOL); + invalidFilterAssertion(INVALID_FILTER_WITH_LAST_INVALID_SYMBOL); + } + + private void nameAndObjectIdTokensAssertionValid(PropertyFilter propertyFilter) + { + + for (String token : FILTER_TOKENS) + { + assertTrue(propertyFilter.allow(token)); + } + + for (String token : TOKENS_THAT_ARE_NOT_ALLOWED) + { + assertFalse(propertyFilter.allow(token)); + } + } + + private void onlyNameTokensAssertionValid(PropertyFilter propertyFilter) + { + + for (String token : FILTER_TOKENS) + { + if (!token.equalsIgnoreCase(NAME_TOKEN)) + { + break; + } + + assertTrue(propertyFilter.allow(token)); + } + + for (String token : TOKENS_THAT_ARE_NOT_ALLOWED) + { + assertFalse(propertyFilter.allow(token)); + } + } + + private void allTokensValidAssertion(PropertyFilter propertyFilter) + { + + for (String token : FILTER_TOKENS) + { + assertTrue(propertyFilter.allow(token)); + } + + for (String token : TOKENS_THAT_ARE_NOT_ALLOWED) + { + assertTrue(propertyFilter.allow(token)); + } + } + + private void invalidFilterAssertion(String filterValue) + { + + try + { + new PropertyFilter(filterValue); + + fail("Invalid filter \"" + filterValue + "\" was interpreted as valid"); + } + catch (Throwable e) + { + assertTrue(("Unexpected exception type was thrown: " + e.getClass().getName()), e instanceof FilterNotValidException); + } + } +}