1
2
3
4
5
6 package net.kwfgrid.gwui.graphview;
7
8 import net.kwfgrid.gworkflowdl.structure.*;
9
10 import de.fzi.wim.guibase.graphview.layout.*;
11 import de.fzi.wim.guibase.graphview.graph.Node;
12 import de.fzi.wim.guibase.graphview.graph.Graph;
13
14 import java.util.*;
15 import java.awt.*;
16 import java.awt.geom.*;
17
18 import org.apache.log4j.Logger;
19
20 /***
21 A very simple layout strategy which just applies the positions contained in the workflow,
22 place and transition properties to the graph's nodes.
23 */
24 public class PropertyLayoutStrategy implements LayoutStrategy {
25 private static final Logger logger = Logger.getLogger(PropertyLayoutStrategy.class);
26
27 private WorkflowGraph _graph;
28 private boolean _valid;
29
30 public PropertyLayoutStrategy(WorkflowGraph graph) {
31 logger.debug("Constructed new PropertyLayoutStrategy for graph "+graph);
32
33 _graph = graph;
34 _valid = false;
35 }
36
37 public boolean shouldExecuteStep() {
38 return !_valid;
39 }
40
41 public void executeGraphLayoutStep() {
42 logger.debug("Executing layout step.");
43
44 Iterator i = _graph.getNodes().iterator(); while (i.hasNext()) {
45 Node node = (Node)i.next();
46 node.setFixed(false);
47 try {
48 if (node instanceof PlaceNode) {
49 PlaceNode pn = (PlaceNode)node;
50 Point2D p = createPoint(pn.getPlace().getProperties(), "gwui.layout");
51 if (p != null) {
52 logger.debug("Setting place "+pn.getPlace().getID()+" to "+p.getX()+","+p.getY());
53 pn.setLocation(p.getX(), p.getY());
54 pn.setFixed(true);
55 } else {
56 logger.warn("No layout information for place "+pn.getPlace().getID());
57 }
58 } else if (node instanceof TransitionNode) {
59 TransitionNode pn = (TransitionNode)node;
60 Transition transition = pn.getTransition();
61 Point2D p = createPoint(transition.getProperties(), "gwui.layout");
62 if (p != null) {
63 logger.debug("Setting transition "+transition.getID()+" to "+p.getX()+","+p.getY());
64 pn.setLocation(p.getX(), p.getY());
65 pn.setFixed(true);
66 } else {
67 logger.warn("No layout information for transition "+transition.getID());
68 }
69
70 Iterator inedges = pn.getEdgesTo().iterator(); while (inedges.hasNext()) {
71 ArcEdge edge = (ArcEdge)inedges.next();
72 String edgepropertyprefix = "gwui.layout.inedge."+edge.getPlace().getPlace().getID();
73 String cpspec = transition.getProperties().get(edgepropertyprefix+".cp");
74 if (cpspec != null) {
75 Point2D[] cp = createControlPoints(cpspec);
76 edge.setControlPoints(cp);
77 } else {
78 logger.warn("No control point information for edge "+edge.getPlace().getPlace().getID()+" -> "+transition.getID());
79 }
80 Point2D ps = createPoint(transition.getProperties(), edgepropertyprefix+".ps");
81 edge.setPointOfArrowAtStart(ps);
82 Point2D pe = createPoint(transition.getProperties(), edgepropertyprefix+".pe");
83 edge.setPointOfArrowAtEnd(pe);
84 Point2D lp = createPoint(transition.getProperties(), edgepropertyprefix+".lp");
85 edge.setLabelPosition(lp);
86 }
87
88 Iterator outedges = pn.getEdgesFrom().iterator(); while (outedges.hasNext()) {
89 ArcEdge edge = (ArcEdge)outedges.next();
90 String edgepropertyprefix = "gwui.layout.outedge."+edge.getPlace().getPlace().getID();
91 String cpspec = transition.getProperties().get(edgepropertyprefix+".cp");
92 if (cpspec != null) {
93 Point2D[] cp = createControlPoints(cpspec);
94 edge.setControlPoints(cp);
95 } else {
96 logger.warn("No control point information for edge "+transition.getID()+" -> "+edge.getPlace().getPlace().getID());
97 }
98 Point2D ps = createPoint(transition.getProperties(), edgepropertyprefix+".ps");
99 edge.setPointOfArrowAtStart(ps);
100 Point2D pe = createPoint(transition.getProperties(), edgepropertyprefix+".pe");
101 edge.setPointOfArrowAtEnd(pe);
102 Point2D lp = createPoint(transition.getProperties(), edgepropertyprefix+".lp");
103 edge.setLabelPosition(lp);
104 }
105 }
106 } catch (NumberFormatException x) {
107 logger.warn("Invalid layout information.", x);
108 }
109 }
110 _valid = true;
111 }
112
113 protected Point2D[] createControlPoints(String spec) throws NumberFormatException {
114 StringTokenizer parser = new StringTokenizer(spec, ",() ", false);
115 Collection points = new LinkedList();
116 try {
117 while (parser.hasMoreTokens()) {
118 String x = parser.nextToken();
119 String y = parser.nextToken();
120 points.add(createPoint(x, y));
121 }
122 } catch (NoSuchElementException x) {
123 NumberFormatException nx = new NumberFormatException("Can not parse control point information: "+spec);
124 nx.initCause(x);
125 throw nx;
126 }
127 return (Point2D[])points.toArray(new Point2D[points.size()]);
128 }
129
130 protected Point2D createPoint(GenericProperties props, String pointprefix) throws NumberFormatException {
131 String x = props.get(pointprefix+".x");
132 String y = props.get(pointprefix+".y");
133 return createPoint(x, y);
134 }
135
136 protected Point2D createPoint(String x, String y) throws NumberFormatException {
137 if (x!=null && y!=null) {
138 int ix = Integer.parseInt(x);
139 int iy = Integer.parseInt(y);
140 return new Point2D.Double(ix, iy);
141 } else {
142 return null;
143 }
144 }
145
146 public Graph getGraph() {
147 return _graph;
148 }
149
150 public void elementsAdded(Collection nodes, Collection edges) {
151 _valid = false;
152 }
153
154 public void elementsRemoved(Collection nodes, Collection edges) {
155 _valid = false;
156 }
157
158 public void graphContentsChanged() {
159 _valid = false;
160 }
161
162 public void notifyGraphLayoutUpdated() {
163
164 }
165 }