org.jbpm.simulation.PathContextManager Maven / Gradle / Ivy
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jbpm.simulation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import org.eclipse.bpmn2.FlowElement;
import org.eclipse.bpmn2.SequenceFlow;
import org.jbpm.simulation.PathContext.Type;
public class PathContextManager {
private final int maxPathSize = Integer.parseInt(System.getProperty("org.jbpm.simulation.max.paths", "100"));
private Stack paths = new Stack();
private List completePaths = new ArrayList();
private Set completedPathsIds = new HashSet();
protected Map catchingEvents = null;
public Map getCatchingEvents() {
return catchingEvents;
}
public void setCatchingEvents(Map catchingEvents) {
this.catchingEvents = catchingEvents;
}
public PathContext getContextFromStack() {
checkSize();
if (this.paths.isEmpty()) {
this.paths.push(new PathContext());
}
return this.paths.peek();
}
public Stack getContextsFromStack() {
checkSize();
if (this.paths.isEmpty()) {
this.paths.push(new PathContext());
}
Stack contexts = new Stack();
for (PathContext ctx : this.paths) {
if (ctx.getType() == PathContext.Type.ACTIVE) {
contexts.add(cloneGivenWithoutPush(ctx));
}
}
if (contexts.isEmpty()) {
contexts.add(this.paths.peek());
}
return contexts;
}
public void addToPath(FlowElement element, PathContext context) {
if (context.getType() == Type.ROOT) {
context.addPathElement(element);
} else {
// add nodes to all active contexts
for (PathContext ctx : this.paths) {
if (ctx.getType() == PathContext.Type.ACTIVE) {
ctx.addPathElement(element);
}
}
}
}
public void removeFromPath(FlowElement element, PathContext context) {
if (context.getType() == Type.ROOT) {
context.removePathElement(element);
} else {
// add nodes to all active contexts
for (PathContext ctx : this.paths) {
if (ctx.getType() == PathContext.Type.ACTIVE) {
ctx.removePathElement(element);
}
}
}
}
public void addAllToPath(List elements, PathContext context) {
if (context.getType() == Type.ROOT) {
context.addAllPathElement(elements);
} else {
// add nodes to all active contexts
for (PathContext ctx : this.paths) {
if (ctx.getType() == PathContext.Type.ACTIVE) {
ctx.addAllPathElement(elements);
}
}
}
}
public PathContext cloneGiven(PathContext toclone) {
PathContext clone = new PathContext(Type.ACTIVE);
clone.setCanBeFinishedNoIncrement(toclone.isCanBeFinished());
clone.setCanBeFinishedCounter(toclone.getCanBeFinishedCounter());
clone.setPathElements(new LinkedHashSet(toclone.getPathElements()));
clone.setVisitedSplitPoint(new LinkedHashSet(toclone.getVisitedSplitPoint()));
this.paths.push(clone);
return clone;
}
public PathContext cloneGivenWithoutPush(PathContext toclone) {
PathContext clone = new PathContext(Type.ACTIVE);
clone.setCanBeFinishedNoIncrement(toclone.isCanBeFinished());
clone.setCanBeFinishedCounter(toclone.getCanBeFinishedCounter());
clone.setPathElements(new LinkedHashSet(toclone.getPathElements()));
clone.setVisitedSplitPoint(new LinkedHashSet(toclone.getVisitedSplitPoint()));
toclone.setType(Type.TEMP);
return clone;
}
public Stack getPaths() {
return this.paths;
}
public void finalizePath() {
PathContext context = getContextFromStack();
if (context.isCanBeFinished()) {
// no outgoing sequence flow means end of path
PathContext completePath = this.paths.pop();
completePath.setType(Type.COMPLETED);
addToCompleted(completePath);
}
}
public void finalizePathOnLeave() {
Iterator it = paths.iterator();
while (it.hasNext()) {
PathContext context = it.next();
if (context.isCanBeFinished() && context.getType() == Type.ACTIVE) {
// no outgoing sequence flow means end of path
PathContext completePath = context;
completePath.setType(Type.COMPLETED);
addToCompleted(completePath);
it.remove();
}
}
}
public void finalizePath(PathContext context) {
if (context.isCanBeFinished()) {
context.setType(Type.COMPLETED);
addToCompleted(context);
}
}
public void clearCurrentContext() {
this.paths.pop();
}
public void complete() {
for (PathContext context : this.paths) {
if (context.getType() != PathContext.Type.ROOT && context.getType() != PathContext.Type.TEMP) {
addToCompleted(context);
}
}
}
public List getCompletePaths() {
return completePaths;
}
protected void addToCompleted(PathContext context) {
//generate path id
StringBuffer pathIdElements = new StringBuffer();
List list = new ArrayList(context.getPathElements());
Collections.sort(list, new Comparator() {
public int compare(FlowElement o1, FlowElement o2) {
return o1.getId().compareTo(o2.getId());
}
});
for (FlowElement fe : list) {
pathIdElements.append(fe.getId());
}
int elementsId = pathIdElements.toString().hashCode();
context.setPathId("Path" + elementsId + "-" + this.completePaths.size());
if (!completedPathsIds.contains(elementsId+"")) {
this.completePaths.add(context);
completedPathsIds.add(elementsId+"");
}
}
protected void checkSize() {
if (paths.size() > maxPathSize) {
throw new RuntimeException("Unable to calculate paths of the process - max size (" + maxPathSize + ") of paths exceeded");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy