如何仅使用Java更新alfresco工作流任务中的自定义属性?

时间:2017-07-15 11:50:48

标签: java alfresco alfresco-webscripts

首先,我要感谢所有花时间帮助我解决问题的人,因为我正在寻找一个多星期的时间来解决我的问题。这是:

我的目标是在Alfresco社区5.2中启动自定义工作流,并通过仅使用Public Java API的Web脚本在第一个任务中设置一些自定义属性。我的类正在扩展AbstractWebScript。目前,我已经成功启动了工作流程并设置了bpm:workflowDescription等属性,但我无法在任务中设置自定义属性。

以下是代码:

    public class StartWorkflow extends AbstractWebScript {
    /**
     * The Alfresco Service Registry that gives access to all public content services in Alfresco.
     */
    private ServiceRegistry serviceRegistry;

    public void setServiceRegistry(ServiceRegistry serviceRegistry) {
        this.serviceRegistry = serviceRegistry;
    }

    @Override
    public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException {       

        // Create JSON object for the response
        JSONObject obj = new JSONObject();

        try {                        
            // Check if parameter defName is present in the request            
            String wfDefFromReq = req.getParameter("defName");
            if (wfDefFromReq == null) {
                obj.put("resultCode", "1 (Error)");
                obj.put("errorMessage", "Parameter defName not found.");
                return;      
            }            
            // Get the WFL Service
            WorkflowService workflowService = serviceRegistry.getWorkflowService();
            // Build WFL Definition name
            String wfDefName = "activiti$" + wfDefFromReq;
            // Get WorkflowDefinition object
            WorkflowDefinition wfDef = workflowService.getDefinitionByName(wfDefName);
            // Check if such WorkflowDefinition exists
            if (wfDef == null) {
                obj.put("resultCode", "1 (Error)");
                obj.put("errorMessage", "No workflow definition found for defName = " + wfDefName);
                return;
            }                       

            // Get parameters from the request
            Content reqContent = req.getContent();
            if (reqContent == null) {
                throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing request body.");
            }
            String content;
            content = reqContent.getContent();

            if (content.isEmpty()) {
                throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Content is empty");
            }

            JSONTokener jsonTokener = new JSONTokener(content);
            JSONObject json = new JSONObject(jsonTokener);           

            // Set the workflow description
            Map<QName, Serializable> params = new HashMap();
            params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "Workflow started from JAVA API");          

            // Start the workflow
            WorkflowPath wfPath = workflowService.startWorkflow(wfDef.getId(), params);

            // Get params from the POST request
            Map<QName, Serializable> reqParams = new HashMap();
            Iterator<String> i = json.keys();
            while (i.hasNext()) {
                String paramName = i.next();
                QName qName = QName.createQName(paramName);
                String value = json.getString(qName.getLocalName());
                reqParams.put(qName, value);  
            }

            // Try to update the task properties

            // Get the next active task which contains the properties to update
            WorkflowTask wfTask = workflowService.getTasksForWorkflowPath(wfPath.getId()).get(0);
            // Update properties
            WorkflowTask updatedTask = workflowService.updateTask(wfTask.getId(), reqParams, null, null);

            obj.put("resultCode", "0 (Success)");
            obj.put("workflowId", wfPath.getId());

        } catch (JSONException e) {
            throw new WebScriptException(Status.STATUS_BAD_REQUEST, 
                    e.getLocalizedMessage());
        } catch (IOException ioe) {
            throw new WebScriptException(Status.STATUS_BAD_REQUEST, 
                    "Error when parsing the request.", 
                    ioe);
        } finally {
            // build a JSON string and send it back
            String jsonString = obj.toString();
            res.getWriter().write(jsonString);
        }

    }  
}

以下是我如何调用webscript:

curl -v -uadmin:admin -X POST -d @postParams.json localhost:8080/alfresco/s/workflow/startJava?defName=nameOfTheWFLDefinition -H "Content-Type:application/json"

在postParams.json文件中,我有需要更新的属性/值对:

{
"cmprop:propOne" : "Value 1",
"cmprop:propTwo" : "Value 2",
"cmprop:propThree" : "Value 3"

}

工作流已启动,bpm:workflowDescription已正确设置,但任务中的属性不可见。

我创建了一个JS脚本,我在工作流启动时调用它:

execution.setVariable('bpm_workflowDescription', 'Some String ' + execution.getVariable('cmprop:propOne'));

实际上使用了cmprop:propOne的值并且描述已正确更新 - 这意味着这些属性在某处更新(在执行级别上可能?)但我无法弄清楚当我打开任务时它们不可见的原因。

我成功启动工作流程并使用JavaScript API更新属性:

if (wfdef) {

        // Get the params
        wfparams = {};
        if (jsonRequest) {
            for ( var prop in jsonRequest) {
                wfparams[prop] = jsonRequest[prop];
            }
        }

        wfpackage = workflow.createPackage();

        wfpath = wfdef.startWorkflow(wfpackage, wfparams);

问题是我只想使用公共Java API,请帮忙。 谢谢!

2 个答案:

答案 0 :(得分:0)

您是否在任务中本地设置了变量?从我看来,似乎你在执行级别定义变量,而不是在状态级别定义。如果你看一下ootb adhoc.bpmn20.xml文件(https://github.com/Activiti/Activiti-Designer/blob/master/org.activiti.designer.eclipse/src/main/resources/templates/adhoc.bpmn20.xml),你会注意到一个在本地设置变量的事件监听器:

<extensionElements>
    <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
       <activiti:field name="script">
          <activiti:string>
           if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
           if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
          </activiti:string>
       </activiti:field>
    </activiti:taskListener>
</extensionElements>

答案 1 :(得分:0)

通常,我只是尝试导入自定义模型前缀的所有任务。所以对你来说,看起来应该是这样的:

import java.util.Set;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.apache.log4j.Logger;

public class ImportVariables extends AbstractTaskListener {

    private Logger logger = Logger.getLogger(ImportVariables.class);

    @Override
    public void notify(DelegateTask task) {

        logger.debug("Inside ImportVariables.notify()");
        logger.debug("Task ID:" + task.getId());
        logger.debug("Task name:" + task.getName());
        logger.debug("Task proc ID:" + task.getProcessInstanceId());
        logger.debug("Task def key:" + task.getTaskDefinitionKey());

        DelegateExecution execution = task.getExecution();

        Set<String> executionVariables = execution.getVariableNamesLocal();
        for (String variableName : executionVariables) {
            // If the variable starts by "cmprop_"
            if (variableName.startsWith("cmprop_")) {
                // Publish it at the task level
                task.setVariableLocal(variableName, execution.getVariableLocal(variableName));
            }
        }
    }

}