Merged DEV (5.1) to HEAD (5.1)

117318: ACE-4421: Minor tweak (JavaDoc comment + fix boolean),
   117293: ACE-4421: Custom behaviours cannot be disabled (using disableBehaviour(QName))
      - Changed the ClassBehaviourIndex#find as the main logic is handled by BehaviourFilterImpl#isEnabled
      - Updated the BehaviourFilter interface accordingly.,
   115822: ACE-4421: Custom behaviours cannot be disabled (using disableBehaviour(QName))
      - Reworked the solution to use only one new method: disable(QName className, boolean includeSubClasses)
      - Modified the isEnabled(QName className) to correspond with the new logic
      - Modified the JUnit tests.,
   115078: ACE-4421: Minor tweak (JavaDoc comment + fix boolean),
   115071: ACE-4421: Custom behaviours cannot be disabled (using disableBehaviour(QName))
      - Added new API for disabling behaviours.
      - Added JUnit tests.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@117981 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Alex Mukha
2015-11-18 17:13:08 +00:00
parent e657c5b5fc
commit c0c2a9c1d1
6 changed files with 900 additions and 196 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2015 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -81,6 +81,11 @@ public interface BehaviourFilter
/** /**
* Disable behaviour for a type or aspect for all nodes. * Disable behaviour for a type or aspect for all nodes.
* <br>
* Given a direct instance of className (ie. not a subclass)
* all behaviour is disabled (including superclass behaviour).
* </br>
* <br>The same as calling {@link #disableBehaviour(QName, boolean)} with <code>false</code></br>
* <p> * <p>
* The change applies <b>ONLY</b> to the current transaction. * The change applies <b>ONLY</b> to the current transaction.
* *
@@ -88,6 +93,22 @@ public interface BehaviourFilter
*/ */
public void disableBehaviour(QName className); public void disableBehaviour(QName className);
/**
* Disable behaviour for a type or aspect for all nodes.
* <br>
* Given an instance of className (including instances that are subclasses of className, if includeSubClasses is true)
* all behaviour is disabled (including superclass behaviour).
* </br>
* <br>Successive calls (within the current transaction) will overwrite the filter for this class.</br>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param className the type/aspect behaviour to disable
* @param includeSubClasses set to <code>true</code> to disable the behaviours of subclasses
*
* @since 5.1
*/
public void disableBehaviour(QName className, boolean includeSubClasses);
/** /**
* Disable behaviour for specific node and class * Disable behaviour for specific node and class
* <p> * <p>
@@ -114,6 +135,7 @@ public interface BehaviourFilter
/** /**
* Enable behaviour for all nodes * Enable behaviour for all nodes
* <br>This is also applied to the to the disabled behaviours with {@link #disableBehaviour(QName, boolean)}</br>
* <p> * <p>
* The change applies <b>ONLY</b> to the current transaction. * The change applies <b>ONLY</b> to the current transaction.
* *

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2015 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -24,6 +24,7 @@ import java.util.Map;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.repo.transaction.TransactionalResourceHelper;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -115,30 +116,34 @@ public class BehaviourFilterImpl implements BehaviourFilter
@Override @Override
public void disableBehaviour(QName className) public void disableBehaviour(QName className)
{
disableBehaviour(className, false);
}
@Override
public void disableBehaviour(QName className, boolean includeSubClasses)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + className); logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + className);
} }
ParameterCheck.mandatory("className", className); ParameterCheck.mandatory("className", className);
ClassFilter classFilter = new ClassFilter(className, includeSubClasses);
TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT); TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT);
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS); Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
MutableInt filter = classFilters.get(className); MutableInt filterNumber = classFilters.get(classFilter);
if (filter == null) if (filterNumber == null)
{ {
filter = new MutableInt(1); // Already incremented filterNumber = new MutableInt(0);
classFilters.put(className, filter);
}
else
{
filter.increment();
} }
filterNumber.increment();
classFilters.put(classFilter, filterNumber);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug(" Now: " + filter); logger.debug(" Now: " + filterNumber);
} }
} }
@@ -241,25 +246,33 @@ public class BehaviourFilterImpl implements BehaviourFilter
// Nothing was disabled // Nothing was disabled
return; return;
} }
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS); Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
MutableInt filter = classFilters.get(className); MutableInt filterNumber = null;
if (filter == null) for (ClassFilter classFilter : classFilters.keySet())
{
if (classFilter.getClassName().equals(className))
{
filterNumber = classFilters.get(classFilter);
break;
}
}
if (filterNumber == null)
{ {
// Class was not disabled // Class was not disabled
return; return;
} }
else if (filter.intValue() <= 0) else if (filterNumber.intValue() <= 0)
{ {
// Can't go below zero for this // Can't go below zero for this
} }
else else
{ {
filter.decrement(); filterNumber.decrement();
} }
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug(" Now: "+ filter); logger.debug(" Now: "+ filterNumber);
} }
} }
@@ -358,6 +371,22 @@ public class BehaviourFilterImpl implements BehaviourFilter
return TransactionalResourceHelper.getCount(KEY_GLOBAL_FILTERS) <= 0; return TransactionalResourceHelper.getCount(KEY_GLOBAL_FILTERS) <= 0;
} }
/**
* @param className the class name
* @return the super class or <code>null</code>
*/
private QName generaliseClass(QName className)
{
ClassDefinition classDefinition = dictionaryService.getClass(className);
if (classDefinition == null)
{
// The class definition doesn't exist
return null;
}
QName parentClassName = classDefinition.getParentName();
return parentClassName;
}
@Override @Override
public boolean isEnabled(QName className) public boolean isEnabled(QName className)
{ {
@@ -374,9 +403,68 @@ public class BehaviourFilterImpl implements BehaviourFilter
// Nothing was disabled // Nothing was disabled
return true; return true;
} }
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS); Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
MutableInt classFilter = classFilters.get(className);
return (classFilter == null) || classFilter.intValue() <= 0; // Check this class to be disabled
ClassFilter classFilter = getClassFilter(className);
if (classFilter != null)
{
MutableInt filterNumber = classFilters.get(classFilter);
if (filterNumber != null && filterNumber.intValue() > 0) {
// the class is disabled
return false;
}
}
// Search for the super classes to be disabled with subclasses
while (className != null)
{
classFilter = getClassFilter(className);
if (classFilter != null && classFilter.isDisableSubClasses())
{
MutableInt filterNumber = classFilters.get(classFilter);
if (filterNumber != null && filterNumber.intValue() > 0)
{
// the class is disabled
return false;
}
}
// continue search
// look up the hierarchy
className = generaliseClass(className);
}
return true;
}
private ClassFilter getClassFilter(QName className)
{
ParameterCheck.mandatory("className", className);
// Check the global, first
if (!isEnabled())
{
return null;
}
if (!TransactionalResourceHelper.isResourcePresent(KEY_CLASS_FILTERS))
{
// Nothing was disabled
return null;
}
Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
for (ClassFilter classFilter : classFilters.keySet())
{
if (classFilter.getClassName().equals(className))
{
MutableInt filterNumber = classFilters.get(classFilter);
if (filterNumber != null && filterNumber.intValue() > 0 )
{
return classFilter;
}
break;
}
}
return null;
} }
@Override @Override

