Merged DEV to HEAD

31489: Fix MT NodeRef translation in policy filter (ALF-10178)
   31452: Sync DEV branch with HEAD
      30312: Reintegrated HEAD
      30281: Comprehensive DEBUG logging to track behaviour enable/disable states for transactions
             - Part of ALF-10178: BehaviourFilter fails when nesting disable/enable calls
      30280: Fixed importer's use of behaviour filter
             - The change in the BehaviourFilter contract means that all disable calls must be matched
               with an equivalent enable call.  Enabling globally no longer wipes out vetos put in place
               by other code.
             - Part of ALF-10178: BehaviourFilter fails when nesting disable/enable calls
      30279: Removed unnecessary behaviour enablement checks is VersionService (ALF-10178)
      30278: Fixed behaviour re-enabling for StoreSelectorAspectContentStore (ALF-10178)
      30240: Fixed ALF-10178: BehaviourFilter fails when nesting disable/enable calls
             - Behaviour enable/disable now uses reference counting to check the state of different behaviour levels
             - Added unit test to test
             - Re-enabled test for ALF-10177: Test disabled: CheckOutCheckInServiceImplTest.testalfrescoCheckoutDoesntModifyNode
               but renamed to CheckOutCheckInServiceImplTest.testAlfrescoCheckoutDoesNotModifyNode
             - Going into DEV branch to run through tests
      30236: Branch for fixing BehaviourFilter nesting


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@31619 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2011-11-01 16:07:11 +00:00
parent 5ac0c42265
commit 80cce9c0f2
15 changed files with 709 additions and 279 deletions

View File

@@ -26,37 +26,71 @@ import org.alfresco.service.namespace.QName;
*
* @See org.alfresco.repo.policy.PolicyComponent
*
* @author David Caruana
* @author Derek Hulley
*/
public interface BehaviourFilter
{
/**
* @deprecated Since 4.0 use {@link #enableBehaviour(NodeRef)}
*/
public void enableBehaviours(NodeRef nodeRef);
/**
* @deprecated Since 4.0 use {@link #enableBehaviour(NodeRef)}
*/
public void disableAllBehaviours();
/**
* @deprecated Since 4.0 use {@link #disableBehaviour()}
*/
public void enableAllBehaviours();
/**
* Disable behaviour for all types
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*/
public void disableBehaviour();
/**
* Disable behaviour for a type or aspect for all nodes.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param className the type/aspect behaviour to disable
* @return true => already disabled
* @param className the type/aspect behaviour to disable
*/
public boolean disableBehaviour(QName className);
public void disableBehaviour(QName className);
/**
* Disable behaviour for specific node
* Disable behaviour for specific node and class
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param nodeRef the node to disable for
* @param className the type/aspect behaviour to disable
* @return true => already disabled
* @param nodeRef the node to disable for
* @param className the type/aspect behaviour to disable
*/
public boolean disableBehaviour(NodeRef nodeRef, QName className);
public void disableBehaviour(NodeRef nodeRef, QName className);
/**
* Disable all behaviours for a given node
*
* @param nodeRef the node to disable for
*/
public void disableBehaviour(NodeRef nodeRef);
/**
* Enable behaviours for all classes.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*/
public void enableBehaviour();
/**
* Enable behaviour for all nodes
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param className the type/aspect behaviour to enable
* @param className the type/aspect behaviour to enable
*/
public void enableBehaviour(QName className);
@@ -65,53 +99,45 @@ public interface BehaviourFilter
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param nodeRef the node to enable for
* @param className the type/aspect behaviour to enable
* @param nodeRef the node to enable for
* @param className the type/aspect behaviour to enable or <tt>null</tt> for all classes
*/
public void enableBehaviour(NodeRef nodeRef, QName className);
/**
* Enable behaviour for a specific node
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param nodeRef the node to enable for
*
* @since 4.0
*/
public void enableBehaviour(NodeRef nodeRef);
/**
* Enable all behaviours for specific node
* Determine if behaviour is globally enabled.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param nodeRef the node to enable for
* @return true => behaviour is enabled
*
* @since 4.0
*/
public void enableBehaviours(NodeRef nodeRef);
public boolean isEnabled();
/**
* Disable all behaviours. Once this method is called the node and class level filters, enableBehaviours and disableBehaviours
* methods have no effect, every behaviour is disabled.
* EnableAllBehaviours reverses the result of calling this method.
* <p>
* Calling this method may result in nodes existing in your repository that do not conform to your policies.
*
* <p>
* The change applies <b>ONLY</b> to the current transaction.
* @see #enableAllBehaviours
*/
public void disableAllBehaviours();
/**
* Enable all behaviours i.e. undo all disable calls - at the global,
* node and class level.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*/
public void enableAllBehaviours();
/**
* Determine if behaviour is enabled across all nodes.
* Determine if behaviour is enabled for a class.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param className the behaviour to test for
* @return true => behaviour is enabled
* @param className the behaviour to test for
* @return true => behaviour is enabled
*/
public boolean isEnabled(QName className);
/**
* Determine if behaviour is enabled for specific node.
* Determine if behaviour is enabled for specific node and class.
* <p>
* Note: A node behaviour is enabled only when:
* a) the behaviour is not disabled across all nodes
@@ -119,18 +145,28 @@ public interface BehaviourFilter
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @param nodeRef the node to test for
* @param className the behaviour to test for
* @return true => behaviour is enabled
* @param nodeRef the node to test for
* @param className the behaviour to test for
* @return true => behaviour is enabled
*/
public boolean isEnabled(NodeRef nodeRef, QName className);
/**
* Determine if any behaviours have been disabled?
* Determine if behaviour is enabled for a specific node.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @return true => behaviours have been filtered
* @param nodeRef the node to test for
* @return true => behaviour is enabled
*/
public boolean isEnabled(NodeRef nodeRef);
/**
* Determine if any behaviours have been disabled or altered.
* <p>
* The change applies <b>ONLY</b> to the current transaction.
*
* @return true => behaviours have been altered
*/
public boolean isActivated();
}

