workflowalfrescoactivitialfresco-shareworkflow-activity

Integrate applet on workflow Alfresco


Question: I have an applet that makes "changes" on PDFs, and after this I have to save the changes to the respective file on the respository. How can I integrate this applet on a workflow? Any hint or document to read?

I thought in a task form (in a task-edit page), with a new component with a button to call the applet, but this is a good idea? And works? Because I wanted when the person press the accept button, the applet is called, and only then when the change was made, the task would be completed. But how?


Solution

  • I do not have the details of your applet and so I cannot be sure that it is possible, but you can try to simply use some javascript to access public methods of your applet.

    The form-engine in Alfresco is easily customisable writing your custom controls. The custom control will generate the html and the javascript necessary to embed your applet in the form and call it when a button is pressed.

    It would be useful to know if you can intercept on Alfresco the update executed by the applet. For example, you can have a listener (behaviour) in Alfresco that will be called when the document is updated. If, based on your business logic, the listener can understand that the applet has completed the operation, it can automatically fire the transition of the workflow. This solution is robust because the update executed by the applet and the update of the task will be transactional: they both succeed or the update is rolled back.

    If possible, do not call the applet and the transition of the workflow separately: the two operations won't be atomic and you can end up with an inconsistent repository.

    Update To avoid any customisation of Alfresco functionality, do not modify the acitiviti transitions. Given that you only need to add a button to call your applet, use a custom ftl and specify it in the configuration of your form.

    The following article is a good guide to learn how to do it (I strongly suggest to read it and follow the exercise):

    Jeff Potts' article on Advanced Workflows

    As you can see at paragraph Edit share-config-custom.xml, you can specify the free marker template for rendering each field in your form. You can specify, if you prefer, a different template to use for your transition button. This template will render the applet and the html and javascript to call it.

    The following class is an example (it is a snippet copied from real code, I have not tested it, it is meant only to show the main part of a behaviour) of a behaviour that listens for the creation of a node or the update of its properties. You have to choose what it is better for you. What exactly does the applet? Does it create a new node? Or update its properties ? Or update the content of the node?

    The following link gives you an example of code that triggers the transition: Trigger Activiti workflow for task sitting in ReceiveTask looping

    package com.someco.alfresco.behaviours;
    
    import java.io.Serializable;
    import java.util.List;
    import java.util.Map;
    
    import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
    import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
    import org.alfresco.repo.policy.Behaviour;
    import org.alfresco.repo.policy.JavaBehaviour;
    import org.alfresco.service.cmr.repository.ChildAssociationRef;
    import org.alfresco.service.cmr.repository.NodeRef;
    import org.alfresco.service.cmr.site.SiteInfo;
    import org.alfresco.service.namespace.NamespaceService;
    import org.alfresco.service.namespace.QName;
    import org.apache.log4j.Logger;
    
    
    public class SomeObjectCreatePolicy implements OnCreateNodePolicy, OnUpdatePropertiesPolicy {
        private final Logger logger = Logger.getLogger(SomeObjectCreatePolicy.class);
    
        @Override
        public void init() {
            this.policyComponent.bindClassBehaviour(
                    QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
                    Model.TYPE_ENTITY_OBJECT,
                    new JavaBehaviour(this, "onCreateNode", 
                            Behaviour.NotificationFrequency.TRANSACTION_COMMIT));
    
            this.policyComponent.bindClassBehaviour(
                    QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
                    Model.TYPE_ENTITY_OBJECT,
                    new JavaBehaviour(this, "onUpdateProperties", 
                            Behaviour.NotificationFrequency.EVERY_EVENT));
        }
    
        @Override
        public void onCreateNode(ChildAssociationRef childAssocRef) {
            /* Your logic to fire the transition */
        }
    
        @Override
        public void onUpdateProperties(NodeRef nodeRef,
                Map<QName, Serializable> before, Map<QName, Serializable> after) {
            /* Your logic to fire the transition */
        }
    }
    

    Of course, you can instantiate the object using Spring:

    <bean id="org.alfresco.behaviours.someObjectCreatePolicy" class="com.someco.alfresco.policy.SomeObjectCreatePolicy"
            init-method="init">
    </bean>