/*
* Copyright 2015 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.
*
* 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.kie.server.services.jbpm.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import org.drools.core.util.StringUtils;
import org.jbpm.kie.services.impl.FormManagerService;
import org.jbpm.services.api.DefinitionService;
import org.jbpm.services.api.RuntimeDataService;
import org.jbpm.services.api.UserTaskService;
import org.jbpm.services.api.model.ProcessDefinition;
import org.kie.api.task.model.Task;
import org.kie.server.services.api.KieServerRegistry;
import org.kie.server.services.impl.KieContainerInstanceImpl;
import org.kie.server.services.impl.locator.ContainerLocatorProvider;
import org.kie.server.services.jbpm.ui.api.UIFormProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FormServiceBase {
public static final Logger logger = LoggerFactory.getLogger(FormServiceBase.class);
private static final ServiceLoader<UIFormProvider> formProviders = ServiceLoader.load(UIFormProvider.class);
private DefinitionService definitionService;
private RuntimeDataService dataService;
private UserTaskService userTaskService;
private KieServerRegistry registry;
private Set<UIFormProvider> providers = new LinkedHashSet<UIFormProvider>();
public enum FormType {
FORM_MODELLER_TYPE("FORM", "xml"),
FORM_TYPE("FRM", "json"),
FREE_MARKER_TYPE("FTL", "xml"),
ANY( "ANY", null );
private String name;
private String contentType;
private FormType(String name, String contentType) {
this.name = name;
this.contentType = contentType;
}
public String getName() {
return name;
}
public String getContentType() {
return contentType;
}
public static FormType fromName(String name) {
if (FORM_MODELLER_TYPE.getName().equals(name)) {
return FORM_MODELLER_TYPE;
} else if (FORM_TYPE.getName().equals(name)) {
return FORM_TYPE;
} else if (FREE_MARKER_TYPE.getName().equals(name)) {
return FREE_MARKER_TYPE;
} else if ( ANY.getName().equals( name ) ) {
return ANY;
} else {
throw new IllegalArgumentException("No FormType enum value for " + name);
}
}
}
public FormServiceBase(DefinitionService definitionService, RuntimeDataService dataService, UserTaskService userTaskService, FormManagerService formManagerService, KieServerRegistry registry) {
this.definitionService = definitionService;
this.dataService = dataService;
this.userTaskService = userTaskService;
this.registry = registry;
providers.addAll(collectFormProviders(formManagerService));
}
public String getFormDisplayProcess(String containerId, String processId, String lang, boolean filterContent, String formType) {
containerId = registry.getContainerId(containerId, ContainerLocatorProvider.get().getLocator());
ProcessDefinition processDesc = definitionService.getProcessDefinition(containerId, processId);
if (processDesc == null) {
throw new IllegalStateException("Process definition " + containerId + " : " + processId + " not found");
}
Map<String, String> processData = definitionService.getProcessVariables(containerId, processId);
if (processData == null) {
processData = new HashMap<>();
}
Map<String, Object> renderContext = new HashMap<>();
renderContext.put("process", processDesc);
renderContext.put("outputs", processData);
renderContext.put("lang", lang);
renderContext.put("filterForm", filterContent);
for (UIFormProvider provider : providers) {
// if there's no formType or formType is ANY the first provider able to generate the formContent wins
if ( !FormType.ANY.getName().equals( formType ) && !provider.getType().equals( formType ) ) {
logger.debug( "Provider {} does not support {} form type", provider, formType );
continue;
}
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());
throw new IllegalStateException("No form for process with id " + processDesc.getName() + " found");
}
public String getFormDisplayTask(long taskId, String lang, boolean filterContent, String formType) {
Task task = userTaskService.getTask(taskId);
if (task == null) {
throw new IllegalStateException("No task with id " + taskId + " found");
}
String name = task.getName();
ProcessDefinition processDesc = dataService.getProcessesByDeploymentIdProcessId(task.getTaskData()
.getDeploymentId(), task.getTaskData().getProcessId());
Map<String, Object> renderContext = new HashMap<>();
renderContext.put("filterForm", filterContent);
Map<String, Object> input = userTaskService.getTaskInputContentByTaskId(taskId);
renderContext.put("inputs", input);
for (Map.Entry<String, Object> inputVar : input.entrySet()) {
renderContext.put(inputVar.getKey(), inputVar.getValue());
}
Map<String, String> outputDef = definitionService.getTaskOutputMappings(task.getTaskData().getDeploymentId(), task.getTaskData().getProcessId(), task.getName());
Map<String, Object> output = userTaskService.getTaskOutputContentByTaskId(taskId);
renderContext.put("outputs", output);
for (Map.Entry<String, Object> outputVar : output.entrySet()) {
renderContext.put(outputVar.getKey(), outputVar.getValue());
}
outputDef.forEach((k, v) -> {
if ( !renderContext.containsKey( k ) ) {
renderContext.put(k, "");
}
});
renderContext.put("lang", lang);
renderContext.put("task", task);
for (UIFormProvider provider : providers) {
// if there's no formType or formType is ANY the first provider able to generate the formContent wins
if ( !FormType.ANY.getName().equals( formType ) && !provider.getType().equals( formType ) ) {
logger.debug( "Provider {} does not support {} form type", provider, formType );
continue;
}
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.getName());
throw new IllegalStateException("No form for task with id " + taskId + " found");
}
protected List<UIFormProvider> collectFormProviders(FormManagerService formManagerService) {
List<UIFormProvider> uiFormProviders = new ArrayList<UIFormProvider>();
for (UIFormProvider formProvider : formProviders) {
formProvider.configure(formManagerService);
uiFormProviders.add(formProvider);
}
Collections.sort(uiFormProviders, new Comparator<UIFormProvider>() {
@Override
public int compare(UIFormProvider e1, UIFormProvider e2) {
return Integer.valueOf(e1.getPriority()).compareTo(Integer.valueOf(e2.getPriority()));
}
});
return uiFormProviders;
}
}