Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
Content Modeling
Policies
Behaviors
See Services Framework#Component Policies for description of Policies.
The Policy Component allows:
Each Policy is defined as an interface with a single method. A Policy is either of type Class, Property or Association which is indicated by inheriting from one of the following marker interfaces:
Policy method parameters define the state available to each bound behaviour. Policy method return values define the expected results of a behaviour.
Examples:
interface CalculateVersionLabelPolicy extends ClassPolicy
{
String calculateVersionLabel(QName classRef,
Version preceedingVersion,
int versionNumber,
Map<String, Serializable> versionProperties);
}
interface BeforeCreatePolicy extends ClassPolicy
{
void beforeCreate(ClassRef classRef);
}
interface BeforeSetPropertyPolicy extends PropertyPolicy
{
void beforeSetProperty(QName property, Serializable newValue);
}
The following policy meta-data is supported:
Future support will allow for meta-data provision via Annotations.
Example:
@Policy(namespace='namespaceURI')
interface VersionLabelPolicy extends ClassPolicy
{
string getVersionLabel(NodeRef node);
}
Current support will allow for meta-data provision via static variables.
Example:
interface VersionLabelPolicy extends ClassPolicy
{
static String NAMESPACE = 'namespaceURI';
string getVersionLabel(NodeRef node);
}
Policies are registered during the initialisation of a Service using the PolicyComponent (injected via DI).
Example:
public void NodeService
{
private ClassPolicyDelegate<BeforeCreatePolicy> beforeCreateDelegate;
public void init()
{
beforeCreateDelegate = policyComponent.registerClassPolicy(BeforeCreatePolicy.class);
}
...
}
The PolicyComponent updates its registry of available Policies by interrogating the passed Policy interface (and associated meta-data). A Policy is registered for each method.
Registration returns a PolicyDelegate (parameterized by the passed Policy Interface). The service keeps hold of the delegate to invoke Policies.
public interface PolicyComponent
{
....
publicClassPolicyDelegate<P> registerClassPolicy(Class<P> policy);
public <P extends PropertyPolicy> PropertyPolicyDelegate<P> registerPropertyPolicy(Class<P> policy);
public <P extends AssociationPolicy> AssociationPolicyDelegate<P> registerAssociationPolicy(Class<P> policy);
public Collection<PolicyDefinition> getRegisteredPolicies();
public PolicyDefinition<Policy> getRegisteredPolicy(PolicyType policyType, QName policy);
public boolean isRegisteredPolicy(PolicyType policyType, QName policy);
....
}
Please refer to JavaDoc for more details.
A Service invokes a Policy via the PolicyDelegate. Given an appropriate context (e.g. ClassRef for a ClassPolicy), the PolicyDelegate returns a bound implementation of the registered Policy interface.
The service then calls the appropriate Policy method(s) on the interface to invoke any registered behaviour for that context.
Example:
public void NodeService
{
public NodeRef createNode(...)
{
...
BeforeCreatePolicy policy = beforeCreateDelegate.get(nodeClassRef);
policy.beforeCreate(nodeClassRef);
...
}
}
A Service does not necessarily concern itself with how many behaviours are registered with the policy for a given context. It may be that none, one or many have been registered. In any case, the above code applies.
However, there are some scenarios where a service may wish to have more control over the behaviours invoked. For example, a Policy may have a return value, or a service may want control over prioritisation, conflicts etc. In this case, the delegate provides an alternate form of get where an array of Policy interfaces is returned (one for each registered behaviour).
Example:
public void NodeService
{
public NodeRef createNode(...)
{
...
BeforeCreatePolicy[] policies = beforeCreateDelegate.getList(nodeRef);
for (policy in policies)
{
policy.beforeCreate(nodeClassRef);
}
...
AfterCreatePolicy[] policies = beforeCreateDelegate.getList(nodeRef);
for (policy in policies)
{
policy.afterCreate(nodeClassRef);
}
}
}
class ClassPolicyDelegate<T extends ClassPolicy>
{
T get(ClassRef classRef);
T get(NodeRef nodeRef);
T[] getList(ClassRef classRef);
T[] getList(NodeRef nodeRef);
}
class PropertyPolicyDelegate<T extends PropertyPolicy>
{
T get(ClassRef classRef, QName property);
T get(NodeRef classRef, QName property);
T[] getList(ClassRef classRef, QName property);
T[] getList(NodeRef classRef, QName property);
}
class PropertyPolicyDelegate<T extends AssociationPolicy>
{
T get(ClassRef classRef, QName association);
T get(NodeRef classRef, QName association);
T[] getList(ClassRef classRef, QName association);
T[] getList(NodeRef classRef, QName association);
}
Note:
Behaviour can be bound to a policy using the PolicyComponent. Typically, behaviour is associated with a given Type or Aspect in the Content Domain Model. But in some scenarios, the behaviour may not be type specific, and as such, is always applied.
Example:
public void FolderComponent
{
public void init()
{
policyComponent.bindBehaviour('alf:getVersionLabel', new ClassBinding('alf:Folder'),
new JavaBehaviourDelegate(this, 'getVersionLabel'));
}
private string getVersionLabel(NodeRef ref)
{
...
}
}
The bindBehaviour method takes the following arguments:
policyName - name of policy (as registered) to bind to
binding - the context in which the behaviour applies (can also be Property and AssociationBinding) or null (always apply)
behaviourDelegate - pointer to the behaviour (default Java, but could also be ScriptedBehaviourDelegate)
<pre>
public interface PolicyComponent
{
....
public BehaviourDefinition<ClassBehaviourBinding> bindClassBehaviour(QName policy, QName className, Behaviour behaviour);
public BehaviourDefinition<ServiceBehaviourBinding> bindClassBehaviour(QName policy, Object service, Behaviour behaviour);
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindPropertyBehaviour(QName policy, QName className, QName propertyName, Behaviour behaviour);
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindPropertyBehaviour(QName policy, QName className, Behaviour behaviour);
public BehaviourDefinition<ServiceBehaviourBinding> bindPropertyBehaviour(QName policy, Object service, Behaviour behaviour);
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, QName assocName, Behaviour behaviour);
public BehaviourDefinition<ClassFeatureBehaviourBinding> bindAssociationBehaviour(QName policy, QName className, Behaviour behaviour);
public BehaviourDefinition<ServiceBehaviourBinding> bindAssociationBehaviour(QName policy, Object service, Behaviour behaviour);
....
}
Please refer to JavaDoc for more details.
There is no enforced compile-time dependency between a behaviour provider and policy provider. This allows services, aspects and types to be plugged in and out of a Repository (i.e. install/de-install) without breaking code.
Components can bind behaviours without the policy having been registered (or exist), and services can invoke policies without there being any bound behaviour. Warnings etc can be given in these scenarios.
However, there may be cases where it does not matter that code dependencies exist between behaviour and policy (e.g. behaviours registered for core NodeService policies). In these cases, the behaviour implementor can always import the policy interface and implement it on the their behaviour class to ensure compile time checks of method signatures.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.