use of io.automatiko.engine.workflow.bpmn2.core.Definitions in project automatiko-engine by automatiko-io.
the class ErrorHandler 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 errorCode = attrs.getValue("errorCode");
String structureRef = attrs.getValue("structureRef");
Definitions definitions = (Definitions) parser.getParent();
List<Error> errors = definitions.getErrors();
if (errors == null) {
errors = new ArrayList<Error>();
definitions.setErrors(errors);
((ProcessBuildData) parser.getData()).setMetaData("Errors", errors);
}
Error e = new Error(id, errorCode, structureRef);
errors.add(e);
return e;
}
use of io.automatiko.engine.workflow.bpmn2.core.Definitions in project automatiko-engine by automatiko-io.
the class ProcessHandler method linkAssociations.
public static void linkAssociations(Definitions definitions, NodeContainer nodeContainer, List<Association> associations) {
if (associations != null) {
for (Association association : associations) {
String sourceRef = association.getSourceRef();
Object source = null;
try {
source = findNodeOrDataStoreByUniqueId(definitions, nodeContainer, sourceRef, "Could not find source [" + sourceRef + "] for association " + association.getId() + "]");
} catch (IllegalArgumentException e) {
// source not found
}
String targetRef = association.getTargetRef();
Object target = null;
try {
target = findNodeOrDataStoreByUniqueId(definitions, nodeContainer, targetRef, "Could not find target [" + targetRef + "] for association [" + association.getId() + "]");
} catch (IllegalArgumentException e) {
// target not found
}
if (source == null || target == null) {
// TODO: ignoring this association for now
} else if (target instanceof DataStore || source instanceof DataStore) {
// TODO: ignoring data store associations for now
} else if (source instanceof EventNode) {
EventNode sourceNode = (EventNode) source;
Node targetNode = (Node) target;
checkBoundaryEventCompensationHandler(association, sourceNode, targetNode);
// make sure IsForCompensation is set to true on target
NodeImpl targetNodeImpl = (NodeImpl) target;
String isForCompensation = "isForCompensation";
Object compensationObject = targetNodeImpl.getMetaData(isForCompensation);
if (compensationObject == null) {
targetNodeImpl.setMetaData(isForCompensation, true);
logger.warn("Setting {} attribute to true for node {}", isForCompensation, targetRef);
} else if (!Boolean.parseBoolean(compensationObject.toString())) {
throw new IllegalArgumentException(isForCompensation + " attribute [" + compensationObject + "] should be true for Compensation Activity [" + targetRef + "]");
}
// put Compensation Handler in CompensationHandlerNode
NodeContainer sourceParent = sourceNode.getParentContainer();
NodeContainer targetParent = targetNode.getParentContainer();
if (!sourceParent.equals(targetParent)) {
throw new IllegalArgumentException("Compensation Associations may not cross (sub-)process boundaries,");
}
// connect boundary event to compensation activity
ConnectionImpl connection = new ConnectionImpl(sourceNode, NodeImpl.CONNECTION_DEFAULT_TYPE, targetNode, NodeImpl.CONNECTION_DEFAULT_TYPE);
connection.setMetaData("UniqueId", association.getId());
connection.setMetaData("hidden", true);
connection.setMetaData("association", true);
// Compensation use cases:
// - boundary event --associated-> activity
// - implicit sub process compensation handler + recursive?
/**
* BPMN2 spec, p.442: "A Compensation Event Sub-process becomes enabled when its
* parent Activity transitions into state Completed. At that time, a snapshot of
* the data associated with the parent Acitivity is taken and kept for later
* usage by the Compensation Event Sub-Process."
*/
}
}
}
}
use of io.automatiko.engine.workflow.bpmn2.core.Definitions 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>");
}
use of io.automatiko.engine.workflow.bpmn2.core.Definitions in project automatiko-engine by automatiko-io.
the class SubProcessHandler method handleCompositeContextNode.
@SuppressWarnings("unchecked")
protected void handleCompositeContextNode(final Node node, final Element element, final String uri, final String localName, final ExtensibleXmlParser parser) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
CompositeContextNode compositeNode = (CompositeContextNode) node;
List<SequenceFlow> connections = (List<SequenceFlow>) compositeNode.getMetaData(ProcessHandler.CONNECTIONS);
handleScript(compositeNode, element, "onEntry");
handleScript(compositeNode, element, "onExit");
List<IntermediateLink> throwLinks = (List<IntermediateLink>) compositeNode.getMetaData(ProcessHandler.LINKS);
ProcessHandler.linkIntermediateLinks(compositeNode, throwLinks);
ProcessHandler processHandler = new ProcessHandler();
processHandler.linkConnections(compositeNode, connections);
processHandler.linkBoundaryEvents(compositeNode);
// This must be done *after* linkConnections(process, connections)
// because it adds hidden connections for compensations
List<Association> associations = (List<Association>) compositeNode.getMetaData(ProcessHandler.ASSOCIATIONS);
ProcessHandler.linkAssociations((Definitions) compositeNode.getMetaData("Definitions"), compositeNode, associations);
// TODO: do we fully support interruping ESP's?
/**
* for( org.kie.api.definition.process.Node subNode : compositeNode.getNodes() )
* { if( subNode instanceof StartNode ) { if( ! ((StartNode)
* subNode).isInterrupting() ) { throw new
* IllegalArgumentException("Non-interrupting event subprocesses are not yet
* fully supported." ); } } }
*/
}
use of io.automatiko.engine.workflow.bpmn2.core.Definitions in project automatiko-engine by automatiko-io.
the class XmlBPMNProcessDumper method visitErrors.
protected void visitErrors(Definitions definitions, StringBuilder xmlDump) {
if (definitions == null) {
return;
}
List<Error> errors = definitions.getErrors();
if (errors == null || errors.isEmpty()) {
return;
}
for (io.automatiko.engine.workflow.bpmn2.core.Error error : errors) {
String id = XmlBPMNProcessDumper.replaceIllegalCharsAttribute(error.getId());
String code = error.getErrorCode();
xmlDump.append(" <error id=\"" + id + "\"");
if (error.getErrorCode() != null) {
code = XmlBPMNProcessDumper.replaceIllegalCharsAttribute(code);
xmlDump.append(" errorCode=\"" + code + "\"");
}
String structureRef = error.getStructureRef();
if (structureRef != null) {
structureRef = XmlBPMNProcessDumper.replaceIllegalCharsAttribute(structureRef);
xmlDump.append(" structureRef=\"" + structureRef + "\"");
}
xmlDump.append("/>" + EOL);
}
}
Aggregations