use of org.jbpm.bpmn2.core.Association in project jbpm by kiegroup.
the class SubProcessHandler method handleForEachNode.
@SuppressWarnings("unchecked")
protected void handleForEachNode(final Node node, final Element element, final String uri, final String localName, final ExtensibleXmlParser parser, boolean isAsync) throws SAXException {
super.handleNode(node, element, uri, localName, parser);
ForEachNode forEachNode = (ForEachNode) node;
org.w3c.dom.Node xmlNode = element.getFirstChild();
while (xmlNode != null) {
String nodeName = xmlNode.getNodeName();
if ("ioSpecification".equals(nodeName)) {
readIoSpecification(xmlNode, dataInputs, dataOutputs);
} else if ("dataInputAssociation".equals(nodeName)) {
readDataInputAssociation(xmlNode, inputAssociation);
} else if ("dataOutputAssociation".equals(nodeName)) {
readDataOutputAssociation(xmlNode, outputAssociation);
} else if ("multiInstanceLoopCharacteristics".equals(nodeName)) {
readMultiInstanceLoopCharacteristics(xmlNode, forEachNode, parser);
}
xmlNode = xmlNode.getNextSibling();
}
handleScript(forEachNode, element, "onEntry");
handleScript(forEachNode, element, "onExit");
List<SequenceFlow> connections = (List<SequenceFlow>) forEachNode.getMetaData(ProcessHandler.CONNECTIONS);
ProcessHandler.linkConnections(forEachNode, connections);
ProcessHandler.linkBoundaryEvents(forEachNode);
// This must be done *after* linkConnections(process, connections)
// because it adds hidden connections for compensations
List<Association> associations = (List<Association>) forEachNode.getMetaData(ProcessHandler.ASSOCIATIONS);
ProcessHandler.linkAssociations((Definitions) forEachNode.getMetaData("Definitions"), forEachNode, associations);
applyAsync(node, isAsync);
}
use of org.jbpm.bpmn2.core.Association in project jbpm by kiegroup.
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.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 org.jbpm.bpmn2.core.Association in project jbpm by kiegroup.
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.getNodeContainer();
NodeContainer targetParent = targetNode.getNodeContainer();
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", null);
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 org.jbpm.bpmn2.core.Association in project jbpm by kiegroup.
the class ProcessHandler method linkConnections.
public static void linkConnections(NodeContainer nodeContainer, List<SequenceFlow> connections) {
if (connections != null) {
for (SequenceFlow connection : connections) {
String sourceRef = connection.getSourceRef();
Node source = findNodeByIdOrUniqueIdInMetadata(nodeContainer, sourceRef, "Could not find source node for connection:" + sourceRef);
if (source instanceof EventNode) {
for (EventFilter eventFilter : ((EventNode) source).getEventFilters()) {
if (eventFilter instanceof EventTypeFilter) {
if ("Compensation".equals(((EventTypeFilter) eventFilter).getType())) {
// BPMN Method & Style, 2nd Ed. (Silver), states this on P. 131
throw new IllegalArgumentException("A Compensation Boundary Event can only be *associated* with a compensation activity via an Association, not via a Sequence Flow element.");
}
}
}
}
String targetRef = connection.getTargetRef();
Node target = findNodeByIdOrUniqueIdInMetadata(nodeContainer, targetRef, "Could not find target node for connection:" + targetRef);
Connection result = new ConnectionImpl(source, NodeImpl.CONNECTION_DEFAULT_TYPE, target, NodeImpl.CONNECTION_DEFAULT_TYPE);
result.setMetaData("bendpoints", connection.getBendpoints());
result.setMetaData("UniqueId", connection.getId());
if ("true".equals(System.getProperty("jbpm.enable.multi.con"))) {
NodeImpl nodeImpl = (NodeImpl) source;
Constraint constraint = buildConstraint(connection, nodeImpl);
if (constraint != null) {
nodeImpl.addConstraint(new ConnectionRef(target.getId(), NodeImpl.CONNECTION_DEFAULT_TYPE), constraint);
}
} else if (source instanceof Split) {
Split split = (Split) source;
Constraint constraint = buildConstraint(connection, split);
split.addConstraint(new ConnectionRef(target.getId(), NodeImpl.CONNECTION_DEFAULT_TYPE), constraint);
}
}
}
}
use of org.jbpm.bpmn2.core.Association in project jbpm by kiegroup.
the class AssociationHandler method start.
public Object start(final String uri, final String localName, final Attributes attrs, final ExtensibleXmlParser parser) throws SAXException {
parser.startElementBuilder(localName, attrs);
Association association = new Association();
association.setId(attrs.getValue("id"));
association.setSourceRef(attrs.getValue("sourceRef"));
association.setTargetRef(attrs.getValue("targetRef"));
String direction = attrs.getValue("associationDirection");
if (direction != null) {
boolean acceptableDirection = false;
direction = direction.toLowerCase();
String[] possibleDirections = { "none", "one", "both" };
for (String acceptable : possibleDirections) {
if (acceptable.equals(direction)) {
acceptableDirection = true;
break;
}
}
if (!acceptableDirection) {
throw new IllegalArgumentException("Unknown direction '" + direction + "' used in Association " + association.getId());
}
}
association.setDirection(direction);
/**
* BPMN2 spec, p. 66:
* "At this point, BPMN provides three standard Artifacts: Associations,
* Groups, and Text Annotations.
* ...
* When an Artifact is defined it is contained within a Collaboration
* or a FlowElementsContainer (a Process or Choreography)."
*
* (In other words: associations must be defined within a process, not outside)
*/
List<Association> associations = null;
NodeContainer nodeContainer = (NodeContainer) parser.getParent();
if (nodeContainer instanceof Process) {
RuleFlowProcess process = (RuleFlowProcess) nodeContainer;
associations = (List<Association>) process.getMetaData(ASSOCIATIONS);
if (associations == null) {
associations = new ArrayList<Association>();
process.setMetaData(ASSOCIATIONS, associations);
}
} else if (nodeContainer instanceof CompositeNode) {
CompositeContextNode compositeNode = (CompositeContextNode) nodeContainer;
associations = (List<Association>) compositeNode.getMetaData(ASSOCIATIONS);
if (associations == null) {
associations = new ArrayList<Association>();
compositeNode.setMetaData(ProcessHandler.ASSOCIATIONS, associations);
}
}
associations.add(association);
return association;
}
Aggregations