/* * Copyright (C) 2005 Alfresco, Inc. * * Licensed under the Mozilla Public License version 1.1 * with a permitted attribution clause. You may obtain a * copy of the License at * * http://www.alfresco.org/legal/license.txt * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the * License. */ package org.alfresco.repo.rule; import java.io.File; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.transaction.UserTransaction; import junit.framework.TestCase; import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ActionServiceImplTest; import org.alfresco.repo.action.ActionServiceImplTest.AsyncTest; import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; import org.alfresco.repo.action.evaluator.InCategoryEvaluator; import org.alfresco.repo.action.evaluator.NoConditionEvaluator; import org.alfresco.repo.action.executer.AddFeaturesActionExecuter; import org.alfresco.repo.action.executer.CheckInActionExecuter; import org.alfresco.repo.action.executer.CheckOutActionExecuter; import org.alfresco.repo.action.executer.CopyActionExecuter; import org.alfresco.repo.action.executer.ImageTransformActionExecuter; import org.alfresco.repo.action.executer.LinkCategoryActionExecuter; import org.alfresco.repo.action.executer.MailActionExecuter; import org.alfresco.repo.action.executer.MoveActionExecuter; import org.alfresco.repo.action.executer.SimpleWorkflowActionExecuter; import org.alfresco.repo.action.executer.TransformActionExecuter; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.content.transform.ContentTransformerRegistry; import org.alfresco.repo.dictionary.DictionaryDAO; import org.alfresco.repo.dictionary.M2Aspect; import org.alfresco.repo.dictionary.M2Model; import org.alfresco.repo.dictionary.M2Property; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.transaction.TransactionUtil; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionCondition; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.coci.CheckOutCheckInService; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockStatus; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.rule.Rule; import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.rule.RuleServiceException; import org.alfresco.service.cmr.rule.RuleType; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.transaction.TransactionService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.util.StopWatch; /** * @author Roy Wetherall */ public class RuleServiceCoverageTest extends TestCase { /** * Application context used during the test */ static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:alfresco/application-context.xml"); /** * Services used during the tests */ private TransactionService transactionService; private RuleService ruleService; private NodeService nodeService; private StoreRef testStoreRef; private NodeRef rootNodeRef; private NodeRef nodeRef; private CheckOutCheckInService cociService; private LockService lockService; private ContentService contentService; private ServiceRegistry serviceRegistry; private DictionaryDAO dictionaryDAO; private ActionService actionService; private ContentTransformerRegistry transformerRegistry; private CopyService copyService; private AuthenticationComponent authenticationComponent; /** * Category related values */ private static final String TEST_NAMESPACE = "http://www.alfresco.org/test/rulesystemtest"; private static final QName CAT_PROP_QNAME = QName.createQName(TEST_NAMESPACE, "region"); private QName regionCategorisationQName; private NodeRef catContainer; private NodeRef catRoot; private NodeRef catRBase; private NodeRef catROne; private NodeRef catRTwo; @SuppressWarnings("unused") private NodeRef catRThree; /** * Standard content text */ private static final String STANDARD_TEXT_CONTENT = "standardTextContent"; /** * Setup method */ @Override protected void setUp() throws Exception { // Get the required services this.serviceRegistry = (ServiceRegistry)applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY); this.nodeService = serviceRegistry.getNodeService(); this.ruleService = serviceRegistry.getRuleService(); this.cociService = serviceRegistry.getCheckOutCheckInService(); this.lockService = serviceRegistry.getLockService(); this.copyService = serviceRegistry.getCopyService(); this.contentService = serviceRegistry.getContentService(); this.dictionaryDAO = (DictionaryDAO)applicationContext.getBean("dictionaryDAO"); this.actionService = serviceRegistry.getActionService(); this.transactionService = serviceRegistry.getTransactionService(); this.transformerRegistry = (ContentTransformerRegistry)applicationContext.getBean("contentTransformerRegistry"); this.authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent"); //authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); //authenticationComponent.setSystemUserAsCurrentUser(); authenticationComponent.setCurrentUser("admin"); this.testStoreRef = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis()); this.rootNodeRef = this.nodeService.getRootNode(this.testStoreRef); // Create the node used for tests this.nodeRef = this.nodeService.createNode( this.rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTAINER).getChildRef(); } private Rule createRule( String ruleTypeName, String actionName, Map actionParams, String conditionName, Map conditionParams) { Rule rule = new Rule(); rule.setRuleType(ruleTypeName); Action action = this.actionService.createAction(actionName, actionParams); ActionCondition condition = this.actionService.createActionCondition(conditionName, conditionParams); action.addActionCondition(condition); rule.setAction(action); return rule; } /** * Create the categories used in the tests */ private void createTestCategories() { // Create the test model M2Model model = M2Model.createModel("test:rulecategory"); model.createNamespace(TEST_NAMESPACE, "test"); model.createImport(NamespaceService.DICTIONARY_MODEL_1_0_URI, "d"); model.createImport(NamespaceService.CONTENT_MODEL_1_0_URI, NamespaceService.CONTENT_MODEL_PREFIX); // Create the region category regionCategorisationQName = QName.createQName(TEST_NAMESPACE, "Region"); M2Aspect generalCategorisation = model.createAspect("test:" + regionCategorisationQName.getLocalName()); generalCategorisation.setParentName("cm:" + ContentModel.ASPECT_CLASSIFIABLE.getLocalName()); M2Property genCatProp = generalCategorisation.createProperty("test:region"); genCatProp.setIndexed(true); genCatProp.setIndexedAtomically(true); genCatProp.setMandatory(true); genCatProp.setMultiValued(false); genCatProp.setStoredInIndex(true); genCatProp.setTokenisedInIndex(true); genCatProp.setType("d:" + DataTypeDefinition.CATEGORY.getLocalName()); // Save the mode dictionaryDAO.putModel(model); // Create the category value container and root catContainer = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "categoryContainer"), ContentModel.TYPE_CONTAINER).getChildRef(); catRoot = nodeService.createNode(catContainer, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "categoryRoot"), ContentModel.TYPE_CATEGORYROOT).getChildRef(); // Create the category values catRBase = nodeService.createNode(catRoot, ContentModel.ASSOC_CATEGORIES, QName.createQName(TEST_NAMESPACE, "Region"), ContentModel.TYPE_CATEGORY).getChildRef(); catROne = nodeService.createNode(catRBase, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "Europe"), ContentModel.TYPE_CATEGORY).getChildRef(); catRTwo = nodeService.createNode(catRBase, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "RestOfWorld"), ContentModel.TYPE_CATEGORY).getChildRef(); catRThree = nodeService.createNode(catRTwo, ContentModel.ASSOC_SUBCATEGORIES, QName.createQName(TEST_NAMESPACE, "US"), ContentModel.TYPE_CATEGORY).getChildRef(); } /** * Asynchronous rule tests */ /** * Check async rule execution */ public void testAsyncRuleExecution() { final NodeRef newNodeRef = TransactionUtil.executeInUserTransaction( this.transactionService, new TransactionUtil.TransactionWork() { public NodeRef doWork() { RuleServiceCoverageTest.this.nodeService.addAspect( RuleServiceCoverageTest.this.nodeRef, ContentModel.ASPECT_LOCKABLE, null); Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); rule.setExecuteAsynchronously(true); RuleServiceCoverageTest.this.ruleService.saveRule(RuleServiceCoverageTest.this.nodeRef, rule); NodeRef newNodeRef = RuleServiceCoverageTest.this.nodeService.createNode( RuleServiceCoverageTest.this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); return newNodeRef; } }); ActionServiceImplTest.postAsyncActionTest( this.transactionService, 1000, 10, new AsyncTest() { public boolean executeTest() { return RuleServiceCoverageTest.this.nodeService.hasAspect( newNodeRef, ContentModel.ASPECT_VERSIONABLE); }; }); } // TODO check compensating action execution /** * Standard rule coverage tests */ /** * Test: * rule type: inbound * condition: no-condition() * action: add-features( * aspect-name = versionable) */ public void testAddFeaturesAction() { this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null); Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); Map params2 = new HashMap(2); params2.put(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ApplicationModel.ASPECT_SIMPLE_WORKFLOW); params2.put(ApplicationModel.PROP_APPROVE_STEP.toString(), "approveStep"); params2.put(ApplicationModel.PROP_APPROVE_MOVE.toString(), false); // Test that rule can be updated and execute correctly //rule.removeAllActions(); Action action2 = this.actionService.createAction(AddFeaturesActionExecuter.NAME, params2); rule.setAction(action2); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef2); assertTrue(this.nodeService.hasAspect(newNodeRef2, ApplicationModel.ASPECT_SIMPLE_WORKFLOW)); assertEquals("approveStep", this.nodeService.getProperty(newNodeRef2, ApplicationModel.PROP_APPROVE_STEP)); assertEquals(false, this.nodeService.getProperty(newNodeRef2, ApplicationModel.PROP_APPROVE_MOVE)); // System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } public void testDisableIndividualRules() { Map params = new HashMap(1); params.put("aspect-name", ApplicationModel.ASPECT_CONFIGURABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); rule.setRuleDisabled(true); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); assertFalse(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_CONFIGURABLE)); Rule rule2 = this.ruleService.getRule(rule.getNodeRef()); rule2.setRuleDisabled(false); this.ruleService.saveRule(this.nodeRef, rule2); // Re-try the test now the rule has been re-enabled NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef2); assertTrue(this.nodeService.hasAspect(newNodeRef2, ApplicationModel.ASPECT_CONFIGURABLE)); } public void testDisableRule() { this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null); Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); this.ruleService.disableRule(rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); this.ruleService.enableRule(rule); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef2); assertTrue(this.nodeService.hasAspect(newNodeRef2, ContentModel.ASPECT_VERSIONABLE)); } public void testAddFeaturesToAFolder() { Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_TEMPLATABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_FOLDER).getChildRef(); assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_TEMPLATABLE)); // System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } public void testCopyFolderToTriggerRules() { // Create the folders and content NodeRef copyToFolder = this.nodeService.createNode( this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}copyToFolder"), ContentModel.TYPE_FOLDER).getChildRef(); NodeRef folderToCopy = this.nodeService.createNode( this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}folderToCopy"), ContentModel.TYPE_FOLDER).getChildRef(); NodeRef contentToCopy = this.nodeService.createNode( folderToCopy, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}contentToCopy"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(contentToCopy); Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_TEMPLATABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); rule.applyToChildren(true); this.ruleService.saveRule(copyToFolder, rule); // Copy the folder in order to try and trigger the rule NodeRef copiedFolder = this.copyService.copy(folderToCopy, copyToFolder, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}coppiedFolder"), true); assertNotNull(copiedFolder); // Check that the rule has been applied to the copied folder and content assertTrue(this.nodeService.hasAspect(copiedFolder, ContentModel.ASPECT_TEMPLATABLE)); for (ChildAssociationRef childAssoc : this.nodeService.getChildAssocs(copiedFolder)) { assertTrue(this.nodeService.hasAspect(childAssoc.getChildRef(), ContentModel.ASPECT_TEMPLATABLE)); } //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } private Map getContentProperties() { // Map properties = new HashMap(1); // properties.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); return null; } /** * Test: * rule type: inbound * condition: no-condition * action: simple-workflow */ public void testSimpleWorkflowAction() { this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null); Map params = new HashMap(1); params.put(SimpleWorkflowActionExecuter.PARAM_APPROVE_STEP, "approveStep"); params.put(SimpleWorkflowActionExecuter.PARAM_APPROVE_FOLDER, this.rootNodeRef); params.put(SimpleWorkflowActionExecuter.PARAM_APPROVE_MOVE, true); params.put(SimpleWorkflowActionExecuter.PARAM_REJECT_STEP, "rejectStep"); params.put(SimpleWorkflowActionExecuter.PARAM_REJECT_FOLDER, this.rootNodeRef); params.put(SimpleWorkflowActionExecuter.PARAM_REJECT_MOVE, false); Rule rule = createRule( RuleType.INBOUND, SimpleWorkflowActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); assertTrue(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_SIMPLE_WORKFLOW)); assertEquals("approveStep", this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_STEP)); assertEquals(this.rootNodeRef, this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_FOLDER)); assertTrue(((Boolean)this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_APPROVE_MOVE)).booleanValue()); assertTrue(this.nodeService.hasAspect(newNodeRef, ApplicationModel.ASPECT_SIMPLE_WORKFLOW)); assertEquals("rejectStep", this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_STEP)); assertEquals(this.rootNodeRef, this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_FOLDER)); assertFalse(((Boolean)this.nodeService.getProperty(newNodeRef, ApplicationModel.PROP_REJECT_MOVE)).booleanValue()); // System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } /** * Test: * rule type: inbound * condition: in-category * action: add-feature */ public void testInCategoryCondition() { // Create categories used in tests createTestCategories(); try { Map params = new HashMap(1); params.put(InCategoryEvaluator.PARAM_CATEGORY_ASPECT, this.regionCategorisationQName); params.put(InCategoryEvaluator.PARAM_CATEGORY_VALUE, this.catROne); Map params2 = new HashMap(1); params2.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params2, InCategoryEvaluator.NAME, params); this.ruleService.saveRule(this.nodeRef, rule); // Check rule does not get fired when a node without the aspect is added NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "noAspect"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef2); assertFalse(this.nodeService.hasAspect(newNodeRef2, ContentModel.ASPECT_VERSIONABLE)); // Check rule gets fired when node contains category value UserTransaction tx = transactionService.getUserTransaction(); tx.begin(); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "hasAspectAndValue"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); Map catProps = new HashMap(); catProps.put(CAT_PROP_QNAME, this.catROne); this.nodeService.addAspect(newNodeRef, this.regionCategorisationQName, catProps); tx.commit(); assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Check rule does not get fired when the node has the incorrect category value UserTransaction tx3 = transactionService.getUserTransaction(); tx3.begin(); NodeRef newNodeRef3 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "hasAspectAndValue"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef3); Map catProps3 = new HashMap(); catProps3.put(CAT_PROP_QNAME, this.catRTwo); this.nodeService.addAspect(newNodeRef3, this.regionCategorisationQName, catProps3); tx3.commit(); assertFalse(this.nodeService.hasAspect(newNodeRef3, ContentModel.ASPECT_VERSIONABLE)); //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } catch (Exception exception) { throw new RuntimeException(exception); } } /** * Test: * rule type: inbound * condition: no-condition * action: link-category */ public void testLinkCategoryAction() { // Create categories used in tests createTestCategories(); Map params = new HashMap(1); params.put(LinkCategoryActionExecuter.PARAM_CATEGORY_ASPECT, this.regionCategorisationQName); params.put(LinkCategoryActionExecuter.PARAM_CATEGORY_VALUE, this.catROne); Rule rule = createRule( RuleType.INBOUND, LinkCategoryActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "noAspect"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef2); // Check that the category value has been set NodeRef setValue = (NodeRef)this.nodeService.getProperty(newNodeRef2, CAT_PROP_QNAME); assertNotNull(setValue); assertEquals(this.catROne, setValue); } /** * Test: * rule type: inbound * condition: no-condition * action: mail * * Note: this test will be removed from the standard list since it is not currently automated */ public void xtestMailAction() { this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null); Map params = new HashMap(1); params.put(MailActionExecuter.PARAM_TO, "alfresco.test@gmail.com"); params.put(MailActionExecuter.PARAM_SUBJECT, "Unit test"); params.put(MailActionExecuter.PARAM_TEXT, "This is a test to check that the mail action is working."); Rule rule = createRule( RuleType.INBOUND, MailActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); // An email should appear in the recipients email // System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } /** * Test: * rule type: inbound * condition: no-condition() * action: copy() */ public void testCopyAction() { Map params = new HashMap(1); params.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.rootNodeRef); params.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CHILDREN); params.put(MoveActionExecuter.PARAM_ASSOC_QNAME, QName.createQName(TEST_NAMESPACE, "copy")); Rule rule = createRule( RuleType.INBOUND, CopyActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "origional"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); // Check that the created node is still there List origRefs = this.nodeService.getChildAssocs( this.nodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "origional")); assertNotNull(origRefs); assertEquals(1, origRefs.size()); NodeRef origNodeRef = origRefs.get(0).getChildRef(); assertEquals(newNodeRef, origNodeRef); // Check that the created node has been copied List copyChildAssocRefs = this.nodeService.getChildAssocs( this.rootNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "copy")); assertNotNull(copyChildAssocRefs); // ********************************** // NOTE: Changed expected result to get build running // ********************************** assertEquals(1, copyChildAssocRefs.size()); NodeRef copyNodeRef = copyChildAssocRefs.get(0).getChildRef(); assertTrue(this.nodeService.hasAspect(copyNodeRef, ContentModel.ASPECT_COPIEDFROM)); NodeRef source = (NodeRef)this.nodeService.getProperty(copyNodeRef, ContentModel.PROP_COPY_REFERENCE); assertEquals(newNodeRef, source); // TODO test deep copy !! } /** * Test: * rule type: inbound * condition: no-condition() * action: transform() */ public void testTransformAction() { if (this.transformerRegistry.getTransformer(MimetypeMap.MIMETYPE_EXCEL, MimetypeMap.MIMETYPE_TEXT_PLAIN) != null) { try { Map params = new HashMap(1); params.put(TransformActionExecuter.PARAM_MIME_TYPE, MimetypeMap.MIMETYPE_TEXT_PLAIN); params.put(TransformActionExecuter.PARAM_DESTINATION_FOLDER, this.rootNodeRef); params.put(TransformActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CHILDREN); params.put(TransformActionExecuter.PARAM_ASSOC_QNAME, QName.createQName(TEST_NAMESPACE, "transformed")); Rule rule = createRule( RuleType.INBOUND, TransformActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); UserTransaction tx = transactionService.getUserTransaction(); tx.begin(); Map props =new HashMap(1); props.put(ContentModel.PROP_NAME, "test.xls"); // Create the node at the root NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "origional"), ContentModel.TYPE_CONTENT, props).getChildRef(); // Set some content on the origional ContentWriter contentWriter = this.contentService.getWriter(newNodeRef, ContentModel.PROP_CONTENT, true); contentWriter.setMimetype(MimetypeMap.MIMETYPE_EXCEL); File testFile = AbstractContentTransformerTest.loadQuickTestFile("xls"); contentWriter.putContent(testFile); tx.commit(); //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent"); authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); // Check that the created node is still there List origRefs = this.nodeService.getChildAssocs( this.nodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "origional")); assertNotNull(origRefs); assertEquals(1, origRefs.size()); NodeRef origNodeRef = origRefs.get(0).getChildRef(); assertEquals(newNodeRef, origNodeRef); // Check that the created node has been copied List copyChildAssocRefs = this.nodeService.getChildAssocs( this.rootNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "transformed")); assertNotNull(copyChildAssocRefs); assertEquals(1, copyChildAssocRefs.size()); NodeRef copyNodeRef = copyChildAssocRefs.get(0).getChildRef(); assertTrue(this.nodeService.hasAspect(copyNodeRef, ContentModel.ASPECT_COPIEDFROM)); NodeRef source = (NodeRef)this.nodeService.getProperty(copyNodeRef, ContentModel.PROP_COPY_REFERENCE); assertEquals(newNodeRef, source); // Check the transformed content ContentData contentData = (ContentData) nodeService.getProperty(copyNodeRef, ContentModel.PROP_CONTENT); assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentData.getMimetype()); } catch (Exception exception) { throw new RuntimeException(exception); } } } /** * Test image transformation * */ public void testImageTransformAction() { if (this.transformerRegistry.getTransformer(MimetypeMap.MIMETYPE_IMAGE_GIF, MimetypeMap.MIMETYPE_IMAGE_JPEG) != null) { try { Map params = new HashMap(1); params.put(ImageTransformActionExecuter.PARAM_DESTINATION_FOLDER, this.rootNodeRef); params.put(ImageTransformActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CHILDREN); params.put(TransformActionExecuter.PARAM_MIME_TYPE, MimetypeMap.MIMETYPE_IMAGE_JPEG); params.put(ImageTransformActionExecuter.PARAM_ASSOC_QNAME, QName.createQName(TEST_NAMESPACE, "transformed")); params.put(ImageTransformActionExecuter.PARAM_CONVERT_COMMAND, "-negate"); Rule rule = createRule( RuleType.INBOUND, ImageTransformActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); UserTransaction tx = transactionService.getUserTransaction(); tx.begin(); Map props =new HashMap(1); props.put(ContentModel.PROP_NAME, "test.gif"); // Create the node at the root NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "origional"), ContentModel.TYPE_CONTENT, props).getChildRef(); // Set some content on the origional ContentWriter contentWriter = this.contentService.getWriter(newNodeRef, ContentModel.PROP_CONTENT, true); contentWriter.setMimetype(MimetypeMap.MIMETYPE_IMAGE_GIF); File testFile = AbstractContentTransformerTest.loadQuickTestFile("gif"); contentWriter.putContent(testFile); tx.commit(); //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); // Check that the created node is still there List origRefs = this.nodeService.getChildAssocs( this.nodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "origional")); assertNotNull(origRefs); assertEquals(1, origRefs.size()); NodeRef origNodeRef = origRefs.get(0).getChildRef(); assertEquals(newNodeRef, origNodeRef); // Check that the created node has been copied List copyChildAssocRefs = this.nodeService.getChildAssocs( this.rootNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "transformed")); assertNotNull(copyChildAssocRefs); assertEquals(1, copyChildAssocRefs.size()); NodeRef copyNodeRef = copyChildAssocRefs.get(0).getChildRef(); assertTrue(this.nodeService.hasAspect(copyNodeRef, ContentModel.ASPECT_COPIEDFROM)); NodeRef source = (NodeRef)this.nodeService.getProperty(copyNodeRef, ContentModel.PROP_COPY_REFERENCE); assertEquals(newNodeRef, source); } catch (Exception exception) { throw new RuntimeException(exception); } } } /** * Test: * rule type: inbound * condition: no-condition() * action: move() */ public void testMoveAction() { Map params = new HashMap(1); params.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.rootNodeRef); params.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CHILDREN); params.put(MoveActionExecuter.PARAM_ASSOC_QNAME, QName.createQName(TEST_NAMESPACE, "copy")); Rule rule = createRule( RuleType.INBOUND, MoveActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "origional"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); // Check that the created node has been moved List origRefs = this.nodeService.getChildAssocs( this.nodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "origional")); assertNotNull(origRefs); assertEquals(0, origRefs.size()); // Check that the created node is in the new location List copyChildAssocRefs = this.nodeService.getChildAssocs( this.rootNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(TEST_NAMESPACE, "copy")); assertNotNull(copyChildAssocRefs); assertEquals(1, copyChildAssocRefs.size()); NodeRef movedNodeRef = copyChildAssocRefs.get(0).getChildRef(); assertEquals(newNodeRef, movedNodeRef); } /** * Test: * rule type: inbound * condition: no-condition() * action: checkout() */ public void testCheckOutAction() { Rule rule = createRule( RuleType.INBOUND, CheckOutActionExecuter.NAME, null, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); NodeRef newNodeRef = null; UserTransaction tx = this.transactionService.getUserTransaction(); try { tx.begin(); // Create a new node newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "checkout"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); tx.commit(); } catch (Exception exception) { throw new RuntimeException(exception); } //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); // Check that the new node has been checked out List children = this.nodeService.getChildAssocs(this.nodeRef); assertNotNull(children); assertEquals(3, children.size()); // includes rule folder for (ChildAssociationRef child : children) { NodeRef childNodeRef = child.getChildRef(); if (childNodeRef.equals(newNodeRef) == true) { // check that the node has been locked LockStatus lockStatus = this.lockService.getLockStatus(childNodeRef); assertEquals(LockStatus.LOCK_OWNER, lockStatus); } else if (this.nodeService.hasAspect(childNodeRef, ContentModel.ASPECT_WORKING_COPY) == true) { // assert that it is the working copy that relates to the origional node NodeRef copiedFromNodeRef = (NodeRef)this.nodeService.getProperty(childNodeRef, ContentModel.PROP_COPY_REFERENCE); assertEquals(newNodeRef, copiedFromNodeRef); } } } /** * Test: * rule type: inbound * condition: no-condition() * action: checkin() */ @SuppressWarnings("unchecked") public void testCheckInAction() { Map params = new HashMap(1); params.put(CheckInActionExecuter.PARAM_DESCRIPTION, "The version description."); Rule rule = createRule( RuleType.INBOUND, CheckInActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); List list = TransactionUtil.executeInUserTransaction( this.transactionService, new TransactionUtil.TransactionWork>() { public List doWork() { // Create a new node and check-it out NodeRef newNodeRef = RuleServiceCoverageTest.this.nodeService.createNode( RuleServiceCoverageTest.this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "origional"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); NodeRef workingCopy = RuleServiceCoverageTest.this.cociService.checkout(newNodeRef); // Move the working copy into the actionable folder RuleServiceCoverageTest.this.nodeService.moveNode( workingCopy, RuleServiceCoverageTest.this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "moved")); List result = new ArrayList(); result.add(newNodeRef); result.add(workingCopy); return result; } }); // Check that the working copy has been removed assertFalse(this.nodeService.exists(list.get(1))); // Check that the origional is no longer locked assertEquals(LockStatus.NO_LOCK, this.lockService.getLockStatus(list.get(0))); //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); } /** * Check that the rules can be enabled and disabled */ public void testRulesDisabled() { Map actionParams = new HashMap(1); actionParams.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, actionParams, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); this.ruleService.disableRules(this.nodeRef); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef); assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); this.ruleService.enableRules(this.nodeRef); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef2); assertTrue(this.nodeService.hasAspect(newNodeRef2, ContentModel.ASPECT_VERSIONABLE)); } /** * Adds content to a given node. *

* Used to trigger rules of type of incomming. * * @param nodeRef the node reference */ private void addContentToNode(NodeRef nodeRef) { ContentWriter contentWriter = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); contentWriter.setEncoding("UTF-8"); assertNotNull(contentWriter); contentWriter.putContent(STANDARD_TEXT_CONTENT + System.currentTimeMillis()); } /** * Test checkMandatoryProperties method */ public void testCheckMandatoryProperties() { Map actionParams = new HashMap(1); actionParams.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Map condParams = new HashMap(1); // should be setting the condition parameter here Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, actionParams, ComparePropertyValueEvaluator.NAME, condParams); this.ruleService.saveRule(this.nodeRef, rule); try { // Try and create a node .. should fail since the rule is invalid Map props2 = getContentProperties(); props2.put(ContentModel.PROP_NAME, "bobbins.doc"); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, props2).getChildRef(); addContentToNode(newNodeRef2); fail("An exception should have been thrown since a mandatory parameter was missing from the condition."); } catch (Throwable ruleServiceException) { // Success since we where expecting the exception } } /** * Test: * rule type: inbound * condition: match-text( * text = .doc, * operation = CONTAINS) * action: add-features( * aspect-name = versionable) */ public void testContainsTextCondition() { Map actionParams = new HashMap(1); actionParams.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); // ActionCondition parameter's Map condParams = new HashMap(1); condParams.put(ComparePropertyValueEvaluator.PARAM_VALUE, ".doc"); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, actionParams, ComparePropertyValueEvaluator.NAME, condParams); this.ruleService.saveRule(this.nodeRef, rule); // Test condition failure Map props1 = new HashMap(); props1.put(ContentModel.PROP_NAME, "bobbins.txt"); // props1.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, props1).getChildRef(); addContentToNode(newNodeRef); //Map map = this.nodeService.getProperties(newNodeRef); //String value = (String)this.nodeService.getProperty(newNodeRef, ContentModel.PROP_NAME); assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Test condition success Map props2 = new HashMap(); props2.put(ContentModel.PROP_NAME, "bobbins.doc"); //props2.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, props2).getChildRef(); addContentToNode(newNodeRef2); assertTrue(this.nodeService.hasAspect( newNodeRef2, ContentModel.ASPECT_VERSIONABLE)); try { // Test name not set NodeRef newNodeRef3 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, getContentProperties()).getChildRef(); addContentToNode(newNodeRef3); } catch (RuleServiceException exception) { // Correct since text-match is a mandatory property } // Test begins with Map condParamsBegins = new HashMap(1); condParamsBegins.put(ComparePropertyValueEvaluator.PARAM_VALUE, "bob*"); rule.getAction().removeAllActionConditions(); ActionCondition condition1 = this.actionService.createActionCondition(ComparePropertyValueEvaluator.NAME, condParamsBegins); rule.getAction().addActionCondition(condition1); this.ruleService.saveRule(this.nodeRef, rule); Map propsx = new HashMap(); propsx.put(ContentModel.PROP_NAME, "mybobbins.doc"); //propsx.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); NodeRef newNodeRefx = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, propsx).getChildRef(); addContentToNode(newNodeRefx); assertFalse(this.nodeService.hasAspect(newNodeRefx, ContentModel.ASPECT_VERSIONABLE)); Map propsy = new HashMap(); propsy.put(ContentModel.PROP_NAME, "bobbins.doc"); //propsy.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); NodeRef newNodeRefy = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, propsy).getChildRef(); addContentToNode(newNodeRefy); assertTrue(this.nodeService.hasAspect( newNodeRefy, ContentModel.ASPECT_VERSIONABLE)); // Test ends with Map condParamsEnds = new HashMap(1); condParamsEnds.put(ComparePropertyValueEvaluator.PARAM_VALUE, "*s.doc"); rule.getAction().removeAllActionConditions(); ActionCondition condition2 = this.actionService.createActionCondition(ComparePropertyValueEvaluator.NAME, condParamsEnds); rule.getAction().addActionCondition(condition2); this.ruleService.saveRule(this.nodeRef, rule); Map propsa = new HashMap(); propsa.put(ContentModel.PROP_NAME, "bobbins.document"); // propsa.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); NodeRef newNodeRefa = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, propsa).getChildRef(); addContentToNode(newNodeRefa); assertFalse(this.nodeService.hasAspect(newNodeRefa, ContentModel.ASPECT_VERSIONABLE)); Map propsb = new HashMap(); propsb.put(ContentModel.PROP_NAME, "bobbins.doc"); //propsb.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT); NodeRef newNodeRefb = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT, propsb).getChildRef(); addContentToNode(newNodeRefb); assertTrue(this.nodeService.hasAspect( newNodeRefb, ContentModel.ASPECT_VERSIONABLE)); } public void testInboundRuleType() { Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); // Create a non-content node NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTAINER).getChildRef(); assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Create a content node NodeRef contentNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT).getChildRef(); assertFalse(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); addContentToNode(contentNodeRef); assertTrue(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Create a node to be moved NodeRef moveNode = this.nodeService.createNode( newNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT).getChildRef(); addContentToNode(moveNode); assertFalse(this.nodeService.hasAspect(moveNode, ContentModel.ASPECT_VERSIONABLE)); this.nodeService.moveNode( moveNode, this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children")); assertTrue(this.nodeService.hasAspect(moveNode, ContentModel.ASPECT_VERSIONABLE)); // Enusre the rule type does not get fired when the node is updated this.nodeService.removeAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE); assertFalse(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); this.nodeService.setProperty(contentNodeRef, ContentModel.PROP_NAME, "name.txt"); assertFalse(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); addContentToNode(contentNodeRef); assertFalse(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); } public void testUpdateRuleType() { Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.UPDATE, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); // Create a non-content node NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_FOLDER).getChildRef(); assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Update the non-content node this.nodeService.setProperty(newNodeRef, ContentModel.PROP_NAME, "testName"); assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Create a content node NodeRef contentNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTENT).getChildRef(); assertFalse(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); addContentToNode(contentNodeRef); assertFalse(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); addContentToNode(contentNodeRef); assertTrue(this.nodeService.hasAspect(contentNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Create a non content node, setting a property at the same time Map props = new HashMap(1); props.put(ContentModel.PROP_NAME, "testName"); NodeRef nodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_FOLDER, props).getChildRef(); assertFalse(this.nodeService.hasAspect(nodeRef2, ContentModel.ASPECT_VERSIONABLE)); this.nodeService.setProperty(nodeRef2, ContentModel.PROP_NAME, "testName"); assertFalse(this.nodeService.hasAspect(nodeRef2, ContentModel.ASPECT_VERSIONABLE)); this.nodeService.setProperty(nodeRef2, ContentModel.PROP_NAME, "testName2"); assertTrue(this.nodeService.hasAspect(nodeRef2, ContentModel.ASPECT_VERSIONABLE)); TransactionUtil.executeInUserTransaction(this.transactionService, new TransactionUtil.TransactionWork() { public Object doWork() throws Exception { Map props = new HashMap(1); props.put(ContentModel.PROP_NAME, "testName"); NodeRef nodeRef3 = RuleServiceCoverageTest.this.nodeService.createNode( RuleServiceCoverageTest.this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_FOLDER, props).getChildRef(); assertFalse(RuleServiceCoverageTest.this.nodeService.hasAspect(nodeRef3, ContentModel.ASPECT_VERSIONABLE)); RuleServiceCoverageTest.this.nodeService.setProperty(nodeRef3, ContentModel.PROP_NAME, "testName2"); assertFalse(RuleServiceCoverageTest.this.nodeService.hasAspect(nodeRef3, ContentModel.ASPECT_VERSIONABLE)); return null; } }); } /** * Test: * rule type: outbound * condition: no-condition() * action: add-features( * aspect-name = versionable) */ public void testOutboundRuleType() { this.nodeService.addAspect(this.nodeRef, ContentModel.ASPECT_LOCKABLE, null); Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( "outbound", AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); // Create a node NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTAINER).getChildRef(); assertFalse(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Move the node out of the actionable folder this.nodeService.moveNode( newNodeRef, this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children")); assertTrue(this.nodeService.hasAspect(newNodeRef, ContentModel.ASPECT_VERSIONABLE)); // Check the deletion of a node //System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.testStoreRef)); NodeRef newNodeRef2 = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTAINER).getChildRef(); this.nodeService.deleteNode(newNodeRef2); } /** * Performance guideline test * */ public void xtestPerformanceOfRuleExecution() { try { StopWatch sw = new StopWatch(); // Create actionable nodes sw.start("create nodes with no rule executed"); UserTransaction userTransaction1 = this.transactionService.getUserTransaction(); userTransaction1.begin(); for (int i = 0; i < 100; i++) { this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS, ContentModel.TYPE_CONTAINER).getChildRef(); assertFalse(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE)); } userTransaction1.commit(); sw.stop(); Map params = new HashMap(1); params.put("aspect-name", ContentModel.ASPECT_VERSIONABLE); Rule rule = createRule( RuleType.INBOUND, AddFeaturesActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); this.ruleService.saveRule(this.nodeRef, rule); sw.start("create nodes with one rule run (apply versionable aspect)"); UserTransaction userTransaction2 = this.transactionService.getUserTransaction(); userTransaction2.begin(); NodeRef[] nodeRefs = new NodeRef[100]; for (int i = 0; i < 100; i++) { NodeRef nodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "children"), ContentModel.TYPE_CONTAINER).getChildRef(); addContentToNode(nodeRef); nodeRefs[i] = nodeRef; // Check that the versionable aspect has not yet been applied assertFalse(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE)); } userTransaction2.commit(); sw.stop(); // Check that the versionable aspect has been applied to all the created nodes for (NodeRef ref : nodeRefs) { assertTrue(this.nodeService.hasAspect(ref, ContentModel.ASPECT_VERSIONABLE)); } System.out.println(sw.prettyPrint()); } catch (Exception exception) { throw new RuntimeException(exception); } } public void testAsyncExecutionWithPotentialLoop() { if (this.transformerRegistry.getTransformer(MimetypeMap.MIMETYPE_EXCEL, MimetypeMap.MIMETYPE_TEXT_PLAIN) != null) { try { Map params = new HashMap(1); params.put(TransformActionExecuter.PARAM_MIME_TYPE, MimetypeMap.MIMETYPE_TEXT_PLAIN); params.put(TransformActionExecuter.PARAM_DESTINATION_FOLDER, this.nodeRef); params.put(TransformActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS); params.put(TransformActionExecuter.PARAM_ASSOC_QNAME, QName.createQName(TEST_NAMESPACE, "transformed")); Rule rule = createRule( RuleType.INBOUND, TransformActionExecuter.NAME, params, NoConditionEvaluator.NAME, null); rule.setExecuteAsynchronously(true); rule.setTitle("Transform document to text"); UserTransaction tx0 = transactionService.getUserTransaction(); tx0.begin(); this.ruleService.saveRule(this.nodeRef, rule); tx0.commit(); UserTransaction tx = transactionService.getUserTransaction(); tx.begin(); Map props =new HashMap(1); props.put(ContentModel.PROP_NAME, "test.xls"); // Create the node at the root NodeRef newNodeRef = this.nodeService.createNode( this.nodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(TEST_NAMESPACE, "origional"), ContentModel.TYPE_CONTENT, props).getChildRef(); // Set some content on the origional ContentWriter contentWriter = this.contentService.getWriter(newNodeRef, ContentModel.PROP_CONTENT, true); contentWriter.setMimetype(MimetypeMap.MIMETYPE_EXCEL); File testFile = AbstractContentTransformerTest.loadQuickTestFile("xls"); contentWriter.putContent(testFile); tx.commit(); // Sleep to ensure work is done b4 execution is canceled Thread.sleep(10000); } catch (Exception exception) { throw new RuntimeException(exception); } } } }