package edu.neu.ccs.demeter; import java.util.*; import edu.neu.ccs.demeter.Ident; import java.io.*; /** Utility class for TAO. */ public class Graph { public Graph(Hashtable t) {graph = t;} public Graph() {graph= new Hashtable();} private Hashtable graph = new Hashtable(); public static Graph fromString(String str) { return fromString(new StreamTokenizer(new StringReader(str))); } public static Graph fromString(StreamTokenizer instr) { instr.lowerCaseMode(false); instr.wordChars('_','_'); instr.ordinaryChar('.'); Hashtable g= new Hashtable(); Ident cn,pn,pc; Object[] em; try { instr.nextToken(); while ((instr.ttype != '.')&&(instr.ttype != -1)) { // for each class cn = new Ident(instr.sval); // System.out.print("\n"+cn); instr.nextToken(); // the open paren if (instr.ttype != '(') {System.out.println("Confused"); System.exit(1);} instr.nextToken(); int numparts = (int) instr.nval; instr.nextToken(); em = new Object[2*numparts+1]; g.put(cn,em); int partcount =1; while (instr.ttype != ')') { // for each edge pn = new Ident(instr.sval); // part name // System.out.print(" <"+pn+"> "); instr.nextToken(); pc = new Ident(instr.sval); // and class // System.out.print(pc); instr.nextToken(); em[2*partcount-1]=pn; em[2*partcount ]=pc; partcount++; } instr.nextToken(); } } catch (IOException e) { System.err.println(e); System.exit(1); } return new Graph(g); } public String toString() { String str = ""; for(Enumeration e = graph.keys(); e.hasMoreElements();) { Ident key = (Ident) e.nextElement(); str = str+key+" ( "; Object[] parts = (Object[]) graph.get(key); int numparts=(parts.length-1)/2; str = str + numparts +" "; for (int i =1;i <= numparts;i++) { Ident pn = (Ident) parts[2*i-1]; Ident pc = (Ident) parts[2*i]; str=str+pn+" "+pc+" "; } str = str + " ) "; } return str+" ."; } public Enumeration nodes() { return graph.keys(); } public boolean nodeexists(Ident node) { return graph.containsKey(node); } public boolean edgeexists(Ident from, Ident name) { if (! nodeexists(from)) return false; Object[] parts = edgesfrom(from); int numparts=(parts.length-1)/2; for (int i =1;i <= numparts;i++) { if (name.equals((Ident) parts[2*i-1])) return true; } return false; } public Object[] edgesfrom(Ident node) { if (nodeexists(node)) { return (Object[]) graph.get(node); } else { Object[] e = new Object[1]; graph.put(node,e); return e; } } public Object getdestnode(Ident node, Ident edgename) { Object[] parts = edgesfrom(node); for (int numparts=(parts.length -1)/2; numparts >0; numparts--) { if (((Ident)parts[numparts*2-1])==edgename) return parts[numparts*2]; } return null; } public void makeedge(Ident from, Ident edgename, Ident to) { Object[] parts = edgesfrom(from); Object[] newparts = new Object[parts.length +2]; // assume the part does not exist newparts[0]=parts[0]; newparts[parts.length]=edgename; newparts[parts.length+1]=to; graph.put(from,newparts); for (int numparts=(parts.length -1)/2; numparts >0; numparts--) { // if the assumption was wrong, undo the damage if (((Ident) parts[numparts*2-1])==edgename) { parts[numparts*2]=to; graph.put(from,parts); break; } else { newparts[numparts*2-1]=parts[numparts*2-1]; newparts[numparts*2]=parts[numparts*2]; } } } public void clearnode(Ident from) { graph.put(from, new Object[1]); } public void removeincoming(Ident to) { Enumeration thenodes = nodes(); while (thenodes.hasMoreElements()) { Ident cn = (Ident) thenodes.nextElement(); Object[] parts = edgesfrom(cn); if (parts.length < 3) continue; Object[] newparts = new Object[parts.length-2]; int numparts = (parts.length-1)/2; int partcount=1; while ((partcount