Java tutorial
/* * #%L * Alfresco Remote API * %% * 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.rest.api.tests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.Serializable; import java.io.StringWriter; import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.alfresco.cmis.client.AlfrescoDocument; import org.alfresco.cmis.client.AlfrescoFolder; import org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl; import org.alfresco.cmis.client.type.AlfrescoType; import org.alfresco.model.ContentModel; import org.alfresco.opencmis.CMISDispatcherRegistry.Binding; import org.alfresco.opencmis.dictionary.CMISStrictDictionaryService; import org.alfresco.opencmis.dictionary.QNameFilter; import org.alfresco.opencmis.dictionary.QNameFilterImpl; import org.alfresco.opencmis.mapping.NodeRefProperty; import org.alfresco.repo.action.ActionModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.filestore.FileContentWriter; import org.alfresco.repo.dictionary.DictionaryBootstrap; import org.alfresco.repo.dictionary.DictionaryDAO; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; 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.RetryingTransactionCallback; import org.alfresco.repo.version.VersionableAspectTest; import org.alfresco.rest.api.tests.RepoService.SiteInformation; import org.alfresco.rest.api.tests.RepoService.TestNetwork; import org.alfresco.rest.api.tests.RepoService.TestPerson; import org.alfresco.rest.api.tests.RepoService.TestSite; import org.alfresco.rest.api.tests.client.HttpResponse; import org.alfresco.rest.api.tests.client.PublicApiClient.CmisSession; import org.alfresco.rest.api.tests.client.PublicApiClient.Comments; import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse; import org.alfresco.rest.api.tests.client.PublicApiClient.Nodes; import org.alfresco.rest.api.tests.client.PublicApiClient.Sites; import org.alfresco.rest.api.tests.client.PublicApiException; import org.alfresco.rest.api.tests.client.RequestContext; import org.alfresco.rest.api.tests.client.data.CMISNode; import org.alfresco.rest.api.tests.client.data.Comment; import org.alfresco.rest.api.tests.client.data.FolderNode; import org.alfresco.rest.api.tests.client.data.MemberOfSite; import org.alfresco.rest.api.tests.client.data.NodeRating; import org.alfresco.rest.api.tests.client.data.NodeRating.Aggregate; import org.alfresco.rest.api.tests.client.data.Person; import org.alfresco.rest.api.tests.client.data.SiteRole; import org.alfresco.rest.api.tests.client.data.Tag; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockType; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.service.namespace.QName; import org.alfresco.util.GUID; import org.alfresco.util.TempFileProvider; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.Document; import org.apache.chemistry.opencmis.client.api.FileableCmisObject; import org.apache.chemistry.opencmis.client.api.Folder; import org.apache.chemistry.opencmis.client.api.ItemIterable; import org.apache.chemistry.opencmis.client.api.ObjectId; import org.apache.chemistry.opencmis.client.api.ObjectType; import org.apache.chemistry.opencmis.client.api.OperationContext; import org.apache.chemistry.opencmis.client.api.Property; import org.apache.chemistry.opencmis.client.api.Relationship; import org.apache.chemistry.opencmis.client.api.Repository; import org.apache.chemistry.opencmis.client.api.SecondaryType; import org.apache.chemistry.opencmis.client.api.Session; import org.apache.chemistry.opencmis.client.api.SessionFactory; import org.apache.chemistry.opencmis.client.api.Tree; import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl; import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.SessionParameter; import org.apache.chemistry.opencmis.commons.data.ContentStream; import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; import org.apache.chemistry.opencmis.commons.enums.VersioningState; import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException; import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.extensions.surf.util.URLEncoder; public class TestCMIS extends EnterpriseTestApi { private static final String CMIS_VERSION_10 = "1.0"; private static final String CMIS_VERSION_11 = "1.1"; private static final String TYPE_CMIS_DOCUMENT = "cmis:document"; private static final String DOCUMENT_LIBRARY_CONTAINER_NAME = "documentLibrary"; private static final String TEST_SITE_NAME_PATTERN = "testSite-%d"; private static final String TEST_USER_NAME_PATTERN = "testUser-%d"; private static final String TEST_DOCUMENT_NAME_PATTERN = "testDocument-%s.txt"; private static final String DOCUMENT_LIBRARY_PATH_PATTERN = "/Sites/%s/" + DOCUMENT_LIBRARY_CONTAINER_NAME; private static final String TEST_PASSWORD = "password"; private DictionaryDAO dictionaryDAO; private LockService lockService; private TenantService tenantService; private CMISStrictDictionaryService cmisDictionary; private QNameFilter cmisTypeExclusions; private NodeService nodeService; private Properties globalProperties; @Before public void before() throws Exception { ApplicationContext ctx = getTestFixture().getApplicationContext(); this.dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO"); this.lockService = (LockService) ctx.getBean("lockService"); this.tenantService = (TenantService) ctx.getBean("tenantService"); this.cmisDictionary = (CMISStrictDictionaryService) ctx.getBean("OpenCMISDictionaryService"); this.cmisTypeExclusions = (QNameFilter) ctx.getBean("cmisTypeExclusions"); this.nodeService = (NodeService) ctx.getBean("NodeService"); this.globalProperties = (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"); } private void checkSecondaryTypes(Document doc, Set<String> expectedSecondaryTypes, Set<String> expectedMissingSecondaryTypes) { final List<SecondaryType> secondaryTypesList = doc.getSecondaryTypes(); assertNotNull(secondaryTypesList); List<String> secondaryTypes = new AbstractList<String>() { @Override public String get(int index) { SecondaryType type = secondaryTypesList.get(index); return type.getId(); } @Override public int size() { return secondaryTypesList.size(); } }; if (expectedSecondaryTypes != null) { assertTrue("Missing secondary types: " + secondaryTypes, secondaryTypes.containsAll(expectedSecondaryTypes)); } if (expectedMissingSecondaryTypes != null) { assertTrue("Expected missing secondary types but at least one is still present: " + secondaryTypes, !secondaryTypes.containsAll(expectedMissingSecondaryTypes)); } } private String getBareObjectId(String objectId) { int idx = objectId.indexOf(";"); String bareObjectId = null; if (idx != -1) { bareObjectId = objectId.substring(0, idx); } else { bareObjectId = objectId; } return bareObjectId; } /** * Tests OpenCMIS api. */ @SuppressWarnings("unchecked") @Test public void testCMIS() throws Exception { // Test Case cloud-2353 // Test Case cloud-2354 // Test Case cloud-2356 // Test Case cloud-2378 // Test Case cloud-2357 // Test Case cloud-2358 // Test Case cloud-2360 final TestNetwork network1 = getTestFixture().getRandomNetwork(); Iterator<String> personIt = network1.getPersonIds().iterator(); final String personId = personIt.next(); assertNotNull(personId); Person person = repoService.getPerson(personId); assertNotNull(person); // Create a site final TestSite site = TenantUtil.runAsUserTenant(new TenantRunAsWork<TestSite>() { @Override public TestSite doWork() throws Exception { String siteName = "site" + System.currentTimeMillis(); SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = network1.createSite(siteInfo); return site; } }, personId, network1.getId()); publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); Nodes nodesProxy = publicApiClient.nodes(); Comments commentsProxy = publicApiClient.comments(); String expectedContent = "Ipsum and so on"; Document doc = null; Folder documentLibrary = (Folder) cmisSession .getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary"); FolderNode expectedDocumentLibrary = (FolderNode) CMISNode.createNode(documentLibrary); Document testDoc = null; Folder testFolder = null; FolderNode testFolderNode = null; // create some sub-folders and documents { for (int i = 0; i < 3; i++) { Map<String, String> properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder"); properties.put(PropertyIds.NAME, "folder-" + i); } Folder f = documentLibrary.createFolder(properties); FolderNode fn = (FolderNode) CMISNode.createNode(f); if (testFolder == null) { testFolder = f; testFolderNode = fn; } expectedDocumentLibrary.addFolder(fn); for (int k = 0; k < 3; k++) { properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder"); properties.put(PropertyIds.NAME, "folder-" + k); } Folder f1 = f.createFolder(properties); FolderNode childFolder = (FolderNode) CMISNode.createNode(f1); fn.addFolder(childFolder); } for (int j = 0; j < 3; j++) { properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, "doc-" + j); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent(expectedContent); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } Document d = f.createDocument(properties, fileContent, VersioningState.MAJOR); if (testDoc == null) { testDoc = d; } CMISNode childDocument = CMISNode.createNode(d); fn.addNode(childDocument); } } for (int i = 0; i < 10; i++) { Map<String, String> properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, "doc-" + i); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent(expectedContent); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } documentLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); } } // try to add and remove ratings, comments, tags to folders created by CMIS { Aggregate aggregate = new Aggregate(1, null); NodeRating expectedNodeRating = new NodeRating("likes", true, aggregate); Comment expectedComment = new Comment("commenty", "commenty", false, null, person, person); Tag expectedTag = new Tag("taggy"); NodeRating rating = nodesProxy.createNodeRating(testFolder.getId(), expectedNodeRating); expectedNodeRating.expected(rating); assertNotNull(rating.getId()); Tag tag = nodesProxy.createNodeTag(testFolder.getId(), expectedTag); expectedTag.expected(tag); assertNotNull(tag.getId()); Comment comment = commentsProxy.createNodeComment(testFolder.getId(), expectedComment); expectedComment.expected(comment); assertNotNull(comment.getId()); } // try to add and remove ratings, comments, tags to documents created by CMIS { Aggregate aggregate = new Aggregate(1, null); NodeRating expectedNodeRating = new NodeRating("likes", true, aggregate); Comment expectedComment = new Comment("commenty", "commenty", false, null, person, person); Tag expectedTag = new Tag("taggy"); NodeRating rating = nodesProxy.createNodeRating(testDoc.getId(), expectedNodeRating); expectedNodeRating.expected(rating); assertNotNull(rating.getId()); Tag tag = nodesProxy.createNodeTag(testDoc.getId(), expectedTag); expectedTag.expected(tag); assertNotNull(tag.getId()); Comment comment = commentsProxy.createNodeComment(testDoc.getId(), expectedComment); expectedComment.expected(comment); assertNotNull(comment.getId()); } // descendants { List<Tree<FileableCmisObject>> descendants = documentLibrary.getDescendants(4); expectedDocumentLibrary.checkDescendants(descendants); } // upload/setContent { Map<String, String> fileProps = new HashMap<String, String>(); { fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent(expectedContent); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } doc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR); String nodeId = stripCMISSuffix(doc.getId()); final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId); ContentReader reader = TenantUtil.runAsUserTenant(new TenantRunAsWork<ContentReader>() { @Override public ContentReader doWork() throws Exception { ContentReader reader = repoService.getContent(nodeRef, ContentModel.PROP_CONTENT); return reader; } }, personId, network1.getId()); String actualContent = reader.getContentString(); assertEquals(expectedContent, actualContent); } // get content { ContentStream stream = doc.getContentStream(); StringWriter writer = new StringWriter(); IOUtils.copy(stream.getStream(), writer, "UTF-8"); String actualContent = writer.toString(); assertEquals(expectedContent, actualContent); } // get children { Folder folder = (Folder) cmisSession .getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary/" + testFolder.getName()); ItemIterable<CmisObject> children = folder.getChildren(); testFolderNode.checkChildren(children); } // query { Folder folder = (Folder) cmisSession .getObjectByPath("/Sites/" + site.getSiteId() + "/documentLibrary/" + testFolder.getName()); String folderId = folder.getId(); Set<String> expectedFolderNames = new HashSet<String>(); for (CMISNode n : testFolderNode.getFolderNodes().values()) { expectedFolderNames.add((String) n.getProperty("cmis:name")); } int expectedNumFolders = expectedFolderNames.size(); int numMatchingFoldersFound = 0; List<CMISNode> results = cmisSession.query( "SELECT * FROM cmis:folder WHERE IN_TREE('" + folderId + "')", false, 0, Integer.MAX_VALUE); for (CMISNode node : results) { String name = (String) node.getProperties().get("cmis:name"); if (expectedFolderNames.contains(name)) { numMatchingFoldersFound++; } } assertEquals(expectedNumFolders, numMatchingFoldersFound); Set<String> expectedDocNames = new HashSet<String>(); for (CMISNode n : testFolderNode.getDocumentNodes().values()) { expectedDocNames.add((String) n.getProperty("cmis:name")); } int expectedNumDocs = expectedDocNames.size(); int numMatchingDocsFound = 0; results = cmisSession.query("SELECT * FROM cmis:document where IN_TREE('" + folderId + "')", false, 0, Integer.MAX_VALUE); for (CMISNode node : results) { String name = (String) node.getProperties().get("cmis:name"); if (expectedDocNames.contains(name)) { numMatchingDocsFound++; } } assertEquals(expectedNumDocs, numMatchingDocsFound); } // versioning { String nodeId = stripCMISSuffix(doc.getId()); final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId); // checkout ObjectId pwcId = doc.checkOut(); Document pwc = (Document) cmisSession.getObject(pwcId.getId()); Boolean isCheckedOut = TenantUtil.runAsUserTenant(new TenantRunAsWork<Boolean>() { @Override public Boolean doWork() throws Exception { Boolean isCheckedOut = repoService.isCheckedOut(nodeRef); return isCheckedOut; } }, personId, network1.getId()); assertTrue(isCheckedOut); // checkin with new content expectedContent = "Big bad wolf"; ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent(expectedContent); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } ObjectId checkinId = pwc.checkIn(true, Collections.EMPTY_MAP, fileContent, "checkin 1"); doc = (Document) cmisSession.getObject(checkinId.getId()); isCheckedOut = TenantUtil.runAsUserTenant(new TenantRunAsWork<Boolean>() { @Override public Boolean doWork() throws Exception { Boolean isCheckedOut = repoService.isCheckedOut(nodeRef); return isCheckedOut; } }, personId, network1.getId()); assertFalse(isCheckedOut); // check that the content has been updated ContentStream stream = doc.getContentStream(); StringWriter writer = new StringWriter(); IOUtils.copy(stream.getStream(), writer, "UTF-8"); String actualContent = writer.toString(); assertEquals(expectedContent, actualContent); List<Document> allVersions = doc.getAllVersions(); assertEquals(2, allVersions.size()); assertEquals("2.0", allVersions.get(0).getVersionLabel()); assertEquals(CMIS_VERSION_10, allVersions.get(1).getVersionLabel()); } { // https://issues.alfresco.com/jira/browse/PUBLICAPI-95 // Test that documents are created with autoVersion=true Map<String, String> fileProps = new HashMap<String, String>(); { fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } { // a versioned document Document autoVersionedDoc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR); String objectId = autoVersionedDoc.getId(); String bareObjectId = getBareObjectId(objectId); final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, bareObjectId); Boolean autoVersion = TenantUtil.runAsUserTenant(new TenantRunAsWork<Boolean>() { @Override public Boolean doWork() throws Exception { Boolean autoVersion = (Boolean) repoService.getProperty(nodeRef, ContentModel.PROP_AUTO_VERSION); return autoVersion; } }, personId, network1.getId()); assertEquals(Boolean.TRUE, autoVersion); } // https://issues.alfresco.com/jira/browse/PUBLICAPI-92 // Test that a get on an objectId without a version suffix returns the current version of the document { // do a few checkout, checkin cycles to create some versions fileProps = new HashMap<String, String>(); { fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } Document autoVersionedDoc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR); String objectId = autoVersionedDoc.getId(); String bareObjectId = getBareObjectId(objectId); for (int i = 0; i < 3; i++) { Document doc1 = (Document) cmisSession.getObject(bareObjectId); ObjectId pwcId = doc1.checkOut(); Document pwc = (Document) cmisSession.getObject(pwcId.getId()); ContentStreamImpl contentStream = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); expectedContent = GUID.generate(); writer.putContent(expectedContent); ContentReader reader = writer.getReader(); contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); contentStream.setStream(reader.getContentInputStream()); } pwc.checkIn(true, Collections.EMPTY_MAP, contentStream, "checkin " + i); } // get the object, supplying an objectId without a version suffix Document doc1 = (Document) cmisSession.getObject(bareObjectId); String versionLabel = doc1.getVersionLabel(); ContentStream cs = doc1.getContentStream(); String content = IOUtils.toString(cs.getStream()); assertEquals("4.0", versionLabel); assertEquals(expectedContent, content); } } } /** * Tests CMIS and non-CMIS public api interactions */ @SuppressWarnings("deprecation") @Test public void testScenario1() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); Iterator<String> personIt = network1.getPersonIds().iterator(); final String person = personIt.next(); assertNotNull(person); Sites sitesProxy = publicApiClient.sites(); Comments commentsProxy = publicApiClient.comments(); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); ListResponse<MemberOfSite> sites = sitesProxy.getPersonSites(person, null); assertTrue(sites.getList().size() > 0); MemberOfSite siteMember = sites.getList().get(0); String siteId = siteMember.getSite().getSiteId(); Folder documentLibrary = (Folder) cmisSession.getObjectByPath("/Sites/" + siteId + "/documentLibrary"); System.out.println("documentLibrary id = " + documentLibrary.getId()); Map<String, String> fileProps = new HashMap<String, String>(); { fileProps.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); fileProps.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } Document doc = documentLibrary.createDocument(fileProps, fileContent, VersioningState.MAJOR); System.out.println("Document id = " + doc.getId()); Comment c = commentsProxy.createNodeComment(doc.getId(), new Comment("comment title 1", "comment 1")); System.out.println("Comment = " + c); // Now lock the document String nodeRefStr = (String) doc.getPropertyValue("alfcmis:nodeRef"); final NodeRef nodeRef = new NodeRef(nodeRefStr); final TenantRunAsWork<Void> runAsWork = new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { lockService.lock(nodeRef, LockType.WRITE_LOCK); return null; } }; RetryingTransactionCallback<Void> txnWork = new RetryingTransactionCallback<Void>() { @Override public Void execute() throws Throwable { TenantUtil.runAsUserTenant(runAsWork, "bob", network1.getId()); return null; } }; transactionHelper.doInTransaction(txnWork); // Now attempt to update the document's metadata try { doc.delete(); } catch (CmisUpdateConflictException e) { // Expected: ACE-762 BM-0012: NodeLockedException not handled by CMIS } } //@Test public void testInvalidMethods() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); Iterator<String> personIt = network1.getPersonIds().iterator(); final String person = personIt.next(); assertNotNull(person); try { publicApiClient.setRequestContext(new RequestContext(network1.getId(), person)); publicApiClient.post(Binding.atom, CMIS_VERSION_10, null, null); fail(); } catch (PublicApiException e) { assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode()); } try { publicApiClient.setRequestContext(new RequestContext(network1.getId(), person)); publicApiClient.head(Binding.atom, CMIS_VERSION_10, null, null); fail(); } catch (PublicApiException e) { assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode()); } try { publicApiClient.setRequestContext(new RequestContext(network1.getId(), person)); publicApiClient.options(Binding.atom, CMIS_VERSION_10, null, null); fail(); } catch (PublicApiException e) { assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode()); } try { publicApiClient.setRequestContext(new RequestContext(network1.getId(), person)); publicApiClient.trace(Binding.atom, CMIS_VERSION_10, null, null); fail(); } catch (PublicApiException e) { assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode()); } try { publicApiClient.setRequestContext(new RequestContext(network1.getId(), person)); publicApiClient.patch(Binding.atom, CMIS_VERSION_10, null, null); fail(); } catch (PublicApiException e) { assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, e.getHttpResponse().getStatusCode()); } } @Test public void testPublicApi110() throws Exception { Iterator<TestNetwork> networksIt = getTestFixture().networksIterator(); final TestNetwork network1 = networksIt.next(); Iterator<String> personIt = network1.getPersonIds().iterator(); final String person1Id = personIt.next(); final String person2Id = personIt.next(); final List<NodeRef> nodes = new ArrayList<NodeRef>(5); // Create some favourite targets, sites, files and folders TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { String siteName1 = "site" + GUID.generate(); SiteInformation siteInfo1 = new SiteInformation(siteName1, siteName1, siteName1, SiteVisibility.PUBLIC); TestSite site1 = network1.createSite(siteInfo1); String siteName2 = "site" + GUID.generate(); SiteInformation siteInfo2 = new SiteInformation(siteName2, siteName2, siteName2, SiteVisibility.PRIVATE); TestSite site2 = network1.createSite(siteInfo2); NodeRef nodeRef1 = repoService.createDocument( site1.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), "Test Doc1", "Test Doc1 Title", "Test Doc1 Description", "Test Content"); nodes.add(nodeRef1); NodeRef nodeRef2 = repoService.createDocument( site1.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), "Test Doc2", "Test Doc2 Title", "Test Doc2 Description", "Test Content"); nodes.add(nodeRef2); NodeRef nodeRef3 = repoService.createDocument( site2.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), "Test Doc2", "Test Doc2 Title", "Test Doc2 Description", "Test Content"); nodes.add(nodeRef3); repoService.createAssociation(nodeRef2, nodeRef1, ContentModel.ASSOC_ORIGINAL); repoService.createAssociation(nodeRef3, nodeRef1, ContentModel.ASSOC_ORIGINAL); site1.inviteToSite(person2Id, SiteRole.SiteCollaborator); return null; } }, person1Id, network1.getId()); { OperationContext cmisOperationCtxOverride = new OperationContextImpl(); cmisOperationCtxOverride.setIncludeRelationships(IncludeRelationships.BOTH); publicApiClient .setRequestContext(new RequestContext(network1.getId(), person2Id, cmisOperationCtxOverride)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); CmisObject o1 = cmisSession.getObject(nodes.get(0).getId()); List<Relationship> relationships = o1.getRelationships(); assertEquals(1, relationships.size()); Relationship r = relationships.get(0); CmisObject source = r.getSource(); CmisObject target = r.getTarget(); String sourceVersionSeriesId = (String) source.getProperty(PropertyIds.VERSION_SERIES_ID) .getFirstValue(); String targetVersionSeriesId = (String) target.getProperty(PropertyIds.VERSION_SERIES_ID) .getFirstValue(); assertEquals(nodes.get(1).getId(), sourceVersionSeriesId); assertEquals(nodes.get(0).getId(), targetVersionSeriesId); } } @Test public void testObjectIds() throws Exception { String username = "enterpriseuser" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person = repoService.createUser(personInfo, username, null); String personId = person.getId(); final List<NodeRef> folders = new ArrayList<NodeRef>(); final List<NodeRef> documents = new ArrayList<NodeRef>(); AuthenticationUtil.runAs(new RunAsWork<Void>() { @Override public Void doWork() throws Exception { String siteName = "site" + System.currentTimeMillis(); SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); folders.add(folderNodeRef); name = GUID.generate(); NodeRef docNodeRef = repoService.createDocument(folderNodeRef, name, "test content"); documents.add(docNodeRef); return null; } }, personId); NodeRef folderNodeRef = folders.get(0); NodeRef docNodeRef = documents.get(0); publicApiClient.setRequestContext(new RequestContext(personId)); // use cmisatom endpoint List<Repository> repositories = publicApiClient.getCMISRepositories(); CmisSession cmisSession = publicApiClient.getCMISSession(repositories.get(0)); // test CMIS accepts NodeRefs and guids as input // if input is NodeRef, return NodeRef. If input is guid, return guid. { String nodeRefStr = docNodeRef.toString(); CmisObject o = cmisSession.getObject(nodeRefStr); assertEquals(docNodeRef.toString(), stripCMISSuffix(o.getId())); nodeRefStr = folderNodeRef.toString(); o = cmisSession.getObject(nodeRefStr); assertEquals(folderNodeRef.toString(), stripCMISSuffix(o.getId())); String objectId = docNodeRef.getId(); o = cmisSession.getObject(objectId); assertEquals(objectId, stripCMISSuffix(o.getId())); objectId = folderNodeRef.getId(); o = cmisSession.getObject(objectId); assertEquals(objectId, stripCMISSuffix(o.getId())); } // query { // searching by NodeRef, expect result objectIds to be Noderefs Set<String> expectedObjectIds = new HashSet<String>(); expectedObjectIds.add(docNodeRef.toString()); int numMatchingDocs = 0; // NodeRef input List<CMISNode> results = cmisSession.query( "SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.toString() + "')", false, 0, Integer.MAX_VALUE); assertEquals(expectedObjectIds.size(), results.size()); for (CMISNode node : results) { String objectId = stripCMISSuffix((String) node.getProperties().get(PropertyIds.OBJECT_ID)); if (expectedObjectIds.contains(objectId)) { numMatchingDocs++; } } assertEquals(expectedObjectIds.size(), numMatchingDocs); // searching by guid, expect result objectIds to be NodeRefs numMatchingDocs = 0; // node guid input results = cmisSession.query( "SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.getId() + "')", false, 0, Integer.MAX_VALUE); assertEquals(expectedObjectIds.size(), results.size()); for (CMISNode node : results) { String objectId = stripCMISSuffix((String) node.getProperties().get(PropertyIds.OBJECT_ID)); System.out.println("objectId = " + objectId); if (expectedObjectIds.contains(objectId)) { numMatchingDocs++; } } assertEquals(expectedObjectIds.size(), numMatchingDocs); } // public api Iterator<TestNetwork> networksIt = getTestFixture().networksIterator(); final TestNetwork network1 = networksIt.next(); Iterator<String> personIt = network1.getPersonIds().iterator(); final String person1Id = personIt.next(); final List<NodeRef> folders1 = new ArrayList<NodeRef>(); final List<NodeRef> documents1 = new ArrayList<NodeRef>(); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { String siteName = "site" + System.currentTimeMillis(); SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); folders1.add(folderNodeRef); name = GUID.generate(); NodeRef docNodeRef = repoService.createDocument(folderNodeRef, name, "test content"); documents1.add(docNodeRef); return null; } }, person1Id, network1.getId()); folderNodeRef = folders1.get(0); docNodeRef = documents1.get(0); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); // test CMIS accepts NodeRefs and guids as input // objectIds returned from public api CMIS are always the guid { String nodeRefStr = docNodeRef.toString(); CmisObject o = cmisSession.getObject(nodeRefStr); String objectId = docNodeRef.getId(); assertEquals(objectId, stripCMISSuffix(o.getId())); nodeRefStr = folderNodeRef.toString(); o = cmisSession.getObject(nodeRefStr); objectId = folderNodeRef.getId(); assertEquals(objectId, stripCMISSuffix(o.getId())); o = cmisSession.getObject(objectId); assertEquals(objectId, stripCMISSuffix(o.getId())); objectId = folderNodeRef.getId(); o = cmisSession.getObject(objectId); assertEquals(objectId, stripCMISSuffix(o.getId())); } // query { // searching by NodeRef, expect result objectIds to be objectId Set<String> expectedObjectIds = new HashSet<String>(); expectedObjectIds.add(docNodeRef.getId()); int numMatchingDocs = 0; // NodeRef input List<CMISNode> results = cmisSession.query( "SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.toString() + "')", false, 0, Integer.MAX_VALUE); assertEquals(expectedObjectIds.size(), results.size()); for (CMISNode node : results) { String objectId = stripCMISSuffix((String) node.getProperties().get(PropertyIds.OBJECT_ID)); if (expectedObjectIds.contains(objectId)) { numMatchingDocs++; } } assertEquals(expectedObjectIds.size(), numMatchingDocs); // searching by guid, expect result objectIds to be objectId numMatchingDocs = 0; // node guid input results = cmisSession.query( "SELECT * FROM cmis:document WHERE IN_TREE('" + folderNodeRef.getId() + "')", false, 0, Integer.MAX_VALUE); assertEquals(expectedObjectIds.size(), results.size()); for (CMISNode node : results) { String objectId = stripCMISSuffix((String) node.getProperties().get(PropertyIds.OBJECT_ID)); System.out.println("objectId = " + objectId); if (expectedObjectIds.contains(objectId)) { numMatchingDocs++; } } assertEquals(expectedObjectIds.size(), numMatchingDocs); } } @Test public void testAspects() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final List<NodeRef> folders = new ArrayList<NodeRef>(); final List<NodeRef> documents = new ArrayList<NodeRef>(); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { String siteName = "site" + System.currentTimeMillis(); SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); folders.add(folderNodeRef); for (int i = 0; i < 3; i++) { name = GUID.generate(); NodeRef docNodeRef = repoService.createDocument(folderNodeRef, name, "test content"); assertFalse(repoService.getAspects(docNodeRef).contains(ContentModel.ASPECT_TITLED)); documents.add(docNodeRef); } return null; } }, person1Id, network1.getId()); final NodeRef doc1NodeRef = documents.get(0); final NodeRef doc2NodeRef = documents.get(1); final NodeRef doc3NodeRef = documents.get(2); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession atomCmisSession10 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); CmisSession atomCmisSession11 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); CmisSession browserCmisSession11 = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11); // Test that adding aspects works for both 1.0 and 1.1 // 1.0 { AlfrescoDocument doc = (AlfrescoDocument) atomCmisSession10.getObject(doc1NodeRef.getId()); doc = (AlfrescoDocument) doc.addAspect("P:cm:titled"); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc1NodeRef); assertTrue("Missing aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); return null; } }, person1Id, network1.getId()); doc.removeAspect("P:cm:titled"); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc1NodeRef); assertFalse("Unexpected aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); return null; } }, person1Id, network1.getId()); } // 1.1 atom (secondary types) { final Document doc = (Document) atomCmisSession11.getObject(doc2NodeRef.getId()); final List<SecondaryType> secondaryTypesList = doc.getSecondaryTypes(); final List<String> secondaryTypes = new ArrayList<String>(); if (secondaryTypesList != null) { for (SecondaryType secondaryType : secondaryTypesList) { secondaryTypes.add(secondaryType.getId()); } } secondaryTypes.add("P:sys:temporary"); secondaryTypes.add("P:cm:titled"); Map<String, Object> properties = new HashMap<String, Object>(); { // create a document with 2 secondary types properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); } Document doc1 = (Document) doc.updateProperties(properties); checkSecondaryTypes(doc1, new HashSet<String>(Arrays.asList(new String[] { "P:sys:temporary", "P:cm:titled" })), null); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc2NodeRef); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY)); return null; } }, person1Id, network1.getId()); secondaryTypes.add("P:cm:author"); properties = new HashMap<String, Object>(); { // create a document with 2 secondary types properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); } Document doc2 = (Document) doc1.updateProperties(properties); checkSecondaryTypes(doc2, new HashSet<String>( Arrays.asList(new String[] { "P:sys:temporary", "P:cm:titled", "P:cm:author" })), null); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc2NodeRef); String title = (String) repoService.getProperty(doc2NodeRef, ContentModel.PROP_TITLE); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); assertEquals(null, title); return null; } }, person1Id, network1.getId()); // remove a secondary type secondaryTypes.remove("P:cm:titled"); properties = new HashMap<String, Object>(); { properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); } Document doc3 = (Document) doc2.updateProperties(properties); checkSecondaryTypes(doc3, new HashSet<String>(Arrays.asList(new String[] { "P:sys:temporary", "P:cm:author" })), new HashSet<String>(Arrays.asList(new String[] { "P:cm:titled" }))); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc2NodeRef); String title = (String) repoService.getProperty(doc2NodeRef, ContentModel.PROP_TITLE); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY)); assertFalse("Unexpected aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); assertEquals(null, title); return null; } }, person1Id, network1.getId()); } // 1.1 browser (secondary types) { Document doc = (Document) browserCmisSession11.getObject(doc3NodeRef.getId()); final List<SecondaryType> secondaryTypesList = doc.getSecondaryTypes(); final List<String> secondaryTypes = new ArrayList<String>(); if (secondaryTypesList != null) { for (SecondaryType secondaryType : secondaryTypesList) { secondaryTypes.add(secondaryType.getId()); } } secondaryTypes.add("P:sys:temporary"); secondaryTypes.add("P:cm:titled"); Map<String, Object> properties = new HashMap<String, Object>(); { // create a document with 2 secondary types properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); } Document doc1 = (Document) doc.updateProperties(properties); checkSecondaryTypes(doc1, new HashSet<String>(Arrays.asList(new String[] { "P:sys:temporary", "P:cm:titled" })), null); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc3NodeRef); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY)); return null; } }, person1Id, network1.getId()); secondaryTypes.add("P:cm:author"); properties = new HashMap<String, Object>(); { // create a document with 2 secondary types properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); } Document doc2 = (Document) doc1.updateProperties(properties); checkSecondaryTypes(doc2, new HashSet<String>( Arrays.asList(new String[] { "P:sys:temporary", "P:cm:titled", "P:cm:author" })), null); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc3NodeRef); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR)); return null; } }, person1Id, network1.getId()); secondaryTypes.remove("P:cm:titled"); properties = new HashMap<String, Object>(); { // create a document with 2 secondary types properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); } Document doc3 = (Document) doc2.updateProperties(properties); checkSecondaryTypes(doc3, new HashSet<String>(Arrays.asList(new String[] { "P:sys:temporary", "P:cm:author" })), new HashSet<String>(Arrays.asList(new String[] { "P:cm:titled" }))); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { Set<QName> aspects = repoService.getAspects(doc3NodeRef); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_AUTHOR)); assertTrue("Missing aspects in current set " + aspects, aspects.contains(ContentModel.ASPECT_TEMPORARY)); assertFalse("Unexpected aspect in current set " + aspects, aspects.contains(ContentModel.ASPECT_TITLED)); return null; } }, person1Id, network1.getId()); } } /** * ALF-18968 * * @see QNameFilterImpl#listOfHardCodedExcludedTypes() */ @Test public void testTypeFiltering() throws Exception { // Force an exclusion in order to test the exclusion inheritance cmisTypeExclusions.setExcluded(ActionModel.TYPE_ACTION_BASE, true); // Quick check assertTrue(cmisTypeExclusions.isExcluded(ActionModel.TYPE_ACTION_BASE)); // Test that a type defined with this excluded parent type does not break the CMIS dictionary DictionaryBootstrap bootstrap = new DictionaryBootstrap(); List<String> bootstrapModels = new ArrayList<String>(); bootstrapModels.add("publicapi/test-model.xml"); bootstrap.setModels(bootstrapModels); bootstrap.setDictionaryDAO(dictionaryDAO); bootstrap.setTenantService(tenantService); bootstrap.bootstrap(); cmisDictionary.afterDictionaryInit(); final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); // test that this type is excluded; the 'action' model (act prefix) is in the list of hardcoded exclusions QName type = QName.createQName("{http://www.alfresco.org/test/testCMIS}type1"); assertTrue(cmisTypeExclusions.isExcluded(type)); // and that we can't get to it through CMIS publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); try { cmisSession.getTypeDefinition("D:testCMIS:type1"); fail("Type should not be available"); } catch (CmisObjectNotFoundException e) { // ok } } /** * MNT-12680 * The creation date of version should be the same as creation date of the original node * @throws Exception */ @Test public void testCreationDate() throws Exception { // create a site final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC); final TestSite site = network1.createSite(siteInfo); final NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"), "testdoc.txt", "Test Doc1 Title", "Test Doc1 Description", "Test Content"); return resNode; } }, person1Id, network1.getId()); // create a document publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); AlfrescoFolder docLibrary = (AlfrescoFolder) cmisSession .getObjectByPath("/Sites/" + siteName + "/documentLibrary"); Map<String, String> properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("some content"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } Document autoVersionedDoc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); String objectId = autoVersionedDoc.getId(); String bareObjectId = getBareObjectId(objectId); // create versions for (int i = 0; i < 3; i++) { Document doc1 = (Document) cmisSession.getObject(bareObjectId); ObjectId pwcId = doc1.checkOut(); Document pwc = (Document) cmisSession.getObject(pwcId.getId()); ContentStreamImpl contentStream = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent(GUID.generate()); ContentReader reader = writer.getReader(); contentStream.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); contentStream.setStream(reader.getContentInputStream()); } pwc.checkIn(true, Collections.EMPTY_MAP, contentStream, "checkin " + i); } GregorianCalendar cDateFirst = cmisSession.getAllVersions(bareObjectId).get(0).getCreationDate(); GregorianCalendar cDateSecond = cmisSession.getAllVersions(bareObjectId).get(2).getCreationDate(); if (cDateFirst.before(cDateSecond) || cDateFirst.after(cDateSecond)) { fail("The creation date of version should be the same as creation date of the original node"); } } /** * Test that updating properties does not automatically create a new version. * Test that updating content creates a new version automatically. * */ @Test public void testVersioning() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); AlfrescoFolder docLibrary = (AlfrescoFolder) cmisSession .getObjectByPath("/Sites/" + siteName + "/documentLibrary"); Map<String, String> properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } AlfrescoDocument doc = (AlfrescoDocument) docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); String versionLabel = doc.getVersionLabel(); // ...and check that updating its properties does not create a new version properties = new HashMap<String, String>(); { properties.put(PropertyIds.DESCRIPTION, GUID.generate()); } AlfrescoDocument doc1 = (AlfrescoDocument) doc.updateProperties(properties); doc1 = (AlfrescoDocument) doc1.getObjectOfLatestVersion(false); String versionLabel1 = doc1.getVersionLabel(); assertTrue(Float.parseFloat(versionLabel) < Float.parseFloat(versionLabel1)); // ...and check that updating its content creates a new version fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } doc1.setContentStream(fileContent, true); AlfrescoDocument doc2 = (AlfrescoDocument) doc1.getObjectOfLatestVersion(false); @SuppressWarnings("unused") String versionLabel2 = doc2.getVersionLabel(); assertTrue("Set content stream should create a new version automatically", Float.parseFloat(versionLabel1) < Float.parseFloat(versionLabel2)); } /** * Test that updating properties does automatically create a new version if * <b>autoVersion</b>, <b>initialVersion</b> and <b>autoVersionOnUpdateProps</b> are TRUE */ @Test public void testVersioningUsingUpdateProperties() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService.createFolder(site.getContainerNodeRef("documentLibrary"), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, "1.0", AlfrescoObjectFactoryImpl.class.getName()); AlfrescoFolder docLibrary = (AlfrescoFolder) cmisSession .getObjectByPath("/Sites/" + siteName + "/documentLibrary"); Map<String, String> properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document"); properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } AlfrescoDocument doc = (AlfrescoDocument) docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); String versionLabel = doc.getVersionLabel(); String nodeRefStr = doc.getPropertyValue(NodeRefProperty.NodeRefPropertyId).toString(); final NodeRef nodeRef = new NodeRef(nodeRefStr); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { // ensure autoversioning is enabled assertTrue(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE)); Map<QName, Serializable> versionProperties = new HashMap<QName, Serializable>(); versionProperties.put(ContentModel.PROP_AUTO_VERSION, true); versionProperties.put(ContentModel.PROP_INITIAL_VERSION, true); versionProperties.put(ContentModel.PROP_AUTO_VERSION_PROPS, true); nodeService.addProperties(nodeRef, versionProperties); return null; } }, person1Id, network1.getId()); // ...and check that updating its properties creates a new minor version... properties = new HashMap<String, String>(); { properties.put(PropertyIds.DESCRIPTION, GUID.generate()); } AlfrescoDocument doc1 = (AlfrescoDocument) doc.getObjectOfLatestVersion(false).updateProperties(properties); doc1 = (AlfrescoDocument) doc.getObjectOfLatestVersion(false); String versionLabel1 = doc1.getVersionLabel(); assertTrue(Double.parseDouble(versionLabel) < Double.parseDouble(versionLabel1)); // ...and check that updating its content creates a new version fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } doc1.setContentStream(fileContent, true); AlfrescoDocument doc2 = (AlfrescoDocument) doc1.getObjectOfLatestVersion(false); String versionLabel2 = doc2.getVersionLabel(); assertTrue("Set content stream should create a new version automatically", Double.parseDouble(versionLabel1) < Double.parseDouble(versionLabel2)); assertTrue("It should be latest version : " + versionLabel2, doc2.isLatestVersion()); doc2.deleteContentStream(); AlfrescoDocument doc3 = (AlfrescoDocument) doc2.getObjectOfLatestVersion(false); String versionLabel3 = doc3.getVersionLabel(); assertTrue("Delete content stream should create a new version automatically", Double.parseDouble(versionLabel1) < Double.parseDouble(versionLabel3)); assertTrue("It should be latest version : " + versionLabel3, doc3.isLatestVersion()); } /** * 1) Creating a file with incorrect char in description property * 2) Get xml with incorrect char in description * 3) Check xml * @throws Exception */ @Test public void testGetXmlWithIncorrectDesctiption() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); NodeRef fileNode = TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC); final TestSite site = network1.createSite(siteInfo); NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"), "testdoc \u0010.txt", "Test Doc1 Title \u0010", "d\u0010", "Test Content"); return resNode; } }, person1Id, network1.getId()); String cmisId = fileNode.getId(); HashMap<String, String> reqParams = new HashMap<String, String>(); reqParams.put("id", cmisId + ";1.0"); reqParams.put("filter", "*"); reqParams.put("includeAllowableActions", "true"); reqParams.put("includeACL", "true"); reqParams.put("includePolicyIds", "true"); reqParams.put("includeRelationships", "both"); reqParams.put("renditionFilter", "*"); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); HttpResponse resp = publicApiClient.get(Binding.atom, CMIS_VERSION_11, "id", reqParams); String xml = resp.getResponse(); // Response hasn't full info at error - writer just stops at incorrect character. // Therefore we can check end tag of root element assertTrue("No end tag was found", xml.endsWith("</atom:entry>")); } /** * 1) Creating a file with currency symbols in the name, title and description (MNT-15044) * 2) Get the document with correct chars in the properties. * @throws Exception */ @Test public void testGetXmlWithCorrectCurrencySymbols() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, "password", null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); NodeRef fileNode = TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PUBLIC); final TestSite site = network1.createSite(siteInfo); NodeRef resNode = repoService.createDocument(site.getContainerNodeRef("documentLibrary"), "Euro \u20AC Pound \u00A3 Franc \u20A3.txt", "Euro \u20AC Pound \u00A3 Franc \u20A3 File", "\u20A3 \u00A3 \u20A3", "\u20A3 \u00A3 \u20A3"); return resNode; } }, person1Id, network1.getId()); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession atomCmisSession10 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); String objectId = fileNode.getId(); Document doc = (Document) atomCmisSession10.getObject(objectId); String name = (String) doc.getProperty(PropertyIds.NAME).getFirstValue(); String title = (String) doc.getProperty("cm:title").getFirstValue(); String description = (String) doc.getProperty("cm:description").getFirstValue(); assertEquals("Euro \u20AC Pound \u00A3 Franc \u20A3.txt", name); assertEquals("Euro \u20AC Pound \u00A3 Franc \u20A3 File", title); assertEquals("\u20A3 \u00A3 \u20A3", description); } /* * Test that creating a document with a number of initial aspects does not create lots of initial versions */ @Test public void testALF19320() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); AlfrescoFolder docLibrary = (AlfrescoFolder) cmisSession .getObjectByPath("/Sites/" + siteName + "/documentLibrary"); Map<String, String> properties = new HashMap<String, String>(); { // create a document with 2 aspects properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document,P:cm:titled,P:cm:author"); properties.put(PropertyIds.NAME, "mydoc-" + GUID.generate() + ".txt"); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } AlfrescoDocument doc = (AlfrescoDocument) docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); String versionLabel = doc.getVersionLabel(); assertEquals(CMIS_VERSION_10, versionLabel); AlfrescoDocument doc1 = (AlfrescoDocument) doc.getObjectOfLatestVersion(false); String versionLabel1 = doc1.getVersionLabel(); assertEquals(CMIS_VERSION_10, versionLabel1); } /* MNT-10175 test */ @Test public void testAppendContentVersioning() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); // Use CMIS 1.1 to test content appending CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Folder docLibrary = (Folder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary"); String name = GUID.generate() + ".txt"; Map<String, String> properties = new HashMap<String, String>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, name); } // Create content to append ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); String versionLabel1 = doc.getObjectOfLatestVersion(false).getVersionLabel(); // append a few times for (int i = 0; i < 5; i++) { doc.appendContentStream(fileContent, false); } String versionLabel2 = doc.getObjectOfLatestVersion(false).getVersionLabel(); // Version label should not be incremented by appending with isLustChunk = false assertEquals(versionLabel1, versionLabel2); doc.appendContentStream(fileContent, true); String versionLabel3 = doc.getObjectOfLatestVersion(false).getVersionLabel(); Integer majorVer1 = Integer.valueOf(versionLabel2.substring(0, 1)); Integer majorVer2 = Integer.valueOf(versionLabel3.substring(0, 1)); Integer minorVer1 = Integer.valueOf(versionLabel2.substring(2, 3)); Integer minorVer2 = Integer.valueOf(versionLabel3.substring(2, 3)); // Only one MINOR version should be created assertEquals(majorVer1, majorVer2); assertEquals(Integer.valueOf(minorVer1 + 1), minorVer2); } @Test public void testAppendContentStream() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Folder docLibrary = (Folder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary"); String name = "mydoc-" + GUID.generate() + ".txt"; Map<String, String> properties = new HashMap<String, String>(); { // create a document with 2 aspects properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, name); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); // append a few times for (int i = 0; i < 5; i++) { fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter( TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } doc.appendContentStream(fileContent, false); } fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } doc.appendContentStream(fileContent, true); // check the appends String path = "/Sites/" + siteName + "/documentLibrary/" + name; Document doc1 = (Document) cmisSession.getObjectByPath(path); ContentStream contentStream = doc1.getContentStream(); InputStream in = contentStream.getStream(); StringWriter writer = new StringWriter(); IOUtils.copy(in, writer, "UTF-8"); String content = writer.toString(); assertEquals( "Ipsum and so onIpsum and so onIpsum and so onIpsum and so onIpsum and so onIpsum and so onIpsum and so on", content); } @Test public void testSecondaryTypes() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Folder docLibrary = (Folder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary"); String name = "mydoc-" + GUID.generate() + ".txt"; final List<String> secondaryTypes = new ArrayList<String>(); secondaryTypes.add("P:cm:summarizable"); Map<String, Object> properties = new HashMap<String, Object>(); { // create a document with 2 aspects properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.SECONDARY_OBJECT_TYPE_IDS, secondaryTypes); properties.put("cm:summary", "My summary"); properties.put(PropertyIds.NAME, name); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); { // check that the secondary types and properties are present { checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null); String summary = (String) doc.getProperty("cm:summary").getFirstValue(); assertEquals("My summary", summary); } { doc = (Document) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary/" + name); checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null); String summary = (String) doc.getProperty("cm:summary").getFirstValue(); assertEquals("My summary", summary); } } // update property and check { properties = new HashMap<String, Object>(); { properties.put("cm:summary", "My updated summary"); } doc.updateProperties(properties); { doc = (Document) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary/" + name); checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null); String summary = (String) doc.getProperty("cm:summary").getFirstValue(); assertEquals("My updated summary", summary); } { checkSecondaryTypes(doc, Collections.singleton("P:cm:summarizable"), null); String summary = (String) doc.getProperty("cm:summary").getFirstValue(); assertEquals("My updated summary", summary); } } } /* MNT-10161 related test - mapping of cmis:description for CMIS 1.1 */ @Test public void testMNT_10161() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); final String nodeDescription = "Test description"; final String nodeName = GUID.generate(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), nodeName); /* create node with property description */ return repoService.createDocument(folderNodeRef, nodeName, "title", nodeDescription, "content"); } }, person1Id, network1.getId()); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Document doc = (Document) cmisSession .getObjectByPath("/Sites/" + siteName + "/documentLibrary/" + nodeName + "/" + nodeName); /* ensure we got the node */ assertNotNull(doc); /* get mapped cmis:description */ Property<?> descrProperty = doc.getProperty(PropertyIds.DESCRIPTION); /* ensure that cmis:description is set properly */ assertTrue(nodeDescription.equals(descrProperty.getValue())); } /* MNT-10687 related test - appendContent to PWC CMIS 1.1 */ @Test public void testMNT_10687() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Folder docLibrary = (Folder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary"); String name = "mydoc-" + GUID.generate() + ".txt"; Map<String, Object> properties = new HashMap<String, Object>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, name); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } /* Create document */ Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); /* Checkout document */ ObjectId pwcId = doc.checkOut(); Document pwc = (Document) cmisSession.getObject(pwcId.getId()); /* append content to PWC */ fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent(" and so on"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } pwc.appendContentStream(fileContent, true); pwc.checkIn(false, null, null, "Check In"); ContentStream contentStream = doc.getObjectOfLatestVersion(false).getContentStream(); InputStream in = contentStream.getStream(); StringWriter writer = new StringWriter(); IOUtils.copy(in, writer, "UTF-8"); String content = writer.toString(); assertEquals("Ipsum and so on", content); } @Test public void testMNT_13057() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); String guid = GUID.generate(); String name = guid + "_KRUIS_LOGO_100%_PMS.txt"; String urlFileName = guid + "_KRUIS_LOGO_100%25_PMS.txt"; final String siteName = "site" + System.currentTimeMillis(); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, person1Id, network1.getId()); // Create a document... publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Folder docLibrary = (Folder) cmisSession.getObjectByPath("/Sites/" + siteName + "/documentLibrary"); Map<String, Object> properties = new HashMap<String, Object>(); { properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, name); } ContentStreamImpl fileContent = new ContentStreamImpl(); { ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(GUID.generate(), ".txt")); writer.putContent("Ipsum"); ContentReader reader = writer.getReader(); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(reader.getContentInputStream()); } /* Create document */ Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); String id = doc.getId(); assertNotNull(id); Map<String, String> params = new HashMap<String, String>(); params.put("id", URLEncoder.encode(id)); urlFileName += "?id=" + URLEncoder.encode(id); HttpResponse response = publicApiClient .get(network1.getId() + "/public/cmis/versions/1.1/atom/content/" + urlFileName, null); assertEquals(200, response.getStatusCode()); } @Test public void testMNT10430() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person1 = network1.createUser(personInfo); String person1Id = person1.getId(); publicApiClient.setRequestContext(new RequestContext(network1.getId(), person1Id)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.browser, CMIS_VERSION_11, "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl"); ObjectType objectType = cmisSession.getTypeDefinition("D:testcmis:maDoc"); // try and get the mandatory aspects List<String> mandatoryAspects = ((AlfrescoType) objectType).getMandatoryAspects(); System.out.println("Mandatory Aspects"); for (String mandatoryAspect : mandatoryAspects) { System.out.println(mandatoryAspect); } assertTrue("The aspects should have P:cm:generalclassifiable", mandatoryAspects.contains("P:cm:generalclassifiable")); } @Test public void testMnt11631() throws Exception { final TestNetwork network = getTestFixture().getRandomNetwork(); String username = String.format(TEST_USER_NAME_PATTERN, System.currentTimeMillis()); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person = network.createUser(personInfo); String personId = person.getId(); final String siteName = String.format(TEST_SITE_NAME_PATTERN, System.currentTimeMillis()); TenantUtil.runAsUserTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); String name = GUID.generate(); NodeRef folderNodeRef = repoService .createFolder(site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), name); return folderNodeRef; } }, personId, network.getId()); publicApiClient.setRequestContext(new RequestContext(network.getId(), personId)); CmisSession cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); Folder docLibrary = (Folder) cmisSession .getObjectByPath(String.format(DOCUMENT_LIBRARY_PATH_PATTERN, siteName)); String name = String.format(TEST_DOCUMENT_NAME_PATTERN, GUID.generate()); Map<String, Object> properties = new HashMap<String, Object>(); properties.put(PropertyIds.OBJECT_TYPE_ID, TYPE_CMIS_DOCUMENT); properties.put(PropertyIds.NAME, name); ContentStreamImpl fileContent = new ContentStreamImpl(); ByteArrayInputStream stream = new ByteArrayInputStream(GUID.generate().getBytes()); fileContent.setMimeType(MimetypeMap.MIMETYPE_TEXT_PLAIN); fileContent.setStream(stream); Document doc = docLibrary.createDocument(properties, fileContent, VersioningState.MAJOR); ObjectId pwcId = doc.checkOut(); Document pwc = (Document) cmisSession.getObject(pwcId.getId()); assertIsPwcProperty(pwc, false); cmisSession = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10); CmisObject pwc10 = cmisSession.getObject(pwc.getId()); assertIsPwcProperty(pwc10, true); } private void assertIsPwcProperty(CmisObject pwc, boolean nullExpected) { boolean isPwcFound = false; Boolean isPwcValueTrue = null; for (Property<?> property : pwc.getProperties()) { if ((null != property) && PropertyIds.IS_PRIVATE_WORKING_COPY.equals(property.getId())) { isPwcFound = true; isPwcValueTrue = property.getValue(); break; } } if (nullExpected) { assertTrue(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property is not null!"), !isPwcFound || (null == isPwcValueTrue)); return; } assertTrue(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property has not been found!"), isPwcFound); assertNotNull(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property value must not be null!"), isPwcValueTrue); assertTrue(("'" + PropertyIds.IS_PRIVATE_WORKING_COPY + "' property value must be equal to 'true'!"), isPwcValueTrue); } @Test public void testCanConnectCMISUsingDefaultTenant() throws Exception { testCanConnectCMISUsingDefaultTenantImpl(Binding.atom, CMIS_VERSION_11); testCanConnectCMISUsingDefaultTenantImpl(Binding.atom, CMIS_VERSION_10); testCanConnectCMISUsingDefaultTenantImpl(Binding.browser, CMIS_VERSION_11); } private void testCanConnectCMISUsingDefaultTenantImpl(Binding binding, String cmisVersion) { String url = httpClient.getPublicApiCmisUrl(TenantUtil.DEFAULT_TENANT, binding, cmisVersion, null); Map<String, String> parameters = new HashMap<String, String>(); // user credentials parameters.put(SessionParameter.USER, "admin"); parameters.put(SessionParameter.PASSWORD, "admin"); parameters.put(SessionParameter.ATOMPUB_URL, url); parameters.put(SessionParameter.BROWSER_URL, url); parameters.put(SessionParameter.BINDING_TYPE, binding.getOpenCmisBinding().value()); SessionFactory factory = SessionFactoryImpl.newInstance(); // perform request : http://host:port/alfresco/api/-default-/public/cmis/versions/${cmisVersion}/${binding} List<Repository> repositories = factory.getRepositories(parameters); assertTrue(repositories.size() > 0); parameters.put(SessionParameter.REPOSITORY_ID, TenantUtil.DEFAULT_TENANT); Session session = factory.createSession(parameters); // perform request : http://host:port/alfresco/api/-default-/public/cmis/versions/${cmisVersion}/${binding}/type?id=cmis:document ObjectType objectType = session.getTypeDefinition("cmis:document"); assertNotNull(objectType); } @Test public void testACE3433() throws Exception { final TestNetwork network = getTestFixture().getRandomNetwork(); NodeRef rootNodeRef = TenantUtil.runAsSystemTenant(new TenantRunAsWork<NodeRef>() { @Override public NodeRef doWork() throws Exception { NodeRef rootNodeRef = repoService.getNodeService() .getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); List<ChildAssociationRef> childAssocs = repoService.getNodeService() .getChildAssocsByPropertyValue(rootNodeRef, ContentModel.PROP_TITLE, "Company Home"); assertEquals(1, childAssocs.size()); NodeRef companyHomeNodeRef = childAssocs.get(0).getChildRef(); return companyHomeNodeRef; } }, network.getId()); assertNotNull(rootNodeRef); // atom { Binding binding = Binding.atom; String url = httpClient.getPublicApiCmisUrl(TenantUtil.DEFAULT_TENANT, binding, "1.1", null); Map<String, String> parameters = new HashMap<String, String>(); // user credentials parameters.put(SessionParameter.USER, "admin@" + network.getId()); parameters.put(SessionParameter.PASSWORD, "admin"); parameters.put(SessionParameter.ATOMPUB_URL, url); parameters.put(SessionParameter.BINDING_TYPE, binding.getOpenCmisBinding().value()); SessionFactory factory = SessionFactoryImpl.newInstance(); Repository repository = factory.getRepositories(parameters).get(0); String rootFolderId = repository.getRootFolderId(); assertEquals(rootNodeRef.getId(), rootFolderId); } { Binding binding = Binding.browser; String url = httpClient.getPublicApiCmisUrl(TenantUtil.DEFAULT_TENANT, binding, "1.1", null); Map<String, String> parameters = new HashMap<String, String>(); // user credentials parameters.put(SessionParameter.USER, "admin@" + network.getId()); parameters.put(SessionParameter.PASSWORD, "admin"); parameters.put(SessionParameter.BROWSER_URL, url); parameters.put(SessionParameter.BINDING_TYPE, binding.getOpenCmisBinding().value()); SessionFactory factory = SessionFactoryImpl.newInstance(); Repository repository = factory.getRepositories(parameters).get(0); String rootFolderId = repository.getRootFolderId(); assertEquals(rootNodeRef.getId(), rootFolderId); } } @Test public void testMNT12956QueryingCMIS11UsesDictionary11() throws Exception { final TestNetwork network1 = getTestFixture().getRandomNetwork(); String username = "user" + System.currentTimeMillis(); PersonInfo personInfo = new PersonInfo(username, username, username, TEST_PASSWORD, null, null, null, null, null, null, null); TestPerson person = network1.createUser(personInfo); String personId = person.getId(); final List<NodeRef> documents = new ArrayList<NodeRef>(); final String filename = GUID.generate(); TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>() { @Override public Void doWork() throws Exception { String siteName = "site" + System.currentTimeMillis(); SiteInformation siteInfo = new SiteInformation(siteName, siteName, siteName, SiteVisibility.PRIVATE); TestSite site = repoService.createSite(null, siteInfo); NodeRef docNodeRef = repoService.createDocument( site.getContainerNodeRef(DOCUMENT_LIBRARY_CONTAINER_NAME), filename, "test content"); documents.add(docNodeRef); return null; } }, personId, network1.getId()); NodeRef docNodeRef = documents.get(0); publicApiClient.setRequestContext(new RequestContext(network1.getId(), personId)); CmisSession atomCmisSession10 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_10, AlfrescoObjectFactoryImpl.class.getName()); CmisSession atomCmisSession11 = publicApiClient.createPublicApiCMISSession(Binding.atom, CMIS_VERSION_11); // query { // searching by NodeRef, expect result objectIds to be objectId Set<String> expectedObjectIds = new HashSet<String>(); expectedObjectIds.add(docNodeRef.getId()); int numMatchingDocs = 0; // NodeRef input List<CMISNode> results = atomCmisSession11.query( "SELECT cmis:objectId,cmis:name,cmis:secondaryObjectTypeIds FROM cmis:document WHERE cmis:name LIKE '" + filename + "'", false, 0, Integer.MAX_VALUE); assertEquals(expectedObjectIds.size(), results.size()); for (CMISNode node : results) { String objectId = stripCMISSuffix((String) node.getProperties().get(PropertyIds.OBJECT_ID)); if (expectedObjectIds.contains(objectId)) { numMatchingDocs++; } } assertEquals(expectedObjectIds.size(), numMatchingDocs); try { results = atomCmisSession10.query( "SELECT cmis:objectId,cmis:name,cmis:secondaryObjectTypeIds FROM cmis:document WHERE cmis:name LIKE '" + filename + "'", false, 0, Integer.MAX_VALUE); fail("OpenCMIS 1.0 knows nothing about cmis:secondaryObjectTypeIds"); } catch (CmisInvalidArgumentException expectedException) { // ok } } } }