/* * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * * 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 . */ package org.alfresco.repo.version; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockStatus; import org.alfresco.service.cmr.lock.LockType; import org.alfresco.service.cmr.repository.ContentService; 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.search.ResultSet; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.version.VersionType; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ApplicationContextHelper; import org.springframework.context.ApplicationContext; /** * @author Dmitry Velichkevich */ public class VersionableAspectTest extends TestCase { private static final String NAME_AND_EXT_DELIMETER = "."; private static final String NAME_AND_EXT_DELIMETER_REGEXP = "\\" + NAME_AND_EXT_DELIMETER; private static final String ADMIN_CREDENTIAL = "admin"; private static final String ROOT_NODE_TERM = "PATH:\"/app\\:company_home\""; private static final String DOCUMENT_NAME = "ChildDocumentWithVersionLabel-.txt"; private static final String PARENT_FOLDER_NAME = "ParentFolder-" + System.currentTimeMillis(); private static final String TEST_CONTENT_01 = "Test Content version 0.1\n"; private static final String TEST_CONTENT_10 = "Test Content version 1.0\n"; private ApplicationContext applicationContext = ApplicationContextHelper.getApplicationContext(); private NodeService nodeService = (NodeService) applicationContext.getBean("nodeService"); private LockService lockService = (LockService) applicationContext.getBean("lockService"); private SearchService searchService = (SearchService) applicationContext.getBean("searchService"); private ContentService contentService = (ContentService) applicationContext.getBean("contentService"); private TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionService"); private CheckOutCheckInService checkOutCheckInService = (CheckOutCheckInService) applicationContext.getBean("checkOutCheckInService"); private AuthenticationService authenticationService = (AuthenticationService) applicationContext.getBean("authenticationService"); private NodeRef document; private NodeRef parentFolder; @Override protected void setUp() throws Exception { transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { authenticationService.authenticate(ADMIN_CREDENTIAL, ADMIN_CREDENTIAL.toCharArray()); ResultSet query = null; NodeRef rootNode = null; try { query = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, ROOT_NODE_TERM); rootNode = query.getNodeRef(0); } finally { if (null != query) { query.close(); } } Map properties = new HashMap(); properties.put(ContentModel.PROP_NAME, PARENT_FOLDER_NAME); parentFolder = nodeService.createNode(rootNode, ContentModel.ASSOC_CONTAINS, QName.createQName(ContentModel.USER_MODEL_URI, PARENT_FOLDER_NAME), ContentModel.TYPE_FOLDER, properties).getChildRef(); properties.clear(); properties.put(ContentModel.PROP_NAME, DOCUMENT_NAME); document = nodeService.createNode(parentFolder, ContentModel.ASSOC_CONTAINS, QName.createQName(ContentModel.USER_MODEL_URI, DOCUMENT_NAME), ContentModel.TYPE_CONTENT, properties).getChildRef(); contentService.getWriter(document, ContentModel.PROP_CONTENT, true).putContent(TEST_CONTENT_01); if (!nodeService.hasAspect(document, ContentModel.ASPECT_VERSIONABLE)) { Map versionProperties = new HashMap(); versionProperties.put(ContentModel.PROP_VERSION_LABEL, "0.1"); versionProperties.put(ContentModel.PROP_INITIAL_VERSION, true); versionProperties.put(ContentModel.PROP_VERSION_TYPE, VersionType.MINOR); nodeService.addAspect(document, ContentModel.ASPECT_VERSIONABLE, versionProperties); } return null; } }); } @Override protected void tearDown() throws Exception { transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { if (null != parentFolder) { nodeService.deleteNode(parentFolder); } authenticationService.clearCurrentSecurityContext(); return null; } }); } public void testAutoVersionIncrementOnPropertiesUpdateAfterCheckInAlf14584() throws Exception { final String name02 = generateDocumentName(DOCUMENT_NAME, "0.2"); final String name11 = generateDocumentName(DOCUMENT_NAME, "1.1"); transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { Map properties = getAndAssertProperties(document, "0.1"); Serializable autoVersionProps = properties.get(ContentModel.PROP_AUTO_VERSION_PROPS); assertNotNull(("Autoversion property is NULL! NodeRef = '" + document.toString() + "'"), autoVersionProps); assertTrue(("Autoversion must be TRUE! NodeRef = '" + document.toString() + "'"), (Boolean) autoVersionProps); nodeService.setProperty(document, ContentModel.PROP_NAME, name02); return null; } }); transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { Map properties = getAndAssertProperties(document, "0.2"); assertEquals(name02, properties.get(ContentModel.PROP_NAME)); NodeRef workingCopy = checkOutCheckInService.checkout(document); contentService.getWriter(workingCopy, ContentModel.PROP_CONTENT, true).putContent(TEST_CONTENT_10); Map versionProperties = new HashMap(); versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR); document = checkOutCheckInService.checkin(workingCopy, versionProperties); return null; } }); assertDocumentVersionAndName("1.0", name02); transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { nodeService.setProperty(document, ContentModel.PROP_NAME, name11); return null; } }); assertDocumentVersionAndName("1.1", name11); } public void testAutoVersionIncrementOnPropertiesUpdateByLockOwnerAlf14584() throws Exception { final String name = generateDocumentName(DOCUMENT_NAME, "0.2"); transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { Map properties = getAndAssertProperties(document, "0.1"); Serializable autoVersionProps = properties.get(ContentModel.PROP_AUTO_VERSION_PROPS); assertNotNull(("Autoversion property is NULL! NodeRef = '" + document.toString() + "'"), autoVersionProps); assertTrue(("Autoversion must be TRUE! NodeRef = '" + document.toString() + "'"), (Boolean) autoVersionProps); lockService.lock(document, LockType.WRITE_LOCK); LockStatus lockStatus = lockService.getLockStatus(document); assertFalse( ("Node with NodeRef = '" + document.toString() + "' must not be locked for " + AuthenticationUtil.getFullyAuthenticatedUser() + " user! The user is lock owner"), isLocked(document)); assertEquals(LockStatus.LOCK_OWNER, lockService.getLockStatus(document)); nodeService.setProperty(document, ContentModel.PROP_NAME, name); return null; } }); assertDocumentVersionAndName("0.2", name); } // Copy of code from VersionableAspect which really should be in LockService private boolean isLocked(NodeRef nodeRef) { LockStatus lockStatus = lockService.getLockStatus(nodeRef); return (LockStatus.NO_LOCK != lockStatus) && (LockStatus.LOCK_OWNER != lockStatus); } private void assertDocumentVersionAndName(final String versionLabel, final String name) { transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() { @Override public Void execute() throws Throwable { Map properties = getAndAssertProperties(document, versionLabel); assertEquals(name, properties.get(ContentModel.PROP_NAME)); return null; } }, true); } private Map getAndAssertProperties(NodeRef nodeRef, String versionLabel) { assertNotNull("NodeRef of document is NULL!", nodeRef); Map properties = nodeService.getProperties(nodeRef); assertNotNull(("Properties must not be NULL! NodeRef = '" + nodeRef.toString() + "'"), properties); assertFalse(("Version specific properties can't be found! NodeRef = '" + nodeRef.toString() + "'"), properties.isEmpty()); assertEquals(versionLabel, properties.get(ContentModel.PROP_VERSION_LABEL)); return properties; } private String generateDocumentName(String namePattern, String versionLabel) { int i = 0; String[] nameAndExt = namePattern.split(NAME_AND_EXT_DELIMETER_REGEXP); StringBuilder result = new StringBuilder(nameAndExt[i++]).append(versionLabel).append(NAME_AND_EXT_DELIMETER).append(nameAndExt[i++]); return result.toString(); } }