mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
- ensure that the returned token is always updated. This is currently not the case when there are no more items. The next token is set to null in that case, even though there might be (maxItems-1) results. - added Junit tests
4034 lines
188 KiB
Java
4034 lines
188 KiB
Java
|
|
/*
|
|
* #%L
|
|
* Alfresco Repository
|
|
* %%
|
|
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
|
* %%
|
|
* This file is part of the Alfresco software.
|
|
* If the software was purchased under a paid Alfresco license, the terms of
|
|
* the paid license agreement will prevail. Otherwise, the software is
|
|
* provided under the following open source license terms:
|
|
*
|
|
* Alfresco is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Alfresco 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
* #L%
|
|
*/
|
|
|
|
package org.alfresco.opencmis;
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
import static org.junit.Assert.assertFalse;
|
|
import static org.junit.Assert.assertNotNull;
|
|
import static org.junit.Assert.assertNull;
|
|
import static org.junit.Assert.assertTrue;
|
|
import static org.junit.Assert.fail;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.File;
|
|
import java.io.Serializable;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigInteger;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
|
|
import org.alfresco.model.ContentModel;
|
|
import org.alfresco.opencmis.dictionary.CMISDictionaryService;
|
|
import org.alfresco.opencmis.dictionary.PropertyDefinitionWrapper;
|
|
import org.alfresco.opencmis.dictionary.TypeDefinitionWrapper;
|
|
import org.alfresco.opencmis.search.CMISQueryOptions;
|
|
import org.alfresco.opencmis.search.CMISQueryOptions.CMISQueryMode;
|
|
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
|
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
|
|
import org.alfresco.repo.audit.AuditComponent;
|
|
import org.alfresco.repo.audit.AuditComponentImpl;
|
|
import org.alfresco.repo.audit.AuditServiceImpl;
|
|
import org.alfresco.repo.audit.UserAuditFilter;
|
|
import org.alfresco.repo.audit.model.AuditModelRegistryImpl;
|
|
import org.alfresco.repo.content.MimetypeMap;
|
|
import org.alfresco.repo.dictionary.DictionaryDAO;
|
|
import org.alfresco.repo.dictionary.M2Model;
|
|
import org.alfresco.repo.domain.audit.AuditDAO;
|
|
import org.alfresco.repo.domain.node.ContentDataWithId;
|
|
import org.alfresco.repo.domain.node.NodeDAO;
|
|
import org.alfresco.repo.model.Repository;
|
|
import org.alfresco.repo.node.archive.NodeArchiveService;
|
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
|
import org.alfresco.repo.security.authentication.AuthenticationContext;
|
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
|
import org.alfresco.repo.tenant.TenantAdminService;
|
|
import org.alfresco.repo.tenant.TenantService;
|
|
import org.alfresco.repo.tenant.TenantUtil;
|
|
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
|
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
|
import org.alfresco.repo.version.VersionableAspectTest;
|
|
import org.alfresco.repo.workflow.WorkflowDeployer;
|
|
import org.alfresco.service.ServiceRegistry;
|
|
import org.alfresco.service.cmr.action.ActionCondition;
|
|
import org.alfresco.service.cmr.action.ActionService;
|
|
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
import org.alfresco.service.cmr.lock.LockService;
|
|
import org.alfresco.service.cmr.lock.LockType;
|
|
import org.alfresco.service.cmr.model.FileFolderService;
|
|
import org.alfresco.service.cmr.model.FileInfo;
|
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
import org.alfresco.service.cmr.repository.ContentService;
|
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
|
import org.alfresco.service.cmr.repository.NodeRef;
|
|
import org.alfresco.service.cmr.repository.NodeService;
|
|
import org.alfresco.service.cmr.repository.StoreRef;
|
|
import org.alfresco.service.cmr.rule.Rule;
|
|
import org.alfresco.service.cmr.rule.RuleService;
|
|
import org.alfresco.service.cmr.rule.RuleType;
|
|
import org.alfresco.service.cmr.search.SearchService;
|
|
import org.alfresco.service.cmr.security.AccessPermission;
|
|
import org.alfresco.service.cmr.security.AuthorityService;
|
|
import org.alfresco.service.cmr.security.AuthorityType;
|
|
import org.alfresco.service.cmr.security.PermissionService;
|
|
import org.alfresco.service.cmr.tagging.TaggingService;
|
|
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.cmr.workflow.WorkflowAdminService;
|
|
import org.alfresco.service.cmr.workflow.WorkflowService;
|
|
import org.alfresco.service.namespace.NamespaceService;
|
|
import org.alfresco.service.namespace.QName;
|
|
import org.alfresco.service.transaction.TransactionService;
|
|
import org.alfresco.util.ApplicationContextHelper;
|
|
import org.alfresco.util.Pair;
|
|
import org.alfresco.util.testing.category.LuceneTests;
|
|
import org.alfresco.util.testing.category.RedundantTests;
|
|
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
|
import org.apache.chemistry.opencmis.commons.data.Ace;
|
|
import org.apache.chemistry.opencmis.commons.data.AllowableActions;
|
|
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
|
|
import org.apache.chemistry.opencmis.commons.data.ContentStream;
|
|
import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectData;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectList;
|
|
import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
|
|
import org.apache.chemistry.opencmis.commons.data.Properties;
|
|
import org.apache.chemistry.opencmis.commons.data.PropertyData;
|
|
import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
|
|
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
|
|
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
|
|
import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
|
|
import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
|
|
import org.apache.chemistry.opencmis.commons.enums.Action;
|
|
import org.apache.chemistry.opencmis.commons.enums.ChangeType;
|
|
import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
|
|
import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
|
|
import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
|
|
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
|
|
import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ExtensionDataImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDecimalDefinitionImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerDefinitionImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
|
|
import org.apache.chemistry.opencmis.commons.impl.server.AbstractServiceFactory;
|
|
import org.apache.chemistry.opencmis.commons.server.CallContext;
|
|
import org.apache.chemistry.opencmis.commons.server.CmisService;
|
|
import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
|
|
import org.apache.chemistry.opencmis.commons.spi.Holder;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.junit.After;
|
|
import org.junit.Before;
|
|
import org.junit.Test;
|
|
import org.junit.experimental.categories.Category;
|
|
import org.springframework.context.ApplicationContext;
|
|
import org.springframework.extensions.webscripts.GUID;
|
|
|
|
/**
|
|
* OpenCMIS tests.
|
|
*
|
|
* @author steveglover
|
|
*
|
|
*/
|
|
@Category(LuceneTests.class)
|
|
public class CMISTest
|
|
{
|
|
private static Log logger = LogFactory.getLog(CMISTest.class);
|
|
|
|
private static final QName TEST_START_TASK = QName.createQName("http://www.alfresco.org/model/workflow/test/1.0", "startTaskVarScriptAssign");
|
|
private static final QName TEST_WORKFLOW_TASK = QName.createQName("http://www.alfresco.org/model/workflow/test/1.0", "assignVarTask");
|
|
|
|
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(new String[]{ApplicationContextHelper.CONFIG_LOCATIONS[0],"classpath:test-cmisinteger_modell-context.xml"});
|
|
|
|
private FileFolderService fileFolderService;
|
|
private TransactionService transactionService;
|
|
private NodeService nodeService;
|
|
private ContentService contentService;
|
|
private Repository repositoryHelper;
|
|
private VersionService versionService;
|
|
private LockService lockService;
|
|
private TaggingService taggingService;
|
|
private NamespaceService namespaceService;
|
|
private AuthorityService authorityService;
|
|
private AuditModelRegistryImpl auditSubsystem;
|
|
private PermissionService permissionService;
|
|
private DictionaryDAO dictionaryDAO;
|
|
private CMISDictionaryService cmisDictionaryService;
|
|
private AuditDAO auditDAO;
|
|
private ActionService actionService;
|
|
private RuleService ruleService;
|
|
private NodeArchiveService nodeArchiveService;
|
|
private DictionaryService dictionaryService;
|
|
private WorkflowService workflowService;
|
|
private WorkflowAdminService workflowAdminService;
|
|
private AuthenticationContext authenticationContext;
|
|
private TenantAdminService tenantAdminService;
|
|
private TenantService tenantService;
|
|
private SearchService searchService;
|
|
private java.util.Properties globalProperties;
|
|
private AuditComponentImpl auditComponent;
|
|
|
|
private AlfrescoCmisServiceFactory factory;
|
|
|
|
private CMISConnector cmisConnector;
|
|
|
|
private NodeDAO nodeDAO;
|
|
|
|
/**
|
|
* Test class to provide the service factory
|
|
*
|
|
* @author Derek Hulley
|
|
* @since 4.0
|
|
*/
|
|
public static class TestCmisServiceFactory extends AbstractServiceFactory
|
|
{
|
|
private static AlfrescoCmisServiceFactory serviceFactory = (AlfrescoCmisServiceFactory) ctx.getBean("CMISServiceFactory");
|
|
@Override
|
|
public void init(Map<String, String> parameters)
|
|
{
|
|
serviceFactory.init(parameters);
|
|
}
|
|
|
|
@Override
|
|
public void destroy()
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public CmisService getService(CallContext context)
|
|
{
|
|
return serviceFactory.getService(context);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test class to provide the service factory
|
|
*
|
|
* @author Derek Hulley
|
|
* @since 4.0
|
|
*/
|
|
public static class TestCmisServiceFactory11 extends AbstractServiceFactory
|
|
{
|
|
private static AlfrescoCmisServiceFactory serviceFactory = (AlfrescoCmisServiceFactory) ctx.getBean("CMISServiceFactory1.1");
|
|
@Override
|
|
public void init(Map<String, String> parameters)
|
|
{
|
|
serviceFactory.init(parameters);
|
|
}
|
|
|
|
@Override
|
|
public void destroy()
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public CmisService getService(CallContext context)
|
|
{
|
|
return serviceFactory.getService(context);
|
|
}
|
|
}
|
|
|
|
public static class SimpleCallContext implements CallContext
|
|
{
|
|
private final Map<String, Object> contextMap = new HashMap<String, Object>();
|
|
private CmisVersion cmisVersion;
|
|
|
|
public SimpleCallContext(String user, String password, CmisVersion cmisVersion)
|
|
{
|
|
contextMap.put(USERNAME, user);
|
|
contextMap.put(PASSWORD, password);
|
|
this.cmisVersion = cmisVersion;
|
|
}
|
|
|
|
public String getBinding()
|
|
{
|
|
return BINDING_LOCAL;
|
|
}
|
|
|
|
public Object get(String key)
|
|
{
|
|
return contextMap.get(key);
|
|
}
|
|
|
|
public String getRepositoryId()
|
|
{
|
|
return (String) get(REPOSITORY_ID);
|
|
}
|
|
|
|
public String getUsername()
|
|
{
|
|
return (String) get(USERNAME);
|
|
}
|
|
|
|
public String getPassword()
|
|
{
|
|
return (String) get(PASSWORD);
|
|
}
|
|
|
|
public String getLocale()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public BigInteger getOffset()
|
|
{
|
|
return (BigInteger) get(OFFSET);
|
|
}
|
|
|
|
public BigInteger getLength()
|
|
{
|
|
return (BigInteger) get(LENGTH);
|
|
}
|
|
|
|
public boolean isObjectInfoRequired()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public File getTempDirectory()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public int getMemoryThreshold()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
public long getMaxContentSize()
|
|
{
|
|
return Long.MAX_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public boolean encryptTempFiles()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public CmisVersion getCmisVersion()
|
|
{
|
|
return cmisVersion;
|
|
}
|
|
}
|
|
|
|
@Before
|
|
public void before()
|
|
{
|
|
this.actionService = (ActionService)ctx.getBean("actionService");
|
|
this.ruleService = (RuleService)ctx.getBean("ruleService");
|
|
this.fileFolderService = (FileFolderService)ctx.getBean("FileFolderService");
|
|
this.transactionService = (TransactionService)ctx.getBean("transactionService");
|
|
this.nodeService = (NodeService)ctx.getBean("NodeService");
|
|
this.contentService = (ContentService)ctx.getBean("ContentService");
|
|
this.versionService = (VersionService) ctx.getBean("versionService");
|
|
this.lockService = (LockService) ctx.getBean("lockService");
|
|
this.taggingService = (TaggingService) ctx.getBean("TaggingService");
|
|
this.namespaceService = (NamespaceService) ctx.getBean("namespaceService");
|
|
this.repositoryHelper = (Repository)ctx.getBean("repositoryHelper");
|
|
this.factory = (AlfrescoCmisServiceFactory)ctx.getBean("CMISServiceFactory");
|
|
this.versionService = (VersionService) ctx.getBean("versionService");
|
|
this.cmisConnector = (CMISConnector) ctx.getBean("CMISConnector");
|
|
this.nodeDAO = (NodeDAO) ctx.getBean("nodeDAO");
|
|
this.authorityService = (AuthorityService)ctx.getBean("AuthorityService");
|
|
this.auditSubsystem = (AuditModelRegistryImpl) ctx.getBean("Audit");
|
|
this.permissionService = (PermissionService) ctx.getBean("permissionService");
|
|
this.dictionaryDAO = (DictionaryDAO)ctx.getBean("dictionaryDAO");
|
|
this.cmisDictionaryService = (CMISDictionaryService)ctx.getBean("OpenCMISDictionaryService1.1");
|
|
this.auditDAO = (AuditDAO) ctx.getBean("auditDAO");
|
|
this.nodeArchiveService = (NodeArchiveService) ctx.getBean("nodeArchiveService");
|
|
this.dictionaryService = (DictionaryService) ctx.getBean("dictionaryService");
|
|
this.workflowService = (WorkflowService) ctx.getBean("WorkflowService");
|
|
this.workflowAdminService = (WorkflowAdminService) ctx.getBean("workflowAdminService");
|
|
this.authenticationContext = (AuthenticationContext) ctx.getBean("authenticationContext");
|
|
this.tenantAdminService = (TenantAdminService) ctx.getBean("tenantAdminService");
|
|
this.tenantService = (TenantService) ctx.getBean("tenantService");
|
|
this.searchService = (SearchService) ctx.getBean("SearchService");
|
|
this.auditComponent = (AuditComponentImpl) ctx.getBean("auditComponent");
|
|
|
|
this.globalProperties = (java.util.Properties) ctx.getBean("global-properties");
|
|
this.globalProperties.setProperty(VersionableAspectTest.AUTO_VERSION_PROPS_KEY, "true");
|
|
}
|
|
|
|
@After
|
|
public void after()
|
|
{
|
|
this.globalProperties.setProperty(VersionableAspectTest.AUTO_VERSION_PROPS_KEY, "false");
|
|
}
|
|
|
|
/**
|
|
* MNT-10868 CMIS: Incorrect value of Latest Major version on Versions and Properties tabs.
|
|
*/
|
|
@Test
|
|
public void testIsLatestMajorVersionMNT10868()
|
|
{
|
|
CallContext context = new SimpleCallContext("admin", "admin", CmisVersion.CMIS_1_0);
|
|
|
|
String repositoryId = null;
|
|
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
CmisService cmisService = factory.getService(context);
|
|
try
|
|
{
|
|
// get repository id
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
repositoryId = repo.getId();
|
|
final String folderName = "testfolder" + GUID.generate();
|
|
final String docName = "testdoc.txt" + GUID.generate();
|
|
final FileInfo fileInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
nodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_VERSIONABLE, null);
|
|
|
|
return fileInfo;
|
|
}
|
|
});
|
|
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true, IncludeRelationships.NONE, null, false, true, null);
|
|
|
|
PropertyData<?> pd = getPropIsLatestMajorVersion(objectData);
|
|
|
|
if (pd != null)
|
|
{
|
|
assertTrue("The CMISDictionaryModel.PROP_IS_LATEST_MAJOR_VERSION should be true as major version was created", (Boolean) pd.getValues().get(0));
|
|
}
|
|
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_TITLE, docName);
|
|
|
|
// Create minor version
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
|
|
{
|
|
public Object execute() throws Throwable
|
|
{
|
|
// get an updating writer
|
|
ContentWriter writer = contentService.getWriter(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
|
|
|
|
writer.setMimetype("text/plain");
|
|
|
|
writer.putContent("New Version");
|
|
return null;
|
|
}
|
|
});
|
|
|
|
objectData = cmisService.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true, IncludeRelationships.NONE, null, false, true, null);
|
|
|
|
pd = getPropIsLatestMajorVersion(objectData);
|
|
|
|
if (pd != null)
|
|
{
|
|
assertFalse("The CMISDictionaryModel.PROP_IS_LATEST_MAJOR_VERSION should be false as minor version was created", (Boolean) pd.getValues().get(0));
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
cmisService.close();
|
|
}
|
|
}
|
|
|
|
private PropertyData<?> getPropIsLatestMajorVersion(ObjectData objectData)
|
|
{
|
|
List<PropertyData<?>> properties = objectData.getProperties().getPropertyList();
|
|
boolean found = false;
|
|
PropertyData<?> propIsLatestMajorVersion = null;
|
|
for (PropertyData<?> property : properties)
|
|
{
|
|
if (property.getId().equals(PropertyIds.IS_LATEST_MAJOR_VERSION))
|
|
{
|
|
found = true;
|
|
propIsLatestMajorVersion = property;
|
|
break;
|
|
}
|
|
}
|
|
//properties..contains(PropertyIds.IS_LATEST_MAJOR_VERSION);
|
|
assertTrue("The PropertyIds.IS_LATEST_MAJOR_VERSION property was not found", found);
|
|
if (found)
|
|
{
|
|
return propIsLatestMajorVersion;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Test for MNT-9203.
|
|
*/
|
|
@Test
|
|
public void testCheckIn()
|
|
{
|
|
String repositoryId = null;
|
|
ObjectData objectData = null;
|
|
Holder<String> objectId = null;
|
|
CallContext context = new SimpleCallContext("admin", "admin", CmisVersion.CMIS_1_0);
|
|
|
|
final String folderName = "testfolder." + GUID.generate();
|
|
final String docName = "testdoc.txt." + GUID.generate();
|
|
final String customModel = "cmistest.model";
|
|
|
|
final QName testCustomTypeQName = QName.createQName(customModel, "sop");
|
|
final QName authorisedByQname = QName.createQName(customModel, "authorisedBy");
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
try
|
|
{
|
|
final FileInfo fileInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, testCustomTypeQName);
|
|
Map<QName, Serializable> customProperties = new HashMap<QName, Serializable>();
|
|
|
|
customProperties.put(authorisedByQname, "customPropertyString");
|
|
customProperties.put(ContentModel.PROP_NAME, docName);
|
|
nodeService.setProperties(fileInfo.getNodeRef(), customProperties);
|
|
|
|
return fileInfo;
|
|
}
|
|
});
|
|
|
|
CmisService service = factory.getService(context);
|
|
try
|
|
{
|
|
List<RepositoryInfo> repositories = service.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
repositoryId = repo.getId();
|
|
objectData = service.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true, IncludeRelationships.NONE, null, false, true, null);
|
|
|
|
// checkout
|
|
objectId = new Holder<String>(objectData.getId());
|
|
service.checkOut(repositoryId, objectId, null, new Holder<Boolean>(true));
|
|
}
|
|
finally
|
|
{
|
|
service.close();
|
|
}
|
|
|
|
try
|
|
{
|
|
service = factory.getService(context);
|
|
|
|
PropertyStringImpl prop = new PropertyStringImpl();
|
|
prop.setId("abc:" + authorisedByQname.toPrefixString());
|
|
prop.setValue(null);
|
|
|
|
Collection<PropertyData<?>> propsList = new ArrayList<PropertyData<?>>();
|
|
propsList.add(prop);
|
|
|
|
Properties properties = new PropertiesImpl(propsList);
|
|
|
|
// checkIn on pwc
|
|
service.checkIn(repositoryId, objectId, false, properties, null, null, null, null, null, null);
|
|
}
|
|
finally
|
|
{
|
|
service.close();
|
|
}
|
|
// check that value is null
|
|
assertTrue(nodeService.getProperty(fileInfo.getNodeRef(), authorisedByQname) == null);
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for MNT-10537.
|
|
*/
|
|
@Test
|
|
public void testModelAvailability() throws Exception
|
|
{
|
|
final WorkflowDeployer testWorkflowDeployer = new WorkflowDeployer();
|
|
|
|
// setup dependencies
|
|
testWorkflowDeployer.setTransactionService(transactionService);
|
|
testWorkflowDeployer.setWorkflowService(workflowService);
|
|
testWorkflowDeployer.setWorkflowAdminService(workflowAdminService);
|
|
testWorkflowDeployer.setAuthenticationContext(authenticationContext);
|
|
testWorkflowDeployer.setDictionaryDAO(dictionaryDAO);
|
|
testWorkflowDeployer.setTenantAdminService(tenantAdminService);
|
|
testWorkflowDeployer.setTenantService(tenantService);
|
|
testWorkflowDeployer.setNodeService(nodeService);
|
|
testWorkflowDeployer.setNamespaceService(namespaceService);
|
|
testWorkflowDeployer.setSearchService(searchService);
|
|
|
|
// populate workflow parameters
|
|
java.util.Properties props = new java.util.Properties();
|
|
props.setProperty(WorkflowDeployer.ENGINE_ID, "activiti");
|
|
props.setProperty(WorkflowDeployer.LOCATION, "activiti/testCustomActiviti.bpmn20.xml");
|
|
props.setProperty(WorkflowDeployer.MIMETYPE, "text/xml");
|
|
props.setProperty(WorkflowDeployer.REDEPLOY, Boolean.FALSE.toString());
|
|
|
|
List<java.util.Properties> definitions = new ArrayList<java.util.Properties>(1);
|
|
definitions.add(props);
|
|
|
|
testWorkflowDeployer.setWorkflowDefinitions(definitions);
|
|
|
|
List<String> models = new ArrayList<String>(1);
|
|
models.add("activiti/testWorkflowModel.xml");
|
|
|
|
testWorkflowDeployer.setModels(models);
|
|
|
|
// deploy test workflow
|
|
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
|
txnHelper.setForceWritable(true);
|
|
txnHelper.doInTransaction(new RetryingTransactionCallback<Object>()
|
|
{
|
|
@Override
|
|
public Object execute() throws Throwable
|
|
{
|
|
return AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
{
|
|
public Object doWork()
|
|
{
|
|
testWorkflowDeployer.init();
|
|
return null;
|
|
}
|
|
}, AuthenticationUtil.getSystemUserName());
|
|
}
|
|
|
|
}, false, true);
|
|
|
|
org.alfresco.service.cmr.dictionary.TypeDefinition startTaskTypeDefinition = this.dictionaryService.getType(TEST_START_TASK);
|
|
org.alfresco.service.cmr.dictionary.TypeDefinition workflowTaskTypeDefinition = this.dictionaryService.getType(TEST_WORKFLOW_TASK);
|
|
|
|
// check that workflow types were correctly bootstrapped
|
|
assertNotNull(startTaskTypeDefinition);
|
|
assertNotNull(workflowTaskTypeDefinition);
|
|
|
|
// caches are refreshed asynchronously
|
|
Thread.sleep(5000);
|
|
|
|
// check that loaded model is available via CMIS API
|
|
CallContext context = new SimpleCallContext("admin", "admin", CmisVersion.CMIS_1_1);
|
|
CmisService service = factory.getService(context);
|
|
try
|
|
{
|
|
List<RepositoryInfo> repositories = service.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
List<TypeDefinitionContainer> container = service.getTypeDescendants(repositories.get(0).getId(), null, new BigInteger("-1"), true, null);
|
|
assertTrue("Workflow model haven't been loaded", container.toString().contains("testwf:startTaskVarScriptAssign"));
|
|
}
|
|
finally
|
|
{
|
|
service.close();
|
|
}
|
|
}
|
|
|
|
private FileInfo createContent(final String folderName, final String docName,
|
|
final boolean isRule)
|
|
{
|
|
return createContent(null, folderName, docName, isRule);
|
|
}
|
|
|
|
private FileInfo createContent(final FileInfo parentFolder, final String folderName, final String docName, final boolean isRule)
|
|
{
|
|
final FileInfo folderInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef nodeRef;
|
|
|
|
if (parentFolder != null)
|
|
{
|
|
nodeRef = parentFolder.getNodeRef();
|
|
}
|
|
else
|
|
{
|
|
nodeRef = repositoryHelper.getCompanyHome();
|
|
}
|
|
|
|
FileInfo folderInfo = fileFolderService.create(nodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
FileInfo fileInfo;
|
|
if (docName != null)
|
|
{
|
|
fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
assertNotNull(fileInfo);
|
|
}
|
|
|
|
if (isRule)
|
|
{
|
|
Rule rule = addRule(true, folderName);
|
|
|
|
assertNotNull(rule);
|
|
|
|
// Attach the rule to the node
|
|
ruleService.saveRule(folderInfo.getNodeRef(), rule);
|
|
|
|
assertTrue(ruleService.getRules(folderInfo.getNodeRef()).size() > 0);
|
|
}
|
|
|
|
return folderInfo;
|
|
}
|
|
});
|
|
|
|
return folderInfo;
|
|
}
|
|
|
|
private Rule addRule(boolean isAppliedToChildren, String title)
|
|
{
|
|
|
|
// Rule properties
|
|
Map<String, Serializable> conditionProps = new HashMap<String, Serializable>();
|
|
conditionProps.put(ComparePropertyValueEvaluator.PARAM_VALUE, ".txt");
|
|
|
|
Map<String, Serializable> actionProps = new HashMap<String, Serializable>();
|
|
actionProps.put(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
|
|
|
|
List<String> ruleTypes = new ArrayList<String>(1);
|
|
ruleTypes.add(RuleType.INBOUND);
|
|
|
|
// Create the action
|
|
org.alfresco.service.cmr.action.Action action = actionService.createAction(title);
|
|
action.setParameterValues(conditionProps);
|
|
|
|
ActionCondition actionCondition = actionService.createActionCondition(ComparePropertyValueEvaluator.NAME);
|
|
actionCondition.setParameterValues(conditionProps);
|
|
action.addActionCondition(actionCondition);
|
|
|
|
// Create the rule
|
|
Rule rule = new Rule();
|
|
rule.setRuleTypes(ruleTypes);
|
|
rule.setTitle(title);
|
|
rule.setDescription("description");
|
|
rule.applyToChildren(isAppliedToChildren);
|
|
rule.setAction(action);
|
|
|
|
return rule;
|
|
}
|
|
|
|
private <T extends Object> T withCmisService(CmisServiceCallback<T> callback)
|
|
{
|
|
return withCmisService(callback, CmisVersion.CMIS_1_0);
|
|
}
|
|
|
|
private <T extends Object> T withCmisService(CmisServiceCallback<T> callback, CmisVersion cmisVersion)
|
|
{
|
|
CmisService cmisService = null;
|
|
|
|
try
|
|
{
|
|
CallContext context = new SimpleCallContext("admin", "admin", cmisVersion);
|
|
cmisService = factory.getService(context);
|
|
T ret = callback.execute(cmisService);
|
|
return ret;
|
|
}
|
|
finally
|
|
{
|
|
if(cmisService != null)
|
|
{
|
|
cmisService.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static interface CmisServiceCallback<T>
|
|
{
|
|
T execute(CmisService cmisService);
|
|
}
|
|
|
|
/**
|
|
* ALF-18006 Test content mimetype auto-detection into CmisStreamInterceptor when "Content-Type" is not defined.
|
|
*/
|
|
@Test
|
|
public void testContentMimeTypeDetection()
|
|
{
|
|
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
|
FileFolderService ffs = serviceRegistry.getFileFolderService();
|
|
AuthenticationComponent authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
|
final String isoEncoding = "ISO-8859-1";
|
|
final String utfEncoding = "UTF-8";
|
|
|
|
// get repository id
|
|
List<RepositoryInfo> repositories = withCmisService(new CmisServiceCallback<List<RepositoryInfo>>()
|
|
{
|
|
@Override
|
|
public List<RepositoryInfo> execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
return repositories;
|
|
}
|
|
});
|
|
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
final String repositoryId = repo.getId();
|
|
|
|
// create simple text plain content
|
|
final PropertiesImpl properties = new PropertiesImpl();
|
|
String objectTypeId = "cmis:document";
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, objectTypeId));
|
|
String fileName = "textFile" + GUID.generate();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.NAME, fileName));
|
|
final ContentStreamImpl contentStream = new ContentStreamImpl(fileName, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Simple text plain document");
|
|
|
|
String objectId = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
String objectId = cmisService.create(repositoryId, properties, repositoryHelper.getCompanyHome().getId(), contentStream, VersioningState.MAJOR, null, null);
|
|
return objectId;
|
|
}
|
|
});
|
|
|
|
final Holder<String> objectIdHolder = new Holder<String>(objectId);
|
|
final String path = "/" + fileName;
|
|
|
|
// create content stream with undefined mimetype and file name
|
|
{
|
|
final ContentStreamImpl contentStreamHTML = new ContentStreamImpl(null, null, "<html><head><title> Hello </title></head><body><p> Test html</p></body></html></body></html>");
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
cmisService.setContentStream(repositoryId, objectIdHolder, true, null, contentStreamHTML, null);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
// check mimetype
|
|
ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
return cmisService.getObjectByPath(repositoryId, path, null, false, IncludeRelationships.NONE, null, false, false, null);
|
|
}
|
|
});
|
|
|
|
final String objectId1 = objectData.getId();
|
|
String contentType = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
String contentType = cmisService.getObjectInfo(repositoryId, objectId1).getContentType();
|
|
return contentType;
|
|
}
|
|
});
|
|
assertEquals("Mimetype is not defined correctly.", MimetypeMap.MIMETYPE_HTML, contentType);
|
|
|
|
// check that the encoding is detected correctly
|
|
checkEncoding(ffs, authenticationComponent, objectData, utfEncoding);
|
|
}
|
|
|
|
// create content stream with mimetype and encoding as UTF-8
|
|
{
|
|
String mimeType = MimetypeMap.MIMETYPE_TEXT_PLAIN + "; charset="+isoEncoding;
|
|
// NOTE that we intentionally specify the wrong charset here.
|
|
// Alfresco will detect the encoding (as UTF-8 - given by the ContentStreamImpl constructor)
|
|
final ContentStreamImpl contentStreamHTML = new ContentStreamImpl(null, mimeType, "<html><head><title> Hello </title></head><body><p> Test html</p></body></html></body></html>");
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
Holder<String> latestObjectIdHolder = getHolderOfObjectOfLatestVersion(cmisService, repositoryId, objectIdHolder);
|
|
cmisService.setContentStream(repositoryId, latestObjectIdHolder, true, null, contentStreamHTML, null);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
// check mimetype
|
|
final ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, path, null, false, IncludeRelationships.NONE, null, false, false, null);
|
|
return objectData;
|
|
}
|
|
});
|
|
String contentType = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
String contentType = cmisService.getObjectInfo(repositoryId, objectData.getId()).getContentType();
|
|
return contentType;
|
|
}
|
|
});
|
|
assertEquals("Mimetype is not defined correctly.", MimetypeMap.MIMETYPE_TEXT_PLAIN, contentType);
|
|
|
|
// check that the encoding is detected correctly
|
|
checkEncoding(ffs, authenticationComponent, objectData, utfEncoding);
|
|
}
|
|
|
|
// create content stream with mimetype and encoding as ISO-8859-1
|
|
{
|
|
String mimeType = MimetypeMap.MIMETYPE_TEXT_PLAIN + "; charset=" + utfEncoding;
|
|
// NOTE that we intentionally specify the wrong charset here.
|
|
// Alfresco will detect the encoding (as ISO-8859-1 - given by the ContentStreamImpl with streams)
|
|
String content = "<html><head><title>aegif Mind Share Leader Generating New Paradigms by aegif corporation</title></head><body><p> Test html</p></body></html></body></html>";
|
|
byte[] buf = null;
|
|
try
|
|
{
|
|
buf = content.getBytes(isoEncoding); // set the encoding here for the content stream
|
|
}
|
|
catch (UnsupportedEncodingException e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
|
|
ByteArrayInputStream input = new ByteArrayInputStream(buf);
|
|
|
|
final ContentStream contentStreamHTML = new ContentStreamImpl(null, BigInteger.valueOf(buf.length), mimeType, input);
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
Holder<String> latestObjectIdHolder = getHolderOfObjectOfLatestVersion(cmisService, repositoryId,
|
|
objectIdHolder);
|
|
cmisService.setContentStream(repositoryId, latestObjectIdHolder, true, null, contentStreamHTML, null);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
// check mimetype
|
|
final ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, path, null, false,
|
|
IncludeRelationships.NONE, null, false, false, null);
|
|
return objectData;
|
|
}
|
|
});
|
|
String contentType = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
String contentType = cmisService.getObjectInfo(repositoryId, objectData.getId()).getContentType();
|
|
return contentType;
|
|
}
|
|
});
|
|
assertEquals("Mimetype is not defined correctly.", MimetypeMap.MIMETYPE_TEXT_PLAIN, contentType);
|
|
|
|
// check that the encoding is detected correctly
|
|
checkEncoding(ffs, authenticationComponent, objectData, isoEncoding);
|
|
}
|
|
|
|
// checkout/checkin object with mimetype and encoding
|
|
{
|
|
ObjectData objectDa = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
return cmisService.getObjectByPath(repositoryId, path, null, false, IncludeRelationships.NONE, null, false, false, null);
|
|
}
|
|
});
|
|
|
|
|
|
objectIdHolder.setValue(objectDa.getId());
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
cmisService.checkOut(repositoryId, objectIdHolder, null, new Holder<Boolean>());
|
|
return null;
|
|
}
|
|
});
|
|
String mimeType = MimetypeMap.MIMETYPE_HTML + "; charset=UTF-8";
|
|
final ContentStreamImpl contentStreamHTML = new ContentStreamImpl(null, mimeType, "<html><head><title> Hello </title></head><body><p> Test html</p></body></html></body></html>");
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
cmisService.checkIn(repositoryId, objectIdHolder, false, null, contentStreamHTML, "checkin", null, null, null, null);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
// check mimetype
|
|
final ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, path, null, false, IncludeRelationships.NONE, null, false, false, null);
|
|
return objectData;
|
|
}
|
|
});
|
|
String contentType = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
String contentType = cmisService.getObjectInfo(repositoryId, objectData.getId()).getContentType();
|
|
return contentType;
|
|
}
|
|
});
|
|
assertEquals("Mimetype is not defined correctly.", MimetypeMap.MIMETYPE_HTML, contentType);
|
|
|
|
checkEncoding(ffs, authenticationComponent, objectData, utfEncoding);
|
|
}
|
|
}
|
|
|
|
protected void checkEncoding(FileFolderService ffs, AuthenticationComponent authenticationComponent,
|
|
final ObjectData objectData, String expectedEncoding)
|
|
{
|
|
// Authenticate as system to check the properties in alfresco
|
|
authenticationComponent.setSystemUserAsCurrentUser();
|
|
try
|
|
{
|
|
NodeRef doc1NodeRef = cmisIdToNodeRef(objectData.getId());
|
|
doc1NodeRef.getId();
|
|
|
|
FileInfo fileInfo = ffs.getFileInfo(doc1NodeRef);
|
|
Map<QName, Serializable> properties2 = fileInfo.getProperties();
|
|
|
|
ContentDataWithId contentData = (ContentDataWithId) properties2
|
|
.get(QName.createQName("{http://www.alfresco.org/model/content/1.0}content"));
|
|
String encoding = contentData.getEncoding();
|
|
|
|
assertEquals(expectedEncoding, encoding);
|
|
}
|
|
finally
|
|
{
|
|
authenticationComponent.clearCurrentSecurityContext();
|
|
}
|
|
}
|
|
/**
|
|
* Turns a CMIS id into a node ref
|
|
* @param nodeId
|
|
* @return
|
|
*/
|
|
private NodeRef cmisIdToNodeRef(String nodeId)
|
|
{
|
|
int idx = nodeId.indexOf(";");
|
|
if(idx != -1)
|
|
{
|
|
nodeId = nodeId.substring(0, idx);
|
|
}
|
|
NodeRef nodeRef = new NodeRef(nodeId);
|
|
return nodeRef;
|
|
}
|
|
private Holder<String> getHolderOfObjectOfLatestVersion(CmisService cmisService, String repositoryId, Holder<String> currentHolder)
|
|
{
|
|
ObjectData oData = cmisService.getObjectOfLatestVersion(repositoryId, currentHolder.getValue(), null, Boolean.FALSE, null, null, null, null, null, null, null);
|
|
return new Holder<String>(oData.getId());
|
|
}
|
|
|
|
/**
|
|
* ALF-20389 Test Alfresco cmis stream interceptor that checks content stream for mimetype. Only ContentStreamImpl extensions should take palace.
|
|
*/
|
|
@Test
|
|
public void testGetRepositoryInfos()
|
|
{
|
|
boolean cmisEx = false;
|
|
List<RepositoryInfo> infoDataList = null;
|
|
try
|
|
{
|
|
infoDataList = withCmisService(new CmisServiceCallback<List<RepositoryInfo>>()
|
|
{
|
|
@Override
|
|
public List<RepositoryInfo> execute(CmisService cmisService)
|
|
{
|
|
ExtensionDataImpl result = new ExtensionDataImpl();
|
|
List<CmisExtensionElement> extensions = new ArrayList<CmisExtensionElement>();
|
|
result.setExtensions(extensions);
|
|
|
|
return cmisService.getRepositoryInfos(result);
|
|
}
|
|
});
|
|
}
|
|
catch (CmisRuntimeException e)
|
|
{
|
|
cmisEx = true;
|
|
}
|
|
|
|
assertNotNull(cmisEx ? "CmisRuntimeException was thrown. Please, take a look on ALF-20389" : "No CMIS repository information was retrieved", infoDataList);
|
|
}
|
|
|
|
private static class TestContext
|
|
{
|
|
private String repositoryId = null;
|
|
@SuppressWarnings("unused")
|
|
private ObjectData objectData = null;
|
|
private Holder<String> objectId = null;
|
|
|
|
public TestContext()
|
|
{
|
|
super();
|
|
}
|
|
|
|
public String getRepositoryId()
|
|
{
|
|
return repositoryId;
|
|
}
|
|
|
|
public void setRepositoryId(String repositoryId)
|
|
{
|
|
this.repositoryId = repositoryId;
|
|
}
|
|
|
|
public void setObjectData(ObjectData objectData)
|
|
{
|
|
this.objectData = objectData;
|
|
}
|
|
|
|
public Holder<String> getObjectId()
|
|
{
|
|
return objectId;
|
|
}
|
|
|
|
public void setObjectId(Holder<String> objectId)
|
|
{
|
|
this.objectId = objectId;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for ALF-16310.
|
|
*
|
|
* Check that, for AtomPub binding, cancel checkout on the originating checked out document i.e. not the working
|
|
* copy throws an exception and does not delete the document.
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
@Test
|
|
public void testCancelCheckout()
|
|
{
|
|
final TestContext testContext = new TestContext();
|
|
|
|
final String folderName = "testfolder." + GUID.generate();
|
|
final String docName = "testdoc.txt." + GUID.generate();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
try
|
|
{
|
|
final FileInfo folderInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
return folderInfo;
|
|
}
|
|
});
|
|
|
|
final ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
testContext.setRepositoryId(repositoryId);
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true,
|
|
IncludeRelationships.NONE, null, false, true, null);
|
|
testContext.setObjectData(objectData);
|
|
|
|
// checkout
|
|
Holder<String> objectId = new Holder<String>(objectData.getId());
|
|
testContext.setObjectId(objectId);
|
|
cmisService.checkOut(repositoryId, objectId, null, new Holder<Boolean>(true));
|
|
|
|
return objectData;
|
|
}
|
|
});
|
|
|
|
// AtomPub cancel checkout
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
try
|
|
{
|
|
// check allowable actions
|
|
ObjectData originalDoc = cmisService.getObject(testContext.getRepositoryId(), objectData.getId(), null, true, IncludeRelationships.NONE, null, false, true, null);
|
|
AllowableActions allowableActions = originalDoc.getAllowableActions();
|
|
assertNotNull(allowableActions);
|
|
assertFalse(allowableActions.getAllowableActions().contains(Action.CAN_DELETE_OBJECT));
|
|
|
|
// try to cancel the checkout
|
|
cmisService.deleteObjectOrCancelCheckOut(testContext.getRepositoryId(), objectData.getId(), Boolean.TRUE, null);
|
|
fail();
|
|
}
|
|
catch(CmisConstraintException e)
|
|
{
|
|
// expected
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
// cancel checkout on pwc
|
|
cmisService.deleteObjectOrCancelCheckOut(testContext.getRepositoryId(), testContext.getObjectId().getValue(), Boolean.TRUE, null);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
// get original document
|
|
ObjectData originalDoc = cmisService.getObject(testContext.getRepositoryId(), objectData.getId(), null, true, IncludeRelationships.NONE, null, false, true, null);
|
|
Map<String, PropertyData<?>> properties = originalDoc.getProperties().getProperties();
|
|
PropertyData<Boolean> isVersionSeriesCheckedOutProp = (PropertyData<Boolean>)properties.get(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT);
|
|
assertNotNull(isVersionSeriesCheckedOutProp);
|
|
Boolean isVersionSeriesCheckedOut = isVersionSeriesCheckedOutProp.getFirstValue();
|
|
assertNotNull(isVersionSeriesCheckedOut);
|
|
assertEquals(Boolean.FALSE, isVersionSeriesCheckedOut);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
// delete original document
|
|
cmisService.deleteObject(testContext.getRepositoryId(), objectData.getId(), true, null);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
List<FileInfo> children = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<FileInfo>>()
|
|
{
|
|
@Override
|
|
public List<FileInfo> execute() throws Throwable
|
|
{
|
|
List<FileInfo> children = fileFolderService.list(folderInfo.getNodeRef());
|
|
return children;
|
|
}
|
|
});
|
|
assertEquals(0, children.size());
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for MNT-13366.
|
|
*/
|
|
@Test
|
|
public void testDeleteTree()
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
FileInfo parentFolder = null;
|
|
FileInfo childFolder1 = null;
|
|
|
|
try
|
|
{
|
|
// Create a parent folder: parentFolder:
|
|
String parentFolderName = "parentFolder" + GUID.generate();
|
|
parentFolder = createContent(parentFolderName, null, false);
|
|
final NodeRef parentFolderNodeRef = parentFolder.getNodeRef();
|
|
final String parentFolderID = parentFolderNodeRef.getId();
|
|
|
|
// Create a child folder: parentFolder -> childFolder1:
|
|
String childFolder1Name = "childFolder1" + GUID.generate();
|
|
childFolder1 = createContent(parentFolder, childFolder1Name, null, false);
|
|
final NodeRef childFolder1NodeRef = childFolder1.getNodeRef();
|
|
|
|
// Create a child folder for previous child folder, which will contain a file:
|
|
// parentFolder -> childFolder1 -> childFolder2 -> testdoc.txt
|
|
String childFolder2Name = "childFolder2" + GUID.generate();
|
|
String docName = "testdoc.txt" + GUID.generate();
|
|
final NodeRef childFolder2NodeRef = createContent(childFolder1, childFolder2Name, docName, false).getNodeRef();
|
|
|
|
// Store a reference to the file "testdoc.txt" contained by childFolder2:
|
|
List<FileInfo> childFolder2FileList = fileFolderService.list(childFolder2NodeRef);
|
|
final NodeRef childFolder2FileNodeRef = childFolder2FileList.get(0).getNodeRef();
|
|
|
|
List<RepositoryInfo> repositories = withCmisService(new CmisServiceCallback<List<RepositoryInfo>>()
|
|
{
|
|
@Override
|
|
public List<RepositoryInfo> execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
return repositories;
|
|
}
|
|
});
|
|
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
final String repositoryId = repo.getId();
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
|
|
// CMIS delete tree:
|
|
FailedToDeleteData failedItems = cmisService.deleteTree(repositoryId, parentFolderID, Boolean.TRUE,
|
|
UnfileObject.DELETE, Boolean.TRUE, null);
|
|
|
|
assertEquals(failedItems.getIds().size(), 0);
|
|
|
|
// Reference to the archive root node (the trash-can):
|
|
NodeRef archiveRootNode = nodeArchiveService.getStoreArchiveNode(repositoryHelper.getCompanyHome().getStoreRef());
|
|
|
|
// Get the archived ("canned") version of folders and file and check that hirarchy is correct:
|
|
// ArchiveRoot -> archivedParentFolder -> archivedChildFolder1 -> archivedChildFolder2 -> archivedChildFolder2File.
|
|
|
|
// Check parentFolder:
|
|
NodeRef archivedParentFolderNodeRef = nodeArchiveService.getArchivedNode(parentFolderNodeRef);
|
|
assertTrue(nodeService.getPrimaryParent(archivedParentFolderNodeRef).getParentRef().equals(archiveRootNode));
|
|
|
|
// Check childFolder1:
|
|
NodeRef archivedChildFolder1NodeRef = nodeArchiveService.getArchivedNode(childFolder1NodeRef);
|
|
assertTrue(nodeService.getPrimaryParent(archivedChildFolder1NodeRef).getParentRef().equals(archivedParentFolderNodeRef));
|
|
assertFalse(nodeService.getPrimaryParent(archivedChildFolder1NodeRef).getParentRef().equals(archiveRootNode));
|
|
|
|
// Check childFolder2:
|
|
NodeRef archivedChildFolder2NodeRef = nodeArchiveService.getArchivedNode(childFolder2NodeRef);
|
|
assertTrue(nodeService.getPrimaryParent(archivedChildFolder2NodeRef).getParentRef().equals(archivedChildFolder1NodeRef));
|
|
assertFalse(nodeService.getPrimaryParent(archivedChildFolder2NodeRef).getParentRef().equals(archiveRootNode));
|
|
|
|
// Check childFolder2's file ("testdoc.txt"):
|
|
NodeRef archivedChildFolder2FileNodeRef = nodeArchiveService.getArchivedNode(childFolder2FileNodeRef);
|
|
assertTrue(nodeService.getPrimaryParent(archivedChildFolder2FileNodeRef).getParentRef().equals(archivedChildFolder2NodeRef));
|
|
assertFalse(nodeService.getPrimaryParent(archivedChildFolder2FileNodeRef).getParentRef().equals(archiveRootNode));
|
|
|
|
return null;
|
|
};
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
if (parentFolder != null && fileFolderService.exists(parentFolder.getNodeRef()))
|
|
{
|
|
fileFolderService.delete(parentFolder.getNodeRef());
|
|
}
|
|
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test for ALF-18151.
|
|
*/
|
|
@Test
|
|
public void testDeleteFolder()
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final Map<FileInfo, Boolean> testFolderMap = new HashMap<FileInfo, Boolean>(4);
|
|
|
|
try
|
|
{
|
|
// create folder with file
|
|
String folderName = "testfolder" + GUID.generate();
|
|
String docName = "testdoc.txt" + GUID.generate();
|
|
FileInfo folder = createContent(folderName, docName, false);
|
|
testFolderMap.put(folder, Boolean.FALSE);
|
|
|
|
// create empty folder
|
|
String folderNameEmpty = "testfolder_empty1" + GUID.generate();
|
|
FileInfo folderEmpty = createContent(folderNameEmpty, null, false);
|
|
testFolderMap.put(folderEmpty, Boolean.TRUE);
|
|
|
|
// create folder with file
|
|
String folderNameRule = "testfolde_rule" + GUID.generate();
|
|
String docNameRule = "testdoc_rule.txt" + GUID.generate();
|
|
FileInfo folderWithRule = createContent(folderNameRule, docNameRule, true);
|
|
testFolderMap.put(folderWithRule, Boolean.FALSE);
|
|
|
|
// create empty folder
|
|
String folderNameEmptyRule = "testfolde_empty_rule1" + GUID.generate();
|
|
FileInfo folderEmptyWithRule = createContent(folderNameEmptyRule, null, true);
|
|
testFolderMap.put(folderEmptyWithRule, Boolean.TRUE);
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
for (Map.Entry<FileInfo, Boolean> entry : testFolderMap.entrySet())
|
|
{
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + entry.getKey().getName(), null, true, IncludeRelationships.NONE, null, false, true, null);
|
|
|
|
Holder<String> objectId = new Holder<String>(objectData.getId());
|
|
|
|
try
|
|
{
|
|
// delete folder
|
|
cmisService.deleteObjectOrCancelCheckOut(repositoryId, objectId.getValue(), Boolean.TRUE, null);
|
|
}
|
|
catch (CmisConstraintException ex)
|
|
{
|
|
assertTrue(!entry.getValue());
|
|
continue;
|
|
}
|
|
|
|
assertTrue(entry.getValue());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
for (Map.Entry<FileInfo, Boolean> entry : testFolderMap.entrySet())
|
|
{
|
|
if (fileFolderService.exists(entry.getKey().getNodeRef()))
|
|
{
|
|
fileFolderService.delete(entry.getKey().getNodeRef());
|
|
}
|
|
}
|
|
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test
|
|
* <ul>
|
|
* <li>MNT-8825: READ_ONLYLOCK prevent getAllVersions via new CMIS enpoint.</li>
|
|
* <li>ACE-762: BM-0012: NodeLockedException not handled by CMIS</li>
|
|
* </ul>
|
|
*/
|
|
@Test
|
|
public void testOperationsOnReadOnlyLockedNode()
|
|
{
|
|
final String folderName = "testfolder." + GUID.generate();
|
|
final String docName = "testdoc.txt." + GUID.generate();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
|
|
|
|
try
|
|
{
|
|
final FileInfo fileInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
versionService.createVersion(fileInfo.getNodeRef(), new HashMap<String, Serializable>());
|
|
lockService.lock(fileInfo.getNodeRef(), LockType.READ_ONLY_LOCK, 0, true);
|
|
|
|
return fileInfo;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true,
|
|
IncludeRelationships.NONE, null, false, true, null);
|
|
|
|
// Expect no failure
|
|
cmisService.getAllVersions(repositoryId, objectData.getId(), fileInfo.getNodeRef().getId(), null, true, null);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
ObjectData objectData = cmisService.getObjectByPath(
|
|
repositoryId, "/" + folderName + "/" + docName, null, true,
|
|
IncludeRelationships.NONE, null, false, true, null);
|
|
String objectId = objectData.getId();
|
|
|
|
// Expect failure as the node is locked
|
|
try
|
|
{
|
|
cmisService.deleteObject(repositoryId, objectId, true, null);
|
|
fail("Locked node should not be deletable.");
|
|
}
|
|
catch (CmisUpdateConflictException e)
|
|
{
|
|
// Expected
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ALF-18455
|
|
*/
|
|
@Test
|
|
public void testOrderByCreationAndModificationDate()
|
|
{
|
|
final List<FileInfo> nodes = new ArrayList<FileInfo>(10);
|
|
final List<FileInfo> expectedChildrenByCreationDate = new ArrayList<FileInfo>(10);
|
|
final List<FileInfo> expectedChildrenByModificationDate = new ArrayList<FileInfo>(10);
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
try
|
|
{
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
String folderName = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
nodes.add(folderInfo);
|
|
|
|
for(int i = 0; i < 5; i++)
|
|
{
|
|
String docName = GUID.generate();
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(fileInfo);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
expectedChildrenByCreationDate.add(0, fileInfo);
|
|
nodes.add(fileInfo);
|
|
|
|
// make sure there is some difference in creation times
|
|
Thread.sleep(400);
|
|
}
|
|
|
|
// make modifications
|
|
for(int i = 5; i > 0; i--)
|
|
{
|
|
FileInfo fileInfo = nodes.get(i);
|
|
assertNotNull(fileInfo);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_DESCRIPTION, GUID.generate());
|
|
|
|
// "refresh" fileInfo
|
|
fileInfo = fileFolderService.getFileInfo(fileInfo.getNodeRef());
|
|
assertNotNull(fileInfo);
|
|
expectedChildrenByModificationDate.add(0, fileInfo);
|
|
|
|
// make sure there is some difference in modification times
|
|
Thread.sleep(400);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
// get repository id
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
String folderId = nodes.get(0).getNodeRef().getId();
|
|
String orderBy = PropertyIds.CREATION_DATE + " DESC";
|
|
ObjectInFolderList children = cmisService.getChildren(repositoryId, folderId, null, orderBy, false, IncludeRelationships.NONE,
|
|
null, false, BigInteger.valueOf(Integer.MAX_VALUE), BigInteger.valueOf(0), null);
|
|
int i = 0;
|
|
for(ObjectInFolderData child : children.getObjects())
|
|
{
|
|
Map<String, PropertyData<?>> properties = child.getObject().getProperties().getProperties();
|
|
|
|
PropertyData<?> pObjectId = properties.get(PropertyIds.VERSION_SERIES_ID);
|
|
String actualObjectId = (String)pObjectId.getFirstValue();
|
|
PropertyData<?> pCreationDate = properties.get(PropertyIds.CREATION_DATE);
|
|
GregorianCalendar actualCreationDate = (GregorianCalendar)pCreationDate.getFirstValue();
|
|
|
|
FileInfo expectedChild = expectedChildrenByCreationDate.get(i++);
|
|
assertEquals(expectedChild.getNodeRef().toString(), actualObjectId);
|
|
assertEquals(expectedChild.getCreatedDate().getTime(), actualCreationDate.getTimeInMillis());
|
|
}
|
|
|
|
orderBy = PropertyIds.LAST_MODIFICATION_DATE + " DESC";
|
|
children = cmisService.getChildren(repositoryId, folderId, null, orderBy, false, IncludeRelationships.NONE,
|
|
null, false, BigInteger.valueOf(Integer.MAX_VALUE), BigInteger.valueOf(0), null);
|
|
i = 0;
|
|
for(ObjectInFolderData child : children.getObjects())
|
|
{
|
|
Map<String, PropertyData<?>> properties = child.getObject().getProperties().getProperties();
|
|
|
|
PropertyData<?> pObjectId = properties.get(PropertyIds.VERSION_SERIES_ID);
|
|
String actualObjectId = (String)pObjectId.getFirstValue();
|
|
PropertyData<?> pModificationDate = properties.get(PropertyIds.LAST_MODIFICATION_DATE);
|
|
GregorianCalendar actualModificationDate = (GregorianCalendar)pModificationDate.getFirstValue();
|
|
|
|
FileInfo expectedChild = expectedChildrenByModificationDate.get(i++);
|
|
assertEquals(expectedChild.getNodeRef().toString(), actualObjectId);
|
|
assertEquals(expectedChild.getModifiedDate().getTime(), actualModificationDate.getTimeInMillis());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
|
@Test
|
|
public void testSecondaryTypes()
|
|
{
|
|
final String aspectName = "P:cm:indexControl";
|
|
|
|
// get repository id
|
|
final String repositoryId = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
final String repositoryId = repo.getId();
|
|
return repositoryId;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
final String objectId = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
final PropertiesImpl properties = new PropertiesImpl();
|
|
String objectTypeId = "cmis:document";
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, objectTypeId));
|
|
String fileName = "textFile" + GUID.generate();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.NAME, fileName));
|
|
final ContentStreamImpl contentStream = new ContentStreamImpl(fileName, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Simple text plain document");
|
|
|
|
String objectId = cmisService.create(repositoryId, properties, repositoryHelper.getCompanyHome().getId(), contentStream, VersioningState.MAJOR, null, null);
|
|
return objectId;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
final Holder<String> objectIdHolder = new Holder<String>(objectId);
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
final PropertiesImpl properties = new PropertiesImpl();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, Arrays.asList(aspectName)));
|
|
|
|
cmisService.updateProperties(repositoryId, objectIdHolder, null, properties, null);
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
final Properties currentProperties = withCmisService(new CmisServiceCallback<Properties>()
|
|
{
|
|
@Override
|
|
public Properties execute(CmisService cmisService)
|
|
{
|
|
Properties properties = cmisService.getProperties(repositoryId, objectIdHolder.getValue(), null, null);
|
|
return properties;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
List<String> secondaryTypeIds = (List<String>) currentProperties.getProperties().get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS).getValues();
|
|
|
|
assertTrue(secondaryTypeIds.contains(aspectName));
|
|
// We don't actually want to add these! (REPO-2926)
|
|
final Set<String> sysAspectsToAdd = new HashSet<>(Arrays.asList(
|
|
"P:sys:undeletable",
|
|
"P:sys:hidden"));
|
|
// Pre-condition of further test is that these aspects are not present
|
|
assertEquals(0, secondaryTypeIds.stream().filter(sysAspectsToAdd::contains).count());
|
|
// We also want to check that existing sys aspects aren't accidentally removed
|
|
assertTrue(secondaryTypeIds.contains("P:sys:localized"));
|
|
|
|
// Check we can remove an aspect - through its absence
|
|
secondaryTypeIds.remove(aspectName);
|
|
// Check that attempts to update/add sys:* aspects are ignored
|
|
secondaryTypeIds.addAll(sysAspectsToAdd);
|
|
final PropertiesImpl newProperties = new PropertiesImpl();
|
|
newProperties.addProperty(new PropertyStringImpl(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypeIds));
|
|
|
|
final String updatedName = "My_new_name_"+UUID.randomUUID().toString();
|
|
newProperties.replaceProperty(new PropertyStringImpl(PropertyIds.NAME, updatedName));
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
Holder<String> latestObjectIdHolder = getHolderOfObjectOfLatestVersion(cmisService, repositoryId, objectIdHolder);
|
|
// This will result in aspectName being removed
|
|
// but that shouldn't mean that, for example, a cmis:name prop update gets ignored (MNT-18340)
|
|
cmisService.updateProperties(repositoryId, latestObjectIdHolder, null, newProperties, null);
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
Properties currentProperties1 = withCmisService(new CmisServiceCallback<Properties>()
|
|
{
|
|
@Override
|
|
public Properties execute(CmisService cmisService)
|
|
{
|
|
Holder<String> latestObjectIdHolder = getHolderOfObjectOfLatestVersion(cmisService, repositoryId, objectIdHolder);
|
|
Properties properties = cmisService.getProperties(repositoryId, latestObjectIdHolder.getValue(), null, null);
|
|
return properties;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
secondaryTypeIds = (List<String>) currentProperties1.getProperties().get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS).getValues();
|
|
|
|
assertFalse(secondaryTypeIds.contains(aspectName));
|
|
assertEquals(updatedName, currentProperties1.getProperties().get(PropertyIds.NAME).getFirstValue());
|
|
// sys aspects must not be added through CMIS (REPO-2926)
|
|
assertEquals(0, secondaryTypeIds.stream().filter(sysAspectsToAdd::contains).count());
|
|
// Check pre-existing sys aspects aren't accidentally removed
|
|
assertTrue(secondaryTypeIds.contains("P:sys:localized"));
|
|
}
|
|
|
|
/**
|
|
* Test for MNT-9089
|
|
*/
|
|
@Test
|
|
public void testIntegerBoudaries() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
final FileInfo fileInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
QName testIntTypeQName = QName.createQName("http://testCMISIntegersModel/1.0/", "testintegerstype");
|
|
|
|
String folderName = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
String docName = GUID.generate();
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, testIntTypeQName);
|
|
assertNotNull(fileInfo);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
return fileInfo;
|
|
}
|
|
});
|
|
|
|
// get repository id
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
String objectIdStr = fileInfo.getNodeRef().toString();
|
|
|
|
TypeDefinition typeDef = cmisService.getTypeDefinition(repositoryId, "D:tcim:testintegerstype", null);
|
|
|
|
PropertyIntegerDefinitionImpl intNoBoundsTypeDef =
|
|
(PropertyIntegerDefinitionImpl)typeDef.getPropertyDefinitions().get("tcim:int");
|
|
PropertyIntegerDefinitionImpl longNoBoundsTypeDef =
|
|
(PropertyIntegerDefinitionImpl)typeDef.getPropertyDefinitions().get("tcim:long");
|
|
|
|
PropertyIntegerDefinitionImpl intWithBoundsTypeDef =
|
|
(PropertyIntegerDefinitionImpl)typeDef.getPropertyDefinitions().get("tcim:intwithbounds");
|
|
PropertyIntegerDefinitionImpl longWithBoundsTypeDef =
|
|
(PropertyIntegerDefinitionImpl)typeDef.getPropertyDefinitions().get("tcim:longwithbounds");
|
|
|
|
BigInteger minInteger = BigInteger.valueOf(Integer.MIN_VALUE);
|
|
BigInteger maxInteger = BigInteger.valueOf(Integer.MAX_VALUE);
|
|
|
|
BigInteger minLong = BigInteger.valueOf(Long.MIN_VALUE);
|
|
BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE);
|
|
|
|
// test for default boundaries
|
|
assertTrue(intNoBoundsTypeDef.getMinValue().equals(minInteger));
|
|
assertTrue(intNoBoundsTypeDef.getMaxValue().equals(maxInteger));
|
|
|
|
assertTrue(longNoBoundsTypeDef.getMinValue().equals(minLong));
|
|
assertTrue(longNoBoundsTypeDef.getMaxValue().equals(maxLong));
|
|
|
|
// test for pre-defined boundaries
|
|
assertTrue(intWithBoundsTypeDef.getMinValue().equals(BigInteger.valueOf(-10L)));
|
|
assertTrue(intWithBoundsTypeDef.getMaxValue().equals(BigInteger.valueOf(10L)));
|
|
|
|
assertTrue(longWithBoundsTypeDef.getMinValue().equals(BigInteger.valueOf(-10L)));
|
|
assertTrue(longWithBoundsTypeDef.getMaxValue().equals(BigInteger.valueOf(10L)));
|
|
|
|
try // try to overfloat long without boundaries
|
|
{
|
|
BigInteger aValue = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.valueOf(1L));
|
|
setProperiesToObject(cmisService, repositoryId, objectIdStr, "tcim:long", aValue);
|
|
fail();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
assertTrue(e instanceof CmisConstraintException);
|
|
}
|
|
|
|
try // try to overfloat int without boundaries
|
|
{
|
|
BigInteger aValue = BigInteger.valueOf(Integer.MAX_VALUE).add(BigInteger.valueOf(1L));
|
|
setProperiesToObject(cmisService, repositoryId, objectIdStr, "tcim:int", aValue);
|
|
fail();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
assertTrue(e instanceof CmisConstraintException);
|
|
}
|
|
|
|
try // try to overfloat int with boundaries
|
|
{
|
|
BigInteger aValue = BigInteger.valueOf( 11l );
|
|
setProperiesToObject(cmisService, repositoryId, objectIdStr, "tcim:intwithbounds", aValue);
|
|
fail();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
assertTrue(e instanceof CmisConstraintException);
|
|
}
|
|
|
|
try // try to overfloat long with boundaries
|
|
{
|
|
BigInteger aValue = BigInteger.valueOf( 11l );
|
|
setProperiesToObject(cmisService, repositoryId, objectIdStr, "tcim:longwithbounds", aValue);
|
|
fail();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
assertTrue(e instanceof CmisConstraintException);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_0);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
fail(e.getMessage());
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
private void setProperiesToObject(CmisService cmisService, String repositoryId, String objectIdStr, String propertyStr, BigInteger bigIntValue) throws CmisConstraintException{
|
|
Properties properties = cmisService.getProperties(repositoryId, objectIdStr, null, null);
|
|
PropertyIntegerImpl pd = (PropertyIntegerImpl)properties.getProperties().get(propertyStr);
|
|
pd.setValue(bigIntValue);
|
|
|
|
Collection<PropertyData<?>> propsList = new ArrayList<PropertyData<?>>();
|
|
propsList.add(pd);
|
|
|
|
Properties newProps = new PropertiesImpl(propsList);
|
|
|
|
cmisService.updateProperties(repositoryId, new Holder<String>(objectIdStr), null, newProps, null);
|
|
}
|
|
|
|
@Test
|
|
public void testMNT9090() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
final FileInfo fileInfo = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
String folderName = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
String docName = GUID.generate();
|
|
FileInfo fileInfo = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(fileInfo);
|
|
nodeService.setProperty(fileInfo.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
QName ASPECT_AUDIO = QName.createQName(NamespaceService.AUDIO_MODEL_1_0_URI, "audio");
|
|
Map<QName, Serializable> aspectProperties = new HashMap<QName, Serializable>();
|
|
nodeService.addAspect(fileInfo.getNodeRef(), ASPECT_AUDIO, aspectProperties);
|
|
|
|
return fileInfo;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
// get repository id
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
String objectIdStr = fileInfo.getNodeRef().toString();
|
|
Holder<String> objectId = new Holder<String>(objectIdStr);
|
|
|
|
// try to overflow the value
|
|
Object value = BigInteger.valueOf(Integer.MAX_VALUE + 1l);
|
|
|
|
Properties properties = new PropertiesImpl();
|
|
List<CmisExtensionElement> extensions = new ArrayList<CmisExtensionElement>();
|
|
|
|
CmisExtensionElement valueElem = new CmisExtensionElementImpl(CMISConnector.ALFRESCO_EXTENSION_NAMESPACE, "value", null, value.toString());
|
|
List<CmisExtensionElement> valueElems = new ArrayList<CmisExtensionElement>();
|
|
valueElems.add(valueElem);
|
|
|
|
List<CmisExtensionElement> children = new ArrayList<CmisExtensionElement>();
|
|
Map<String, String> attributes = new HashMap<String, String>();
|
|
attributes.put("propertyDefinitionId", "audio:trackNumber");
|
|
children.add(new CmisExtensionElementImpl(CMISConnector.ALFRESCO_EXTENSION_NAMESPACE, "propertyInteger", attributes, valueElems));
|
|
|
|
List<CmisExtensionElement> propertyValuesExtension = new ArrayList<CmisExtensionElement>();
|
|
propertyValuesExtension.add(new CmisExtensionElementImpl(CMISConnector.ALFRESCO_EXTENSION_NAMESPACE, CMISConnector.PROPERTIES, null, children));
|
|
|
|
CmisExtensionElement setAspectsExtension = new CmisExtensionElementImpl(CMISConnector.ALFRESCO_EXTENSION_NAMESPACE, CMISConnector.SET_ASPECTS, null, propertyValuesExtension);
|
|
extensions.add(setAspectsExtension);
|
|
properties.setExtensions(extensions);
|
|
|
|
// should throw a CMISConstraintException
|
|
cmisService.updateProperties(repositoryId, objectId, null, properties, null);
|
|
fail();
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_0);
|
|
}
|
|
catch(CmisConstraintException e)
|
|
{
|
|
assertTrue(e.getMessage().startsWith("Value is out of range for property"));
|
|
// ok
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-20139
|
|
* CmisConnector returns wrong values for changeLogToken and hasMoreItems
|
|
*/
|
|
@Test
|
|
public void testGetContentChanges()
|
|
{
|
|
setupAudit();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
// create folders with files
|
|
createContent("testfolder" + GUID.generate(), "testdoc.txt" + GUID.generate(), false);
|
|
createContent("testfolder" + GUID.generate(), "testdoc.txt" + GUID.generate(), false);
|
|
createContent("testfolder" + GUID.generate(), "testdoc.txt" + GUID.generate(), false);
|
|
|
|
Holder<String> changeLogToken = new Holder<String>();
|
|
|
|
/*
|
|
* GetContentChanges with maxitems = 2 and null changeLogToken
|
|
* Check that changeLogToken should be the latest from the retrieved entries
|
|
*/
|
|
ObjectList ol = this.cmisConnector.getContentChanges(changeLogToken, new BigInteger("2"));
|
|
assertEquals(2, ol.getObjects().size());
|
|
assertEquals("ChangeLogToken should be latest from retrieved entries.", "2", changeLogToken.getValue());
|
|
assertTrue(ol.hasMoreItems());
|
|
|
|
/*
|
|
* GetContentChanges with maxitems = 2 and changeLogToken = 0
|
|
* Check that changeLogToken should be the latest from the retrieved entries
|
|
*/
|
|
changeLogToken.setValue(Integer.toString(0));
|
|
ol = this.cmisConnector.getContentChanges(changeLogToken, new BigInteger("2"));
|
|
assertEquals(2, ol.getObjects().size());
|
|
assertEquals("ChangeLogToken should be latest from retrieved entries.", "2", changeLogToken.getValue());
|
|
assertTrue(ol.hasMoreItems());
|
|
|
|
/*
|
|
* GetContentChanges with changeLogToken = maxChangeLogToken - 2
|
|
* Check that changeLogToken is not null when the latest entries (fromToken) are retrieved
|
|
*/
|
|
Long latestToken = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Long>()
|
|
{
|
|
public Long execute() throws Exception
|
|
{
|
|
return Long.parseLong(cmisConnector.getRepositoryInfo(CmisVersion.CMIS_1_1).getLatestChangeLogToken());
|
|
}
|
|
}, true, false);
|
|
|
|
Long fromToken = latestToken - 2;
|
|
changeLogToken.setValue(fromToken.toString());
|
|
|
|
ol = this.cmisConnector.getContentChanges(changeLogToken, new BigInteger("20"));
|
|
assertEquals(3, ol.getObjects().size());
|
|
assertNotNull(changeLogToken.getValue());
|
|
assertEquals("ChangeLogToken should be the latest from all entries.", latestToken.toString(), changeLogToken.getValue());
|
|
assertFalse(ol.hasMoreItems());
|
|
}
|
|
finally
|
|
{
|
|
auditSubsystem.destroy();
|
|
AuthenticationUtil.popAuthentication();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* MNT-10223
|
|
* Check the IsLatestMajorVersion for a doc with minor version.
|
|
*/
|
|
@SuppressWarnings("unused")
|
|
@Test
|
|
public void testIsLatestMajorVersion()
|
|
{
|
|
final TestContext testContext = new TestContext();
|
|
|
|
// create simple text plain content
|
|
final PropertiesImpl properties = new PropertiesImpl();
|
|
String objectTypeId = "cmis:document";
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, objectTypeId));
|
|
String fileName = "textFile" + GUID.generate();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.NAME, fileName));
|
|
final ContentStreamImpl contentStream = new ContentStreamImpl(fileName, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Simple text plain document");
|
|
|
|
withCmisService(new CmisServiceCallback<String>() {
|
|
@Override
|
|
public String execute(CmisService cmisService) {
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
String objectId = cmisService.create(repositoryId, properties, repositoryHelper.getCompanyHome().getId(), contentStream, VersioningState.MINOR, null, null);
|
|
|
|
ObjectData cmidDoc = cmisService.getObject(repositoryId, objectId, null, true, IncludeRelationships.NONE, null, false, false, null);
|
|
List<PropertyData<?>> properties = cmidDoc.getProperties().getPropertyList();
|
|
boolean found = false;
|
|
PropertyData<?> propIsLatestMajorVersion = null;
|
|
for (PropertyData<?> property : properties)
|
|
{
|
|
if (property.getId().equals(PropertyIds.IS_LATEST_MAJOR_VERSION))
|
|
{
|
|
found = true;
|
|
propIsLatestMajorVersion = property;
|
|
break;
|
|
}
|
|
}
|
|
//properties..contains(CMISDictionaryModel.PROP_IS_LATEST_MAJOR_VERSION);
|
|
assertTrue("The CMISDictionaryModel.PROP_IS_LATEST_MAJOR_VERSION property was not found", found);
|
|
if (found)
|
|
{
|
|
assertFalse("The CMISDictionaryModel.PROP_IS_LATEST_MAJOR_VERSION should be false as minor version was created", (Boolean) propIsLatestMajorVersion.getValues().get(0));
|
|
}
|
|
return objectId;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* ACE-33
|
|
*
|
|
* Cmis Item support
|
|
*/
|
|
@Test
|
|
public void testItems()
|
|
{
|
|
|
|
withCmisService(new CmisServiceCallback<String>() {
|
|
@Override
|
|
public String execute(CmisService cmisService) {
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
TypeDefinition def = cmisService.getTypeDefinition(repositoryId, "cmis:item", null);
|
|
assertNotNull("the cmis:item type is not defined", def);
|
|
|
|
@SuppressWarnings("unused")
|
|
TypeDefinition p = cmisService.getTypeDefinition(repositoryId, "I:cm:person", null);
|
|
assertNotNull("the I:cm:person type is not defined", def);
|
|
|
|
ObjectList result = cmisService.query(repositoryId, "select * from cm:person", Boolean.FALSE, Boolean.TRUE, IncludeRelationships.NONE, "", BigInteger.TEN, BigInteger.ZERO, null);
|
|
assertTrue("", result.getNumItems().intValue() > 0);
|
|
return "";
|
|
|
|
};
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
}
|
|
|
|
/**
|
|
* MNT-11339 related test :
|
|
* Unable to create relationship between cmis:document and cmis:item
|
|
*/
|
|
@Test
|
|
public void testItemRelations()
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final String TEST_NAME = "testItemRelations-";
|
|
final String FOLDER_NAME = TEST_NAME + "FOLDER" + GUID.generate();
|
|
final String DOCUMENT_NAME = TEST_NAME + "DOCUMENT" + GUID.generate();
|
|
final String CLIENT_NAME = "Some Test Client " + GUID.generate();
|
|
|
|
try
|
|
{
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
/* Create folder within companyHome */
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, FOLDER_NAME, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, FOLDER_NAME);
|
|
assertNotNull(folderInfo);
|
|
|
|
// and document
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), DOCUMENT_NAME, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOCUMENT_NAME);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<String>() {
|
|
@SuppressWarnings("unchecked")
|
|
@Override
|
|
public String execute(CmisService cmisService) {
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
// ensure there are custom type, aspect and association defined
|
|
TypeDefinition tpdfn = cmisService.getTypeDefinition(repositoryId, "I:sctst:client", null);
|
|
assertNotNull("the I:sctst:client type is not defined", tpdfn);
|
|
TypeDefinition aspectDfn = cmisService.getTypeDefinition(repositoryId, "P:sctst:clientRelated", null);
|
|
assertNotNull("the P:sctst:clientRelated aspect is not defined", aspectDfn);
|
|
TypeDefinition relDfn = cmisService.getTypeDefinition(repositoryId, "R:sctst:relatedClients", null);
|
|
assertNotNull("the R:sctst:relatedClients association is not defined", relDfn);
|
|
|
|
// create cmis:item within test folder
|
|
PropertiesImpl properties = new PropertiesImpl();
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, tpdfn.getId()));
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.NAME, CLIENT_NAME));
|
|
properties.addProperty(new PropertyStringImpl("sctst:clientId", "id" + GUID.generate()));
|
|
properties.addProperty(new PropertyStringImpl("sctst:clientName", CLIENT_NAME));
|
|
|
|
ObjectData folderData = cmisService.getObjectByPath(repositoryId, "/" + FOLDER_NAME, null, null, null, null, null, null, null);
|
|
|
|
cmisService.createItem(repositoryId, properties, folderData.getId(), null, null, null, null);
|
|
|
|
ObjectData contentData = cmisService.getObjectByPath(repositoryId, "/" + FOLDER_NAME + "/" + DOCUMENT_NAME, null, null, null, null, null, null, null);
|
|
|
|
// add test aspect sctst:clientRelated to document
|
|
Properties props = cmisService.getProperties(repositoryId, contentData.getId(), null, null);
|
|
|
|
PropertyData<?> propAspects = props.getProperties().get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS);
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
List aspects = propAspects.getValues();
|
|
aspects.add("P:sctst:clientRelated");
|
|
|
|
properties = new PropertiesImpl();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, aspects));
|
|
cmisService.updateProperties(repositoryId, new Holder<String>(contentData.getId()), null, properties, null);
|
|
// ensure document has sctst:clientRelated aspect applied
|
|
aspects = cmisService.getProperties(repositoryId, contentData.getId(), null, null).getProperties().get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS).getValues();
|
|
assertTrue("P:sctst:clientRelated excpected", aspects.contains("P:sctst:clientRelated"));
|
|
|
|
ObjectData itemData = cmisService.getObjectByPath(repositoryId, "/" + FOLDER_NAME + "/" + CLIENT_NAME, null, null, null, null, null, null, null);
|
|
// create relationship between cmis:document and cmis:item
|
|
properties = new PropertiesImpl();
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, "R:sctst:relatedClients"));
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.SOURCE_ID, contentData.getId()));
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.TARGET_ID, itemData.getId()));
|
|
cmisService.createRelationship(repositoryId, properties, null, null, null, null);
|
|
|
|
return "";
|
|
|
|
};
|
|
}, CmisVersion.CMIS_1_1);
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testMNT10529() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
final Pair<FileInfo, FileInfo> folderAndDocument = transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<Pair<FileInfo, FileInfo>>()
|
|
{
|
|
@Override
|
|
public Pair<FileInfo, FileInfo> execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
String folderName = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
String docName = GUID.generate();
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
return new Pair<FileInfo, FileInfo>(folderInfo, document);
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertNotNull(repositories);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.iterator().next();
|
|
String repositoryId = repo.getId();
|
|
|
|
String objectIdStr = folderAndDocument.getFirst().getNodeRef().toString();
|
|
|
|
ObjectInFolderList children = cmisService.getChildren(repositoryId, objectIdStr, null, "cmis:name ASC", false, IncludeRelationships.NONE, null, false, null,
|
|
null, null);
|
|
assertChildren(folderAndDocument, children);
|
|
|
|
children = cmisService.getChildren(repositoryId, objectIdStr, null, "cmis:name ASC, cmis:creationDate ASC", false, IncludeRelationships.NONE, null, false,
|
|
null, null, null);
|
|
assertChildren(folderAndDocument, children);
|
|
|
|
children = cmisService.getChildren(repositoryId, objectIdStr, null, " cmis:name ASC", false, IncludeRelationships.NONE, null, false, null, null, null);
|
|
assertChildren(folderAndDocument, children);
|
|
|
|
children = cmisService.getChildren(repositoryId, objectIdStr, null, " cmis:name ASC, cmis:creationDate ASC ", false, IncludeRelationships.NONE, null,
|
|
false, null, null, null);
|
|
assertChildren(folderAndDocument, children);
|
|
|
|
return null;
|
|
}
|
|
|
|
private void assertChildren(final Pair<FileInfo, FileInfo> folderAndDocument, ObjectInFolderList children)
|
|
{
|
|
assertNotNull(children);
|
|
assertTrue(1 == children.getNumItems().longValue());
|
|
|
|
PropertyData<?> nameData = children.getObjects().iterator().next().getObject().getProperties().getProperties().get("cmis:name");
|
|
assertNotNull(nameData);
|
|
Object name = nameData.getValues().iterator().next();
|
|
assertEquals(folderAndDocument.getSecond().getName(), name);
|
|
}
|
|
}, CmisVersion.CMIS_1_0);
|
|
}
|
|
catch (CmisConstraintException e)
|
|
{
|
|
fail(e.toString());
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
@Category(RedundantTests.class)
|
|
@Test
|
|
public void mnt10548test() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final Pair<FileInfo, FileInfo> folderAndDocument = transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<Pair<FileInfo, FileInfo>>()
|
|
{
|
|
private final static String TEST_NAME = "mnt10548test-";
|
|
|
|
@Override
|
|
public Pair<FileInfo, FileInfo> execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
/* Create folder within companyHome */
|
|
String folderName = TEST_NAME + GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
/* Create content */
|
|
String docName = TEST_NAME + GUID.generate();
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
/* Add some tags */
|
|
NodeRef nodeRef = document.getNodeRef();
|
|
taggingService.addTag(nodeRef, "tag1");
|
|
taggingService.addTag(nodeRef, "tag2");
|
|
taggingService.addTag(nodeRef, "tag3");
|
|
|
|
return new Pair<FileInfo, FileInfo>(folderInfo, document);
|
|
}
|
|
});
|
|
|
|
ObjectData objData = withCmisService(
|
|
new CmisServiceCallback<ObjectData>()
|
|
{
|
|
private static final String FILE_FOLDER_SEPARATOR = "/";
|
|
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
String path = FILE_FOLDER_SEPARATOR + folderAndDocument.getFirst().getName() + FILE_FOLDER_SEPARATOR + folderAndDocument.getSecond().getName();
|
|
/* get CMIS object of document */
|
|
ObjectData objData = cmisService.getObjectByPath(repositoryId, path, null, false, null, null, false, false, null);
|
|
return objData;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
Map<String, PropertyData<?>> cmisProps = objData.getProperties().getProperties();
|
|
|
|
String taggable = ContentModel.ASPECT_TAGGABLE.getPrefixedQName(namespaceService).toPrefixString();
|
|
PropertyData<?> propData = cmisProps.get(taggable);
|
|
assertNotNull(propData);
|
|
|
|
List<?> props = propData.getValues();
|
|
assertTrue(props.size() == 3);
|
|
|
|
/* MNT-10548 fix : CMIS should return List of String, not List of NodeRef */
|
|
for(Object o : props)
|
|
{
|
|
assertTrue(o.getClass() + " found but String expected", o instanceof String);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-8804 related test :
|
|
* Check CMISConnector.query for search nodes in environment with corrupted indexes
|
|
*/
|
|
@Test
|
|
public void testQueryNodesWithCorruptedIndexes()
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final String TEST_NAME = "mnt8804test-";
|
|
final String docName = TEST_NAME + GUID.generate();
|
|
|
|
/* Create node */
|
|
final FileInfo document = transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
/* Create folder within companyHome */
|
|
String folderName = TEST_NAME + GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
/* Create document to query */
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
return document;
|
|
}
|
|
});
|
|
|
|
final Pair<Long, NodeRef> nodePair = nodeDAO.getNodePair(document.getNodeRef());
|
|
|
|
/* delete node's metadata directly */
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
Pair<Long, ChildAssociationRef> childAssocPair = nodeDAO.getPrimaryParentAssoc(nodePair.getFirst());
|
|
nodeDAO.deleteChildAssoc(childAssocPair.getFirst());
|
|
nodeDAO.deleteNode(nodePair.getFirst());
|
|
return null;
|
|
}
|
|
});
|
|
|
|
/* ensure the node does not exist */
|
|
assertTrue(!nodeService.exists(nodePair.getSecond()));
|
|
|
|
String queryString = "SELECT * FROM cmis:document WHERE cmis:name='" + docName + "'";
|
|
|
|
ObjectList resultList = cmisConnector.query(queryString, Boolean.FALSE, IncludeRelationships.NONE, "cmis:none", BigInteger.ONE, BigInteger.ZERO);
|
|
assertEquals(resultList.getNumItems(), BigInteger.ZERO);
|
|
|
|
// prepare cmis query
|
|
CMISQueryOptions options = new CMISQueryOptions(queryString, cmisConnector.getRootStoreRef());
|
|
CmisVersion cmisVersion = cmisConnector.getRequestCmisVersion();
|
|
options.setCmisVersion(cmisVersion);
|
|
options.setQueryMode(CMISQueryMode.CMS_WITH_ALFRESCO_EXTENSIONS);
|
|
options.setSkipCount(0);
|
|
options.setMaxItems(100);
|
|
|
|
/* make query bypassing CMISConnector */
|
|
org.alfresco.opencmis.search.CMISResultSet rs = cmisConnector.getOpenCMISQueryService().query(options);
|
|
assertEquals(rs.getNumberFound(), 0);
|
|
}
|
|
|
|
/**
|
|
* CMIS 1.0 aspect properties should provide the following CMIS attributes:
|
|
* propertyDefinitionId, displayName, localName, queryName
|
|
*/
|
|
@Test
|
|
public void testMNT10021() throws Exception
|
|
{
|
|
final String folderName = "testfolder." + GUID.generate();
|
|
final String docName = "testdoc.txt." + GUID.generate();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
// lock adds aspects to the document with properties: lockIsDeep, lockOwner, lockType, expiryDate, lockLifetime
|
|
lockService.lock(document.getNodeRef(), LockType.READ_ONLY_LOCK, 0, true);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
final ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true,
|
|
IncludeRelationships.NONE, null, false, true, null);
|
|
return objectData;
|
|
}
|
|
}, CmisVersion.CMIS_1_0);
|
|
|
|
List<CmisExtensionElement> propertyExtensionList = objectData.getProperties().getExtensions();
|
|
assertEquals("propertyExtensionList should be singletonList", propertyExtensionList.size(), 1);
|
|
List<CmisExtensionElement> extensions = propertyExtensionList.iterator().next().getChildren();
|
|
for (CmisExtensionElement extension : extensions)
|
|
{
|
|
if ("properties".equals(extension.getName()))
|
|
{
|
|
// check properties extension
|
|
List<CmisExtensionElement> propExtensions = extension.getChildren();
|
|
assertTrue("cmisObject should contain aspect properties", propExtensions.size() > 0);
|
|
for (CmisExtensionElement prop : propExtensions)
|
|
{
|
|
Map<String, String> cmisAspectProperty = prop.getAttributes();
|
|
Set<String> cmisAspectPropertyNames = cmisAspectProperty.keySet();
|
|
assertTrue("propertyDefinitionId attribute should be present", cmisAspectPropertyNames.contains("propertyDefinitionId"));
|
|
assertTrue("queryName attribute should be present", cmisAspectPropertyNames.contains("queryName"));
|
|
// optional values that are present for test document
|
|
assertTrue("displayName attribute should be present for property of test node", cmisAspectPropertyNames.contains("displayName"));
|
|
assertTrue("localName attribute should be present for property of test node", cmisAspectPropertyNames.contains("localName"));
|
|
assertEquals(cmisAspectPropertyNames.size(), 4);
|
|
// check values
|
|
for (String aspectPropertyName : cmisAspectPropertyNames)
|
|
{
|
|
String value = cmisAspectProperty.get(aspectPropertyName);
|
|
assertTrue("value for " + aspectPropertyName + " should be present", value != null && value.length() > 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (CmisConstraintException e)
|
|
{
|
|
fail(e.toString());
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void dictionaryTest()
|
|
{
|
|
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
|
{
|
|
@Override
|
|
public Void doWork() throws Exception
|
|
{
|
|
M2Model customModel = M2Model.createModel(
|
|
Thread.currentThread().getContextClassLoader().
|
|
getResourceAsStream("dictionary/dictionarydaotest_model1.xml"));
|
|
dictionaryDAO.putModel(customModel);
|
|
|
|
assertNotNull(cmisDictionaryService.findType("P:cm:dublincore"));
|
|
TypeDefinitionWrapper td = cmisDictionaryService.findType("D:daotest1:type1");
|
|
assertNotNull(td);
|
|
return null;
|
|
}
|
|
}, "user1", "tenant1");
|
|
|
|
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
|
{
|
|
@Override
|
|
public Void doWork() throws Exception
|
|
{
|
|
assertNotNull(cmisDictionaryService.findType("P:cm:dublincore"));
|
|
TypeDefinitionWrapper td = cmisDictionaryService.findType("D:daotest1:type1");
|
|
assertNull(td);
|
|
return null;
|
|
}
|
|
}, "user2", "tenant2");
|
|
}
|
|
|
|
/**
|
|
* MNT-13529: Just-installed Alfresco does not return a CMIS latestChangeLogToken
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
@Test
|
|
public void testMNT13529() throws Exception
|
|
{
|
|
setupAudit();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
try
|
|
{
|
|
// Delete the entries, it simulates just installed Alfresco for reproduce the issue
|
|
final Long appId = auditSubsystem.getAuditApplicationByName("CMISChangeLog").getApplicationId();
|
|
RetryingTransactionCallback<Void> deletedCallback = new RetryingTransactionCallback<Void>()
|
|
{
|
|
public Void execute() throws Throwable
|
|
{
|
|
auditDAO.deleteAuditEntries(appId, null, null);
|
|
return null;
|
|
}
|
|
};
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(deletedCallback);
|
|
|
|
// Retrieve initial latestChangeLogToken
|
|
final String initialChangeLogToken = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertNotNull(repositories);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.iterator().next();
|
|
|
|
return repo.getLatestChangeLogToken();
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
assertNotNull(initialChangeLogToken);
|
|
assertEquals("0", initialChangeLogToken);
|
|
}
|
|
finally
|
|
{
|
|
auditSubsystem.destroy();
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-11726: Test that {@link CMISChangeEvent} contains objectId of node in short form (without StoreRef).
|
|
*/
|
|
@Test
|
|
public void testCMISChangeLogObjectIds() throws Exception
|
|
{
|
|
// setUp audit subsystem
|
|
setupAudit();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
final String changeToken = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertNotNull(repositories);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.iterator().next();
|
|
|
|
return repo.getLatestChangeLogToken();
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
// perform CREATED, UPDATED, SECURITY, DELETED CMIS change type actions
|
|
String folder = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folder, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folder);
|
|
assertNotNull(folderInfo);
|
|
|
|
String content = GUID.generate();
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), content, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, content);
|
|
|
|
permissionService.setPermission(document.getNodeRef(), "SomeAuthority", PermissionService.EXECUTE_CONTENT, true);
|
|
|
|
fileFolderService.delete(document.getNodeRef());
|
|
fileFolderService.delete(folderInfo.getNodeRef());
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertNotNull(repositories);
|
|
assertTrue(repositories.size() > 0);
|
|
String repositoryId = repositories.iterator().next().getId();
|
|
|
|
ObjectList changes = cmisService.getContentChanges(repositoryId, new Holder<String>(changeToken), Boolean.TRUE, null, Boolean.FALSE, Boolean.FALSE, BigInteger.valueOf(1000), null);
|
|
|
|
for (ObjectData od : changes.getObjects())
|
|
{
|
|
ChangeType changeType = od.getChangeEventInfo().getChangeType();
|
|
Object objectId = od.getProperties().getProperties().get("cmis:objectId").getValues().get(0);
|
|
|
|
assertFalse("CMISChangeEvent " + changeType + " should store short form of objectId " + objectId,
|
|
objectId.toString().contains(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE.toString()));
|
|
}
|
|
int expectAtLeast = changes.getObjects().size();
|
|
|
|
// We should also be able to query without passing in any limit
|
|
changes = cmisService.getContentChanges(repositoryId, new Holder<String>(changeToken), Boolean.TRUE, null, Boolean.FALSE, Boolean.FALSE, null, null);
|
|
assertTrue("Expected to still get changes", changes.getObjects().size() >= expectAtLeast);
|
|
// and zero
|
|
changes = cmisService.getContentChanges(repositoryId, new Holder<String>(changeToken), Boolean.TRUE, null, Boolean.FALSE, Boolean.FALSE, BigInteger.valueOf(0), null);
|
|
assertTrue("Expected to still get changes", changes.getObjects().size() >= expectAtLeast);
|
|
// and one
|
|
changes = cmisService.getContentChanges(repositoryId, new Holder<String>(changeToken), Boolean.TRUE, null, Boolean.FALSE, Boolean.FALSE, BigInteger.valueOf(1), null);
|
|
assertEquals("Expected to still get changes", changes.getObjects().size(), 1);
|
|
// Integery.MAX_VALUE must be handled
|
|
// This will limit the number to a sane value
|
|
changes = cmisService.getContentChanges(repositoryId, new Holder<String>(changeToken), Boolean.TRUE, null, Boolean.FALSE, Boolean.FALSE, BigInteger.valueOf(Integer.MAX_VALUE), null);
|
|
assertTrue("Expected to still get changes", changes.getObjects().size() >= expectAtLeast);
|
|
// but not negative
|
|
try
|
|
{
|
|
changes = cmisService.getContentChanges(repositoryId, new Holder<String>(changeToken), Boolean.TRUE, null, Boolean.FALSE, Boolean.FALSE, BigInteger.valueOf(-1), null);
|
|
fail("Negative maxItems is expected to fail");
|
|
}
|
|
catch (CmisInvalidArgumentException e)
|
|
{
|
|
// Expected
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
}
|
|
finally
|
|
{
|
|
auditSubsystem.destroy();
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
private void setupAudit()
|
|
{
|
|
UserAuditFilter userAuditFilter = new UserAuditFilter();
|
|
userAuditFilter.setUserFilterPattern("System;.*");
|
|
userAuditFilter.afterPropertiesSet();
|
|
AuditComponent auditComponent = (AuditComponent) ctx.getBean("auditComponent");
|
|
auditComponent.setUserAuditFilter(userAuditFilter);
|
|
AuditServiceImpl auditServiceImpl = (AuditServiceImpl) ctx.getBean("auditService");
|
|
auditServiceImpl.setAuditComponent(auditComponent);
|
|
|
|
RetryingTransactionCallback<Void> initAudit = new RetryingTransactionCallback<Void>()
|
|
{
|
|
public Void execute() throws Exception
|
|
{
|
|
auditSubsystem.stop();
|
|
auditSubsystem.setProperty("audit.enabled", "true");
|
|
auditSubsystem.setProperty("audit.cmischangelog.enabled", "true");
|
|
auditSubsystem.start();
|
|
return null;
|
|
}
|
|
};
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(initAudit, false, true);
|
|
}
|
|
|
|
/**
|
|
* MNT-11727: move and rename operations should be shown as an UPDATE in the CMIS change log
|
|
*/
|
|
@Test
|
|
public void testMoveRenameWithCMISshouldBeAuditedAsUPDATE() throws Exception
|
|
{
|
|
// setUp audit subsystem
|
|
setupAudit();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
assertTrue("Audit is not enabled", auditSubsystem.isAuditEnabled());
|
|
assertNotNull("CMIS audit is not enabled", auditSubsystem.getAuditApplicationByName("CMISChangeLog"));
|
|
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
String folder = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folder, ContentModel.TYPE_FOLDER);
|
|
|
|
final String actualToken = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<String>()
|
|
{
|
|
public String execute() throws Exception
|
|
{
|
|
return cmisConnector.getRepositoryInfo(CmisVersion.CMIS_1_1).getLatestChangeLogToken();
|
|
}
|
|
}, true, false);
|
|
|
|
String content = GUID.generate();
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), content, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, content);
|
|
|
|
Holder<String> changeLogToken = new Holder<String>();
|
|
changeLogToken.setValue(actualToken);
|
|
ObjectList changeLog = CMISTest.this.cmisConnector.getContentChanges(changeLogToken, new BigInteger("10"));
|
|
List<ObjectData> events = changeLog.getObjects();
|
|
int count = events.size();
|
|
// it should be 3 entries: 1 for previous folder create, 1 new CREATE (for document create)
|
|
// and 1 NEW UPDATE
|
|
assertEquals(3, count);
|
|
|
|
assertEquals(events.get(0).getProperties().getPropertyList().get(0).getValues().get(0), folderInfo.getNodeRef().getId());
|
|
assertEquals(events.get(0).getChangeEventInfo().getChangeType(), ChangeType.CREATED);
|
|
|
|
assertTrue(((String) events.get(1).getProperties().getPropertyList().get(0).getValues().get(0)).contains(document.getNodeRef().getId()));
|
|
assertEquals(events.get(1).getChangeEventInfo().getChangeType(), ChangeType.CREATED);
|
|
|
|
assertTrue(((String) events.get(2).getProperties().getPropertyList().get(0).getValues().get(0)).contains(document.getNodeRef().getId()));
|
|
assertEquals(events.get(2).getChangeEventInfo().getChangeType(), ChangeType.UPDATED);
|
|
|
|
// test rename
|
|
final String actualToken2 = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<String>()
|
|
{
|
|
public String execute() throws Exception
|
|
{
|
|
return cmisConnector.getRepositoryInfo(CmisVersion.CMIS_1_1).getLatestChangeLogToken();
|
|
}
|
|
}, true, false);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, content + "-updated");
|
|
|
|
changeLogToken = new Holder<String>();
|
|
changeLogToken.setValue(actualToken2);
|
|
changeLog = CMISTest.this.cmisConnector.getContentChanges(changeLogToken, new BigInteger("10"));
|
|
events = changeLog.getObjects();
|
|
count = events.size();
|
|
assertEquals(2, count);
|
|
assertEquals("Rename operation should be shown as an UPDATE in the CMIS change log", events.get(1).getChangeEventInfo().getChangeType(), ChangeType.UPDATED);
|
|
|
|
// test move
|
|
String targetFolder = GUID.generate();
|
|
FileInfo targetFolderInfo = fileFolderService.create(companyHomeNodeRef, targetFolder, ContentModel.TYPE_FOLDER);
|
|
|
|
final String actualToken3 = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<String>()
|
|
{
|
|
public String execute() throws Exception
|
|
{
|
|
return cmisConnector.getRepositoryInfo(CmisVersion.CMIS_1_1).getLatestChangeLogToken();
|
|
}
|
|
}, true, false);
|
|
nodeService.moveNode(document.getNodeRef(), targetFolderInfo.getNodeRef(), ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS);
|
|
|
|
changeLogToken = new Holder<String>();
|
|
changeLogToken.setValue(actualToken3);
|
|
changeLog = CMISTest.this.cmisConnector.getContentChanges(changeLogToken, new BigInteger("10"));
|
|
events = changeLog.getObjects();
|
|
count = events.size();
|
|
assertEquals(2, count);
|
|
assertEquals("Move operation should be shown as an UPDATE in the CMIS change log", events.get(1).getChangeEventInfo().getChangeType(), ChangeType.UPDATED);
|
|
}
|
|
finally
|
|
{
|
|
auditSubsystem.destroy();
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-11304: Test that Alfresco has no default boundaries for decimals
|
|
* @throws Exception
|
|
*/
|
|
@Test
|
|
public void testDecimalDefaultBoundaries() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
TypeDefinition decimalTypeDef = cmisService.getTypeDefinition(repositoryId, "D:tcdm:testdecimalstype", null);
|
|
|
|
PropertyDecimalDefinitionImpl floatNoBoundsTypeDef =
|
|
(PropertyDecimalDefinitionImpl)decimalTypeDef.getPropertyDefinitions().get("tcdm:float");
|
|
PropertyDecimalDefinitionImpl doubleNoBoundsTypeDef =
|
|
(PropertyDecimalDefinitionImpl)decimalTypeDef.getPropertyDefinitions().get("tcdm:double");
|
|
|
|
PropertyDecimalDefinitionImpl floatWithBoundsTypeDef =
|
|
(PropertyDecimalDefinitionImpl)decimalTypeDef.getPropertyDefinitions().get("tcdm:floatwithbounds");
|
|
PropertyDecimalDefinitionImpl doubleWithBoundsTypeDef =
|
|
(PropertyDecimalDefinitionImpl)decimalTypeDef.getPropertyDefinitions().get("tcdm:doublewithbounds");
|
|
|
|
// test that there is not default boundaries for decimals
|
|
assertNull(floatNoBoundsTypeDef.getMinValue());
|
|
assertNull(floatNoBoundsTypeDef.getMaxValue());
|
|
|
|
assertNull(doubleNoBoundsTypeDef.getMinValue());
|
|
assertNull(doubleNoBoundsTypeDef.getMaxValue());
|
|
|
|
// test for pre-defined boundaries
|
|
assertTrue(floatWithBoundsTypeDef.getMinValue().equals(BigDecimal.valueOf(-10f)));
|
|
assertTrue(floatWithBoundsTypeDef.getMaxValue().equals(BigDecimal.valueOf(10f)));
|
|
|
|
assertTrue(doubleWithBoundsTypeDef.getMinValue().equals(BigDecimal.valueOf(-10d)));
|
|
assertTrue(doubleWithBoundsTypeDef.getMaxValue().equals(BigDecimal.valueOf(10d)));
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-11876 : Test that Alfresco CMIS 1.1 Implementation is returning aspect and aspect properties as extension data
|
|
* @throws Exception
|
|
*/
|
|
@Test
|
|
public void testExtensionDataIsReturnedViaCmis1_1() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final String FOLDER = "testExtensionDataIsReturnedViaCmis1_1-" + GUID.generate();
|
|
final String CONTENT = FOLDER + "-file";
|
|
|
|
try
|
|
{
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
// create folder
|
|
FileInfo folderInfo = fileFolderService.create(repositoryHelper.getCompanyHome(), FOLDER, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, FOLDER);
|
|
assertNotNull(folderInfo);
|
|
|
|
// create document
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), CONTENT, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, CONTENT);
|
|
|
|
// apply aspect with properties
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
|
props.put(ContentModel.PROP_LATITUDE, Double.valueOf(1.0d));
|
|
props.put(ContentModel.PROP_LONGITUDE, Double.valueOf(1.0d));
|
|
nodeService.addAspect(document.getNodeRef(), ContentModel.ASPECT_GEOGRAPHIC, props);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
final ObjectData objectData = withCmisService(new CmisServiceCallback<ObjectData>()
|
|
{
|
|
@Override
|
|
public ObjectData execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
// get object data
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + FOLDER + "/" + CONTENT, null, true,
|
|
IncludeRelationships.NONE, null, false, true, null);
|
|
return objectData;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
// get extension data from object properties
|
|
List<CmisExtensionElement> extensions = objectData.getProperties().getExtensions().iterator().next().getChildren();
|
|
|
|
Set<String> appliedAspects = new HashSet<String>();
|
|
Set<String> aspectProperties = new HashSet<String>();
|
|
|
|
for (CmisExtensionElement extension : extensions)
|
|
{
|
|
if (CMISConnector.PROPERTIES.equals(extension.getName()))
|
|
{
|
|
// check properties extension
|
|
List<CmisExtensionElement> propExtensions = extension.getChildren();
|
|
assertTrue("cmisObject should contain aspect properties", propExtensions.size() > 0);
|
|
for (CmisExtensionElement prop : propExtensions)
|
|
{
|
|
Map<String, String> cmisAspectProperty = prop.getAttributes();
|
|
Set<String> cmisAspectPropertyNames = cmisAspectProperty.keySet();
|
|
assertTrue("propertyDefinitionId attribute should be present", cmisAspectPropertyNames.contains("propertyDefinitionId"));
|
|
aspectProperties.add(cmisAspectProperty.get("propertyDefinitionId"));
|
|
}
|
|
}
|
|
else if (CMISConnector.APPLIED_ASPECTS.equals(extension.getName()))
|
|
{
|
|
appliedAspects.add(extension.getValue());
|
|
}
|
|
}
|
|
|
|
// extension data should contain applied aspects and aspect properties
|
|
assertTrue("Extensions should contain " + ContentModel.ASPECT_GEOGRAPHIC, appliedAspects.contains("P:cm:geographic"));
|
|
assertTrue("Extensions should contain " + ContentModel.PROP_LATITUDE, aspectProperties.contains("cm:latitude"));
|
|
assertTrue("Extensions should contain " + ContentModel.PROP_LONGITUDE, aspectProperties.contains("cm:longitude"));
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-10165: Check that all concomitant basic CMIS permissions are deleted
|
|
* when permission is deleted vai CMIS 1.1 API. For Atom binding it applies
|
|
* new set of permissions instead of deleting the old ones.
|
|
*/
|
|
@Test
|
|
public void testRemoveACL() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
final String groupName = "group" + GUID.generate();
|
|
final String testGroup = PermissionService.GROUP_PREFIX + groupName;
|
|
try
|
|
{
|
|
// preconditions: create test document
|
|
if (!authorityService.authorityExists(testGroup))
|
|
{
|
|
authorityService.createAuthority(AuthorityType.GROUP, groupName);
|
|
}
|
|
|
|
final FileInfo document = transactionService.getRetryingTransactionHelper().doInTransaction(
|
|
new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
String folderName = GUID.generate();
|
|
FileInfo folderInfo = fileFolderService.create(companyHomeNodeRef, folderName, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, folderName);
|
|
assertNotNull(folderInfo);
|
|
|
|
String docName = GUID.generate();
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), docName, ContentModel.TYPE_CONTENT);
|
|
assertNotNull(document);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, docName);
|
|
|
|
return document;
|
|
}
|
|
});
|
|
|
|
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(document.getNodeRef());
|
|
assertEquals(permissions.size(), 1);
|
|
AccessPermission current = permissions.iterator().next();
|
|
assertEquals(current.getAuthority(), "GROUP_EVERYONE");
|
|
assertEquals(current.getPermission(), "Consumer");
|
|
|
|
// add group1 with Coordinator permissions
|
|
permissionService.setPermission(document.getNodeRef(), testGroup, PermissionService.COORDINATOR, true);
|
|
permissions = permissionService.getAllSetPermissions(document.getNodeRef());
|
|
|
|
Map<String , String> docPermissions = new HashMap<String, String>();
|
|
for (AccessPermission permission : permissions)
|
|
{
|
|
docPermissions.put(permission.getAuthority(), permission.getPermission());
|
|
}
|
|
assertTrue(docPermissions.keySet().contains(testGroup));
|
|
assertEquals(docPermissions.get(testGroup), PermissionService.COORDINATOR);
|
|
|
|
// update permissions for group1 via CMIS 1.1 API
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertNotNull(repositories);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.iterator().next();
|
|
String repositoryId = repo.getId();
|
|
String docIdStr = document.getNodeRef().toString();
|
|
|
|
// when removing Coordinator ACE there are only inherited permissions
|
|
// so empty list of direct permissions is sent to be set
|
|
AccessControlListImpl acesToPut = new AccessControlListImpl();
|
|
List<Ace> acesList = Collections.emptyList();
|
|
acesToPut.setAces(acesList);
|
|
cmisService.applyAcl(repositoryId, docIdStr, acesToPut, AclPropagation.REPOSITORYDETERMINED);
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
// check that permissions are the same as they were before Coordinator was added
|
|
permissions = permissionService.getAllSetPermissions(document.getNodeRef());
|
|
docPermissions = new HashMap<String, String>();
|
|
for (AccessPermission permission : permissions)
|
|
{
|
|
docPermissions.put(permission.getAuthority(), permission.getPermission());
|
|
}
|
|
assertFalse(docPermissions.keySet().contains(testGroup));
|
|
assertEquals(permissions.size(), 1);
|
|
current = permissions.iterator().next();
|
|
assertEquals(current.getAuthority(), "GROUP_EVERYONE");
|
|
assertEquals(current.getPermission(), "Consumer");
|
|
}
|
|
catch (CmisConstraintException e)
|
|
{
|
|
fail(e.toString());
|
|
}
|
|
finally
|
|
{
|
|
if (authorityService.authorityExists(testGroup))
|
|
{
|
|
authorityService.deleteAuthority(testGroup);
|
|
}
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ACE-2904
|
|
*/
|
|
@Test
|
|
public void testACE2904()
|
|
{ // Basic CMIS Types // Additional types from Content Model
|
|
final String[] types = { "cmis:document", "cmis:relationship", "cmis:folder", "cmis:policy", "cmis:item", "R:cm:replaces", "P:cm:author", "I:cm:cmobject" };
|
|
final String[] displayNames = { "Document", "Relationship", "Folder", "Policy", "Item Type", "Replaces", "Author", "Object" };
|
|
final String[] descriptions = { "Document Type", "Relationship Type", "Folder Type", "Policy Type", "CMIS Item", "Replaces", "Author", "I:cm:cmobject" };
|
|
|
|
CmisServiceCallback<String> callback = new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
String repositoryId = repo.getId();
|
|
|
|
for (int i = 0; i < types.length; i++)
|
|
{
|
|
TypeDefinition def = cmisService.getTypeDefinition(repositoryId, types[i], null);
|
|
assertNotNull("The " + types[i] + " type is not defined", def);
|
|
assertNotNull("The display name is incorrect. Please, refer to ACE-2904.", def.getDisplayName());
|
|
assertEquals("The display name is incorrect. Please, refer to ACE-2904.", def.getDisplayName(), displayNames[i]);
|
|
assertEquals("The description is incorrect. Please, refer to ACE-2904.", def.getDescription(), descriptions[i]);
|
|
|
|
for (PropertyDefinition<?> property : def.getPropertyDefinitions().values())
|
|
{
|
|
assertNotNull("Property definition dispaly name is incorrect. Please, refer to ACE-2904.", property.getDisplayName());
|
|
assertNotNull("Property definition description is incorrect. Please, refer to ACE-2904.", property.getDescription());
|
|
}
|
|
}
|
|
|
|
return "";
|
|
};
|
|
};
|
|
|
|
// Lets test types for cmis 1.1 and cmis 1.0
|
|
withCmisService(callback, CmisVersion.CMIS_1_1);
|
|
withCmisService(callback, CmisVersion.CMIS_1_0);
|
|
}
|
|
|
|
/**
|
|
* ACE-3322
|
|
*/
|
|
@Test
|
|
public void testACE3322()
|
|
{
|
|
final String[] types = { "cmis:document", "cmis:relationship", "cmis:folder", "cmis:item" };
|
|
|
|
CmisServiceCallback<String> callback = new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
for (int i = 0; i < types.length; i++)
|
|
{
|
|
|
|
List<TypeDefinitionWrapper> baseTypes = cmisDictionaryService.getBaseTypes();
|
|
assertNotNull(baseTypes);
|
|
checkDefs(baseTypes);
|
|
|
|
List<TypeDefinitionWrapper> children = cmisDictionaryService.getChildren(types[i]);
|
|
assertNotNull(children);
|
|
|
|
// Check that children were updated
|
|
checkDefs(children);
|
|
}
|
|
return "";
|
|
};
|
|
|
|
private void checkDefs(List<TypeDefinitionWrapper> defs)
|
|
{
|
|
for (TypeDefinitionWrapper def : defs)
|
|
{
|
|
assertNotNull("Type definition was not updated. Please refer to ACE-3322", def.getTypeDefinition(false).getDisplayName());
|
|
assertNotNull("Type definition was not updated. Please refer to ACE-3322", def.getTypeDefinition(false).getDescription());
|
|
|
|
// Check that property's display name and description were updated
|
|
for (PropertyDefinitionWrapper property : def.getProperties())
|
|
{
|
|
assertNotNull("Display name is null", property.getPropertyDefinition().getDisplayName());
|
|
assertNotNull("Description is null", property.getPropertyDefinition().getDescription());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
withCmisService(callback, CmisVersion.CMIS_1_1);
|
|
}
|
|
|
|
/**
|
|
* Test auto version behavior for setContentStream, deleteContentStream and appendContentStream according to ALF-21852.
|
|
*/
|
|
@Test
|
|
public void testSetDeleteAppendContentStreamVersioning() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final String DOC1 = "documentProperties1-" + GUID.generate();
|
|
|
|
try
|
|
{
|
|
final FileInfo doc = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<FileInfo>()
|
|
{
|
|
@Override
|
|
public FileInfo execute() throws Throwable
|
|
{
|
|
FileInfo document;
|
|
// create document
|
|
document = fileFolderService.create(repositoryHelper.getCompanyHome(), DOC1, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC1);
|
|
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
|
props.put(ContentModel.PROP_TITLE, "Initial Title");
|
|
props.put(ContentModel.PROP_DESCRIPTION, "Initial Description");
|
|
|
|
nodeService.addAspect(document.getNodeRef(), ContentModel.ASPECT_TITLED, props);
|
|
|
|
// apply versionable aspect with properties
|
|
props = new HashMap<QName, Serializable>();
|
|
// ContentModel.PROP_INITIAL_VERSION always true
|
|
props.put(ContentModel.PROP_INITIAL_VERSION, true);
|
|
props.put(ContentModel.PROP_AUTO_VERSION, true);
|
|
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, true);
|
|
versionService.ensureVersioningEnabled(document.getNodeRef(), props);
|
|
|
|
return document;
|
|
}
|
|
});
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override public Void execute(CmisService cmisService)
|
|
{
|
|
final String documentNodeRefId = doc.getNodeRef().toString();
|
|
final String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
|
|
|
|
ObjectInfo objInfoInitialVersion = cmisService.getObjectInfo(repositoryId, documentNodeRefId);
|
|
assertTrue("We had just created the document - it should be version 1.0", objInfoInitialVersion.getId().endsWith("1.0"));
|
|
|
|
ContentStreamImpl contentStream = new ContentStreamImpl(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Content " + GUID.generate());
|
|
Holder<String> objectIdHolder = new Holder<>(documentNodeRefId);
|
|
// Test setContentStream
|
|
cmisService.setContentStream(repositoryId, objectIdHolder, true, null, contentStream, null);
|
|
assertTrue("The \"output\" parameter should returns the newly created version id: 1.1", objectIdHolder.getValue().endsWith("1.1"));
|
|
// we can use this new version id to get information about the cmis object
|
|
ObjectInfo objInfoAfterSetContentStream = cmisService.getObjectInfo(repositoryId, objectIdHolder.getValue());
|
|
assertTrue("The object info should reflect the version requested: 1.1", objInfoAfterSetContentStream.getId().endsWith("1.1"));
|
|
|
|
// Test deleteContentStream
|
|
cmisService.deleteContentStream(repositoryId, objectIdHolder, null, null);
|
|
assertTrue("The \"output\" parameter should returns the newly created version id: 1.2", objectIdHolder.getValue().endsWith("1.2"));
|
|
// we can use this new version id to get information about the cmis object
|
|
objInfoAfterSetContentStream = cmisService.getObjectInfo(repositoryId, objectIdHolder.getValue());
|
|
assertTrue("The object info should reflect the version requested: 1.2", objInfoAfterSetContentStream.getId().endsWith("1.2"));
|
|
|
|
// Test appendContentStream
|
|
cmisService.appendContentStream(repositoryId, objectIdHolder, null, contentStream, true, null);
|
|
assertTrue("The \"output\" parameter should returns the newly created version id: 1.3", objectIdHolder.getValue().endsWith("1.3"));
|
|
// we can use this new version id to get information about the cmis object
|
|
objInfoAfterSetContentStream = cmisService.getObjectInfo(repositoryId, objectIdHolder.getValue());
|
|
assertTrue("The object info should reflect the version requested: 1.3", objInfoAfterSetContentStream.getId().endsWith("1.3"));
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test to ensure auto version behavior for update properties, set and delete content using both Alfresco and CMIS perspectives.
|
|
* Testing different combinations of <b>cm:initialVersion</b>, <b>cm:autoVersion</b> and <b>cm:autoVersionOnUpdateProps</b> properties
|
|
* <br>
|
|
* OnUpdateProperties MINOR version should be created if <b>cm:initialVersion</b> and <b>cm:autoVersionOnUpdateProps</b> are both TRUE
|
|
* <br>
|
|
* OnContentUpdate MINOR version should be created if <b>cm:initialVersion</b> and <b>cm:autoVersion</b> are both TRUE
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
@Test
|
|
public void testUpdatePropertiesSetDeleteContentVersioning() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final String FOLDER = "testUpdatePropertiesSetDeleteContentVersioning-" + GUID.generate();
|
|
final String DOC1 = "documentProperties1-" + GUID.generate();
|
|
final String DOC2 = "documentProperties2-" + GUID.generate();
|
|
final String DOC3 = "documentProperties3-" + GUID.generate();
|
|
final String DOC4 = "documentProperties4-" + GUID.generate();
|
|
|
|
try
|
|
{
|
|
final List<FileInfo> docs = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<FileInfo>>()
|
|
{
|
|
@Override
|
|
public List<FileInfo> execute() throws Throwable
|
|
{
|
|
// create folder
|
|
FileInfo folderInfo = fileFolderService.create(repositoryHelper.getCompanyHome(), FOLDER, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, FOLDER);
|
|
assertNotNull(folderInfo);
|
|
|
|
FileInfo document;
|
|
List<FileInfo> docs = new ArrayList<FileInfo>();
|
|
// create documents
|
|
document = fileFolderService.create(folderInfo.getNodeRef(), DOC1, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC1);
|
|
docs.add(document);
|
|
document = fileFolderService.create(folderInfo.getNodeRef(), DOC2, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC2);
|
|
docs.add(document);
|
|
document = fileFolderService.create(folderInfo.getNodeRef(), DOC3, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC3);
|
|
docs.add(document);
|
|
document = fileFolderService.create(folderInfo.getNodeRef(), DOC4, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC4);
|
|
docs.add(document);
|
|
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
|
props.put(ContentModel.PROP_TITLE, "Initial Title");
|
|
props.put(ContentModel.PROP_DESCRIPTION, "Initial Description");
|
|
|
|
for (FileInfo fileInfo : docs)
|
|
{
|
|
nodeService.addAspect(fileInfo.getNodeRef(), ContentModel.ASPECT_TITLED, props);
|
|
}
|
|
|
|
// apply versionable aspect with properties
|
|
props = new HashMap<QName, Serializable>();
|
|
// ContentModel.PROP_INITIAL_VERSION always true
|
|
props.put(ContentModel.PROP_INITIAL_VERSION, true);
|
|
|
|
props.put(ContentModel.PROP_AUTO_VERSION, false);
|
|
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
|
|
versionService.ensureVersioningEnabled(docs.get(0).getNodeRef(), props);
|
|
|
|
props.put(ContentModel.PROP_AUTO_VERSION, false);
|
|
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, true);
|
|
versionService.ensureVersioningEnabled(docs.get(1).getNodeRef(), props);
|
|
|
|
props.put(ContentModel.PROP_AUTO_VERSION, true);
|
|
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
|
|
versionService.ensureVersioningEnabled(docs.get(2).getNodeRef(), props);
|
|
|
|
props.put(ContentModel.PROP_AUTO_VERSION, true);
|
|
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, true);
|
|
versionService.ensureVersioningEnabled(docs.get(3).getNodeRef(), props);
|
|
|
|
return docs;
|
|
}
|
|
});
|
|
|
|
assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(1).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(2).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(3).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
|
|
// update node properties using Alfresco
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<Void>>()
|
|
{
|
|
@Override
|
|
public List<Void> execute() throws Throwable
|
|
{
|
|
for (FileInfo fileInfo : docs)
|
|
{
|
|
Map<QName, Serializable> props = nodeService.getProperties(fileInfo.getNodeRef());
|
|
|
|
props.put(ContentModel.PROP_DESCRIPTION, "description-" + GUID.generate());
|
|
props.put(ContentModel.PROP_TITLE, "title-" + GUID.generate());
|
|
|
|
nodeService.setProperties(fileInfo.getNodeRef(), props);
|
|
}
|
|
return null;
|
|
}
|
|
});
|
|
|
|
assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(1).getNodeRef(), "1.1", VersionType.MINOR);
|
|
assertVersions(docs.get(2).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(3).getNodeRef(), "1.1", VersionType.MINOR);
|
|
|
|
// update properties using CMIS perspective
|
|
final String repositoryId = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
|
|
|
|
for (FileInfo fileInfo : docs)
|
|
{
|
|
PropertiesImpl properties = new PropertiesImpl();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.DESCRIPTION, "description-" + GUID.generate()));
|
|
|
|
cmisService.updateProperties(repositoryId, new Holder<String>(fileInfo.getNodeRef().toString()), null, properties, null);
|
|
}
|
|
//This extra check was added due to MNT-16641.
|
|
{
|
|
PropertiesImpl properties = new PropertiesImpl();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, "P:cm:lockable"));
|
|
|
|
Set<QName> existingAspects = nodeService.getAspects(docs.get(0).getNodeRef());
|
|
cmisService.updateProperties(repositoryId,new Holder<String>(docs.get(0).getNodeRef().toString()), null, properties, null);
|
|
Set<QName> updatedAspects = nodeService.getAspects(docs.get(0).getNodeRef());
|
|
updatedAspects.removeAll(existingAspects);
|
|
|
|
assertEquals(ContentModel.ASPECT_LOCKABLE, updatedAspects.iterator().next());
|
|
|
|
}
|
|
return repositoryId;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
|
|
assertVersions(docs.get(2).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(3).getNodeRef(), "1.2", VersionType.MINOR);
|
|
|
|
// CMIS setContentStream
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
for (FileInfo fileInfo : docs)
|
|
{
|
|
ContentStreamImpl contentStream = new ContentStreamImpl(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Content " + GUID.generate());
|
|
|
|
cmisService.setContentStream(repositoryId, new Holder<String>(fileInfo.getNodeRef().toString()), true, null, contentStream, null);
|
|
}
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
|
|
assertVersions(docs.get(2).getNodeRef(), "1.1", VersionType.MINOR);
|
|
assertVersions(docs.get(3).getNodeRef(), "1.3", VersionType.MINOR);
|
|
|
|
// update content using Alfresco
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<Void>>()
|
|
{
|
|
@Override
|
|
public List<Void> execute() throws Throwable
|
|
{
|
|
for (FileInfo fileInfo : docs)
|
|
{
|
|
ContentWriter writer = contentService.getWriter(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
|
|
writer.putContent("Content " + GUID.generate());
|
|
}
|
|
return null;
|
|
}
|
|
});
|
|
|
|
assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
|
|
assertVersions(docs.get(2).getNodeRef(), "1.2", VersionType.MINOR);
|
|
assertVersions(docs.get(3).getNodeRef(), "1.4", VersionType.MINOR);
|
|
|
|
// CMIS deleteContentStream
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
for (FileInfo fileInfo : docs)
|
|
{
|
|
cmisService.deleteContentStream(repositoryId, new Holder<String>(fileInfo.getNodeRef().toString()), null, null);
|
|
}
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
assertVersions(docs.get(0).getNodeRef(), "1.0", VersionType.MAJOR);
|
|
assertVersions(docs.get(1).getNodeRef(), "1.2", VersionType.MINOR);
|
|
assertVersions(docs.get(2).getNodeRef(), "1.3", VersionType.MINOR);
|
|
assertVersions(docs.get(3).getNodeRef(), "1.5", VersionType.MINOR);
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
private void assertVersions(final NodeRef nodeRef, final String expectedVersionLabel, final VersionType expectedVersionType)
|
|
{
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<Void>>()
|
|
{
|
|
@Override
|
|
public List<Void> execute() throws Throwable
|
|
{
|
|
assertTrue("Node should be versionable", nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE));
|
|
|
|
Version version = versionService.getCurrentVersion(nodeRef);
|
|
|
|
assertNotNull(version);
|
|
assertEquals(expectedVersionLabel, version.getVersionLabel());
|
|
assertEquals(expectedVersionType, version.getVersionType());
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
|
|
|
|
ObjectData data =
|
|
cmisService.getObjectOfLatestVersion(repositoryId, nodeRef.toString(), null, Boolean.FALSE, null, null, null, null, null, null, null);
|
|
|
|
assertNotNull(data);
|
|
|
|
PropertyData<?> prop = data.getProperties().getProperties().get(PropertyIds.VERSION_LABEL);
|
|
Object versionLabelCmisValue = prop.getValues().get(0);
|
|
|
|
assertEquals(expectedVersionLabel, versionLabelCmisValue);
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
}
|
|
|
|
/**
|
|
* Test to ensure that set of aspect returned by cmisService#getAllVersions for latest version is the same
|
|
* as for the object returned by cmisService#getObjectByPath.
|
|
*
|
|
* See <a href="https://issues.alfresco.com/jira/browse/MNT-9557">MNT-9557</a>
|
|
*/
|
|
@Test
|
|
public void testLastVersionOfVersionSeries()
|
|
{
|
|
CallContext context = new SimpleCallContext("admin", "admin", CmisVersion.CMIS_1_0);
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
final String FOLDER = "testUpdatePropertiesSetDeleteContentVersioning-" + GUID.generate(),
|
|
DOC = "documentProperties-" + GUID.generate();
|
|
|
|
try
|
|
{
|
|
final NodeRef nodeRef = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
|
{
|
|
@Override
|
|
public NodeRef execute() throws Throwable
|
|
{
|
|
// create folder
|
|
FileInfo folderInfo = fileFolderService.create(repositoryHelper.getCompanyHome(), FOLDER, ContentModel.TYPE_FOLDER);
|
|
nodeService.setProperty(folderInfo.getNodeRef(), ContentModel.PROP_NAME, FOLDER);
|
|
assertNotNull(folderInfo);
|
|
|
|
// create documents
|
|
FileInfo document = fileFolderService.create(folderInfo.getNodeRef(), DOC, ContentModel.TYPE_CONTENT);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_NAME, DOC);
|
|
nodeService.setProperty(document.getNodeRef(), ContentModel.PROP_DESCRIPTION, "Initial doc");
|
|
|
|
return document.getNodeRef();
|
|
}
|
|
});
|
|
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
// make sure that there is no version history yet
|
|
assertNull(versionService.getVersionHistory(nodeRef));
|
|
|
|
// create a version
|
|
// turn off auto-versioning
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
|
props.put(ContentModel.PROP_INITIAL_VERSION, false);
|
|
props.put(ContentModel.PROP_AUTO_VERSION, false);
|
|
props.put(ContentModel.PROP_AUTO_VERSION_PROPS, false);
|
|
|
|
versionService.ensureVersioningEnabled(nodeRef, props);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
assertNotNull(versionService.getVersionHistory(nodeRef));
|
|
// create another one version
|
|
versionService.createVersion(nodeRef, null);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
final String NEW_DOC_NAME = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute() throws Throwable
|
|
{
|
|
// add aspect to the node
|
|
String newDocName = DOC + GUID.generate();
|
|
nodeService.addAspect(nodeRef, ContentModel.ASPECT_AUTHOR, null);
|
|
nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, newDocName);
|
|
|
|
return newDocName;
|
|
}
|
|
});
|
|
|
|
CmisService cmisService = factory.getService(context);
|
|
String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
|
|
|
|
List<ObjectData> versions =
|
|
cmisService.getAllVersions(repositoryId, nodeRef.toString(), null, null, null, null);
|
|
assertNotNull(versions);
|
|
// get the latest version
|
|
ObjectData latestVersion = versions.get(0);
|
|
// get the object
|
|
ObjectData object =
|
|
// cmisService.getObjectOfLatestVersion(repositoryId, nodeRef.toString(), null, false, null, null, null, null, false, false, null);
|
|
cmisService.getObjectByPath(repositoryId, "/" + FOLDER + "/" + NEW_DOC_NAME, null, null, null, null, false, false, null);
|
|
|
|
assertNotNull(latestVersion);
|
|
assertNotNull(object);
|
|
|
|
Object objectDescriptionString = object.getProperties().getProperties().get("cmis:name").getValues().get(0);
|
|
Object latestVersionDescriptionString = latestVersion.getProperties().getProperties().get("cmis:name").getValues().get(0);
|
|
// ensure that node and latest version both have same description
|
|
assertEquals(objectDescriptionString, latestVersionDescriptionString);
|
|
|
|
Set<String> documentAspects = new HashSet<String>();
|
|
for (CmisExtensionElement cmisEE : object.getProperties().getExtensions().get(0).getChildren())
|
|
{
|
|
documentAspects.add(cmisEE.getValue());
|
|
}
|
|
Set<String> latestVersionAspects = new HashSet<String>();
|
|
for (CmisExtensionElement cmisEE : latestVersion.getProperties().getExtensions().get(0).getChildren())
|
|
{
|
|
latestVersionAspects.add(cmisEE.getValue());
|
|
}
|
|
// ensure that node and latest version both have the same set of aspects
|
|
assertEquals(latestVersionAspects, documentAspects);
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test to ensure that versioning properties have default values defined in Alfresco content model.
|
|
* Testing <b>cm:initialVersion</b>, <b>cm:autoVersion</b> and <b>cm:autoVersionOnUpdateProps</b> properties
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
@Test
|
|
public void testVersioningPropertiesHaveDefaultValue() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
// Create document via CMIS
|
|
final NodeRef documentNodeRef = withCmisService(new CmisServiceCallback<NodeRef>()
|
|
{
|
|
@Override
|
|
public NodeRef execute(CmisService cmisService)
|
|
{
|
|
String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
|
|
|
|
String rootNodeId = cmisService.getObjectByPath(repositoryId, "/", null, true, IncludeRelationships.NONE, null, false, true, null).getId();
|
|
|
|
Collection<PropertyData<?>> propsList = new ArrayList<PropertyData<?>>();
|
|
propsList.add(new PropertyStringImpl(PropertyIds.NAME, "Folder-" + GUID.generate()));
|
|
propsList.add(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, "cmis:folder"));
|
|
|
|
String folderId = cmisService.createFolder(repositoryId, new PropertiesImpl(propsList), rootNodeId, null, null, null, null);
|
|
|
|
propsList = new ArrayList<PropertyData<?>>();
|
|
propsList.add(new PropertyStringImpl(PropertyIds.NAME, "File-" + GUID.generate()));
|
|
propsList.add(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, "cmis:document"));
|
|
|
|
String nodeId = cmisService.createDocument(repositoryId, new PropertiesImpl(propsList), folderId, null, null, null, null, null, null);
|
|
|
|
return new NodeRef(nodeId.substring(0, nodeId.indexOf(';')));
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
// check versioning properties
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<Void>>()
|
|
{
|
|
@Override
|
|
public List<Void> execute() throws Throwable
|
|
{
|
|
assertTrue(nodeService.exists(documentNodeRef));
|
|
assertTrue(nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
|
|
|
AspectDefinition ad = dictionaryService.getAspect(ContentModel.ASPECT_VERSIONABLE);
|
|
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> properties = ad.getProperties();
|
|
|
|
for (QName qName : new QName[] {ContentModel.PROP_INITIAL_VERSION, ContentModel.PROP_AUTO_VERSION, ContentModel.PROP_AUTO_VERSION_PROPS})
|
|
{
|
|
Serializable property = nodeService.getProperty(documentNodeRef, qName);
|
|
|
|
assertNotNull(property);
|
|
|
|
org.alfresco.service.cmr.dictionary.PropertyDefinition pd = properties.get(qName);
|
|
assertNotNull(pd.getDefaultValue());
|
|
|
|
assertEquals(property, Boolean.parseBoolean(pd.getDefaultValue()));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testCreateDocWithVersioningStateNone() throws Exception
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
// get repository id
|
|
final String repositoryId = withCmisService(new CmisServiceCallback<String>()
|
|
{
|
|
@Override
|
|
public String execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertTrue(repositories.size() > 0);
|
|
RepositoryInfo repo = repositories.get(0);
|
|
final String repositoryId = repo.getId();
|
|
return repositoryId;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
final NodeRef documentNodeRef = withCmisService(new CmisServiceCallback<NodeRef>()
|
|
{
|
|
@Override
|
|
public NodeRef execute(CmisService cmisService)
|
|
{
|
|
final PropertiesImpl properties = new PropertiesImpl();
|
|
String objectTypeId = "cmis:document";
|
|
properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_TYPE_ID, objectTypeId));
|
|
String fileName = "textFile" + GUID.generate();
|
|
properties.addProperty(new PropertyStringImpl(PropertyIds.NAME, fileName));
|
|
final ContentStreamImpl contentStream = new ContentStreamImpl(fileName, MimetypeMap.MIMETYPE_TEXT_PLAIN, "Simple text plain document");
|
|
|
|
String nodeId = cmisService.create(repositoryId, properties, repositoryHelper.getCompanyHome().getId(), contentStream, VersioningState.NONE, null, null);
|
|
return new NodeRef(nodeId.substring(0, nodeId.indexOf(';')));
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
|
|
// check versioning properties
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<List<Void>>()
|
|
{
|
|
@Override
|
|
public List<Void> execute() throws Throwable
|
|
{
|
|
assertTrue(nodeService.exists(documentNodeRef));
|
|
assertFalse(nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_VERSIONABLE));
|
|
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* MNT-14951: Test that the list of parents can be retrieved for a folder.
|
|
*/
|
|
@Test
|
|
public void testCMISGetObjectParents() throws Exception
|
|
{
|
|
// setUp audit subsystem
|
|
setupAudit();
|
|
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
try
|
|
{
|
|
final NodeRef folderWithTwoParents = transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
|
{
|
|
@Override
|
|
public NodeRef execute() throws Throwable
|
|
{
|
|
NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
|
|
|
|
String folder1 = GUID.generate();
|
|
FileInfo folderInfo1 = fileFolderService.create(companyHomeNodeRef, folder1, ContentModel.TYPE_FOLDER);
|
|
assertNotNull(folderInfo1);
|
|
|
|
String folder2 = GUID.generate();
|
|
FileInfo folderInfo2 = fileFolderService.create(companyHomeNodeRef, folder2, ContentModel.TYPE_FOLDER);
|
|
assertNotNull(folderInfo2);
|
|
|
|
// Create folder11 as a subfolder of folder1
|
|
String folder11 = GUID.generate();
|
|
FileInfo folderInfo11 = fileFolderService.create(folderInfo1.getNodeRef(), folder11, ContentModel.TYPE_FOLDER);
|
|
assertNotNull(folderInfo11);
|
|
|
|
// Add folder2 as second parent for folder11
|
|
nodeService.addChild(folderInfo2.getNodeRef(), folderInfo11.getNodeRef(), ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS);
|
|
|
|
return folderInfo11.getNodeRef();
|
|
}
|
|
});
|
|
|
|
withCmisService(new CmisServiceCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute(CmisService cmisService)
|
|
{
|
|
List<RepositoryInfo> repositories = cmisService.getRepositoryInfos(null);
|
|
assertNotNull(repositories);
|
|
assertTrue(repositories.size() > 0);
|
|
String repositoryId = repositories.iterator().next().getId();
|
|
|
|
List<ObjectParentData> parents = cmisService.getObjectParents(repositoryId, folderWithTwoParents.getId(), null, Boolean.FALSE, IncludeRelationships.NONE,
|
|
"cmis:none", Boolean.FALSE, null);
|
|
// Check if the second parent was also returned.
|
|
assertEquals(2, parents.size());
|
|
|
|
return null;
|
|
}
|
|
}, CmisVersion.CMIS_1_1);
|
|
}
|
|
finally
|
|
{
|
|
auditSubsystem.destroy();
|
|
AuthenticationUtil.popAuthentication();
|
|
}
|
|
}
|
|
/*
|
|
* REPO-3627 / MNT-19630: CMIS: Unable to call getAllVersions() if node is checked out and if binding type is WSDL
|
|
*
|
|
* For WS binding the getAllVersions call is made with null objectId
|
|
*/
|
|
@Test
|
|
public void getAllVersionsWithNullObjectId()
|
|
{
|
|
AuthenticationUtil.pushAuthentication();
|
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
|
|
|
// Create folder with file
|
|
String folderName = "testfolder" + GUID.generate();
|
|
String docName = "testdoc.txt" + GUID.generate();
|
|
NodeRef folderRef = createContent(folderName, docName, false).getNodeRef();
|
|
List<FileInfo> folderFileList = fileFolderService.list(folderRef);
|
|
final NodeRef fileRef = folderFileList.get(0).getNodeRef();
|
|
|
|
// Create new version for file
|
|
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>()
|
|
{
|
|
@Override
|
|
public Void execute() throws Throwable
|
|
{
|
|
// create a new version
|
|
versionService.createVersion(fileRef, null);
|
|
|
|
return null;
|
|
}
|
|
});
|
|
|
|
// Checkout document and get all versions
|
|
List<ObjectData> versions = withCmisService(new CmisServiceCallback<List<ObjectData>>()
|
|
{
|
|
@Override
|
|
public List<ObjectData> execute(CmisService cmisService)
|
|
{
|
|
String repositoryId = cmisService.getRepositoryInfos(null).get(0).getId();
|
|
ObjectData objectData = cmisService.getObjectByPath(repositoryId, "/" + folderName + "/" + docName, null, true, IncludeRelationships.NONE, null,
|
|
false, true, null);
|
|
|
|
// Checkout
|
|
Holder<String> objectId = new Holder<String>(objectData.getId());
|
|
cmisService.checkOut(repositoryId, objectId, null, new Holder<Boolean>(true));
|
|
|
|
// Call get all versions with null objectId
|
|
List<ObjectData> versions = cmisService.getAllVersions(repositoryId, null, fileRef.toString(), null, null, null);
|
|
|
|
return versions;
|
|
}
|
|
});
|
|
|
|
// Check that the correct versions are retrieved
|
|
assertEquals(2, versions.size());
|
|
assertEquals(versions.get(0).getProperties().getProperties().get("cmis:versionLabel").getFirstValue(), "pwc");
|
|
assertEquals(versions.get(1).getProperties().getProperties().get("cmis:versionLabel").getFirstValue(), "0.1");
|
|
}
|
|
}
|