package sushi.query.bpmn; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import sushi.bpmn.decomposition.Component; import sushi.bpmn.decomposition.SubProcessComponent; import sushi.bpmn.element.AbstractBPMNElement; import sushi.query.SushiPatternQuery; /** * @author micha */ public class SubProcessQueryFactory extends AbstractPatternQueryFactory { public SubProcessQueryFactory(PatternQueryGenerator patternQueryGenerator) { super(patternQueryGenerator); } @Override protected SushiPatternQuery generateQuery(AbstractBPMNElement element, AbstractBPMNElement catchingMonitorableElement, SushiPatternQuery parentQuery) { if(element instanceof Component){ Component component = (Component) element; SushiPatternQuery query = null; if(component instanceof SubProcessComponent){ SubProcessComponent subProcessComponent = (SubProcessComponent) component; List<AbstractBPMNElement> catchingMonitorableElements = getCatchingMonitorableElement(subProcessComponent); AbstractBPMNElement subProcessCatchingMonitorableElement = null; if(!catchingMonitorableElements.isEmpty()){ subProcessCatchingMonitorableElement = catchingMonitorableElements.get(0); } //Sollte nur ein Element (Polygon-Component) sein, wenn SubProcess wohlstrukturiert ist List<AbstractBPMNElement> subProcessChildren = processDecompositionTree.getChildren(subProcessComponent); if(subProcessChildren.size() == 1 && subProcessChildren.get(0) instanceof Component){ query = new PatternQueryFactory(patternQueryGenerator).generateQuery(subProcessChildren.get(0), subProcessCatchingMonitorableElement, parentQuery); } else { throw new RuntimeException("SubProcess is not well structured."); } } return query; } else { System.err.println("Input element should be a component for an OR-query!"); return null; } } /** * Tries to find the first monitorable element on a path after a subprocess starting with its catching intermediate event. * @param component * @return */ private List<AbstractBPMNElement> getCatchingMonitorableElement(SubProcessComponent component) { Set<AbstractBPMNElement> successingMonitorableElements = new HashSet<AbstractBPMNElement>(); Set<AbstractBPMNElement> visitedElements = new HashSet<AbstractBPMNElement>(); AbstractBPMNElement attachedEvent = component.getSubProcess().getAttachedIntermediateEvent(); if(attachedEvent != null){ traverseSuccessingMonitorableElements(attachedEvent, visitedElements, successingMonitorableElements); } return new ArrayList<AbstractBPMNElement>(successingMonitorableElements); } }