View File

@@ -18,33 +18,66 @@
*/
package org.alfresco.repo.policy;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionalResourceHelper;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.mutable.MutableInt;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.ParameterCheck;
/**
* Implementation of Behaviour Filter. All methods operate on transactionally-bound
* resources. Behaviour will therefore never span transactions; the filter state has
* the same lifespan as the transaction in which it was created.
* <p/>
* Since 4.0, the behaviour enabling/disabling is recorded using reference counting,
* meaning that the outermost disable call in a stack has an effective veto. Use
* proper try-finally patterns to ensure behaviour is released after it is no longer
* needed.
* <pre><code>
* behaviourFilter.disableBehaviour(abc);
* try
* {
* behaviourFilter.disableBehaviour(abc);
* try
* {
* // Do something that might have triggered 'abc' but will not
* }
* finally
* {
* behaviourFilter.enableBehaviour(abc);
* }
* // Do something that might have triggered 'abc' but will not despite the last enable call
* }
* finally
* {
* behaviourFilter.enableBehaviour(abc);
* }
* </code></pre>
* <p/>
* <b>Multitenancy and disabling by <tt>NodeRef</tt>:</b><br/>
* Conversions based on the current tenant context are done automatically.
*
* @author David Caruana
* @author Derek Hulley
*/
public class BehaviourFilterImpl implements BehaviourFilter
{
private static final String KEY_GLOBAL_FILTER = "BehaviourFilterImpl.gloalFilter";
private static final String KEY_CLASS_FILTER = "BehaviourFilterImpl.classFilter";
private static final String KEY_NODEREF_FILTER = "BehaviourFilterImpl.nodeRefFilter";
private static final String KEY_FILTER_COUNT = "BehaviourFilterImpl.filterCount";
private static final String KEY_GLOBAL_FILTERS = "BehaviourFilterImpl.globalFilters";
private static final String KEY_CLASS_FILTERS = "BehaviourFilterImpl.classFilters";
private static final String KEY_INSTANCE_CLASS_FILTERS = "BehaviourFilterImpl.instanceClassFilters";
private static final String KEY_INSTANCE_FILTERS = "BehaviourFilterImpl.instanceFilters";
private static final Log logger = LogFactory.getLog(BehaviourFilterImpl.class);
// Dictionary Service
private DictionaryService dictionaryService;
// Tenant Service
private TenantService tenantService;
/**
@@ -62,150 +95,389 @@ public class BehaviourFilterImpl implements BehaviourFilter
{
this.tenantService = tenantService;
}
public boolean disableBehaviour(QName className)
{
List<QName> classFilters = TransactionalResourceHelper.getList(KEY_CLASS_FILTER);
boolean alreadyDisabled = classFilters.contains(className);
if (!alreadyDisabled)
{
classFilters.add(className);
}
return alreadyDisabled;
}
public boolean disableBehaviour(NodeRef nodeRef, QName className)
{
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef,List<QName>> nodeRefFilters = TransactionalResourceHelper.getMap(KEY_NODEREF_FILTER);
List<QName> classNames = nodeRefFilters.get(nodeRef);
if (classNames == null)
{
classNames = new ArrayList<QName>();
nodeRefFilters.put(nodeRef, classNames);
}
boolean alreadyDisabled = classNames.contains(className);
if (!alreadyDisabled)
{
classNames.add(className);
}
return alreadyDisabled;
}
public void enableBehaviour(QName className)
{
List<QName> classFilters = TransactionalResourceHelper.getList(KEY_CLASS_FILTER);
classFilters.remove(className);
}
public void enableBehaviour(NodeRef nodeRef, QName className)
{
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef,List<QName>> nodeRefFilters = TransactionalResourceHelper.getMap(KEY_NODEREF_FILTER);
List<QName> classNames = nodeRefFilters.get(nodeRef);
if (classNames != null)
{
classNames.remove(className);
if (classNames.size() == 0)
{
nodeRefFilters.remove(nodeRef);
}
}
}
@Deprecated
@Override
// TODO
public void enableBehaviours(NodeRef nodeRef)
{
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef,List<QName>> nodeRefFilters = TransactionalResourceHelper.getMap(KEY_NODEREF_FILTER);
nodeRefFilters.remove(nodeRef);
enableBehaviour(nodeRef);
}
@Deprecated
@Override
// TODO
public void disableAllBehaviours()
{
TransactionalResourceHelper.setBoolean(KEY_GLOBAL_FILTER);
disableBehaviour();
}
@Deprecated
@Override
// TODO
public void enableAllBehaviours()
{
TransactionalResourceHelper.resetBoolean(KEY_GLOBAL_FILTER);
Map<NodeRef,List<QName>> filters = TransactionalResourceHelper.getMap(KEY_NODEREF_FILTER);
filters.clear();
enableBehaviour();
}
public boolean isEnabled(NodeRef nodeRef, QName className)
@Override
public void disableBehaviour()
{
if(TransactionalResourceHelper.testBoolean(KEY_GLOBAL_FILTER))
if (logger.isDebugEnabled())
{
return false;
logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): ALL");
}
// check global filters
if (!isEnabled(className))
TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT);
TransactionalResourceHelper.incrementCount(KEY_GLOBAL_FILTERS);
if (logger.isDebugEnabled())
{
return false;
logger.debug(" Now: " + TransactionalResourceHelper.getCount(KEY_GLOBAL_FILTERS));
}
}
@Override
public void disableBehaviour(QName className)
{
if (logger.isDebugEnabled())
{
logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + className);
}
ParameterCheck.mandatory("className", className);
TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT);
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
MutableInt filter = classFilters.get(className);
if (filter == null)
{
filter = new MutableInt(1); // Already incremented
classFilters.put(className, filter);
}
else
{
filter.increment();
}
if (logger.isDebugEnabled())
{
logger.debug(" Now: " + filter);
}
}
@Override
public void disableBehaviour(NodeRef nodeRef, QName className)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("className", className);
nodeRef = tenantService.getName(nodeRef);
// check node level filters
Map<NodeRef,List<QName>> filters = TransactionalResourceHelper.getMap(KEY_NODEREF_FILTER);
List<QName> nodeClassFilters = filters.get(nodeRef);
if (nodeClassFilters != null)
if (logger.isDebugEnabled())
{
boolean filtered = nodeClassFilters.contains(className);
if (filtered)
{
return false;
}
for (QName filterName : nodeClassFilters)
{
filtered = dictionaryService.isSubClass(className, filterName);
if (filtered)
{
return false;
}
}
logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + nodeRef + "/" + className);
}
nodeRef = tenantService.getName(nodeRef);
return true;
TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT);
Map<NodeRef, Map<QName, MutableInt>> instanceClassFilters = TransactionalResourceHelper.getMap(KEY_INSTANCE_CLASS_FILTERS);
Map<QName, MutableInt> classFilters = instanceClassFilters.get(nodeRef);
if (classFilters == null)
{
classFilters = new HashMap<QName, MutableInt>(3);
instanceClassFilters.put(nodeRef, classFilters);
}
MutableInt filter = classFilters.get(className);
if (filter == null)
{
filter = new MutableInt(0);
classFilters.put(className, filter);
}
filter.increment();
if (logger.isDebugEnabled())
{
logger.debug(" Now: " + filter);
}
}
@Override
public void disableBehaviour(NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
if (logger.isDebugEnabled())
{
logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + nodeRef + "/ALL:");
}
nodeRef = tenantService.getName(nodeRef);
TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT);
Map<NodeRef, MutableInt> instanceFilters = TransactionalResourceHelper.getMap(KEY_INSTANCE_FILTERS);
MutableInt filter = instanceFilters.get(nodeRef);
if (filter == null)
{
filter = new MutableInt(0);
instanceFilters.put(nodeRef, filter);
}
filter.increment();
if (logger.isDebugEnabled())
{
logger.debug(" Now:" + filter);
}
}
@Override
public void enableBehaviour()
{
if (logger.isDebugEnabled())
{
logger.debug("Behaviour: ENABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): ALL");
}
TransactionalResourceHelper.decrementCount(KEY_FILTER_COUNT, false);
TransactionalResourceHelper.decrementCount(KEY_GLOBAL_FILTERS, false);
if (logger.isDebugEnabled())
{
logger.debug(" Now: " + TransactionalResourceHelper.getCount(KEY_GLOBAL_FILTERS));
}
}
@Override
public void enableBehaviour(QName className)
{
ParameterCheck.mandatory("className", className);
if (logger.isDebugEnabled())
{
logger.debug("Behaviour: ENABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + className);
}
TransactionalResourceHelper.decrementCount(KEY_FILTER_COUNT, false);
if (!TransactionalResourceHelper.isResourcePresent(KEY_CLASS_FILTERS))
{
// Nothing was disabled
return;
}
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
MutableInt filter = classFilters.get(className);
if (filter == null)
{
// Class was not disabled
return;
}
else if (filter.intValue() <= 0)
{
// Can't go below zero for this
}
else
{
filter.decrement();
}
if (logger.isDebugEnabled())
{
logger.debug(" Now: "+ filter);
}
}
@Override
public void enableBehaviour(NodeRef nodeRef, QName className)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("className", className);
if (logger.isDebugEnabled())
{
logger.debug("Behaviour: ENABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + nodeRef + "/" + className);
}
TransactionalResourceHelper.decrementCount(KEY_FILTER_COUNT, false);
if (!TransactionalResourceHelper.isResourcePresent(KEY_INSTANCE_CLASS_FILTERS))
{
// Nothing was disabled
return;
}
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef, Map<QName, MutableInt>> instanceClassFilters = TransactionalResourceHelper.getMap(KEY_INSTANCE_CLASS_FILTERS);
Map<QName, MutableInt> classFilters = instanceClassFilters.get(nodeRef);
if (classFilters == null)
{
// Instance classes were not disabled
return;
}
MutableInt filter = classFilters.get(className);
if (filter == null)
{
// Class was not disabled
return;
}
else if (filter.intValue() <= 0)
{
// Can't go below zero for this
}
else
{
filter.decrement();
}
if (logger.isDebugEnabled())
{
logger.debug(" Now: "+ filter);
}
}
@Override
public void enableBehaviour(NodeRef nodeRef)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
if (logger.isDebugEnabled())
{
logger.debug("Behaviour: ENABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + nodeRef + "/ALL");
}
TransactionalResourceHelper.decrementCount(KEY_FILTER_COUNT, false);
if (!TransactionalResourceHelper.isResourcePresent(KEY_INSTANCE_FILTERS))
{
// Nothing was disabled
return;
}
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef, MutableInt> instanceFilters = TransactionalResourceHelper.getMap(KEY_INSTANCE_FILTERS);
MutableInt filter = instanceFilters.get(nodeRef);
if (filter == null)
{
// Instance was not disabled
return;
}
else if (filter.intValue() <= 0)
{
// Can't go below zero for this
}
else
{
filter.decrement();
}
if (logger.isDebugEnabled())
{
logger.debug(" Now:" + filter);
}
}
@Override
public boolean isEnabled()
{
return TransactionalResourceHelper.getCount(KEY_GLOBAL_FILTERS) <= 0;
}
@Override
public boolean isEnabled(QName className)
{
if(TransactionalResourceHelper.testBoolean(KEY_GLOBAL_FILTER))
ParameterCheck.mandatory("className", className);
// Check the global, first
if (!isEnabled())
{
return false;
}
// check global class filters
List<QName> classFilters = TransactionalResourceHelper.getList(KEY_CLASS_FILTER);
boolean filtered = classFilters.contains(className);
if (filtered)
if (!TransactionalResourceHelper.isResourcePresent(KEY_CLASS_FILTERS))
{
// Nothing was disabled
return true;
}
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
MutableInt classFilter = classFilters.get(className);
return (classFilter == null) || classFilter.intValue() <= 0;
}
@Override
public boolean isEnabled(NodeRef nodeRef, QName className)
{
ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("className", className);
// Check the class (includes global) and instance, first
if (!isEnabled(className) || !isEnabled(nodeRef))
{
return false;
}
for (QName classFilter : classFilters)
if (!TransactionalResourceHelper.isResourcePresent(KEY_INSTANCE_CLASS_FILTERS))
{
filtered = dictionaryService.isSubClass(className, classFilter);
if (filtered)
// Nothing was disabled
return true;
}
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef, Map<QName, MutableInt>> instanceClassFilters = TransactionalResourceHelper.getMap(KEY_INSTANCE_CLASS_FILTERS);
Map<QName, MutableInt> classFilters = instanceClassFilters.get(nodeRef);
if (classFilters == null)
{
// Instance classes were not disabled
return true;
}
for (QName classCheck : classFilters.keySet())
{
// Ignore if it is not part of the hierarchy we are requesting
if (!dictionaryService.isSubClass(className, classCheck))
{
continue;
}
MutableInt filter = classFilters.get(className);
if (filter != null && filter.intValue() > 0)
{
// Class was disabled
return false;
}
}
return true;
}
public boolean isActivated()
@Override
public boolean isEnabled(NodeRef nodeRef)
{
List<QName> classFilters = TransactionalResourceHelper.getList(KEY_CLASS_FILTER);
Map<NodeRef,List<QName>> nodeRefFilters = TransactionalResourceHelper.getMap(KEY_NODEREF_FILTER);
boolean globalFlag = TransactionalResourceHelper.testBoolean(KEY_GLOBAL_FILTER);
return ((!classFilters.isEmpty()) || (!nodeRefFilters.isEmpty()) || globalFlag);
ParameterCheck.mandatory("nodeRef", nodeRef);
// Check the class (includes global) and instance, first
if (!isEnabled())
{
return false;
}
if (!TransactionalResourceHelper.isResourcePresent(KEY_INSTANCE_FILTERS))
{
// Nothing was disabled
return true;
}
nodeRef = tenantService.getName(nodeRef);
Map<NodeRef, MutableInt> instanceFilters = TransactionalResourceHelper.getMap(KEY_INSTANCE_FILTERS);
MutableInt filter = instanceFilters.get(nodeRef);
if (filter != null && filter.intValue() > 0)
{
// Instance was disabled
return false;
}
return true;
}
@Override
public boolean isActivated()
{
return TransactionalResourceHelper.getCount(KEY_FILTER_COUNT) > 0;
}
}

View File

@@ -32,6 +32,7 @@ import org.alfresco.repo.policy.Policy.Arg;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
@@ -50,6 +51,7 @@ public class PolicyComponentTransactionTest extends TestCase
private static ApplicationContext applicationContext = ApplicationContextHelper.getApplicationContext();
private static ClassPolicyDelegate<SideEffectTestPolicy> sideEffectDelegate = null;
private PolicyComponent policyComponent;
private BehaviourFilter behaviourFilter;
private TransactionService trxService;
private AuthenticationComponent authenticationComponent;
@@ -68,6 +70,7 @@ public class PolicyComponentTransactionTest extends TestCase
// retrieve policy component
this.policyComponent = (PolicyComponent)applicationContext.getBean("policyComponent");
this.behaviourFilter = (BehaviourFilter) applicationContext.getBean("policyBehaviourFilter");
this.trxService = (TransactionService) applicationContext.getBean("transactionComponent");
this.authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
this.authenticationComponent.setSystemUserAsCurrentUser();
@@ -283,9 +286,100 @@ public class PolicyComponentTransactionTest extends TestCase
{
try { userTransaction2.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
NodeRef nodeRef = new NodeRef(TEST_NAMESPACE, "test", "123");
// Check enabling and disabling of behaviours within the transaction
// We disable multiple times and enable, including enabling when not disabled
UserTransaction userTransaction3 = trxService.getUserTransaction();
try
{
userTransaction3.begin();
// Check all enabled to start
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
// Check instance with nesting
behaviourFilter.enableBehaviour(nodeRef);
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
behaviourFilter.disableBehaviour(nodeRef);
checkBehaviour(BASE_TYPE, nodeRef, true, true, false, false);
behaviourFilter.disableBehaviour(nodeRef);
checkBehaviour(BASE_TYPE, nodeRef, true, true, false, false);
behaviourFilter.enableBehaviour(nodeRef);
checkBehaviour(BASE_TYPE, nodeRef, true, true, false, false);
behaviourFilter.enableBehaviour(nodeRef);
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
// Check class and instance with nesting
behaviourFilter.enableBehaviour(nodeRef, BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
behaviourFilter.disableBehaviour(nodeRef, BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, false, true);
behaviourFilter.disableBehaviour(nodeRef, BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, false, true);
behaviourFilter.enableBehaviour(nodeRef, BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, false, true);
behaviourFilter.enableBehaviour(nodeRef, BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
// Check class with nesting
behaviourFilter.enableBehaviour(BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
behaviourFilter.disableBehaviour(BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, false, false, true);
behaviourFilter.disableBehaviour(BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, false, false, true);
behaviourFilter.enableBehaviour(BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, false, false, true);
behaviourFilter.enableBehaviour(BASE_TYPE);
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
// Check global with nesting
behaviourFilter.enableBehaviour();
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
behaviourFilter.disableBehaviour();
checkBehaviour(BASE_TYPE, nodeRef, false, false, false, false);
behaviourFilter.disableBehaviour();
checkBehaviour(BASE_TYPE, nodeRef, false, false, false, false);
behaviourFilter.enableBehaviour();
checkBehaviour(BASE_TYPE, nodeRef, false, false, false, false);
behaviourFilter.enableBehaviour();
checkBehaviour(BASE_TYPE, nodeRef, true, true, true, true);
userTransaction3.commit();
}
catch(Exception e)
{
try { userTransaction3.rollback(); } catch (IllegalStateException ee) {}
throw e;
}
}
/**
* @param className the class to check
* @param nodeRef the node instance to check
* @param globalEnabled <tt>true</tt> if the global filter should be enabled
* @param classEnabled <tt>true</tt> if the class should be enabled
* @param classInstanceEnabled <tt>true</tt> if the class and instance should be enabled
* @param instanceEnabled <tt>true</tt> if the instance should be enabled
*/
private void checkBehaviour(
QName className, NodeRef nodeRef,
boolean globalEnabled,
boolean classEnabled,
boolean classInstanceEnabled,
boolean instanceEnabled)
{
assertEquals("Incorrect behaviour state: global: ", globalEnabled, behaviourFilter.isEnabled());
assertEquals("Incorrect behaviour state: class: ", classEnabled, behaviourFilter.isEnabled(className));
assertEquals("Incorrect behaviour state: classAndInstance", classInstanceEnabled, behaviourFilter.isEnabled(nodeRef, className));
assertEquals("Incorrect behaviour state: instance", instanceEnabled, behaviourFilter.isEnabled(nodeRef));
assertEquals("'Active' flag incorrect: ",
!(globalEnabled && classEnabled && classInstanceEnabled && instanceEnabled),
behaviourFilter.isActivated());
}
//
// Behaviour Implementations