use of io.automatiko.engine.api.definition.process.WorkflowProcess in project automatiko-engine by automatiko-io.
the class WorkflowProcessInstanceImpl method getEventDescriptions.
@Override
public Set<EventDescription<?>> getEventDescriptions() {
if (getState() == ProcessInstance.STATE_COMPLETED || getState() == ProcessInstance.STATE_ABORTED) {
return Collections.emptySet();
}
VariableScope variableScope = (VariableScope) ((ContextContainer) getProcess()).getDefaultContext(VariableScope.VARIABLE_SCOPE);
Set<EventDescription<?>> eventDesciptions = new LinkedHashSet<>();
List<EventListener> activeListeners = eventListeners.values().stream().flatMap(List::stream).collect(Collectors.toList());
activeListeners.addAll(externalEventListeners.values().stream().flatMap(List::stream).collect(Collectors.toList()));
activeListeners.forEach(el -> eventDesciptions.addAll(el.getEventDescriptions()));
((io.automatiko.engine.workflow.process.core.WorkflowProcess) getProcess()).getNodesRecursively().stream().filter(n -> n instanceof EventNodeInterface).forEach(n -> {
NamedDataType dataType = null;
if (((EventNodeInterface) n).getVariableName() != null) {
Map<String, Object> dataOutputs = (Map<String, Object>) n.getMetaData().get("DataOutputs");
if (dataOutputs != null) {
for (Entry<String, Object> dOut : dataOutputs.entrySet()) {
dataType = new NamedDataType(dOut.getKey(), dOut.getValue());
}
} else {
Variable eventVar = variableScope.findVariable(((EventNodeInterface) n).getVariableName());
if (eventVar != null) {
dataType = new NamedDataType(eventVar.getName(), eventVar.getType());
}
}
}
if (n instanceof BoundaryEventNode) {
BoundaryEventNode boundaryEventNode = (BoundaryEventNode) n;
StateBasedNodeInstance attachedToNodeInstance = (StateBasedNodeInstance) getNodeInstances(true).stream().filter(ni -> ni.getNode().getMetaData().get(UNIQUE_ID).equals(boundaryEventNode.getAttachedToNodeId())).findFirst().orElse(null);
if (attachedToNodeInstance != null) {
Map<String, String> properties = new HashMap<>();
properties.put("AttachedToID", attachedToNodeInstance.getNodeDefinitionId());
properties.put("AttachedToName", attachedToNodeInstance.getNodeName());
String eventType = EVENT_TYPE_SIGNAL;
String eventName = boundaryEventNode.getType();
Map<String, String> timerProperties = attachedToNodeInstance.extractTimerEventInformation();
if (timerProperties != null) {
properties.putAll(timerProperties);
eventType = "timer";
eventName = "timerTriggered";
}
eventDesciptions.add(new BaseEventDescription(eventName, (String) n.getMetaData().get(UNIQUE_ID), n.getName(), eventType, null, getId(), dataType, properties));
}
} else if (n instanceof EventSubProcessNode) {
EventSubProcessNode eventSubProcessNode = (EventSubProcessNode) n;
boolean isContainerActive = false;
if (eventSubProcessNode.getParentContainer() instanceof WorkflowProcess) {
isContainerActive = true;
} else if (eventSubProcessNode.getParentContainer() instanceof CompositeNode) {
isContainerActive = !getNodeInstances(((CompositeNode) eventSubProcessNode.getParentContainer()).getId()).isEmpty();
}
if (isContainerActive) {
Node startNode = eventSubProcessNode.findStartNode();
Map<Timer, ProcessAction> timers = eventSubProcessNode.getTimers();
if (timers != null && !timers.isEmpty()) {
getNodeInstances(eventSubProcessNode.getId()).forEach(ni -> {
Map<String, String> timerProperties = ((StateBasedNodeInstance) ni).extractTimerEventInformation();
if (timerProperties != null) {
eventDesciptions.add(new BaseEventDescription("timerTriggered", (String) startNode.getMetaData().get("UniqueId"), startNode.getName(), "timer", ni.getId(), getId(), null, timerProperties));
}
});
} else {
for (String eventName : eventSubProcessNode.getEvents()) {
if ("variableChanged".equals(eventName)) {
continue;
}
eventDesciptions.add(new BaseEventDescription(eventName, (String) startNode.getMetaData().get("UniqueId"), startNode.getName(), "signal", null, getId(), dataType));
}
}
}
} else if (n instanceof EventNode) {
NamedDataType finalDataType = dataType;
getNodeInstances(n.getId()).forEach(ni -> eventDesciptions.add(new BaseEventDescription(((EventNode) n).getType(), (String) n.getMetaData().get(UNIQUE_ID), n.getName(), (String) n.getMetaData().getOrDefault(EVENT_TYPE, EVENT_TYPE_SIGNAL), ni.getId(), getId(), finalDataType)));
} else if (n instanceof StateNode) {
getNodeInstances(n.getId()).forEach(ni -> eventDesciptions.add(new BaseEventDescription((String) n.getMetaData().get(CONDITION), (String) n.getMetaData().get(UNIQUE_ID), n.getName(), (String) n.getMetaData().getOrDefault(EVENT_TYPE, EVENT_TYPE_SIGNAL), ni.getId(), getId(), null)));
}
});
return eventDesciptions;
}
use of io.automatiko.engine.api.definition.process.WorkflowProcess in project automatiko-engine by automatiko-io.
the class StartNodeVisitor method visitNode.
@Override
public void visitNode(WorkflowProcess process, String factoryField, StartNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
body.addStatement(getAssignedFactoryMethod(factoryField, StartNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId()))).addStatement(getNameMethod(node, "Start")).addStatement(getFactoryMethod(getNodeId(node), METHOD_INTERRUPTING, new BooleanLiteralExpr(node.isInterrupting())));
visitMetaData(node.getMetaData(), body, getNodeId(node));
boolean serverless = ProcessToExecModelGenerator.isServerlessWorkflow(process);
if (serverless) {
for (DataAssociation association : node.getOutAssociations()) {
if (association.getAssignments() != null && !association.getAssignments().isEmpty()) {
TaskOutputJqAssignmentAction action = (TaskOutputJqAssignmentAction) association.getAssignments().get(0).getMetaData("Action");
String outputFilter = action.getOutputFilterExpression();
String scopeFilter = action.getScopeFilter();
body.addStatement(getFactoryMethod(getNodeId(node), METHOD_OUT_JQ_MAPPING, (outputFilter != null ? new StringLiteralExpr().setString(outputFilter) : new NullLiteralExpr()), (scopeFilter != null ? new StringLiteralExpr().setString(scopeFilter) : new NullLiteralExpr()), new BooleanLiteralExpr(action.isIgnoreScopeFilter())));
}
}
} else {
for (DataAssociation entry : node.getOutAssociations()) {
if (entry.getAssignments() != null && !entry.getAssignments().isEmpty()) {
Assignment assignment = entry.getAssignments().get(0);
body.addStatement(getFactoryMethod(getNodeId(node), "outMapping", new StringLiteralExpr(entry.getSources().get(0)), new NullLiteralExpr(), new StringLiteralExpr(assignment.getDialect()), new StringLiteralExpr(assignment.getFrom()), new StringLiteralExpr(assignment.getTo())));
} else {
body.addStatement(getFactoryMethod(getNodeId(node), "outMapping", new StringLiteralExpr(entry.getSources().get(0)), new StringLiteralExpr(entry.getTarget()), new NullLiteralExpr(), new NullLiteralExpr(), new NullLiteralExpr()));
}
}
}
body.addStatement(getDoneMethod(getNodeId(node)));
if (node.getTimer() != null) {
Timer timer = node.getTimer();
body.addStatement(getFactoryMethod(getNodeId(node), METHOD_TIMER, getOrNullExpr(timer.getDelay()), getOrNullExpr(timer.getPeriod()), getOrNullExpr(timer.getDate()), new IntegerLiteralExpr(node.getTimer().getTimeType())));
} else if (node.getTriggers() != null && !node.getTriggers().isEmpty()) {
Map<String, Object> nodeMetaData = node.getMetaData();
TriggerMetaData trigger = new TriggerMetaData((String) nodeMetaData.get(TRIGGER_REF), (String) nodeMetaData.get(TRIGGER_TYPE), (String) nodeMetaData.get(MESSAGE_TYPE), (String) nodeMetaData.get(TRIGGER_MAPPING), String.valueOf(node.getId()), node.getName(), (String) nodeMetaData.get(TRIGGER_CORRELATION), (String) nodeMetaData.get(TRIGGER_CORRELATION_EXPR)).validate();
trigger.addContext(node.getMetaData());
trigger.addContext(Collections.singletonMap("_node_", node));
// mark the trigger as capable of starting new instance only if this is top level start node
if (node.getParentContainer() instanceof WorkflowProcess) {
trigger.setStart(true);
}
metadata.addTrigger(trigger);
handleTrigger(node, nodeMetaData, body, variableScope, metadata);
} else {
// since there is start node without trigger then make sure it is startable
metadata.setStartable(true);
}
}
use of io.automatiko.engine.api.definition.process.WorkflowProcess in project automatiko-engine by automatiko-io.
the class ProcessHandler method processTags.
protected void processTags(WorkflowProcess process) {
String tags = (String) process.getMetaData().get("tags");
List<TagDefinition> tagDefinitions = new ArrayList<TagDefinition>();
if (tags != null) {
String[] tagList = tags.split(",");
int counter = 0;
for (String tag : tagList) {
boolean isExpression = PatternConstants.PARAMETER_MATCHER.matcher(tag).matches();
if (isExpression) {
tagDefinitions.add(new FunctionTagDefinition(String.valueOf(++counter), tag, (exp, vars) -> {
Map<String, Object> replacements = new HashMap<>();
Matcher matcher = PatternConstants.PARAMETER_MATCHER.matcher(exp);
while (matcher.find()) {
String paramName = matcher.group(1);
Object value = MVEL.executeExpression(exp, vars.getVariables());
replacements.put(paramName, value);
}
for (Map.Entry<String, Object> replacement : replacements.entrySet()) {
exp = exp.replace("#{" + replacement.getKey() + "}", replacement.getValue().toString());
}
return exp;
}));
} else {
tagDefinitions.add(new StaticTagDefinition(String.valueOf(++counter), tag));
}
}
}
((Process) process).setTagDefinitions(tagDefinitions);
}
use of io.automatiko.engine.api.definition.process.WorkflowProcess in project automatiko-engine by automatiko-io.
the class LaneHandler method start.
@SuppressWarnings("unchecked")
public Object start(final String uri, final String localName, final Attributes attrs, final ExtensibleXmlParser parser) throws SAXException {
parser.startElementBuilder(localName, attrs);
String id = attrs.getValue("id");
String name = attrs.getValue("name");
WorkflowProcess process = (WorkflowProcess) parser.getParent();
List<Lane> lanes = (List<Lane>) ((ExecutableProcess) process).getMetaData(LaneHandler.LANES);
if (lanes == null) {
lanes = new ArrayList<Lane>();
((ExecutableProcess) process).setMetaData(LaneHandler.LANES, lanes);
}
Lane lane = new Lane(id);
lane.setName(name);
lanes.add(lane);
return lane;
}
use of io.automatiko.engine.api.definition.process.WorkflowProcess in project automatiko-engine by automatiko-io.
the class XmlBPMNProcessDumper method visitProcess.
protected void visitProcess(WorkflowProcess process, StringBuilder xmlDump, int metaDataType) {
String targetNamespace = (String) process.getMetaData().get("TargetNamespace");
if (targetNamespace == null) {
targetNamespace = "https://automatiko.io";
}
xmlDump.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + EOL + "<definitions id=\"Definition\"" + EOL + " targetNamespace=\"" + targetNamespace + "\"" + EOL + " typeLanguage=\"http://www.java.com/javaTypes\"" + EOL + " expressionLanguage=\"http://www.mvel.org/2.0\"" + EOL + " xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\"" + EOL + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + EOL + " xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\"" + EOL + " xmlns:g=\"https://automatiko.io/flow/gpd\"" + EOL + (metaDataType == META_DATA_USING_DI ? " xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\"" + EOL + " xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\"" + EOL + " xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\"" + EOL : "") + " xmlns:tns=\"https://automatiko.io\">" + EOL + EOL);
// item definitions
this.visitedVariables = new HashSet<String>();
VariableScope variableScope = (VariableScope) ((io.automatiko.engine.workflow.base.core.Process) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
Set<String> dumpedItemDefs = new HashSet<String>();
Map<String, ItemDefinition> itemDefs = (Map<String, ItemDefinition>) process.getMetaData().get("ItemDefinitions");
if (itemDefs != null) {
for (ItemDefinition def : itemDefs.values()) {
xmlDump.append(" <itemDefinition id=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(def.getId()) + "\" ");
if (def.getStructureRef() != null && !"java.lang.Object".equals(def.getStructureRef())) {
xmlDump.append("structureRef=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(def.getStructureRef()) + "\" ");
}
xmlDump.append("/>" + EOL);
dumpedItemDefs.add(def.getId().intern());
}
}
visitVariableScope(variableScope, "_", xmlDump, dumpedItemDefs);
visitSubVariableScopes(process.getNodes(), xmlDump, dumpedItemDefs);
visitInterfaces(process.getNodes(), xmlDump);
visitEscalations(process.getNodes(), xmlDump, new ArrayList<String>());
Definitions def = (Definitions) process.getMetaData().get("Definitions");
visitErrors(def, xmlDump);
// data stores
if (def != null && def.getDataStores() != null) {
for (DataStore dataStore : def.getDataStores()) {
visitDataStore(dataStore, xmlDump);
}
}
// the process itself
xmlDump.append(" <process processType=\"Private\" isExecutable=\"true\" ");
if (process.getId() == null || process.getId().trim().length() == 0) {
((ProcessImpl) process).setId("com.sample.bpmn2");
}
xmlDump.append("id=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(process.getId()) + "\" ");
if (process.getName() != null) {
xmlDump.append("name=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(process.getName()) + "\" ");
}
String packageName = process.getPackageName();
if (packageName != null && !"io.automatiko.processes".equals(packageName)) {
xmlDump.append("tns:packageName=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(packageName) + "\" ");
}
if (((io.automatiko.engine.workflow.process.core.WorkflowProcess) process).isDynamic()) {
xmlDump.append("tns:adHoc=\"true\" ");
}
String version = process.getVersion();
if (version != null && !"".equals(version)) {
xmlDump.append("tns:version=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(version) + "\" ");
}
// TODO: package, version
xmlDump.append(">" + EOL + EOL);
visitHeader(process, xmlDump, metaDataType);
List<io.automatiko.engine.workflow.process.core.Node> processNodes = new ArrayList<io.automatiko.engine.workflow.process.core.Node>();
for (Node procNode : process.getNodes()) {
processNodes.add((io.automatiko.engine.workflow.process.core.Node) procNode);
}
visitNodes(processNodes, xmlDump, metaDataType);
visitConnections(process.getNodes(), xmlDump, metaDataType);
// add associations
List<Association> associations = (List<Association>) process.getMetaData().get(ProcessHandler.ASSOCIATIONS);
if (associations != null) {
for (Association association : associations) {
visitAssociation(association, xmlDump);
}
}
xmlDump.append(" </process>" + EOL + EOL);
if (metaDataType == META_DATA_USING_DI) {
xmlDump.append(" <bpmndi:BPMNDiagram>" + EOL + " <bpmndi:BPMNPlane bpmnElement=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(process.getId()) + "\" >" + EOL);
visitNodesDi(process.getNodes(), xmlDump);
visitConnectionsDi(process.getNodes(), xmlDump);
xmlDump.append(" </bpmndi:BPMNPlane>" + EOL + " </bpmndi:BPMNDiagram>" + EOL + EOL);
}
xmlDump.append("</definitions>");
}
Aggregations