View File

@@ -161,19 +161,11 @@ import org.alfresco.util.LockHelper;
{ {
List<BehaviourDefinition> behaviours = new ArrayList<BehaviourDefinition>(); List<BehaviourDefinition> behaviours = new ArrayList<BehaviourDefinition>();
// Determine if behaviour has been disabled
boolean isEnabled = true;
if (filter != null)
{
NodeRef nodeRef = binding.getNodeRef();
QName className = binding.getClassQName();
isEnabled = (nodeRef == null) ? filter.isEnabled(className) : filter.isEnabled(nodeRef, className);
}
if (isEnabled)
{
// Find class behaviour by scanning up the class hierarchy // Find class behaviour by scanning up the class hierarchy
List<BehaviourDefinition<B>> behaviour = null; List<BehaviourDefinition<B>> behaviour = null;
if (isEnabled(binding))
{
while (binding != null) while (binding != null)
{ {
behaviour = classMap.get(binding); behaviour = classMap.get(binding);
@@ -184,7 +176,6 @@ import org.alfresco.util.LockHelper;
binding = (B)binding.generaliseBinding(); binding = (B)binding.generaliseBinding();
} }
} }
// Append all service-level behaviours // Append all service-level behaviours
behaviours.addAll(serviceMap.getAll()); behaviours.addAll(serviceMap.getAll());
@@ -196,7 +187,6 @@ import org.alfresco.util.LockHelper;
} }
} }
@Override @Override
public void addChangeObserver(BehaviourChangeObserver<B> observer) public void addChangeObserver(BehaviourChangeObserver<B> observer)
{ {
@@ -266,4 +256,16 @@ import org.alfresco.util.LockHelper;
} }
} }
private boolean isEnabled(B binding)
{
// Determine if behaviour has been disabled
boolean isEnabled = true;
if (filter != null)
{
NodeRef nodeRef = binding.getNodeRef();
QName className = binding.getClassQName();
isEnabled = (nodeRef == null) ? filter.isEnabled(className) : filter.isEnabled(nodeRef, className);
}
return isEnabled;
}
} }

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2005-2015 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.policy;
import org.alfresco.service.namespace.QName;
/**
* ClassFilter object used to describe the BehaviourFilter for a class
*
* @author alex.mukha
*/
public class ClassFilter
{
private QName className;
private boolean disableSubClasses;
public ClassFilter(QName className, boolean disableSubClasses)
{
this.className = className;
this.disableSubClasses = disableSubClasses;
}
public QName getClassName()
{
return className;
}
public boolean isDisableSubClasses()
{
return disableSubClasses;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassFilter that = (ClassFilter) o;
return !(className != null ? !className.equals(that.className) : that.className != null);
}
@Override
public int hashCode()
{
return className != null ? className.hashCode() : 0;
}
@Override
public String toString()
{
return "ClassFilter{" +
"className=" + className +
", disableSubClasses=" + disableSubClasses +
'}';
}
}

