Last active
July 29, 2019 07:48
-
-
Save marcus-nl/8a9b0ba3636297696058965e2ce4ec27 to your computer and use it in GitHub Desktop.
Camunda custom form handling example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExampleProcessEnginePlugin extends AbstractProcessEnginePlugin { | |
@Override | |
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) { | |
super.preInit(processEngineConfiguration); | |
ExampleFormEngine formEngine = new ExampleFormEngine(); | |
processEngineConfiguration.setCustomFormEngines(singletonList(formEngine)); | |
processEngineConfiguration.setCustomPreBPMNParseListeners(singletonList(new ExampleParseListener(formEngine))); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExampleParseListener extends AbstractBpmnParseListener { | |
private final ExampleFormEngine formEngine; | |
public ExampleParseListener(ExampleFormEngine formEngine) { | |
this.formEngine = formEngine; | |
} | |
@Override | |
public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) { | |
TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activity.getActivityBehavior()).getTaskDefinition(); | |
taskDefinition.setTaskFormHandler(new ExampleFormHandler(formEngine)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExampleFormHandler implements TaskFormHandler, StartFormHandler { | |
private final ExampleFormEngine formEngine; | |
private String deploymentId; | |
private String formKey; // fully qualified name of form class | |
public ExampleFormHandler(ExampleFormEngine formEngine) { | |
this.formEngine = formEngine; | |
} | |
@Override | |
public void parseConfiguration(Element activityElement, DeploymentEntity deployment, ProcessDefinitionEntity processDefinition, BpmnParse bpmnParse) { | |
this.deploymentId = deployment.getId(); | |
this.formKey = activityElement.attributeNS(BpmnParse.CAMUNDA_BPMN_EXTENSIONS_NS, "formKey"); | |
} | |
@Override | |
public StartFormData createStartFormData(ProcessDefinitionEntity processDefinition) { | |
checkState(deploymentId != null, "deploymentId must be set"); | |
checkState(formKey != null, "formKey must be set"); | |
StartFormDataImpl startFormData = new StartFormDataImpl(); | |
startFormData.setDeploymentId(deploymentId); | |
startFormData.setProcessDefinition(processDefinition); | |
startFormData.setFormKey(formKey); | |
return startFormData; | |
} | |
@Override | |
public TaskFormData createTaskForm(TaskEntity task) { | |
checkState(deploymentId != null, "deploymentId must be set"); | |
checkState(formKey != null, "formKey must be set"); | |
TaskFormDataImpl taskFormData = new TaskFormDataImpl(); | |
taskFormData.setDeploymentId(deploymentId); | |
taskFormData.setTask(task); | |
taskFormData.setFormKey(formKey); | |
return taskFormData; | |
} | |
@Override | |
public void submitFormVariables(VariableMap properties, VariableScope variableScope) { | |
Object result = formEngine.submitForm(deploymentId, formKey, properties); | |
variableScope.setVariable(formKey, result); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ExampleFormEngine implements FormEngine { | |
private final ObjectMapper objectMapper = new ObjectMapper(); | |
// and some kind of cache for the form infos | |
@Override | |
public String getName() { | |
return "example"; | |
} | |
@Override | |
public Object renderStartForm(StartFormData startForm) { | |
String deploymentId = startForm.getDeploymentId(); | |
String formKey = startForm.getFormKey(); | |
return renderForm(deploymentId, formKey, null); | |
} | |
@Override | |
public Object renderTaskForm(TaskFormData taskForm) { | |
String deploymentId = taskForm.getDeploymentId(); | |
String formKey = taskForm.getFormKey(); | |
VariableMap vars = ((VariableScope) taskForm.getTask()).getVariablesLocalTyped(); | |
return renderForm(deploymentId, formKey, vars); | |
} | |
ObjectNode renderForm(String deploymentId, String formKey, VariableMap vars) { | |
checkNotNull(deploymentId, "deploymentId required"); | |
checkNotNull(formKey, "formKey required"); | |
FormInfo formInfo = createFormInfo(getFormClass(deploymentId, formKey)); // can be cached | |
return renderForm(formInfo, vars); | |
} | |
@SuppressWarnings("unchecked") | |
ObjectNode renderForm(FormInfo formInfo, VariableMap vars) { | |
ArrayNode fields = objectMapper.createArrayNode(); | |
for (FieldInfo field : formInfo.getFields()) { | |
ObjectNode fieldNode = objectMapper.createObjectNode(); | |
fieldNode.set("name", TextNode.valueOf(field.getName())); | |
fieldNode.set("type", TextNode.valueOf(field.getType().name())); | |
fieldNode.set("label", TextNode.valueOf(field.getLabel())); | |
String valueStr = vars.getValue(field.getName(), String.class); | |
fieldNode.set("value", TextNode.valueOf(valueStr)); | |
fields.add(fieldNode); | |
} | |
ObjectNode formNode = objectMapper.createObjectNode(); | |
formNode.set("fields", fields); | |
return formNode; | |
} | |
Form submitForm(String deploymentId, String formKey, VariableMap vars) { | |
checkNotNull(deploymentId, "deploymentId required"); | |
checkNotNull(formKey, "formKey required"); | |
FormInfo formInfo = createFormInfo(getFormClass(deploymentId, formKey)); // can be cached | |
return submitForm(formInfo, vars); | |
} | |
Form submitForm(FormInfo formInfo, VariableMap vars) { | |
Form form = formInfo.newInstance(); | |
for (FieldInfo field : formInfo.getFields()) { | |
String valueStr = vars.getValue(field.getName(), String.class); | |
Object value = Converters.get(field.getType()).fromString(valueStr); | |
field.setValue(form, value); | |
} | |
return form; | |
} | |
FormInfo getFormInfo(String deploymentId, String formKey) { | |
// we can apply caching here using (deploymentId, formKey) as key | |
return createFormInfo(getFormClass(deploymentId, formKey)); | |
} | |
@SuppressWarnings("unchecked") | |
Class<? extends Form> getFormClass(String deploymentId, String formKey) { | |
try { | |
ProcessApplicationInterface pa = ProcessApplicationContextUtil.getTargetProcessApplication(deploymentId).getProcessApplication(); | |
return (Class<? extends Form>) pa.getProcessApplicationClassloader().loadClass(formKey); | |
} | |
catch (Exception e) { | |
throw new RuntimeException("Unable to get form class for deployment '" + deploymentId + "' and form key '" + formKey + "'", e); | |
} | |
} | |
FormInfo createFormInfo(Class<? extends Form> formClass) { | |
// ... | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment