mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user