/* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.kie.services.impl.form; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.drools.core.util.StringUtils; import org.jbpm.kie.services.api.FormProviderService; import org.jbpm.services.api.DefinitionService; import org.jbpm.services.api.DeploymentService; import org.jbpm.services.api.RuntimeDataService; import org.jbpm.services.api.model.DeployedUnit; import org.jbpm.services.api.model.ProcessDefinition; import org.jbpm.services.task.impl.TaskContentRegistry; import org.jbpm.services.task.utils.ContentMarshallerHelper; import org.kie.api.task.TaskService; import org.kie.api.task.model.Content; import org.kie.api.task.model.Task; import org.kie.internal.runtime.manager.InternalRuntimeManager; import org.kie.internal.task.api.ContentMarshallerContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FormProviderServiceImpl implements FormProviderService { private static Logger logger = LoggerFactory.getLogger(FormProviderServiceImpl.class); private TaskService taskService; private DefinitionService bpmn2Service; private RuntimeDataService dataService; private DeploymentService deploymentService; public void setTaskService(TaskService taskService) { this.taskService = taskService; } public void setBpmn2Service(DefinitionService bpmn2Service) { this.bpmn2Service = bpmn2Service; } public void setDataService(RuntimeDataService dataService) { this.dataService = dataService; } public void setDeploymentService(DeploymentService deploymentService) { this.deploymentService = deploymentService; } public void setProviders(Set<FormProvider> providers) { this.providers = providers; } private Set<FormProvider> providers; @Override public String getFormDisplayProcess(String deploymentId, String processId) { ProcessDefinition processDesc = dataService.getProcessesByDeploymentIdProcessId(deploymentId, processId); Map<String, String> processData = bpmn2Service.getProcessVariables(deploymentId, processId); if (processData == null) { processData = new HashMap<String, String>(); } Map<String, Object> renderContext = new HashMap<String, Object>(); renderContext.put("process", processDesc); renderContext.put("outputs", processData); renderContext.put("marshallerContext", getMarshallerContext(deploymentId, processId)); for (FormProvider provider : providers) { String template = provider.render(processDesc.getName(), processDesc, renderContext); if (!StringUtils.isEmpty(template)) { return template; } } logger.warn("Unable to find form to render for process '{}'", processDesc.getName()); return ""; } @Override @SuppressWarnings("unchecked") public String getFormDisplayTask(long taskId) { Task task = taskService.getTaskById(taskId); if (task == null) { return ""; } String name = task.getName(); final String deploymentId = task.getTaskData().getDeploymentId(); final String processId = task.getTaskData().getProcessId(); ProcessDefinition processDesc = null; if(deploymentId != null && processId != null) { processDesc = dataService.getProcessesByDeploymentIdProcessId(deploymentId, processId); } Map<String, Object> renderContext = new HashMap<String, Object>(); ContentMarshallerContext marshallerContext = getMarshallerContext(task); // read task variables Object input = null; long inputContentId = task.getTaskData().getDocumentContentId(); if (inputContentId != -1) { Content content = taskService.getContentById(inputContentId); input = ContentMarshallerHelper.unmarshall(content.getContent(), marshallerContext.getEnvironment(), marshallerContext.getClassloader()); } if (input == null) { input = new HashMap<String, Object>(); } Object output = null; long outputContentId = task.getTaskData().getOutputContentId(); if (outputContentId != -1) { Content content = taskService.getContentById(outputContentId); output = ContentMarshallerHelper.unmarshall(content.getContent(), marshallerContext.getEnvironment(), marshallerContext.getClassloader()); } if (output == null) { output = new HashMap<String, Object>(); } // prepare task variables for rendering Map<String, Object> finalOutput = new HashMap<String, Object>(); if (processId != null && !processId.equals("")) { // If task has an associated process let's merge the outputs Map<String, String> taskOutputMappings = bpmn2Service.getTaskOutputMappings(deploymentId, processId, task.getName()); if (taskOutputMappings == null) { taskOutputMappings = new HashMap<String, String>(); } // I need to replace the value that comes from the //process mappings with the value that can be stored in the output Content for (String key : taskOutputMappings.keySet()) { Object value = ((Map<String, Object>) output).get(key); if (value == null) { value = ""; } finalOutput.put(key, value); } } else if (output instanceof Map && !((Map)output).isEmpty()) { // If the task doesn't belongs to any project BUT it has outputs let's add them directly to the rendering context. finalOutput.putAll( (Map<String, Object>) output ); } // merge template with process variables renderContext.put("task", task); renderContext.put("marshallerContext", marshallerContext); // add all inputs as direct entries if (input instanceof Map) { renderContext.put("inputs", input); for (Map.Entry<String, Object> inputVar : ((Map<String, Object>) input).entrySet()) { renderContext.put(inputVar.getKey(), inputVar.getValue()); } } else { renderContext.put("input", input); } // add all outputs as direct entries renderContext.put("outputs", finalOutput); for (Map.Entry<String, Object> outputVar : ((Map<String, Object>) finalOutput).entrySet()) { renderContext.put(outputVar.getKey(), outputVar.getValue()); } // find form for (FormProvider provider : providers) { String template = provider.render(name, task, processDesc, renderContext); if (!StringUtils.isEmpty(template)) { return template; } } logger.warn("Unable to find form to render for task '{}' on process '{}'", name, processDesc == null ? "" : processDesc.getName()); return ""; } protected ContentMarshallerContext getMarshallerContext(String deploymentId, String processId) { DeployedUnit deployedUnit = deploymentService.getDeployedUnit(deploymentId); if (deployedUnit == null) { return new ContentMarshallerContext(); } InternalRuntimeManager manager = (InternalRuntimeManager) deployedUnit.getRuntimeManager(); return new ContentMarshallerContext(manager.getEnvironment().getEnvironment(), manager.getEnvironment().getClassLoader()); } protected ContentMarshallerContext getMarshallerContext(Task task) { if (task == null) { return new ContentMarshallerContext(); } return TaskContentRegistry.get().getMarshallerContext(task); } }