cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to register VersionServicePolicies.CalculateVersionLabelPolicy

absmith
Champ in-the-making
Champ in-the-making

I am working with the Java api to implement a class which implements custom behaviors for VersionServicePolicies.CalculateVersionLabelPolicy and VersionServicePolicies.OnCreateVersionPolicy. 

I can get my onCreateVersionPolicy implementation registered and working without issue, however, I am not having success with the CalculateVersionLabelPolicy policy implementation. 

Here is a snippet of the error I recieve when trying to deploy the war containing my class:

Caused by: org.alfresco.error.AlfrescoRuntimeException: 00250020 Failed to execute transaction-level behaviour public abstract void org.alfresco.repo.content.ContentServicePolicies$OnContentUpdatePolicy.onContentUpdate(org.alfresco.service.cmr.repository.NodeRef,boolean) in transaction dd3e3520-1a78-4eaa-8a70-87538118cdca Caused by: org.alfresco.service.cmr.version.VersionServiceException: 00250019 More than one CalculateVersionLabelPolicy behaviour has been registered for the type {http://www.somesite.com/somepage/model/1.0}configuration"}}

Below is my class which implements these two policies:

public class CustomVersionServiceBehavior 
	implements VersionServicePolicies.CalculateVersionLabelPolicy,
	VersionServicePolicies.OnCreateVersionPolicy {
	
	private PolicyComponent policyComponent;
	private Behaviour calculateVersionLabel;
	private Behaviour onCreateVersion;
	
    public void setPolicyComponent(PolicyComponent policyComponent) {
        this.policyComponent = policyComponent;
    }

    public PolicyComponent getPolicyComponent() {
        return this.policyComponent;
    }
	
	public void init() {
		
		this.calculateVersionLabel = new JavaBehaviour(this, "calculateVersionLabel", NotificationFrequency.EVERY_EVENT);
		this.onCreateVersion = new JavaBehaviour(this, "onCreateVersion", NotificationFrequency.EVERY_EVENT);

		this.policyComponent.bindClassBehaviour(
				QName.createQName(NamespaceService.ALFRESCO_URI, "calculateVersionLabel"), 
				ContentModel.TYPE_CONTENT, this.calculateVersionLabel);
				
		this.policyComponent.bindClassBehaviour(VersionServicePolicies.OnCreateVersionPolicy.QNAME, 
				ContentModel.TYPE_CONTENT, this.onCreateVersion);
	}

	@Override
	public String calculateVersionLabel(QName arg0, Version arg1, int arg2, Map<String, Serializable> arg3) {
		System.out.println("Hello from calculateVersionLabel()");
		return null;
	}

	@Override
	public void onCreateVersion(QName arg0, NodeRef arg1, Map<String, Serializable> arg2, PolicyScope arg3) {
		System.out.println("Hello from onCreateVersionPolicy()");
	}

}

What am I missing?

2 REPLIES 2

afaust
Legendary Innovator
Legendary Innovator

The problem is that Alfresco already has a calculate version label policy registered by default, and since policies are always additive / cumulative, never replacing each other, you end up with two if you register a custom policy. I think this is one of those parts of Alfresco where they did not really develop or test for extensibility, and since that policy is not really documented anywhere, they might not even consider it a supported extension point (though it is marked with the @AlfrescoPublicAPI annotation).

upforsin
Star Collaborator
Star Collaborator

Hi @absmith 

@afaust is correct but you can always override default policies in the service-context.xml file.

Particularly in this example, create custom CustomSerialVersionLabelPolicy bean and inject it to the registerContentWithVersionService/registerMLContainerWithVersionService bean.

In the CustomSerialVersionLabelPolicy.java class, you can easily write your own logic.

service-context.xml example:

    <bean id="customSerialVersionLabelPolicy" class="com.example.version.CustomSerialVersionLabelPolicy" >
    </bean>

    <bean id="registerContentWithVersionService" class="org.alfresco.repo.version.VersionServiceVersionLabelRegistrationBean" init-method="register">
       <property name="versionService">
            <ref bean="versionService" />
        </property>
        <property name="namespacePrefixResolver">
            <ref bean="namespaceService" />
        </property>
        <property name="typeQName">
            <value>cm:content</value>
        </property>
        <property name="policy">
             <ref bean="customSerialVersionLabelPolicy" />
        </property>
    </bean>

    <bean id="registerMLContainerWithVersionService" class="org.alfresco.repo.version.VersionServiceVersionLabelRegistrationBean" init-method="register">
       <property name="versionService">
            <ref bean="versionService" />
        </property>
        <property name="namespacePrefixResolver">
            <ref bean="namespaceService" />
        </property>
        <property name="typeQName">
            <value>cm:mlContainer</value>
        </property>
        <property name="policy">
             <ref bean="customSerialVersionLabelPolicy" />
        </property>
    </bean>

Also be aware that this problem exists only if you want to apply custom logic to all content (cm:content), if you want to do it on custom types, you can use behaviours.

howkymike
Alfresco Developer