package iiuf.util.graph; import java.util.Collection; import java.util.HashSet; import java.util.BitSet; import java.util.ArrayList; import java.util.LinkedList; import iiuf.util.DefaultAttributable; import iiuf.util.EventListenerList; import iiuf.util.AttributeFactory; import iiuf.util.graph.GraphException; /** Graph base class. (c) 2000, 2001, IIUF, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public abstract class AbstractGraphModel extends DefaultAttributable implements GraphModel { protected final static int ADD = 0; protected final static int RMV = 1; private HashSet nodes = new HashSet(); private HashSet edges = new HashSet(); private GraphNode[] nodesa; private GraphEdge[] edgesa; private String[] attributes = new String[0]; private AttributeFactory[] factories = new AttributeFactory[0]; private BitSet edgeAttr = new BitSet(); private BitSet nodeAttr = new BitSet(); private BitSet graphAttr = new BitSet(); private BitSet portAttr = new BitSet(); private EventListenerList listeners = new EventListenerList(); public void addGraphModelListener(GraphModelListener listener) { listeners.add(GraphModelListener.class, listener); } public void addGraphModelListener(GraphModelListener listener, boolean weak) { listeners.add(GraphModelListener.class, listener, weak); } public void removeGraphModelListener(GraphModelListener listener) { listeners.remove(GraphModelListener.class, listener); } public void add(GraphEdge edge) { add(edge, null); } public void add(GraphEdge edge, Object[] args) { add(new GraphEdge[] {edge}, args); } public void add(GraphEdge[] edges) { add(edges, null); } private synchronized void add(GraphEdge[] edges_, Object[] args) { for(int j = 0; j < edges_.length; j++) { GraphEdge edge = edges_[j]; for(int i = 0; i < attributes.length; i++) if(isEdgeAttribute(i) && !edge.has(i)) edge.set(i, factories[i].newAttribute(edge, args)); edges.add(edge); } edgesa = null; GraphModelListener[] l = (GraphModelListener[])listeners.getListeners(GraphModelListener.class); for(int i = 0; i < l.length; i++) l[i].edgesAdded(this, edges_); } public void remove(GraphEdge edge) { remove(new GraphEdge[] {edge}); } public synchronized void remove(GraphEdge[] edges_) { for(int j = 0; j < edges_.length; j++) edges.remove(edges_[j]); edgesa = null; GraphModelListener[] l = (GraphModelListener[])listeners.getListeners(GraphModelListener.class); for(int i = 0; i < l.length; i++) l[i].edgesRemoved(this, edges_); for(int j = 0; j < edges_.length; j++) edges_[j].remove(); } public void add(GraphNode node) { add(node, null); } public void add(GraphNode node, Object[] args) { add(new GraphNode[] {node}, args); } public void add(GraphNode[] nodes) { add(nodes, null); } private synchronized void add(GraphNode[] nodes_, Object[] args) { for(int j = 0; j < nodes_.length; j++) { GraphNode node = nodes_[j]; if(node.getEdges().length != 0) throw new IllegalArgumentException("node must have no edges:" + node); for(int i = 0; i < attributes.length; i++) { if(isNodeAttribute(i) && !node.has(i)) node.set(i, factories[i].newAttribute(node, args)); GraphPort[] ports = node.getPorts(); for(int k = 0; k < ports.length; k++) if(isPortAttribute(i) && !ports[k].has(i)) ports[k].set(i, factories[i].newAttribute(ports[k], null)); } nodes.add(node); } nodesa = null; GraphModelListener[] l = (GraphModelListener[])listeners.getListeners(GraphModelListener.class); for(int i = 0; i < l.length; i++) l[i].nodesAdded(this, nodes_); } public void remove(GraphNode node) { remove(new GraphNode[] {node}); } public synchronized void remove(GraphNode[] nodes_) { HashSet removeEdges = new HashSet(); for(int j = 0; j < nodes_.length; j++) { GraphEdge[] es = nodes_[j].getEdges(); for(int i = 0; i < es.length; i++) removeEdges.add(es[i]); nodes.remove(nodes_[j]); } nodesa = null; remove((GraphEdge[])removeEdges.toArray(new GraphEdge[removeEdges.size()])); GraphModelListener[] l = (GraphModelListener[])listeners.getListeners(GraphModelListener.class); for(int i = 0; i < l.length; i++) l[i].nodesRemoved(this, nodes_); } public Collection edges() { return edges; } public Collection nodes() { return nodes; } public synchronized GraphEdge[] edgesArray() { if(edgesa == null) edgesa = (GraphEdge[])edges.toArray(new GraphEdge[edges.size()]); return edgesa; } public synchronized GraphNode[] nodesArray() { if(nodesa == null) nodesa = (GraphNode[])nodes.toArray(new GraphNode[nodes.size()]); return nodesa; } private int attribute(String id, AttributeFactory factory) { int result = attributes.length; String[] tmp = attributes; attributes = new String[result + 1]; System.arraycopy(tmp, 0, attributes, 0, result); attributes[result] = id; AttributeFactory[] tmp1 = factories; factories = new AttributeFactory[result + 1]; System.arraycopy(tmp1, 0, factories, 0, result); factories[result] = factory; return result; } public synchronized int portAttribute(String id, AttributeFactory factory) { int result = attribute(id, factory); portAttr.set(result); GraphNode[] o = nodesArray(); for(int i = 0; i < o.length; i++) { GraphPort[] ports = o[i].getPorts(); for(int j = 0; j < ports.length; j++) ports[j].set(result, factory.newAttribute(ports[j], null)); } return result; } public synchronized int nodeAttribute(String id, AttributeFactory factory) { int result = attribute(id, factory); nodeAttr.set(result); GraphNode[] o = nodesArray(); for(int i = 0; i < o.length; i++) o[i].set(result, factory.newAttribute(o[i], null)); return result; } public synchronized int edgeAttribute(String id, AttributeFactory factory) { int result = attribute(id, factory); edgeAttr.set(result); GraphEdge[] o = edgesArray(); for(int i = 0; i < o.length; i++) o[i].set(result, factory.newAttribute(o[i], null)); return result; } public synchronized int graphAttribute(String id, AttributeFactory factory) { int result = attribute(id, factory); set(result, factory.newAttribute(this, null)); graphAttr.set(result); return result; } public boolean isEdgeAttribute(int id) { return edgeAttr.get(id); } public boolean isNodeAttribute(int id) { return nodeAttr.get(id); } public boolean isGraphAttribute(int id) { return graphAttr.get(id); } public boolean isPortAttribute(int id) { return portAttr.get(id); } public String getId(int id) { return attributes[id]; } public synchronized int[] getIds(String id) { int[] tmp = new int[attributes.length]; int count = 0; for(int i = 0; i < attributes.length; i++) if(attributes[i].equals(id)) tmp[count++] = i; int[] result = new int[count]; System.arraycopy(tmp, 0, result, 0, count); return result; } protected abstract void check(int op, Object change) throws GraphException; } /* $Log: AbstractGraphModel.java,v $ Revision 1.1 2002/07/11 12:00:11 ohitz Initial checkin Revision 1.9 2001/04/30 07:33:17 schubige added webcom to cvstree Revision 1.8 2001/01/12 08:26:21 schubige TJGUI update and some TreeView bug fixes Revision 1.7 2001/01/04 16:28:43 schubige Header update for 2001 and DIUF Revision 1.6 2001/01/03 15:23:51 schubige graph stuff beta Revision 1.5 2000/12/28 09:29:10 schubige SourceWatch beta Revision 1.4 2000/12/18 12:39:09 schubige Added ports to iiuf.util.graph Revision 1.3 2000/11/10 10:07:03 schubige iiuf tree cleanup iter 3 Revision 1.2 2000/11/10 08:50:00 schubige iiuf tree cleanup iter 2 Revision 1.1 2000/11/10 07:30:48 schubige iiuf tree cleanup iter 1 Revision 1.5 2000/10/20 07:38:04 robadey *** empty log message *** Revision 1.4 2000/10/19 08:03:45 schubige Intermediate graph component related checkin Revision 1.3 2000/10/19 07:42:44 schubige Changed breadthFirst to walk only connected graphs Revision 1.2 2000/07/28 12:06:54 schubige Graph stuff update Revision 1.1 2000/07/14 13:48:10 schubige Added graph stuff */