View Javadoc

1   /*
2    * Copyright (c) 2005, The K-Wf Grid Consortium
3    * Fraunhofer Institute for Computer Architecture and Software Technology
4    * See http://www.kwfgrid.eu and http://www.first.fraunhofer.de for more details.
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 	// _valid = false;
164     }
165 }