cancel
Showing results for 
Search instead for 
Did you mean: 

How to get Alfresco services in workflow service task

pnature
Star Contributor
Star Contributor

Hi,

I am new on Alfresco community version 5.2 

I need use Alfresco services (NodeService, ContentService, ServiceRegistry) inside class used for workflow service task.

I created class but I cannot use Alfresco Services. All methods returns null. What I do wrong?

Thanks in advance.

My class and reference are here:

public class myClass implements JavaDelegate {

    private NodeService nodeService;

    private ServiceRegistry serviceRegistry;

    private ContentService contentService;
    private ApplicationContext applicationContext;

    @Override
      public void execute(DelegateExecution execution) throws Exception {

        System.out.println("getContentService() " + getContentService());
        System.out.println("getServiceRegistry() " + getServiceRegistry());

  }

    public ContentReader getContentReader(NodeRef docref) {
        ContentReader reader = contentService.getReader(docref, ContentModel.PROP_CONTENT);
        return reader;
    }

    public void setContentService(ContentService contentService)  {
        this.contentService = contentService;
    }
    
    public ContentService getContentService() {
        return this.contentService;
    }

    public void setNodeService(NodeService nodeService) {
        this.nodeService = nodeService;
    }
    
    public void setServiceRegistry(ServiceRegistry serviceRegistry) {
        //this.serviceRegistry=(ServiceRegistry)applicationContext.getBean("serviceRegistry");   //this line cause error on deploy
        this.serviceRegistry = serviceRegistry;
    }
    
    public ServiceRegistry getServiceRegistry() {
        return this.serviceRegistry;
    }

}

I created file my-class-context.xml on path /myProject/src/main/amp/config/alfresco/extension

I have tried tu put referencies to service-context.xml too.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="myClass" class="com.demo.myProject.task.myClass">
      <property name="contentService">
          <ref bean="ContentService" />
      </property>
      <property name="nodeService">
          <ref bean="NodeService" />
      </property>
        <property name="serviceRegistry">
            <ref bean="ServiceRegistry"></ref>
        </property>
</bean>
</beans>

1 ACCEPTED ANSWER

afaust
Legendary Innovator
Legendary Innovator

There are two ways of dealing with Alfresco services in this case.

  1. Configure a bean instance of your delegate in the Spring context files, register it with the Activiti bean registry and use a delegate expression on your task to call the specific bean instead of constructing a new instance.
  2. Use the Activiti bean registry to get a reference to the Alfresco ServiceRegistry and from that obtain all the necessary services.

The limitation on option #2 is that you can only get public services of Alfresco - any components / services not covered by the ServiceRegistry interface are not accessible (if you don't count a dirty trick of using the ServiceRegistry to lookup any bean).

As an example you can get the NodeService this way with option #2:

Map<Object, Object> registeredBeans = Context.getProcessEngineConfiguration().getBeans();
ServiceRegistry registry = (ServiceRegistry)registeredBeans.get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
NodeService nodeService = registry.getNodeService();‍‍‍‍‍‍‍‍‍‍

View answer in original post

4 REPLIES 4

afaust
Legendary Innovator
Legendary Innovator

There are two ways of dealing with Alfresco services in this case.

  1. Configure a bean instance of your delegate in the Spring context files, register it with the Activiti bean registry and use a delegate expression on your task to call the specific bean instead of constructing a new instance.
  2. Use the Activiti bean registry to get a reference to the Alfresco ServiceRegistry and from that obtain all the necessary services.

The limitation on option #2 is that you can only get public services of Alfresco - any components / services not covered by the ServiceRegistry interface are not accessible (if you don't count a dirty trick of using the ServiceRegistry to lookup any bean).

As an example you can get the NodeService this way with option #2:

Map<Object, Object> registeredBeans = Context.getProcessEngineConfiguration().getBeans();
ServiceRegistry registry = (ServiceRegistry)registeredBeans.get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
NodeService nodeService = registry.getNodeService();‍‍‍‍‍‍‍‍‍‍

pnature
Star Contributor
Star Contributor

Thank you for reply.

I am really new in Alfresco and I cannot find information about using Activiti bean registry. What is it? Where is it? Is it configuration file on Alfresco or in project?

I have tried 2. way and I have got contentService but

ContentReader reader = contentService.getReader(docref, ContentModel.PROP_CONTENT);

failed

No authentication provider for net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken

upforsin
Star Collaborator
Star Collaborator

Could you please elaborate more on the first option?

In service-context.xml we can add new bean:

<bean id="com.example.CreateXML" class="com.example.platformsample.CreateXML" parent="baseJavaDelegate">
<property name="nodeService" ref="NodeService" />
</bean>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

But how we can "register it with the Activiti bean registry" ? Should we somehow override activitiProcessEngineConfiguration bean?

In the myprocess.bpmn20.xml file we can add:

<serviceTask id="approvedInvoiceScript" name="Test" activiti:class="com.example.platformsample.CreateXML">
<extensionElements>
<activiti:field name="nodeService">
<activiti:expression>${NodeService}</activiti:expression>
</activiti:field>
</extensionElements>
</serviceTask>‍‍‍‍‍‍‍‍‍‍‍‍‍‍

An in the CreateXML.java we add:

private NodeService nodeService;
public void setNodeService(NodeService nodeService) {
this.nodeService = nodeService;
}‍‍‍‍

Am I right?

howkymike
Alfresco Developer

afaust
Legendary Innovator
Legendary Innovator

In your example, the CreateXML instance will be registered as a bean in the Activiti bean registry simply through the fact that it inherits from the "baseJavaDelegate". You should rename the ID of the bean to something without using dots, as the ID of the bean is what you would use to resolve it, e.g. now it would be ${com.example.CreateXML} in Activiti expressions, which is way confusing and actually problematic as a bean shell expression, since dots have a special meaning as separators for property accessors.

The NodeService would not be available as a bean in your case since only the enclosing instance of CreateXML will be registered as a bean with Activiti. You could of course write some code in CreateXML that overrides the setBeanRegistry method from the BaseJavaDelegate parent class to put whatever you like in the parameter map (the bean registry).