for (String nodeType : nodeTypes) {
NodeList nodes = processElement.getElementsByTagName(nodeType);
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
try {
TransitionArc arc = arcById.get(node.getAttribute("id"));
if (arc == null) {
continue;
}
String name = node.getAttribute("name");
arc.setName(name);
res.put(name, arc);
StateNode startNode = nodeById.get(node.getAttribute("sourceRef"));
StateNode endNode = nodeById.get(node.getAttribute("targetRef"));
if (startNode == null || endNode == null) {
continue;
}
//calculate line start node which is a center of the start node
int startX = startNode.getX() + startNode.getWidth()/2;
int startY = startNode.getY() + startNode.getHeight()/2;
//and the same for end node
int endX = endNode.getX() + endNode.getWidth()/2;
int endY = endNode.getY() + endNode.getHeight()/2;
arc.getPath().add(0, new TransitionArcPoint(startX, startY));
arc.addPoint(endX, endY);
double a;//remember about vertical line
double b;
endX = arc.getPath().get(1).getX();
endY = arc.getPath().get(1).getY();
if (startX - endX == 0) { //whoa - vertical line - simple case, but requires special approach
if (endY > startNode.getY()+startNode.getHeight()) { //below
startY = startNode.getY()+startNode.getHeight();
} else {
startY = startNode.getY();
}
} else {
a = ((double)(startY-endY))/((double)(startX - endX));
b = (double)startY - (double)startX*a;
for (int x = startX; x <= endX; x++) {
int y = (int) Math.round(a*x+b);
boolean inside = false;
if (x >= startNode.getX() && x <= startNode.getX() + startNode.getWidth()) {
if (y >= startNode.getY() && y <= startNode.getY() + startNode.getHeight()) {
inside = true;
}
}
if (!inside) {
startX = x;
startY = y;
break;
}
}
for (int x = startX; x > endX; x--) {
int y = (int) Math.round(a*x+b);
boolean inside = false;
if (x >= startNode.getX() && x <= startNode.getX() + startNode.getWidth()) {
if (y >= startNode.getY() && y <= startNode.getY() + startNode.getHeight()) {
inside = true;
}
}
if (!inside) {
startX = x;
startY = y;
break;
}
}
}
arc.getPath().get(0).setX(startX);
arc.getPath().get(0).setY(startY);
endX = arc.getPath().get(arc.getPath().size()-1).getX();
endY = arc.getPath().get(arc.getPath().size()-1).getY();
startX = arc.getPath().get(arc.getPath().size()-2).getX();
startY = arc.getPath().get(arc.getPath().size()-2).getY();
if (startX - endX == 0) { //whoa - vertical line - simple case, but requires special approach
if (startY > endNode.getY()+endNode.getHeight()) { //below
endY = endNode.getY()+endNode.getHeight();
} else {
endY = endNode.getY();
}
} else {
a = ((double)(startY-endY))/((double)(startX - endX));//remember about vertical line
//startY = startX*a+b
b = (double)startY - (double)startX*a;
for (int x = endX; x <= startX; x++) {
int y = (int) Math.round(a*x+b);
boolean inside = false;
if (x >= endNode.getX() && x <= endNode.getX() + endNode.getWidth()) {
if (y >= endNode.getY() && y <= endNode.getY() + endNode.getHeight()) {
inside = true;
}
}
if (!inside) {
endX = x;
endY = y;
break;
}
}
for (int x = endX; x > startX; x--) {
int y = (int) Math.round(a*x+b);
boolean inside = false;
if (x >= endNode.getX() && x <= endNode.getX() + endNode.getWidth()) {
if (y >= endNode.getY() && y <= endNode.getY() + endNode.getHeight()) {
inside = true;
}
}
if (!inside) {
endX = x;
endY = y;
break;
}
}
}
arc.getPath().get(arc.getPath().size()-1).setX(endX);
arc.getPath().get(arc.getPath().size()-1).setY(endY);
res.put("__AWF__" + startNode.getLabel() + "_" + endNode.getLabel(),
arc);
res.put("__AWF__default_transition_" + startNode.getLabel(),
arc);