001    package nl.cwi.sen1.gui.plugin;
002    
003    import java.awt.FontMetrics;
004    import java.awt.geom.Point2D;
005    import java.util.HashMap;
006    import java.util.Iterator;
007    import java.util.LinkedList;
008    import java.util.List;
009    import java.util.Map;
010    
011    import nl.cwi.sen1.graph.Factory;
012    import nl.cwi.sen1.graph.types.Attribute;
013    import nl.cwi.sen1.graph.types.AttributeList;
014    import nl.cwi.sen1.graph.types.Color;
015    import nl.cwi.sen1.graph.types.Edge;
016    import nl.cwi.sen1.graph.types.EdgeList;
017    import nl.cwi.sen1.graph.types.Graph;
018    import nl.cwi.sen1.graph.types.Node;
019    import nl.cwi.sen1.graph.types.NodeId;
020    import nl.cwi.sen1.graph.types.NodeList;
021    import nl.cwi.sen1.graph.types.Point;
022    import nl.cwi.sen1.graph.types.Polygon;
023    import nl.cwi.sen1.graph.types.Shape;
024    import nl.cwi.sen1.graph.types.attribute.Location;
025    import nl.cwi.sen1.graph.types.attribute.Size;
026    import nl.cwi.sen1.util.Preferences;
027    import prefuse.util.ColorLib;
028    import prefuse.visual.VisualItem;
029    
030    public class GraphAdapter extends prefuse.data.Graph {
031            public GraphAdapter(nl.cwi.sen1.graph.types.Graph graph) {
032                    super(true);
033    
034                    Map<NodeId, prefuse.data.Node> nodeMap = new HashMap<NodeId, prefuse.data.Node>();
035    
036                    addColumn(GraphConstants.ID, String.class);
037                    addColumn(GraphConstants.LABEL, String.class);
038                    addColumn(GraphDotLayout.DOT_X, int.class);
039                    addColumn(GraphDotLayout.DOT_Y, int.class);
040                    addColumn(GraphDotLayout.DOT_WIDTH, int.class);
041                    addColumn(GraphDotLayout.DOT_HEIGHT, int.class);
042                    addColumn(GraphConstants.SHAPE, Shape.class);
043                    addColumn(GraphDotLayout.CURVE_POINTS, Point2D[].class);
044                    addColumn(GraphConstants.COLOR, int.class);
045                    addColumn(GraphConstants.FILLCOLOR, int.class);
046                    addColumn(GraphConstants.TOOLTIP, String.class);
047    
048                    for (NodeList nodes = graph.getNodes(); !nodes.isEmpty(); nodes = nodes
049                                    .getTail()) {
050                            Node node = nodes.getHead();
051    
052                            prefuse.data.Node pNode = addNode();
053                            pNode.setString(GraphConstants.ID, node.getId().getId().toString());
054                            pNode.setString(GraphConstants.LABEL, getLabel(node));
055                            pNode.setInt(GraphDotLayout.DOT_X, getX(node));
056                            pNode.setInt(GraphDotLayout.DOT_Y, getY(node));
057                            pNode.setInt(GraphDotLayout.DOT_WIDTH, getWidth(node));
058                            pNode.setInt(GraphDotLayout.DOT_HEIGHT, getHeight(node));
059                            pNode.set(GraphConstants.SHAPE, getShape(node));
060                            pNode.set(GraphConstants.TOOLTIP, getTooltip(node));
061    
062                            Color fillColor = getFillColorAttribute(node);
063                            if (fillColor != null) {
064                                    pNode.setInt(GraphConstants.FILLCOLOR, ColorLib.rgb(fillColor
065                                                    .getRed(), fillColor.getGreen(), fillColor.getBlue()));
066                            }
067    
068                            Color color = getColorAttribute(node);
069                            if (color != null) {
070                                    pNode.setInt(GraphConstants.COLOR, ColorLib.rgb(color.getRed(),
071                                                    color.getGreen(), color.getBlue()));
072                            }
073    
074                            nodeMap.put(node.getId(), pNode);
075                    }
076    
077                    for (EdgeList edges = graph.getEdges(); !edges.isEmpty(); edges = edges
078                                    .getTail()) {
079                            Edge edge = edges.getHead();
080                            prefuse.data.Node fromNode = nodeMap.get(edge.getFrom());
081                            prefuse.data.Node toNode = nodeMap.get(edge.getTo());
082                            prefuse.data.Edge pEdge = addEdge(fromNode, toNode);
083    
084                            pEdge.set(GraphDotLayout.CURVE_POINTS, getControlPoints(edge));
085                    }
086            }
087    
088            private Point2D[] getControlPoints(Edge edge) {
089                    Polygon poly = getPolygon(edge);
090                    
091                    if (poly != null) {
092                            List<Point2D> points = new LinkedList<Point2D>();
093    
094                            for (; !poly.isEmpty(); poly = poly.getTail()) {
095                                    Point cp1 = poly.getHead();
096                                    points.add(new Point2D.Float(cp1.getX(), cp1.getY()));
097                            }
098    
099                            Point2D[] result = new Point2D[points.size()];
100                            Iterator<Point2D> iter = points.iterator();
101    
102                            for (int i = 0; iter.hasNext(); i++) {
103                                    result[i] = iter.next();
104                            }
105                            return result;
106                    }
107    
108                    return new Point2D[0];
109            }
110    
111            private Polygon getPolygon(Edge edge) {
112                    AttributeList attrs = edge.getAttributes();
113                    while (!attrs.isEmpty()) {
114                            Attribute attr = attrs.getHead();
115                            if (attr.isCurvePoints()) {
116                                    return attr.getPoints();
117                            }
118                            attrs = attrs.getTail();
119                    }
120    
121                    return null;
122            }
123    
124            private Shape getShape(Node node) {
125                    AttributeList attrs = node.getAttributes();
126                    while (!attrs.isEmpty()) {
127                            Attribute attr = attrs.getHead();
128                            if (attr.isShape()) {
129                                    return attr.getShape();
130                            }
131                            attrs = attrs.getTail();
132                    }
133    
134                    return null;
135            }
136    
137            static private Location getLocationAttribute(Node node) {
138                    AttributeList attrs = node.getAttributes();
139                    while (!attrs.isEmpty()) {
140                            Attribute attr = attrs.getHead();
141                            if (attr.isLocation()) {
142                                    return (Location) attr;
143                            }
144                            attrs = attrs.getTail();
145                    }
146    
147                    return null;
148            }
149    
150            static private Color getFillColorAttribute(Node node) {
151                    AttributeList attrs = node.getAttributes();
152                    while (!attrs.isEmpty()) {
153                            Attribute attr = attrs.getHead();
154                            if (attr.isFillColor()) {
155                                    return attr.getColor();
156                            }
157                            attrs = attrs.getTail();
158                    }
159    
160                    return null;
161            }
162    
163            static private Color getColorAttribute(Node node) {
164                    AttributeList attrs = node.getAttributes();
165                    while (!attrs.isEmpty()) {
166                            Attribute attr = attrs.getHead();
167                            if (attr.isColor()) {
168                                    return attr.getColor();
169                            }
170                            attrs = attrs.getTail();
171                    }
172    
173                    return null;
174            }
175    
176            static public int getX(Node node) {
177                    Location location = getLocationAttribute(node);
178                    if (location != null) {
179                            return location.getX();
180                    }
181                    return 0;
182            }
183    
184            static public int getY(Node node) {
185                    Location location = getLocationAttribute(node);
186                    if (location != null) {
187                            return location.getY();
188                    }
189                    return 0;
190            }
191    
192            static public int getWidth(Node node) {
193                    Size size = getSizeAttribute(node);
194                    if (size != null) {
195                            return size.getWidth();
196                    }
197                    return 0;
198            }
199    
200            static public int getHeight(Node node) {
201                    Size size = getSizeAttribute(node);
202                    if (size != null) {
203                            return size.getHeight();
204                    }
205                    return 0;
206            }
207    
208            static private String getLabel(Node node) {
209                    AttributeList attrs = node.getAttributes();
210    
211                    for (; !attrs.isEmpty(); attrs = attrs.getTail()) {
212                            Attribute attr = attrs.getHead();
213                            if (attr.isLabel()) {
214                                    return attr.getLabel();
215                            }
216                    }
217                    return node.getId().getId().toString();
218            }
219    
220            static private String getTooltip(Node node) {
221                    AttributeList attrs = node.getAttributes();
222    
223                    for (; !attrs.isEmpty(); attrs = attrs.getTail()) {
224                            Attribute attr = attrs.getHead();
225                            if (attr.isTooltip()) {
226                                    return attr.getTooltip();
227                            }
228                    }
229                    return null;
230            }
231    
232            static private Size getSizeAttribute(Node node) {
233                    AttributeList attrs = node.getAttributes();
234                    while (!attrs.isEmpty()) {
235                            Attribute attr = attrs.getHead();
236                            if (attr.isSize()) {
237                                    return (Size) attr;
238                            }
239                            attrs = attrs.getTail();
240                    }
241    
242                    return null;
243            }
244    
245            static private Node setSizeAttribute(Node node, Size sizeAttr) {
246                    Factory factory = node.getGraphFactory();
247                    AttributeList result = factory.makeAttributeList();
248                    AttributeList attrs = node.getAttributes();
249                    while (!attrs.isEmpty()) {
250                            Attribute attr = attrs.getHead();
251                            if (!attr.isSize()) {
252                                    result = factory.makeAttributeList(attr, result);
253                            }
254                            attrs = attrs.getTail();
255                    }
256    
257                    result = factory.makeAttributeList(sizeAttr, result);
258                    return node.setAttributes(result);
259            }
260    
261            static private Node setNodeSize(FontMetrics metrics, Preferences prefs,
262                            Node node) {
263                    Factory factory = node.getGraphFactory();
264                    int borderWidth = prefs.getInt(GraphConstants.NODE_BORDER_WIDTH);
265                    int borderHeight = prefs.getInt(GraphConstants.NODE_BORDER_HEIGHT);
266                    String label = getLabel(node);
267                    int width = metrics.stringWidth(label) + borderWidth * 2;
268                    int height = metrics.getHeight() + borderHeight * 2;
269    
270                    return setSizeAttribute(node, factory.makeAttribute_Size(width, height));
271            }
272    
273            static public Graph sizeGraph(FontMetrics metrics, Preferences prefs,
274                            Graph graph) {
275                    Factory factory = graph.getGraphFactory();
276                    NodeList nodes = graph.getNodes();
277                    NodeList result = factory.makeNodeList();
278    
279                    for (; !nodes.isEmpty(); nodes = nodes.getTail()) {
280                            Node node = nodes.getHead();
281                            node = setNodeSize(metrics, prefs, node);
282                            result = factory.makeNodeList(node, result);
283                    }
284                    return graph.setNodes(result.reverseNodeList());
285            }
286    
287            static public void updateNode(VisualItem node, Attribute attr) {
288                    if (attr.isLabel()) {
289                            node.setString(GraphConstants.LABEL, attr.getLabel());
290                    } else if (attr.isShape()) {
291                            node.set(GraphConstants.SHAPE, attr.getShape());
292                    } else if (attr.isColor()) {
293                            Color color = attr.getColor();
294                            node.setInt(GraphConstants.COLOR, ColorLib.rgb(color.getRed(),
295                                            color.getGreen(), color.getBlue()));
296                    } else if (attr.isFillColor()) {
297                            Color color = attr.getColor();
298                            node.setInt(GraphConstants.FILLCOLOR, ColorLib.rgb(color.getRed(),
299                                            color.getGreen(), color.getBlue()));
300                    }
301            }
302    }