+ *
+ *
+ * The DotParameterSetter sets the various attributes
+ * of a Graph and it's Nodes and Edges,
+ * using attribute/value String pairs (that come from a dot file).
+ */
+public class DotParameterSetter
+{
+
+ private Graph graph;
+ private HashMap nodeMap;
+ private HashMap edgeMap;
+
+ private Edge[] edges;
+ private Node[] nodes;
+ //private NodeLabelRenderer labelRen;
+
+ private static int graphHeight = 0;
+
+
+
+
+ public DotParameterSetter()
+ {
+ //labelRen = new NodeLabelRenderer();
+ }
+
+
+
+
+ /**
+ * Sets the Graph whose Nodes and
+ * Edges the attributes will apply to.
+ *
+ * @param g The Graph
+ */
+ public void setGraph(Graph g)
+ {
+ // Set the graph
+ graph = g;
+
+ // Reset the graph height
+ graphHeight = 0;
+
+ // Extract the Nodes
+ nodes = graph.getNodes();
+
+ // Put the Nodes into the NodeMap. This allows us
+ // to retrive a Node based on the Node label, which
+ // is generated
+ nodeMap = new HashMap(nodes.length);
+
+ for(int i = 0; i < nodes.length; i++)
+ {
+ //nodeMap.put(labelRen.getLabel(nodes[i]), nodes[i]);
+ nodeMap.put(nodes[i].getUserObject().toString(), nodes[i]);
+ }
+
+ edges = graph.getEdges();
+
+ edgeMap = new HashMap(edges.length);
+
+
+ String tail;
+ String head;
+
+ // Put the edge keys into the edge map
+ for(int i = 0; i < edges.length; i++)
+ {
+ //tail = labelRen.getLabel(edges[i].getTailNode());
+ tail = edges[i].getTailNode().getUserObject().toString();
+
+ //head = labelRen.getLabel(edges[i].getHeadNode());
+ head = edges[i].getHeadNode().getUserObject().toString();
+
+ edgeMap.put(new NodeEdgeKey(tail, head), edges[i]);
+ }
+ }
+
+
+
+
+ /**
+ * Sets an attribute for the Graph.
+ *
+ * @param name The name of the attribute, for example,
+ * "bb" will set the Graph bounding box.
+ * @param value The value of the attribute, for example,
+ * the value "10,20,300,400" might represent a bounding
+ * box located at (10, 20), with a width of 300 and height
+ * of 400.
+ */
+ public void setGraphAttribute(String name, String value)
+ {
+ if(name.equals("bb"))
+ {
+ Rectangle r = parseRect(value);
+
+ if(r != null)
+ {
+ graph.setShape(r);
+
+ graphHeight = r.height;
+ }
+ }
+ }
+
+
+
+
+ /**
+ * Sets the attribute for a specified Node.
+ *
+ * @param nodeID The name of the Node.
+ * @param name The name of the attribute
+ * @param value The value of the attribute
+ */
+ public void setNodeAttribute(String nodeID, String name, String value)
+ {
+ if(name.equals("pos"))
+ {
+ Node n = (Node) nodeMap.get(nodeID);
+
+ if(n != null)
+ {
+ Point p = parsePoint(value);
+
+ if(p != null)
+ {
+ n.setPosition(p.x, graphHeight - p.y);
+ }
+ }
+ } else if (name.equals("label")) {
+ Node n = (Node) nodeMap.get(nodeID);
+
+ if (n != null) {
+ n.setLabel(value);
+ }
+ }
+ }
+
+
+
+
+ /**
+ * Sets the attribute for a specified Edge. The Edge
+ * is specified in terms of the Nodes that it connects.
+ *
+ * @param tailNodeID The tail Node name.
+ * @param headNodeID The head Node name.
+ * @param name The name of the attribute
+ * @param value The value of the attribute
+ */
+ public void setEdgeAttribute(String tailNodeID, String headNodeID, String name, String value)
+ {
+ NodeEdgeKey nek = new NodeEdgeKey(tailNodeID, headNodeID);
+
+ Edge edge = (Edge) edgeMap.get(nek);
+
+ if(edge != null)
+ {
+ if(name.equals("pos"))
+ {
+ setEdgePath(edge, value);
+ }
+ else if(name.equals("lp"))
+ {
+ Point lp = new Point();
+
+ lp = parsePoint(value);
+
+ edge.setLabelPosition(lp.x, graphHeight - lp.y);
+ }
+ }
+
+ }
+
+
+
+
+ /**
+ * Sets the positions of a path origin, and the ctrl points
+ * of the path.
+ *
+ * @param edge The Edge that will have it's
+ * points set.
+ * @param value The String containing the edge
+ * start point and ctrl points.
+ */
+ public void setEdgePath(Edge edge, String value)
+ {
+ // Points are separated by spaced
+ // Points be be preceded by the letter
+ // s or the letter e, indicating the arrowhead point
+ // at the start or the arrowhead point at the end.
+
+ // Extract the edge points from the the string - a list of points separated by spaces
+
+ StringTokenizer tokenizer = new StringTokenizer(value);
+
+ String token;
+
+ // Create a list to hold the points in
+ ArrayList edgePoints = new ArrayList(10); // A size of around 10 should be enough
+
+ Point edgePoint;
+
+ Point startPoint = null;
+
+ Point endPoint = null;
+
+ while(tokenizer.hasMoreTokens())
+ {
+ token = tokenizer.nextToken();
+
+ if(token.charAt(0) == 's')
+ {
+ startPoint = parsePoint(token.substring(2, token.length()));
+
+ startPoint.y = graphHeight - startPoint.y;
+ }
+ else if(token.charAt(0) == 'e')
+ {
+ endPoint = parsePoint(token.substring(2, token.length()));
+
+ endPoint.y = graphHeight - endPoint.y;
+ }
+ else
+ {
+ edgePoint = parsePoint(token);
+
+ edgePoint.y = graphHeight - edgePoint.y;
+
+ edgePoints.add(edgePoint);
+ }
+ }
+
+
+ // Put the information into the edge
+ // Clear any information that is in the
+ // edge.
+ edge.resetPath();
+
+ // Set the start of the edge path
+ edgePoint = edgePoints.get(0);
+
+ edge.setPathOrigin(edgePoint.x, edgePoint.y);
+
+
+ // Set the positions of the control points.
+
+ int numberOfCtrlPoints = (edgePoints.size() - 1) / 3;
+
+ // Control points for bezier curve
+ Point cp1, cp2, cp3;
+
+ int ctrlPointIndex;
+ // Remember, the first point in the list is
+ // the arrowhead tip. The second point is
+ // the first point on the edge path.
+ for(int i = 0; i < numberOfCtrlPoints; i++)
+ {
+ ctrlPointIndex = i * 3 + 1;
+
+ cp1 = edgePoints.get(ctrlPointIndex);
+
+ cp2 = edgePoints.get(ctrlPointIndex + 1);
+
+ cp3 = edgePoints.get(ctrlPointIndex + 2);
+
+ edge.pathTo(cp1.x, cp1.y, cp2.x, cp2.y, cp3.x, cp3.y);
+ }
+
+ Point arrowheadBase;
+
+ if(startPoint != null)
+ {
+ // Arrowhead base should be first point in the list
+ arrowheadBase = edgePoints.get(0);
+
+ // Set the arrowhead, which goes from tip to base points
+ edge.setArrowTail(arrowheadBase.x, arrowheadBase.y, startPoint.x, startPoint.y);
+
+ }
+
+ if(endPoint != null)
+ {
+ // Arrowhead base should be the last point in the list
+ arrowheadBase = edgePoints.get(edgePoints.size() - 1);
+
+ // Set the arrowhead, which goes from tip to base points
+ edge.setArrowTail(arrowheadBase.x, arrowheadBase.y, endPoint.x, endPoint.y);
+ }
+
+
+
+ }
+
+
+
+
+ /**
+ * Parses a point in the form of "x,y".
+ *
+ * @param data The String containing the point (in
+ * format "x,y").
+ * @return A point that is located at (x, y)
+ */
+ public Point parsePoint(String data)
+ {
+ Point p = null;
+
+ int commaPos = data.indexOf(",");
+
+ if(commaPos != -1)
+ {
+ int x = (int) Float.parseFloat(data.substring(0, commaPos));
+ int y = (int) Float.parseFloat(data.substring(commaPos + 1, data.length()));
+
+ p = new Point(x, y);
+ }
+
+ return p;
+ }
+
+
+
+
+ /**
+ * Parses a String that describes a Rectangle
+ *
+ * @param data The String in the format "x,y,w,h"
+ * @return A rectangle that is located at (x, y), has a width w and
+ * a height h.
+ */
+ public Rectangle parseRect(String data)
+ {
+ Rectangle rect = null;
+
+ int start = 0;
+ int commaPos = 0;
+
+ commaPos = data.indexOf(',', start);
+
+ rect = new Rectangle();
+
+ rect.x = Integer.parseInt(data.substring(start, commaPos));
+
+ start = commaPos + 1;
+
+ commaPos = data.indexOf(',', start);
+
+ rect.y = Integer.parseInt(data.substring(start, commaPos));
+
+ start = commaPos + 1;
+
+ commaPos = data.indexOf(',', start);
+
+ rect.width = Integer.parseInt(data.substring(start, commaPos));
+
+ start = commaPos + 1;
+
+ rect.height = Integer.parseInt(data.substring(start, data.length()));
+
+
+ return rect;
+ }
+
+
+
+
+ /**
+ * An inner class that is used to key the names of two
+ * Nodes (tail node and head node)
+ * to an edge.
+ */
+ private class NodeEdgeKey
+ {
+
+ private String tail;
+ private String head;
+
+ public NodeEdgeKey(String tail, String head)
+ {
+ this.tail = tail;
+
+ this.head = head;
+ }
+
+ public int hashCode()
+ {
+ int hashCode = tail.hashCode() * 37 + head.hashCode() * 17;
+
+ return hashCode;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(obj == this)
+ {
+ return true;
+ }
+
+ if(getClass() != obj.getClass())
+ {
+ return false;
+ }
+
+ DotParameterSetter.NodeEdgeKey nek = (DotParameterSetter.NodeEdgeKey) obj;
+
+ return nek.head.equals(this.head) && nek.tail.equals(this.tail);
+ }
+
+ public String toString()
+ {
+ return "NodeEdgeKey(" + tail + " -> " + head + " hashCode: " + this.hashCode() + ")";
+ }
+ }
+
+
+}
+
diff --git a/src/de/unibremen/informatik/hets/graphviz/DotPreParser.java b/src/de/unibremen/informatik/hets/graphviz/DotPreParser.java
new file mode 100644
index 0000000..09b52f1
--- /dev/null
+++ b/src/de/unibremen/informatik/hets/graphviz/DotPreParser.java
@@ -0,0 +1,61 @@
+package de.unibremen.informatik.hets.graphviz;
+
+//import org.apache.log4j.Logger;
+
+import java.io.*;
+
+/**
+ * User: matthewhorridge
+ * The Univeristy Of Manchester
+ * Medical Informatics Group
+ * Date: May 18, 2004
+ *
+ */
+public class Edge
+{
+ private Object userObject;
+ private Node tailNode;
+ private Node headNode;
+ private Point labelPos;
+
+ private GeneralPath path;
+ private static final int ARROWHEAD_HALF_BASE_WIDTH = 4;
+
+ private int direction;
+
+
+ public Edge(Node tailNode, Node headNode, Object userObject, int direction)
+ {
+ this.tailNode = tailNode;
+
+ this.headNode = headNode;
+
+ this.userObject = userObject;
+
+ labelPos = new Point();
+
+ path = new GeneralPath();
+
+ /*
+ if(direction == GraphModel.DIRECTION_NONE ||
+ direction == GraphModel.DIRECTION_FORWARD ||
+ direction == GraphModel.DIRECTION_BACK ||
+ direction == GraphModel.DIRECTION_BOTH)
+ {
+ this.direction = direction;
+ }
+ */
+ this.direction = 1;
+ }
+
+ /**
+ * Returns the node that the head of the head
+ * is connected to.
+ * @return The head Node.
+ */
+ public Node getHeadNode()
+ {
+ return headNode;
+ }
+
+ /**
+ * Returns the node that the tail of the edge
+ * is connected to.
+ * @return The tail Node.
+ */
+ public Node getTailNode()
+ {
+ return tailNode;
+ }
+
+ /**
+ * Allows an object to be associated with the Edge
+ * @param o The object to be set as the userObject
+ */
+ public void setUserObject(Object o)
+ {
+ userObject = o;
+ }
+
+ /**
+ * Gets the userObject, previously set with setUserObject(Object o)
+ * @return The userObject, or null if no object has been set.
+ */
+ public Object getUserObject()
+ {
+ return userObject;
+ }
+
+ /**
+ * Causes any information in the path that represents the Egde
+ * to be cleared, such as origin location and any control points.
+ */
+ public void resetPath()
+ {
+ path.reset();
+ }
+
+ /**
+ * Sets the location of the start of the path that represents
+ * the Edge.
+ * @param x The horizontal location.
+ * @param y The vertical location.
+ */
+ public void setPathOrigin(int x, int y)
+ {
+ path.reset();
+
+ path.moveTo(x, y);
+
+ }
+
+ /**
+ * Extends the Edge using the following control points to
+ * form a Bezier curve extension to the end point (x3, y3).
+ * @param x1 Horizontal location of control point 1
+ * @param y1 Vertical location of control point 1
+ * @param x2 Horizontal location of control point 2
+ * @param y2 Vertical location of control point 2
+ * @param x3 Horizontal location of the end point.
+ * @param y3 Vertical location of the end point.
+ */
+ public void pathTo(int x1, int y1, int x2, int y2, int x3, int y3)
+ {
+ // If the path is a horizontal straighline, then add it as
+ // such - there appears to be a 'feature' where
+ // the curve will not be drawn if all y control points
+ // are equal.
+ if(y1 == y2 && y2 == y3)
+ {
+ path.lineTo(x3, y3);
+ }
+ else
+ {
+ path.curveTo(x1, y1, x2, y2, x3, y3);
+ }
+ }
+
+ /**
+ * Extends the Edge to the specified location using
+ * a straight line.
+ * @param x The horizontal location of the end point.
+ * @param y The vertical location of the end point.
+ */
+ public void pathTo(int x, int y)
+ {
+ path.lineTo(x, y);
+ }
+
+ /**
+ * Retrieves the position of the Edge's label.
+ * @return A Point containing the position of
+ * the label.
+ */
+ public Point getLabelPosition()
+ {
+ return labelPos;
+ }
+
+ /**
+ * Sets the Edge's label position.
+ * @param x The horizontal location (in pixels).
+ * @param y The vertical location (in pixels).
+ */
+ public void setLabelPosition(int x, int y)
+ {
+ labelPos.x = x;
+
+ labelPos.y = y;
+ }
+
+ public void setArrowHead(int baseX, int baseY, int tipX, int tipY)
+ {
+ int deltaX = tipX - baseX;
+ int deltaY = tipY - baseY;
+
+ double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+
+ double vecX = (deltaX / length) * ARROWHEAD_HALF_BASE_WIDTH;
+
+ double vecY = (deltaY / length) * ARROWHEAD_HALF_BASE_WIDTH;
+
+
+
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ x1 = (int)(baseX - vecY);
+ y1 = (int)(baseY + vecX);
+ x2 = (int)(baseX + vecY);
+ y2 = (int)(baseY - vecX);
+
+ path.moveTo(tipX, tipY);
+
+ path.lineTo(x1, y1);
+
+ path.lineTo(x2, y2);
+
+ path.lineTo(tipX, tipY);
+ }
+
+
+ /**
+ * Sets the Edge's arrowtail
+ *
+ * @param baseX The x location of the centre of the arrowhead baseline.
+ * @param baseY The y location of the centre of the arrowhead tip.
+ * @param tipX The x location of the tip of the arrowhead.
+ * @param tipY The y location of the tip of the arrowhead.
+ */
+ public void setArrowTail(int baseX, int baseY, int tipX, int tipY)
+ {
+ int deltaX = tipX - baseX;
+ int deltaY = tipY - baseY;
+
+ double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+
+ double vecX = (deltaX / length) * ARROWHEAD_HALF_BASE_WIDTH;
+
+ double vecY = (deltaY / length) * ARROWHEAD_HALF_BASE_WIDTH;
+
+
+
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ x1 = (int)(baseX - vecY);
+ y1 = (int)(baseY + vecX);
+ x2 = (int)(baseX + vecY);
+ y2 = (int)(baseY - vecX);
+
+ path.moveTo(tipX, tipY);
+
+ path.lineTo(x1, y1);
+
+ path.lineTo(x2, y2);
+
+ path.lineTo(tipX, tipY);
+ }
+
+
+ /**
+ * Gets the Shape that represents the Edge.
+ * @return The Shape of the Edge.
+ */
+ public Shape getShape()
+ {
+ return path;
+ }
+
+
+ /**
+ * Gets the direction of the Edge. This is one of the
+ * predefined direction from the Edge interface.
+ *
+ * @return The direction of the Edge.
+ */
+ public int getDirection()
+ {
+ return direction;
+ }
+
+
+ public int hashCode()
+ {
+ return tailNode.hashCode() * 13 + headNode.hashCode() * 37;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(obj instanceof Edge)
+ {
+ if(obj == this)
+ {
+ return true;
+ }
+ else
+ {
+ Edge edge = (Edge)obj;
+
+ if(edge.getTailNode().equals(tailNode) && edge.getHeadNode().equals(headNode))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/de/unibremen/informatik/hets/graphviz/EdgeRenderer.java b/src/de/unibremen/informatik/hets/graphviz/EdgeRenderer.java
new file mode 100644
index 0000000..61ccf53
--- /dev/null
+++ b/src/de/unibremen/informatik/hets/graphviz/EdgeRenderer.java
@@ -0,0 +1,213 @@
+package de.unibremen.informatik.hets.graphviz;
+
+/*
+import uk.ac.man.cs.mig.util.graph.controller.Controller;
+import uk.ac.man.cs.mig.util.graph.graph.Edge;
+import uk.ac.man.cs.mig.util.graph.renderer.EdgeRenderer;
+*/
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * User: matthewhorridge
+ * The Univeristy Of Manchester
+ * Medical Informatics Group
+ * Date: Jan 14, 2004
+ *
+ */
+public class Graph
+{
+ private Map nodes;
+ private Map edges;
+
+ private Shape shape;
+
+ public Graph()
+ {
+ nodes = new HashMap();
+
+ edges = new HashMap();
+
+ shape = new Rectangle();
+ }
+
+ /**
+ * Adds a Node to the graph. If the Graph
+ * already contains the Node then the Node
+ * will not be added.
+ * @param node The node to be added.
+ */
+ public void add(Node node)
+ {
+ if(nodes.containsKey(node) == false)
+ {
+ nodes.put(node, node);
+ }
+
+
+ }
+
+ /**
+ * Removes the specified Node from the Graph.
+ * Note that any edges that have this node as their head node, or tail node
+ * will also be removed.
+ * @param node The Node to be removed.
+ */
+ public void remove(Node node)
+ {
+
+ if(nodes.containsKey(node))
+ {
+ // Remove the node
+ nodes.remove(node);
+
+ Iterator it = getEdgeIterator();
+
+ Edge edge;
+
+ // Remove any edges that are connected to the node.
+ while(it.hasNext())
+ {
+ edge = (Edge)it.next();
+
+ if(node.equals(edge.getTailNode()))
+ {
+ it.remove();
+ }
+ else if(node.equals(edge.getHeadNode()))
+ {
+ it.remove();
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds an Edge to the graph. Note that the Edge will
+ * only be added if the nodes that the edge connects are contained
+ * in the graph.
+ * @param edge The Edge to be added.
+ */
+ public void add(Edge edge)
+ {
+ if(nodes.containsKey(edge.getTailNode()) && nodes.containsKey(edge.getHeadNode()))
+ {
+ EdgeKey key = new EdgeKey(edge);
+
+ edges.put(key, edge);
+ }
+ }
+
+ /**
+ * Removes an Edge from the Graph.
+ * @param edge The Edge to be removed.
+ */
+ public void remove(Edge edge)
+ {
+ edges.remove(new EdgeKey(edge));
+ }
+
+ /**
+ * Removes the Edge that connects the specified
+ * Nodes (if the Nodes are contained
+ * in the Graph.
+ * @param tailNode The Egde's tail Node.
+ * @param headNode The Edge's head Node.
+ */
+ public void remove(Node tailNode, Node headNode)
+ {
+ edges.remove(new EdgeKey(tailNode, headNode));
+ }
+
+ /**
+ * Removes all the edges and nodes from the graph.
+ */
+ public void removeAll()
+ {
+ edges = new HashMap();
+
+ nodes = new HashMap();
+ }
+
+ /**
+ * Returns the number of Nodes that the Graph
+ * contains.
+ * @return The number of Nodes.
+ */
+ public int getNodeCount()
+ {
+ return nodes.size();
+ }
+
+ /**
+ * Returns the number of Edges that the Graph
+ * contains.
+ * @return The number of Edges.
+ */
+ public int getEdgeCount()
+ {
+ return edges.size();
+ }
+
+ /**
+ * Retrieves an Iterator that can be
+ * used to traverse the Nodes in the Graph.
+ * @return The Iterator.
+ */
+ public Iterator getNodeIterator()
+ {
+ return nodes.keySet().iterator();
+ }
+
+ /**
+ * Retrieves an Iterator that can be
+ * used to traverse the Edges in the Graph.
+ * @return The Iterator.
+ */
+ public Iterator getEdgeIterator()
+ {
+ return edges.values().iterator();
+ }
+
+ /**
+ * Gets the shape that isShown all of the Nodes and
+ * Edges belonging to the Graph.
+ * @return A shape that describes the Graphs bounds.
+ */
+ public Shape getShape()
+ {
+ return shape;
+ }
+
+ /**
+ * Sets the shape that describes the Graph bounds.
+ * @param shape The Shape bounding the graph.
+ */
+ public void setShape(Shape shape)
+ {
+ this.shape = shape;
+ }
+
+ /**
+ * Determines if the Graph isShown the specified Node.
+ * @param node The Node
+ * @return true if the Graph isShown the Node
+ * or false if the Graph does not contain the Node.
+ */
+ public boolean contains(Node node)
+ {
+ return nodes.containsKey(node);
+ }
+
+ /**
+ * Determines if the Graph isShown the specified Edge.
+ * @param edge The Edge.
+ * @return true if the Graph isShown the Edge
+ * or false if the Graph does not contain the Edge.
+ */
+ public boolean contains(Edge edge)
+ {
+ return edges.containsKey(new EdgeKey(edge));
+ }
+
+ /**
+ * Gets the Nodes contained in the Graph
+ * as an array.
+ * @return An array containing the Nodes in the Graph.
+ */
+ public Node[] getNodes()
+ {
+ Object [] array = nodes.keySet().toArray();
+
+ Node [] nodeArray = new Node [array.length];
+
+ System.arraycopy(array, 0, nodeArray, 0, array.length);
+
+ return nodeArray;
+ }
+
+ /**
+ * Gets the Edges contained in the Graph as an array.
+ * @return An array containing the Edges in the Graph.
+ */
+ public Edge[] getEdges()
+ {
+ Object [] array = edges.values().toArray();
+
+ Edge [] edgeArray = new Edge [array.length];
+
+ System.arraycopy(array, 0, edgeArray, 0, array.length);
+
+ return edgeArray;
+ }
+
+ public class EdgeKey
+ {
+ private Node tailNode;
+ private Node headNode;
+
+ public EdgeKey(Edge edge)
+ {
+ this.tailNode = edge.getTailNode();
+
+ this.headNode = edge.getHeadNode();
+ }
+
+ public EdgeKey(Node tailNode, Node headNode)
+ {
+ this.tailNode = tailNode;
+
+ this.headNode = headNode;
+ }
+
+ public int hashCode()
+ {
+ return tailNode.hashCode() * 13 + headNode.hashCode() * 37;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(obj.getClass().equals(this.getClass()) == false)
+ {
+ return false;
+ }
+
+ EdgeKey key = (EdgeKey)obj;
+
+ if(key.tailNode.equals(tailNode) && key.headNode.equals(headNode))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/de/unibremen/informatik/hets/graphviz/Node.java b/src/de/unibremen/informatik/hets/graphviz/Node.java
new file mode 100644
index 0000000..46e5e06
--- /dev/null
+++ b/src/de/unibremen/informatik/hets/graphviz/Node.java
@@ -0,0 +1,115 @@
+package de.unibremen.informatik.hets.graphviz;
+
+//import uk.ac.man.cs.mig.util.graph.graph.Node;
+
+import java.awt.*;
+import java.awt.geom.Ellipse2D;
+
+/**
+ * User: matthewhorridge
+ * The Univeristy Of Manchester
+ * Medical Informatics Group
+ * Date: Jan 15, 2004