mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-22 15:12:38 +00:00
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:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -81,13 +81,34 @@ public interface BehaviourFilter
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* The change applies <b>ONLY</b> to the current transaction.
|
||||
*
|
||||
*
|
||||
* @param className the type/aspect behaviour to disable
|
||||
*/
|
||||
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
|
||||
* <p>
|
||||
@@ -114,6 +135,7 @@ public interface BehaviourFilter
|
||||
|
||||
/**
|
||||
* Enable behaviour for all nodes
|
||||
* <br>This is also applied to the to the disabled behaviours with {@link #disableBehaviour(QName, boolean)}</br>
|
||||
* <p>
|
||||
* The change applies <b>ONLY</b> to the current transaction.
|
||||
*
|
||||
@@ -162,7 +184,7 @@ public interface BehaviourFilter
|
||||
* @return true => behaviour is enabled
|
||||
*/
|
||||
public boolean isEnabled(QName className);
|
||||
|
||||
|
||||
/**
|
||||
* Determine if behaviour is enabled for specific node and class.
|
||||
* <p>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -24,6 +24,7 @@ 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.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -115,30 +116,34 @@ public class BehaviourFilterImpl implements BehaviourFilter
|
||||
|
||||
@Override
|
||||
public void disableBehaviour(QName className)
|
||||
{
|
||||
disableBehaviour(className, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableBehaviour(QName className, boolean includeSubClasses)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Behaviour: DISABLE (" + AlfrescoTransactionSupport.getTransactionId() + "): " + className);
|
||||
}
|
||||
ParameterCheck.mandatory("className", className);
|
||||
ClassFilter classFilter = new ClassFilter(className, includeSubClasses);
|
||||
|
||||
TransactionalResourceHelper.incrementCount(KEY_FILTER_COUNT);
|
||||
|
||||
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
|
||||
MutableInt filter = classFilters.get(className);
|
||||
if (filter == null)
|
||||
|
||||
Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
|
||||
MutableInt filterNumber = classFilters.get(classFilter);
|
||||
if (filterNumber == null)
|
||||
{
|
||||
filter = new MutableInt(1); // Already incremented
|
||||
classFilters.put(className, filter);
|
||||
filterNumber = new MutableInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter.increment();
|
||||
}
|
||||
|
||||
filterNumber.increment();
|
||||
classFilters.put(classFilter, filterNumber);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(" Now: " + filter);
|
||||
logger.debug(" Now: " + filterNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,25 +246,33 @@ public class BehaviourFilterImpl implements BehaviourFilter
|
||||
// Nothing was disabled
|
||||
return;
|
||||
}
|
||||
Map<QName, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
|
||||
MutableInt filter = classFilters.get(className);
|
||||
if (filter == null)
|
||||
Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
|
||||
MutableInt filterNumber = null;
|
||||
for (ClassFilter classFilter : classFilters.keySet())
|
||||
{
|
||||
if (classFilter.getClassName().equals(className))
|
||||
{
|
||||
filterNumber = classFilters.get(classFilter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filterNumber == null)
|
||||
{
|
||||
// Class was not disabled
|
||||
return;
|
||||
}
|
||||
else if (filter.intValue() <= 0)
|
||||
else if (filterNumber.intValue() <= 0)
|
||||
{
|
||||
// Can't go below zero for this
|
||||
}
|
||||
else
|
||||
{
|
||||
filter.decrement();
|
||||
filterNumber.decrement();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
public boolean isEnabled(QName className)
|
||||
{
|
||||
@@ -374,9 +403,68 @@ public class BehaviourFilterImpl implements BehaviourFilter
|
||||
// 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;
|
||||
Map<ClassFilter, MutableInt> classFilters = TransactionalResourceHelper.getMap(KEY_CLASS_FILTERS);
|
||||
|
||||
// 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
|
||||
|
@@ -161,19 +161,11 @@ import org.alfresco.util.LockHelper;
|
||||
{
|
||||
List<BehaviourDefinition> behaviours = new ArrayList<BehaviourDefinition>();
|
||||
|
||||
// Determine if behaviour has been disabled
|
||||
boolean isEnabled = true;
|
||||
if (filter != null)
|
||||
// Find class behaviour by scanning up the class hierarchy
|
||||
List<BehaviourDefinition<B>> behaviour = null;
|
||||
|
||||
if (isEnabled(binding))
|
||||
{
|
||||
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
|
||||
List<BehaviourDefinition<B>> behaviour = null;
|
||||
while (binding != null)
|
||||
{
|
||||
behaviour = classMap.get(binding);
|
||||
@@ -184,7 +176,6 @@ import org.alfresco.util.LockHelper;
|
||||
binding = (B)binding.generaliseBinding();
|
||||
}
|
||||
}
|
||||
|
||||
// Append all service-level behaviours
|
||||
behaviours.addAll(serviceMap.getAll());
|
||||
|
||||
@@ -196,7 +187,6 @@ import org.alfresco.util.LockHelper;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addChangeObserver(BehaviourChangeObserver<B> observer)
|
||||
{
|
||||
@@ -264,6 +254,18 @@ import org.alfresco.util.LockHelper;
|
||||
{
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
75
source/java/org/alfresco/repo/policy/ClassFilter.java
Normal file
75
source/java/org/alfresco/repo/policy/ClassFilter.java
Normal 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 +
|
||||
'}';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user