workcraft/CpogPlugin/src/org/workcraft/plugins/cpog/tools/CpogParsingTool.java
package org.workcraft.plugins.cpog.tools;
import org.workcraft.dom.Container;
import org.workcraft.dom.Node;
import org.workcraft.dom.visual.*;
import org.workcraft.dom.visual.connections.VisualConnection;
import org.workcraft.formula.BooleanFormula;
import org.workcraft.formula.BooleanVariable;
import org.workcraft.formula.jj.BooleanFormulaParser;
import org.workcraft.formula.jj.ParseException;
import org.workcraft.formula.visitors.StringGenerator;
import org.workcraft.plugins.cpog.*;
import org.workcraft.utils.DesktopApi;
import org.workcraft.utils.DialogUtils;
import org.workcraft.utils.WorkspaceUtils;
import org.workcraft.workspace.WorkspaceEntry;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
public class CpogParsingTool {
private static final int MAX_SCENARIOS_LINUX = 680;
private static final int MAX_SCENARIOS_OTHER_OS = 340;
private final HashMap<String, Variable> variableMap;
private int xpos;
private final HashMap<String, GraphReference> refMap;
private ArrayList<String> usedReferences;
public CpogParsingTool(HashMap<String, Variable> variableMap, int xpos, HashMap<String, GraphReference> refMap) {
this.variableMap = variableMap;
this.xpos = xpos;
this.refMap = refMap;
}
public BooleanFormula parseBool(String bool, final VisualCpog visualCpog) throws ParseException {
return BooleanFormulaParser.parse(bool, label -> labelToVar(label, visualCpog));
}
private BooleanVariable labelToVar(String label, final VisualCpog visualCpog) {
if (variableMap.containsKey(label)) {
HashSet<VisualVariable> vars = new HashSet<>(visualCpog.getVariables());
if (!vars.contains(variableMap.get(label))) {
if (variableMap.get(label).getParent() != null) {
return variableMap.get(label);
}
variableMap.remove(label);
} else {
variableMap.remove(label);
}
}
VisualVariable visVar = visualCpog.createVisualVariable();
visVar.setLabel(label);
visVar.setPosition(new Point2D.Double(xpos, -2));
xpos++;
variableMap.put(label, visVar.getReferencedComponent());
return variableMap.get(label);
}
public void bfsLayout(Queue<VisualNode> q, VisualCpog visualCpog, double originalX, double originalY) {
ArrayList<ArrayList<VisualNode>> outer = new ArrayList<>();
HashSet<VisualPage> pages = new HashSet<>();
VisualNode current = q.remove();
ArrayList<VisualNode> children = getChildren(visualCpog, current);
outer.add(new ArrayList<>());
outer.get(0).add(current);
outer.add(new ArrayList<>());
for (VisualNode child : children) {
q.add(child);
outer.get(1).add(child);
}
findAllChildren(q, visualCpog, outer, pages);
positionNodes(originalX, originalY, outer);
}
public double positionNodes(double originalX, double originalY, ArrayList<ArrayList<VisualNode>> outer) {
Point2D centre = new Point2D.Double(0.0, originalY);
double x = originalX;
double y = 0;
Iterator<ArrayList<VisualNode>> it = outer.iterator();
while (it.hasNext()) {
ArrayList<VisualNode> inner = it.next();
if (inner.size() > 1) {
y = centre.getY() - (inner.size() / 2);
} else {
y = centre.getY();
}
for (VisualNode n : inner) {
if (n instanceof VisualVertex) {
VisualVertex v = (VisualVertex) n;
if ((v.getParent() instanceof VisualPage) && (refMap.containsKey(((VisualPage) v.getParent()).getLabel()))) {
VisualPage p = (VisualPage) v.getParent();
Point2D.Double newPosition = new
Point2D.Double(refMap.get(p.getLabel()).getVertMap().get(v.getLabel()).getX(),
refMap.get(p.getLabel()).getVertMap().get(v.getLabel()).getY());
v.setPosition(newPosition);
} else {
v.setPosition(new Point2D.Double(x, y));
}
}
y += 1.5;
}
if (it.hasNext()) {
x += 2.5;
}
}
y += 2.5;
return x;
}
public void findAllChildren(Queue<VisualNode> q, VisualCpog visualCpog,
ArrayList<ArrayList<VisualNode>> outer, HashSet<VisualPage> pages) {
VisualNode current;
ArrayList<VisualNode> children;
int index = 0;
HashSet<VisualNode> visitedNodes = new HashSet<>();
while (!q.isEmpty()) {
current = q.remove();
if (!visitedNodes.contains(current)) {
visitedNodes.add(current);
index = findVertex(outer, current);
if ((current.getParent() instanceof VisualScenarioPage) | (current.getParent() instanceof VisualPage)) {
VisualPage vp = (VisualPage) current.getParent();
pages.add(vp);
}
children = getChildren(visualCpog, current);
for (VisualNode child : children) {
q.add(child);
addNode(child, index + 1, outer);
}
}
}
}
public static ArrayList<VisualNode> getChildren(VisualCpog visualCpog, VisualNode node) {
ArrayList<VisualNode> children = new ArrayList<>();
HashSet<VisualArc> arcs = getAllArcs(visualCpog.getRoot(), visualCpog);
for (VisualArc arc : arcs) {
if (arc.getFirst().equals(node)) {
children.add(arc.getSecond());
}
}
return children;
}
public static HashSet<VisualNode> getParents(VisualCpog visualCpog, VisualNode node) {
HashSet<VisualNode> parents = new HashSet<>();
HashSet<VisualArc> arcs = getAllArcs(visualCpog.getRoot(), visualCpog);
for (VisualArc arc : arcs) {
if (arc.getSecond().equals(node)) {
parents.add(arc.getFirst());
}
}
return parents;
}
public static String getExpressionFromGraph(VisualCpog visualCpog) {
Collection<VisualNode> originalSelection = null;
if (visualCpog.getSelection().isEmpty()) {
originalSelection = visualCpog.getSelection();
visualCpog.selectAll();
if (visualCpog.getSelection().isEmpty()) {
DialogUtils.showError("There are no graphs to select");
return "";
}
} else {
originalSelection = copySelected(visualCpog);
}
ArrayList<VisualTransformableNode> groups = getScenarios(visualCpog);
ArrayList<VisualNode> vertices = new ArrayList<>();
ArrayList<String> expression = new ArrayList<>();
String total = "";
// Add vertices from group
if (!groups.isEmpty()) {
for (VisualTransformableNode group : groups) {
expression.add(group.getLabel() + " =");
originalSelection.remove(group);
getAllGroupVertices(vertices, group);
HashSet<VisualNode> roots = getRoots(visualCpog, vertices);
VisualVertex current;
Set<VisualConnection> totalConnections;
ArrayList<VisualConnection> connections = new ArrayList<>();
HashSet<VisualVertex> visitedVertices = new HashSet<>();
HashSet<VisualConnection> visitedConnections = new HashSet<>();
ConcurrentLinkedQueue<VisualNode> q = new ConcurrentLinkedQueue<>();
if (roots.isEmpty()) {
roots.addAll(vertices);
}
Iterator<VisualNode> i = roots.iterator();
while (i.hasNext()) {
q.add(i.next());
while (!q.isEmpty()) {
connections.clear();
current = (VisualVertex) q.remove();
visitedVertices.add(current);
for (VisualNode n : getChildren(visualCpog, current)) {
if (!visitedVertices.contains(n)) {
q.add(n);
}
}
totalConnections = visualCpog.getConnections(current);
describeArcs(expression, totalConnections, visitedConnections, current, vertices, visualCpog);
if ((!q.isEmpty() || i.hasNext()) && !"+".equals(expression.get(expression.size() - 1))) {
expression.add("+");
}
if (i.hasNext() && !"+".equals(expression.get(expression.size() - 1))) {
expression.add("+");
}
}
}
while ("+".equals(expression.get(expression.size() - 1))) {
expression.remove(expression.size() - 1);
}
expression.add("\n");
}
}
if (!originalSelection.isEmpty()) {
vertices.clear();
for (VisualNode n : originalSelection) {
if (n instanceof VisualVertex) {
vertices.add(n);
} else if ((n instanceof VisualScenarioPage) || (n instanceof VisualPage)) {
VisualPage p = (VisualPage) n;
for (Node child : p.getChildren()) {
if (child instanceof VisualVertex) {
vertices.add((VisualVertex) child);
}
}
}
}
HashSet<VisualNode> roots = getRoots(visualCpog, vertices);
Iterator<VisualNode> i = roots.iterator();
VisualVertex current;
Set<VisualConnection> totalConnections;
ArrayList<VisualConnection> connections = new ArrayList<>();
HashSet<VisualVertex> visitedVertices = new HashSet<>();
HashSet<VisualConnection> visitedConnections = new HashSet<>();
ConcurrentLinkedQueue<VisualNode> q = new ConcurrentLinkedQueue<>();
while (i.hasNext()) {
q.add(i.next());
while (!q.isEmpty()) {
connections.clear();
current = (VisualVertex) q.remove();
for (VisualNode n : getChildren(visualCpog, current)) {
if (!visitedVertices.contains(n)) {
q.add(n);
}
}
totalConnections = visualCpog.getConnections(current);
describeArcs(expression, totalConnections, visitedConnections, current, vertices, visualCpog);
if ((!q.isEmpty() || i.hasNext()) && !"+".equals(expression.get(expression.size() - 1))) {
expression.add("+");
}
if (i.hasNext() && !"+".equals(expression.get(expression.size() - 1))) {
expression.add("+");
}
}
}
}
if ("+".equals(expression.get(expression.size() - 1))) {
expression.remove(expression.size() - 1);
}
for (String ex : expression) {
if (ex.contains("=")) {
total += ex;
} else if ("\n".equals(ex)) {
while (total.endsWith(" ") || total.endsWith("+")) {
total = total.substring(0, total.length() - 1);
}
total += ex;
} else if ((ex.contains(" ") || "+".equals(ex)) || (!total.contains(" " + ex + " ") && !total.startsWith(ex + " ") && !total.endsWith(" " + ex))) {
if (!("+".equals(ex) && total.endsWith("+"))) {
if (total.endsWith("\n") || total.isEmpty()) {
total += ex;
} else {
total += ' ' + ex;
}
}
}
}
if (total.endsWith("+")) {
total = total.substring(0, total.length() - 1);
}
total = total.trim();
return total;
}
public static void describeArcs(ArrayList<String> expression, Set<VisualConnection> totalConnections,
HashSet<VisualConnection> visitedConnections, VisualVertex current,
ArrayList<VisualNode> vertices, VisualCpog visualCpog) {
ArrayList<VisualConnection> connections = new ArrayList<>();
for (VisualConnection c : totalConnections) {
if ((!visitedConnections.contains(c)) && (!c.getSecond().equals(current)) && (vertices.contains(c.getSecond()))) {
connections.add(c);
}
}
String currentCondition = formulaToString(current.getCondition());
if (connections.size() == 1) {
VisualArc arc = (VisualArc) connections.get(0);
String insert = "";
String arcCondition = formulaToString(arc.getCondition());
if (!"1".equals(arcCondition)) {
insert = "[" + arcCondition + "](";
}
if (!"1".equals(currentCondition) || currentCondition.compareTo(arcCondition) != 0) {
insert += "[" + currentCondition + "]";
}
insert += current.getLabel() + " -> ";
VisualVertex child = (VisualVertex) arc.getSecond();
if (!"1".equals(formulaToString(child.getCondition())) || !formulaToString(child.getCondition()).equals(arcCondition)) {
insert += "[" + formulaToString(child.getCondition()) + "]";
}
insert += child.getLabel();
visitedConnections.add(arc);
HashSet<VisualArc> localVisitedArcs = new HashSet<>();
localVisitedArcs.add(arc);
boolean finished = false;
while (!finished) {
if (getChildren(visualCpog, child).size() == 1) {
ArrayList<VisualNode> nextVertices = getChildren(visualCpog, child);
VisualVertex nextVertex = (VisualVertex) nextVertices.get(0);
VisualArc nextArc = (VisualArc) visualCpog.getConnection(child, nextVertex);
if (!localVisitedArcs.contains(nextArc)) {
if (formulaToString(nextArc.getCondition()).equals(arcCondition)) {
insert += " -> ";
String nextVertexCondition = formulaToString(nextVertex.getCondition());
String childCondition = formulaToString(child.getCondition());
if (!"1".equals(nextVertexCondition) || !childCondition.equals(arcCondition)) {
insert += "[" + formulaToString(child.getCondition()) + "]";
}
insert += nextVertex.getLabel();
visitedConnections.add(nextArc);
localVisitedArcs.add(nextArc);
child = nextVertex;
}
} else {
finished = true;
}
} else {
finished = true;
}
}
if (!"1".equals(arcCondition)) {
insert += ")";
}
expression.add(insert);
} else if (connections.size() > 1) {
while (!connections.isEmpty()) {
VisualArc arc = (VisualArc) connections.get(0);
String insert = "";
String arcCondition = formulaToString(arc.getCondition());
if (!"1".equals(arcCondition)) {
insert = "[" + arcCondition + "](";
}
if (!"1".equals(currentCondition) || !currentCondition.equals(arcCondition)) {
insert += "[" + currentCondition + "]";
}
insert += current.getLabel() + " -> ";
ArrayList<VisualArc> toBeRemoved = new ArrayList<>();
for (VisualConnection c : connections) {
VisualArc a = (VisualArc) c;
if (a.getCondition().equals(arc.getCondition())) {
toBeRemoved.add(a);
}
}
if (toBeRemoved.size() > 1) {
insert += '(';
}
for (VisualArc a : toBeRemoved) {
insert += ((VisualVertex) a.getSecond()).getLabel() + " + ";
}
while ((insert.endsWith(" ")) || (insert.endsWith("+"))) {
insert = insert.substring(0, insert.length() - 1);
}
if (toBeRemoved.size() > 1) {
insert += ')';
}
visitedConnections.addAll(toBeRemoved);
connections.removeAll(toBeRemoved);
expression.add(insert);
}
} else {
String insert = "";
if (!"1".equals(currentCondition)) {
insert = '[' + currentCondition + ']';
}
insert += current.getLabel();
expression.add(insert);
}
}
private static String formulaToString(BooleanFormula condition) {
return StringGenerator.toString(condition);
}
public static HashSet<VisualNode> getRoots(VisualCpog visualCpog, ArrayList<VisualNode> vertices) {
HashSet<VisualNode> roots = new HashSet<>();
Set<VisualConnection> arcs;
Iterator<VisualConnection> it;
VisualConnection connection;
boolean second = false;
// Get root(s)
for (VisualNode v : vertices) {
arcs = visualCpog.getConnections(v);
it = arcs.iterator();
// The following covers root nodes, and nodes with no connections
while (it.hasNext()) {
connection = it.next();
if ((!connection.getFirst().equals(v)) && (vertices.contains(connection.getFirst()))) {
second = true;
break;
}
}
if (!second) {
roots.add(v);
}
second = false;
}
return roots;
}
public static void getAllGroupVertices(ArrayList<VisualNode> vertices, VisualTransformableNode group) {
vertices.clear();
for (VisualComponent v : group.getComponents()) {
if (v instanceof VisualPage) {
vertices.addAll(getPageVertices((VisualPage) v));
} else vertices.add(v);
}
}
public static void getGroups(VisualCpog visualCpog, ArrayList<VisualTransformableNode> groups) {
ArrayList<VisualNode> prevSelection = copySelected(visualCpog);
visualCpog.selectAll();
for (VisualNode n : visualCpog.getSelection()) {
if ((n instanceof VisualPage) || (n instanceof VisualGroup)) {
if (prevSelection.contains(n)) {
groups.add((VisualTransformableNode) n);
}
}
}
visualCpog.select(prevSelection);
}
public static ArrayList<VisualTransformableNode> getScenarios(VisualCpog visualCpog) {
ArrayList<VisualTransformableNode> scenarios = new ArrayList<>();
TreeSet<String> nameList = new TreeSet<>();
ArrayList<VisualNode> prevSelection = copySelected(visualCpog);
visualCpog.selectAll();
for (VisualNode n : visualCpog.getSelection()) {
if ((n instanceof VisualScenarioPage) || (n instanceof VisualScenario)) {
if (prevSelection.contains(n)) {
scenarios.add((VisualTransformableNode) n);
VisualTransformableNode node = (VisualTransformableNode) n;
nameList.add(node.getLabel());
}
}
}
ArrayList<VisualTransformableNode> result = new ArrayList<>();
for (String name : nameList) {
boolean found = false;
int i = 0;
while (!found) {
if (scenarios.get(i).getLabel().equals(name)) {
result.add(scenarios.remove(i));
found = true;
}
i++;
}
}
visualCpog.select(prevSelection);
return result;
}
public int findVertex(ArrayList<ArrayList<VisualNode>> outer, VisualNode target) {
int index = 0;
for (ArrayList<VisualNode> inner : outer) {
if (inner.contains(target)) {
return index;
}
index++;
}
return -1;
}
public void addNode(VisualNode v, int index, ArrayList<ArrayList<VisualNode>> outer) {
int removalIndex = 0;
removalIndex = findVertex(outer, v);
if (removalIndex >= 0) {
outer.get(removalIndex).remove(v);
}
if (outer.size() - 1 < index) {
outer.add(new ArrayList<>());
}
outer.get(index).add(v);
}
public boolean[][] convertToArrayForm(Collection<VisualVertex> vertices, VisualCpog visualCpog) {
boolean[][] c = new boolean[vertices.size()][vertices.size()];
int i = 0;
for (VisualVertex n1 : vertices) {
int j = 0;
for (VisualVertex n2 : vertices) {
if (visualCpog.hasConnection(n1, n2)) {
c[i][j] = true;
} else {
c[i][j] = false;
}
j++;
}
i++;
}
return c;
}
public void computeTransitiveClosure(boolean[][] c) {
for (int j = 0; j < c.length; j++) {
for (int i = 0; i < c.length; i++) {
for (int k = 0; k < c.length; k++) {
if (c[i][j] && c[j][k]) {
c[i][k] = true;
}
}
}
}
}
public boolean[][] findTransitives(boolean[][] c) {
boolean[][] t = new boolean[c.length][c.length];
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < c.length; j++) {
for (int k = 0; k < c.length; k++) {
if (c[i][j] && c[j][k]) {
t[i][k] = true;
}
}
}
}
return t;
}
public void convertFromArrayForm(boolean[][] t, Collection<VisualVertex> vertices, VisualCpog visualCpog) {
int i = 0;
for (VisualVertex n1 : vertices) {
int j = 0;
for (VisualVertex n2 : vertices) {
if ((t[i][j]) && (visualCpog.hasConnection(n1, n2))) {
if (visualCpog.hasConnection(n1, n2)) {
visualCpog.remove(visualCpog.getConnection(n1, n2));
}
}
j++;
}
i++;
}
}
public boolean hasSelfLoops(boolean[][]c) {
for (int i = 0; i < c.length; i++) {
if (c[i][i]) {
return true;
}
}
return false;
}
public String replaceReferences(String text) {
usedReferences = new ArrayList<>();
boolean added;
for (String k : refMap.keySet()) {
added = false;
if (text.contains(' ' + k + ' ')) {
if (k.startsWith("[")) {
text = text.replace(' ' + k + ' ', " (" + refMap.get(k).getNormalForm() + ") ");
added = true;
} else {
text = text.replace(' ' + k + ' ', " (" + refMap.get(k).getNormalForm() + ") ");
added = true;
}
}
if (text.contains(']' + k + ' ')) {
text = text.replace(']' + k + ' ', "](" + refMap.get(k).getNormalForm() + ") ");
added = true;
}
if (text.contains('(' + k + ')')) {
text = text.replace('(' + k + ')', "(" + refMap.get(k).getNormalForm() + ")");
added = true;
}
if (text.contains('(' + k + ' ')) {
text = text.replace('(' + k + ' ', "((" + refMap.get(k).getNormalForm() + ") ");
added = true;
}
if (text.contains(' ' + k + ')')) {
text = text.replace(' ' + k + ')', " (" + refMap.get(k).getNormalForm() + "))");
added = true;
}
if (text.endsWith(' ' + k)) {
text = text.replace(' ' + k, " (" + refMap.get(k).getNormalForm() + ")");
added = true;
}
if (text.endsWith(']' + k)) {
text = text.replace(']' + k, "](" + refMap.get(k).getNormalForm() + ")");
added = true;
}
if (text.endsWith(' ' + k + ')')) {
text = text.replace(' ' + k + ')', " (" + refMap.get(k).getNormalForm() + "))");
added = true;
}
if (added) {
usedReferences.add(k);
}
}
return text;
}
public void setArcConditions(HashSet<ArcCondition> arcConditionList, VisualCpog visualCpog, HashMap<String, VisualVertex> vertexMap) {
int index;
for (ArcCondition a : arcConditionList) {
if (!a.getBoolForm().isEmpty()) {
index = 0;
ArrayList<String> vertexList = a.getVertexList();
Iterator<String> it = vertexList.iterator();
String first;
String second;
VisualArc arc;
while (it.hasNext()) {
first = it.next();
for (int c = index + 1; c < vertexList.size(); c++) {
second = vertexList.get(c);
ArrayList<String> verts1 = new ArrayList<>();
ArrayList<String> verts2 = new ArrayList<>();
int ind = 0;
if (first.contains("(")) {
first = first.replace("(", "");
first = first.replace(")", "");
while (first.contains("+")) {
ind = first.indexOf("+");
verts1.add(first.substring(0, ind));
first = first.substring(ind + 1);
}
verts1.add(first);
}
verts1.add(first);
if (second.contains("(")) {
second = second.replace("(", "");
second = second.replace(")", "");
while (second.contains("+")) {
ind = second.indexOf("+");
verts2.add(second.substring(0, ind));
second = second.substring(ind + 1);
}
}
verts2.add(second);
for (String vert1 : verts1) {
for (String vert2 : verts2) {
arc = (VisualArc) visualCpog.getConnection(vertexMap.get(vert1), vertexMap.get(vert2));
ArrayList<VisualArc> dupArcs = new ArrayList<>();
if (arc != null) {
for (VisualConnection con : visualCpog.getConnections(vertexMap.get(vert1))) {
if (con.getSecond().equals(vertexMap.get(vert2))) {
dupArcs.add((VisualArc) con);
}
}
boolean conditionFound = false;
ArrayList<VisualArc> toBeRemoved = new ArrayList<>();
if (dupArcs.size() > 1) {
for (VisualArc va : dupArcs) {
if (!"1".equals(StringGenerator.toString(va.getCondition()))) {
toBeRemoved.add(va);
conditionFound = true;
}
}
for (VisualArc va : toBeRemoved) {
dupArcs.remove(va);
}
if (!conditionFound && (dupArcs.size() > 1)) {
for (int i = 1; i < dupArcs.size(); i++) {
visualCpog.remove(dupArcs.get(i));
}
} else {
for (int i = 0; i < dupArcs.size(); i++) {
visualCpog.remove(dupArcs.get(i));
}
}
}
try {
if ("1".equals(StringGenerator.toString(arc.getCondition()))) {
arc.setCondition(parseBool(a.getBoolForm(), visualCpog));
} else {
arc.setCondition(parseBool(StringGenerator.toString(arc.getCondition()) + "|" + a.getBoolForm(), visualCpog));
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}
}
index++;
}
}
}
}
public Point2D getLowestVertex(VisualCpog visualCpog) {
Collection<VisualVertex> vertices = visualCpog.getVertices(visualCpog.getCurrentLevel());
vertices.removeAll(visualCpog.getSelection());
ArrayList<VisualNode> prevSelection = new ArrayList<>();
for (VisualNode n : visualCpog.getSelection()) {
prevSelection.add(n);
}
ArrayList<VisualScenarioPage> pages = new ArrayList<>();
visualCpog.selectAll();
for (VisualNode n : visualCpog.getSelection()) {
if (n instanceof VisualScenarioPage) {
pages.add((VisualScenarioPage) n);
}
}
visualCpog.select(prevSelection);
pages.removeAll(visualCpog.getSelection());
Point2D startPoint = null;
for (VisualVertex vertex : vertices) {
Point2D centre = vertex.getCenter();
if (startPoint == null) {
startPoint = new Point2D.Double(centre.getX(), centre.getY());
} else {
if (centre.getY() > startPoint.getY()) {
startPoint.setLocation(startPoint.getX(), centre.getY());
}
if (centre.getX() < startPoint.getX()) {
startPoint.setLocation(centre.getX(), startPoint.getY());
}
}
}
for (VisualScenarioPage page : pages) {
Rectangle2D.Double rect = (Rectangle2D.Double) page.getBoundingBox();
Point2D.Double bl = new Point2D.Double(0, rect.getCenterY() + (rect.getHeight() / 2));
if (startPoint == null) {
startPoint = new Point2D.Double(bl.getX(), bl.getY());
} else {
if (bl.getY() > startPoint.getY()) {
startPoint.setLocation(startPoint.getX(), bl.getY());
}
}
}
if (startPoint == null) {
startPoint = new Point2D.Double(0, 0);
} else {
startPoint.setLocation(startPoint.getX(), startPoint.getY());
}
return startPoint;
}
public ArrayList<String> getUsedReferences() {
return usedReferences;
}
public static ArrayList<VisualComponent> getPageVertices(VisualPage p) {
ArrayList<VisualComponent> result = new ArrayList<>();
for (VisualComponent c : p.getComponents()) {
if (c instanceof VisualPage) {
result.addAll(getPageVertices((VisualPage) c));
} else {
result.add(c);
}
}
return result;
}
public static ArrayList<VisualNode> copySelected(VisualCpog visualCpog) {
ArrayList<VisualNode> result = new ArrayList<>();
for (VisualNode n : visualCpog.getSelection()) {
result.add(n);
}
return result;
}
public static HashSet<VisualArc> getAllArcs(Container root, VisualCpog visualCpog) {
HashSet<VisualArc> result = new HashSet<>();
for (Node node : root.getChildren()) {
if ((node instanceof VisualPage) || (node instanceof VisualScenarioPage)) {
result.addAll(getAllArcs((VisualPage) node, visualCpog));
} else if (node instanceof VisualScenario) {
result.addAll(getAllArcs((VisualScenario) node, visualCpog));
} else if (node instanceof VisualArc) {
result.add((VisualArc) node);
}
}
return result;
}
public static boolean hasEnoughScenarios(WorkspaceEntry we) {
VisualCpog cpog = WorkspaceUtils.getAs(we, VisualCpog.class);
return getScenarios(cpog).size() > 1;
}
public static boolean hasTooScenarios(WorkspaceEntry we) {
DesktopApi.OsType os = DesktopApi.getOs();
VisualCpog cpog = WorkspaceUtils.getAs(we, VisualCpog.class);
if (os.isLinux()) {
return getScenarios(cpog).size() > MAX_SCENARIOS_LINUX;
} else {
return getScenarios(cpog).size() > MAX_SCENARIOS_OTHER_OS;
}
}
public boolean[][] copyArray(boolean[][] c) {
boolean[][] t = new boolean[c.length][c.length];
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < c.length; j++) {
t[i][j] = c[i][j];
}
}
return t;
}
}