View File

@@ -62,6 +62,10 @@ public class PolicyComponentTransactionTest extends TestCase
private static QName BASE_TYPE = QName.createQName(TEST_NAMESPACE, "base"); private static QName BASE_TYPE = QName.createQName(TEST_NAMESPACE, "base");
private static QName FILE_TYPE = QName.createQName(TEST_NAMESPACE, "file"); private static QName FILE_TYPE = QName.createQName(TEST_NAMESPACE, "file");
private static QName A_TYPE = QName.createQName(TEST_NAMESPACE, "a_type");
private static QName B_TYPE = QName.createQName(TEST_NAMESPACE, "b_type");
private static QName C_TYPE = QName.createQName(TEST_NAMESPACE, "c_type");
private static ApplicationContext applicationContext = ApplicationContextHelper.getApplicationContext(); private static ApplicationContext applicationContext = ApplicationContextHelper.getApplicationContext();
private static ClassPolicyDelegate<SideEffectTestPolicy> sideEffectDelegate = null; private static ClassPolicyDelegate<SideEffectTestPolicy> sideEffectDelegate = null;
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
@@ -72,6 +76,10 @@ public class PolicyComponentTransactionTest extends TestCase
private NodeLocatorService nodeLocatorService; private NodeLocatorService nodeLocatorService;
private NodeRef companyHome; private NodeRef companyHome;
private TestOnCreateNodePolicy aTypeBehavior;
private TestOnCreateNodePolicy bTypeBehavior;
private TestOnCreateNodePolicy cTypeBehavior;
@Override @Override
protected void setUp() throws Exception protected void setUp() throws Exception
@@ -106,8 +114,22 @@ public class PolicyComponentTransactionTest extends TestCase
} }
this.companyHome = nodeLocatorService.getNode(CompanyHomeNodeLocator.NAME, null, null); this.companyHome = nodeLocatorService.getNode(CompanyHomeNodeLocator.NAME, null, null);
createAndEnableBehaviours();
} }
private void createAndEnableBehaviours()
{
aTypeBehavior = new TestOnCreateNodePolicy();
bTypeBehavior = new TestOnCreateNodePolicy();
cTypeBehavior = new TestOnCreateNodePolicy();
// bind custom behavior for super type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, A_TYPE, new JavaBehaviour(aTypeBehavior, "onCreateNode"));
// bind custom behavior for "middle" type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, B_TYPE, new JavaBehaviour(bTypeBehavior, "onCreateNode"));
// bind custom behavior for sub type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, C_TYPE, new JavaBehaviour(cTypeBehavior, "onCreateNode"));
}
@Override @Override
protected void tearDown() throws Exception protected void tearDown() throws Exception
@@ -377,92 +399,495 @@ public class PolicyComponentTransactionTest extends TestCase
} }
} }
/** public void behaviourHierarchyTestWork(QName createDocType, ClassFilter... disableTypes) throws Exception
* Test for MNT_13836
* <p>first show that both behaviours are enabled and triggered for a sub- (child) instance</p>
* @throws Exception
*/
public void testChildParentBehaviours1() throws Exception
{ {
TestOnCreateNodePolicy baseTypeBehavior = new TestOnCreateNodePolicy();
TestOnCreateNodePolicy fileTypeBehavior = new TestOnCreateNodePolicy();
// bind custom behavior for parent type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, BASE_TYPE, new JavaBehaviour(baseTypeBehavior, "onCreateNode"));
// bind custom behavior for child type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, FILE_TYPE, new JavaBehaviour(fileTypeBehavior, "onCreateNode"));
UserTransaction transaction = trxService.getUserTransaction(); UserTransaction transaction = trxService.getUserTransaction();
try try
{ {
transaction.begin(); transaction.begin();
disableBehaviours(disableTypes);
final String name = "Test (" + System.currentTimeMillis() + ").docx";
final Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
contentProps.put(ContentModel.PROP_NAME, name);
// create node of child type
nodeService.createNode(companyHome,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name),
FILE_TYPE,
contentProps);
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
assertTrue("Behavior should be executed for parent type.", baseTypeBehavior.isExecuted());
assertEquals(1, baseTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for child type.", fileTypeBehavior.isExecuted());
assertEquals(1, fileTypeBehavior.getExecutionCount());
}
/**
* Test for MNT_13836
* <p>then disable the super- behaviour only and show that sub behaviour is still enabled and triggered</p>
* @throws Exception
*/
/*
public void testChildParentBehaviours2() throws Exception
{
TestOnCreateNodePolicy baseTypeBehavior = new TestOnCreateNodePolicy();
TestOnCreateNodePolicy fileTypeBehavior = new TestOnCreateNodePolicy();
// bind custom behavior for parent type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, BASE_TYPE, new JavaBehaviour(baseTypeBehavior, "onCreateNode"));
// bind custom behavior for child type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, FILE_TYPE, new JavaBehaviour(fileTypeBehavior, "onCreateNode"));
UserTransaction transaction = trxService.getUserTransaction();
try try
{ {
transaction.begin(); createDocOfType(createDocType);
// disable behavior for parent type
behaviourFilter.disableBehaviour(BASE_TYPE);
// check that behavior is disabled correctly
try
{
checkBehaviour(BASE_TYPE, companyHome, true, false, false, true);
final String name = "Test (" + System.currentTimeMillis() + ").docx";
final Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
contentProps.put(ContentModel.PROP_NAME, name);
// create node of child type
nodeService.createNode(companyHome,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name),
FILE_TYPE,
contentProps);
} }
finally finally
{ {
behaviourFilter.enableBehaviour(BASE_TYPE); enableBehaviours(disableTypes);
checkBehaviour(BASE_TYPE, companyHome, true, true, true, true); }
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyEnableAll1() throws Exception
{
behaviourHierarchyTestWork(A_TYPE);
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyEnableAll2() throws Exception
{
behaviourHierarchyTestWork(B_TYPE);
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyEnableAll3() throws Exception
{
behaviourHierarchyTestWork(C_TYPE);
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(1, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableAllUpHierarchy1() throws Exception
{
behaviourHierarchyTestWork(
A_TYPE,
new ClassFilter(A_TYPE, false),
new ClassFilter(B_TYPE, false),
new ClassFilter(C_TYPE, false)
);
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableAllUpHierarchy2() throws Exception
{
behaviourHierarchyTestWork(
B_TYPE,
new ClassFilter(A_TYPE, false),
new ClassFilter(B_TYPE, false),
new ClassFilter(C_TYPE, false)
);
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableAllUpHierarchy3() throws Exception
{
behaviourHierarchyTestWork(
C_TYPE,
new ClassFilter(A_TYPE, false),
new ClassFilter(B_TYPE, false),
new ClassFilter(C_TYPE, false)
);
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableAllDownHierarchy1() throws Exception
{
behaviourHierarchyTestWork(
A_TYPE,
new ClassFilter(A_TYPE, true),
new ClassFilter(B_TYPE, true),
new ClassFilter(C_TYPE, true)
);
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableAllDownHierarchy2() throws Exception
{
behaviourHierarchyTestWork(
B_TYPE,
new ClassFilter(A_TYPE, true),
new ClassFilter(B_TYPE, true),
new ClassFilter(C_TYPE, true)
);
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableAllDownHierarchy3() throws Exception
{
behaviourHierarchyTestWork(
C_TYPE,
new ClassFilter(A_TYPE, true),
new ClassFilter(B_TYPE, true),
new ClassFilter(C_TYPE, true)
);
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableSuper1() throws Exception
{
behaviourHierarchyTestWork(A_TYPE, new ClassFilter(A_TYPE, false));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableSuper2() throws Exception
{
behaviourHierarchyTestWork(B_TYPE, new ClassFilter(A_TYPE, false));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableSuper3() throws Exception
{
behaviourHierarchyTestWork(C_TYPE, new ClassFilter(A_TYPE, false));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(1, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableSuper4() throws Exception
{
behaviourHierarchyTestWork(A_TYPE, new ClassFilter(A_TYPE, true));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableSuper5() throws Exception
{
behaviourHierarchyTestWork(B_TYPE, new ClassFilter(A_TYPE, true));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableSuper6() throws Exception
{
behaviourHierarchyTestWork(C_TYPE, new ClassFilter(A_TYPE, true));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableMiddle1() throws Exception
{
behaviourHierarchyTestWork(A_TYPE, new ClassFilter(B_TYPE, false));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableMiddle2() throws Exception
{
behaviourHierarchyTestWork(B_TYPE, new ClassFilter(B_TYPE, false));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableMiddle3() throws Exception
{
behaviourHierarchyTestWork(C_TYPE, new ClassFilter(B_TYPE, false));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(1, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableMiddle4() throws Exception
{
behaviourHierarchyTestWork(A_TYPE, new ClassFilter(B_TYPE, true));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableMiddle5() throws Exception
{
behaviourHierarchyTestWork(B_TYPE, new ClassFilter(B_TYPE, true));
assertFalse("Behavior should notbe executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior not should be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableMiddle6() throws Exception
{
behaviourHierarchyTestWork(C_TYPE, new ClassFilter(B_TYPE, true));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableSub1() throws Exception
{
behaviourHierarchyTestWork(A_TYPE, new ClassFilter(C_TYPE, false));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableSub2() throws Exception
{
behaviourHierarchyTestWork(B_TYPE, new ClassFilter(C_TYPE, false));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836
* @throws Exception
*/
public void testBehaviourHierarchyDisableSub3() throws Exception
{
behaviourHierarchyTestWork(C_TYPE, new ClassFilter(C_TYPE, false));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableSub4() throws Exception
{
behaviourHierarchyTestWork(A_TYPE, new ClassFilter(C_TYPE, true));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableSub5() throws Exception
{
behaviourHierarchyTestWork(B_TYPE, new ClassFilter(C_TYPE, true));
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchyDisableSub6() throws Exception
{
behaviourHierarchyTestWork(C_TYPE, new ClassFilter(C_TYPE, true));
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testIsEnabled1() throws Exception
{
UserTransaction transaction = trxService.getUserTransaction();
try
{
transaction.begin();
disableBehaviours(new ClassFilter(B_TYPE, true));
try
{
assertEquals("Incorrect behaviour state: global: ", true, behaviourFilter.isEnabled());
// A_TYPE
assertEquals("Incorrect behaviour state: class: ", true, behaviourFilter.isEnabled(A_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", true, behaviourFilter.isEnabled(companyHome, A_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
// B_TYPE
assertEquals("Incorrect behaviour state: class: ", false, behaviourFilter.isEnabled(B_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", false, behaviourFilter.isEnabled(companyHome, B_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
// C_TYPE
assertEquals("Incorrect behaviour state: class: ", false, behaviourFilter.isEnabled(C_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", false, behaviourFilter.isEnabled(companyHome, C_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
}
finally
{
behaviourFilter.enableBehaviour(B_TYPE);
} }
transaction.commit(); transaction.commit();
} }
@@ -472,42 +897,186 @@ public class PolicyComponentTransactionTest extends TestCase
throw e; throw e;
} }
assertFalse("Behavior should not be executed for parent type.", baseTypeBehavior.isExecuted());
assertEquals(0, baseTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for child type.", fileTypeBehavior.isExecuted());
assertEquals(1, fileTypeBehavior.getExecutionCount());
} }
*/
/** /**
* Test for MNT_13836 * Test for MNT-13836 (new API)
* <p>then also disable the sub- behaviour and show that neither behaviour is triggered</p>
* @throws Exception * @throws Exception
*/ */
public void testChildParentBehaviours3() throws Exception public void testIsEnabled2() throws Exception
{ {
TestOnCreateNodePolicy baseTypeBehavior = new TestOnCreateNodePolicy();
TestOnCreateNodePolicy fileTypeBehavior = new TestOnCreateNodePolicy();
// bind custom behavior for parent type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, BASE_TYPE, new JavaBehaviour(baseTypeBehavior, "onCreateNode"));
// bind custom behavior for child type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, FILE_TYPE, new JavaBehaviour(fileTypeBehavior, "onCreateNode"));
UserTransaction transaction = trxService.getUserTransaction(); UserTransaction transaction = trxService.getUserTransaction();
try try
{ {
transaction.begin(); transaction.begin();
// disable behavior for parent type disableBehaviours(new ClassFilter(B_TYPE, false));
behaviourFilter.disableBehaviour(BASE_TYPE);
// check that behavior is disabled correctly
checkBehaviour(BASE_TYPE, companyHome, true, false, false, true);
// disable behavior for child type
behaviourFilter.disableBehaviour(FILE_TYPE);
// check that behavior is disabled correctly
checkBehaviour(FILE_TYPE, companyHome, true, false, false, true);
try try
{
assertEquals("Incorrect behaviour state: global: ", true, behaviourFilter.isEnabled());
// A_TYPE
assertEquals("Incorrect behaviour state: class: ", true, behaviourFilter.isEnabled(A_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", true, behaviourFilter.isEnabled(companyHome, A_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
// B_TYPE
assertEquals("Incorrect behaviour state: class: ", false, behaviourFilter.isEnabled(B_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", false, behaviourFilter.isEnabled(companyHome, B_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
// C_TYPE
assertEquals("Incorrect behaviour state: class: ", true, behaviourFilter.isEnabled(C_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", true, behaviourFilter.isEnabled(companyHome, C_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
}
finally
{
behaviourFilter.enableBehaviour(B_TYPE);
}
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchySequence1() throws Exception
{
UserTransaction transaction = trxService.getUserTransaction();
try
{
transaction.begin();
disableBehaviours(new ClassFilter(A_TYPE, true), new ClassFilter(B_TYPE, true));
behaviourFilter.enableBehaviour(B_TYPE);
// Should be still disabled
checkBehaviour(B_TYPE, companyHome, true, false, false, true);
try
{
createDocOfType(C_TYPE);
}
finally
{
enableBehaviours(new ClassFilter(A_TYPE, true), new ClassFilter(B_TYPE, true));
}
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
assertFalse("Behavior should not be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(0, aTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(0, bTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(0, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchySequence2() throws Exception
{
UserTransaction transaction = trxService.getUserTransaction();
try
{
transaction.begin();
disableBehaviours(new ClassFilter(A_TYPE, false), new ClassFilter(B_TYPE, true));
behaviourFilter.enableBehaviour(B_TYPE);
assertEquals("Incorrect behaviour state: class: ", true, behaviourFilter.isEnabled(B_TYPE));
assertEquals("Incorrect behaviour state: classAndInstance", true, behaviourFilter.isEnabled(companyHome, B_TYPE));
assertEquals("Incorrect behaviour state: instance", true, behaviourFilter.isEnabled(companyHome));
try
{
createDocOfType(C_TYPE);
}
finally
{
enableBehaviours(new ClassFilter(A_TYPE, true), new ClassFilter(B_TYPE, true));
}
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(1, cTypeBehavior.getExecutionCount());
}
/**
* Test for MNT-13836 (new API)
* @throws Exception
*/
public void testBehaviourHierarchySequence3() throws Exception
{
UserTransaction transaction = trxService.getUserTransaction();
try
{
transaction.begin();
disableBehaviours(new ClassFilter(A_TYPE, false), new ClassFilter(B_TYPE, false));
try
{
createDocOfType(C_TYPE);
}
finally
{
enableBehaviours(new ClassFilter(A_TYPE, true), new ClassFilter(B_TYPE, true));
}
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
assertTrue("Behavior should be executed for a_type.", aTypeBehavior.isExecuted());
assertEquals(1, aTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for b_type.", bTypeBehavior.isExecuted());
assertEquals(1, bTypeBehavior.getExecutionCount());
assertTrue("Behavior should be executed for c_type.", cTypeBehavior.isExecuted());
assertEquals(1, cTypeBehavior.getExecutionCount());
}
private void disableBehaviours(ClassFilter... classFilters)
{
for(int i = 0; i < classFilters.length; i++)
{
behaviourFilter.disableBehaviour(
classFilters[i].getClassName(),
classFilters[i].isDisableSubClasses()
);
// check that behavior is disabled correctly
checkBehaviour(classFilters[i].getClassName(), companyHome, true, false, false, true);
}
}
private void enableBehaviours(ClassFilter... types)
{
for(int i = 0; i < types.length; i++)
{
behaviourFilter.enableBehaviour(types[i].getClassName());
}
for(int i = 0; i < types.length; i++)
{
checkBehaviour(types[i].getClassName(), companyHome, true, true, true, true);
}
}
private void createDocOfType(QName type)
{ {
final String name = "Test (" + System.currentTimeMillis() + ").docx"; final String name = "Test (" + System.currentTimeMillis() + ").docx";
final Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(); final Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
@@ -517,87 +1086,9 @@ public class PolicyComponentTransactionTest extends TestCase
nodeService.createNode(companyHome, nodeService.createNode(companyHome,
ContentModel.ASSOC_CONTAINS, ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name), QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name),
FILE_TYPE, type,
contentProps); contentProps);
} }
finally
{
behaviourFilter.enableBehaviour(BASE_TYPE);
behaviourFilter.enableBehaviour(FILE_TYPE);
checkBehaviour(BASE_TYPE, companyHome, true, true, true, true);
checkBehaviour(FILE_TYPE, companyHome, true, true, true, true);
}
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
assertFalse("Behavior should not be executed for parent type.", baseTypeBehavior.isExecuted());
assertEquals(0, baseTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for child type.", fileTypeBehavior.isExecuted());
assertEquals(0, fileTypeBehavior.getExecutionCount());
}
/**
* Test for MNT_13836
* <p>then vice-versa, ie. disabling sub- behaviour does not disable inherited super- behaviours</p>
* @throws Exception
*/
/*
public void testChildParentBehaviours4() throws Exception
{
TestOnCreateNodePolicy baseTypeBehavior = new TestOnCreateNodePolicy();
TestOnCreateNodePolicy fileTypeBehavior = new TestOnCreateNodePolicy();
// bind custom behavior for parent type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, BASE_TYPE, new JavaBehaviour(baseTypeBehavior, "onCreateNode"));
// bind custom behavior for child type
policyComponent.bindClassBehaviour(OnCreateNodePolicy.QNAME, FILE_TYPE, new JavaBehaviour(fileTypeBehavior, "onCreateNode"));
UserTransaction transaction = trxService.getUserTransaction();
try
{
transaction.begin();
// disable behavior for child type
behaviourFilter.disableBehaviour(FILE_TYPE);
// check that behavior is disabled correctly
checkBehaviour(FILE_TYPE, companyHome, true, false, false, true);
try
{
final String name = "Test (" + System.currentTimeMillis() + ").docx";
final Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
contentProps.put(ContentModel.PROP_NAME, name);
// create node of child type
nodeService.createNode(companyHome,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name),
FILE_TYPE,
contentProps);
}
finally
{
behaviourFilter.enableBehaviour(FILE_TYPE);
checkBehaviour(FILE_TYPE, companyHome, true, true, true, true);
}
transaction.commit();
}
catch(Exception e)
{
try { transaction.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
assertTrue("Behavior should be executed for parent type.", baseTypeBehavior.isExecuted());
assertEquals(1, baseTypeBehavior.getExecutionCount());
assertFalse("Behavior should not be executed for child type.", fileTypeBehavior.isExecuted());
assertEquals(0, fileTypeBehavior.getExecutionCount());
}
*/
/** /**
* @param className the class to check * @param className the class to check

View File

@@ -60,6 +60,32 @@
</associations> </associations>
</type> </type>
<type name="test:a_type">
<parent>sys:base</parent>
<properties>
<property name="test:a_type">
<type>d:text</type>
</property>
</properties>
</type>
<type name="test:b_type">
<parent>test:a_type</parent>
<properties>
<property name="test:b_type">
<type>d:text</type>
</property>
</properties>
</type>
<type name="test:c_type">
<parent>test:b_type</parent>
<properties>
<property name="test:c_type">
<type>d:text</type>
</property>
</properties>
</type>
</types> </types>
<aspects> <aspects>