// cd2gcd.beh // Author - Binoy Samuel // modified: Binoy : May 26 '98 // This program does the conversion from cd format to gcd format and uses // placement algorithm to place the components //******************** Program *****************************/ Program { //main traversal traversal toAllSubclasses(ClassNameTranspVisitor cntv,EdgeVisitor aev) { to {Part, Subclass,RepeatedPart,Superclass,Interface,PlainSyntax , DoParse , DontParse, PackageDirective, LocalImports, ClassName, ClassSpec}; } (@ /** Converts the cd object(Program) to a gcd object(UGraph) input - none output - UGraph corresponding to the class dictionary */ public UGraph print_edges () { ClassNameTranspVisitor cntv = new ClassNameTranspVisitor(); UGraph ug = new UGraph(); EdgeDistinctionVisitor edv = new EdgeDistinctionVisitor(); EdgeVisitor aev = new EdgeVisitor(edv , cntv , ug); this.toAllSubclasses(cntv,aev); // System.out.println("Text-Uml conversion done....\n"); PlacementVisitor placev = new PlacementVisitor(ug); placev.PositionThem(); // System.out.println("Placement done....\n"); //ug.universal_trv0(new DisplayVisitor() ); //for debug // System.out.println(ug.GetGraphString()); //for debug return ug ; //this to be used by the GUI } @) (@ /** a debug entry point. Invokes the cd-gcd conversion input - cd file redirected command line - edu..Program.main < someCd.cd */ public static void main(String args[]) throws Exception { Program p = parse(System.in); p.print_edges(); } @) } //********************end class Program *****************************/ //**************************RepeatedPart********************************************/ RepeatedPart { traversal toClassSpec ( RepClassSpecVisitor csv ) { to ClassSpec; } traversal toSyntaxClassSpec(SomeClassSpecVisitor scv) { bypassing -> *,nonempty,ClassSpec to {PlainSyntax , ClassSpec}; } (@ void setSyntax( UConstEdge uce) { SomeClassSpecVisitor sv = new SomeClassSpecVisitor(uce); toSyntaxClassSpec(sv); } @) } //**************************end RepeatedPart********************************************/ //******************************InterfaceDef*********************************/ /*InterfaceDef { traversal toInterfaceKeyword (IntModVisitor v) { to PublicInterface ; } (@ public InterfaceModifier_List getIntMods() { InterfaceModifier_List il = new InterfaceModifier_List(); toInterfaceKeyword(new IntModVisitor(il)); return il; } @) }*/ //******************************end InterfaceDef*********************************/ //******************************ClassDef*********************************/ ClassDef { traversal toClassKeyword (ClassModVisitor v) { to {PublicClass , FinalClass }; } (@ public ScopeIdentifier_List getClassMods() { ScopeIdentifier_List sl = new ScopeIdentifier_List(); toClassKeyword(new ClassModVisitor(sl)); return sl; } @) } //******************************end ClassDef*********************************/ //******************************Part*********************************/ Part { traversal toPartKeyword (PartModVisitor v) { to {FinalPart , StaticPart , ReadOnlyPart , PrivatePart}; } (@ public PartModifier_List getPartMods() { PartModifier_List pl = new PartModifier_List(); toPartKeyword(new PartModVisitor(pl)); return pl; } @) } //******************************end Part*********************************/ //*************************************************************************************/ //******************* VISITORS USED IN THE APPLCIATION ********************************/ //*************************************************************************************/ //*************************SomeClassSpecVisitor************************************/ SomeClassSpecVisitor { (@ String bef_syntax; String aft_syntax; String var_syntax; @) before RepeatedPart (@ bef_syntax = null; aft_syntax = null; var_syntax = null; @) before PlainSyntax (@ if(var_syntax != null) var_syntax += host.get_string(); else var_syntax = host.get_string(); @) before ClassSpec (@ bef_syntax = var_syntax; var_syntax = null; @) after RepeatedPart (@ aft_syntax = var_syntax; var_syntax = null; this.get_uce().set_beforeSyntax(bef_syntax); this.get_uce().set_afterSyntax(aft_syntax); @) } //*************************end SomeClassSpecVisitor********************************/ //*************************ClassNameTranspVisitor********************************/ ClassNameTranspVisitor { before ClassDef (@ this.set_pcn(host.get_paramclassname()); @) } //************************* end class ClassNameTranspVisitor*********************/ //************************* ClassNameRetVisitor*********************/ ClassNameRetVisitor { before ClassName (@ this.set_cn(host); @) } //************************* ens class ClassNameTranspVisitor*********************/ //************************* EdgeDistinctionVisitor*********************/ //**Distinguishes the alternation and construction edges */ EdgeDistinctionVisitor { } //*******************end class EdgeDistinctionVisitor*********************/ //*****************EdgeVisitor**************************************/ //EdgeVisitor = EdgeDistinctionVisitor ClassNameTranspVisitor // UGraph. EdgeVisitor { before { DontParseWithStars,DontParseWithoutStars, DoParseWithStars,DoParseWithoutStars } {{ }} traversal toClassName( ClassNameRetVisitor cnrv ) { bypassing -> *,parameters,* to ClassName; } (@ /** Retrieve the class name from the visitor. Requires a traversal from the visitor class which itself needs a visitor. */ public ClassName dig_out() { ClassNameRetVisitor cnrv = new ClassNameRetVisitor(); this.toClassName(cnrv); return cnrv.get_cn(); } Hashtable hTable = new Hashtable(50); //magic number why 50? //for want of anything better UVertex uv; //create a UVertex* in the visitor //creating instances before ClassDef UEdge ue; //create a UEdge* in the visitor //creating instances before Part & Subclass boolean bFlag ; //to diff alt and const vertex. //false = alt vertex. boolean bOptFlag; //for diff cardinality.(optional = 0). //true = optional part. boolean bFirstUID; boolean bParse ; //this one for individual classwise parse/noparse boolean bBlockParse ; //parse/noparse for a block boolean bClassDef ; //set when a classdef is encountered in traversal String class_before; String class_after; String edge_before; String edge_after; String var_syntax; boolean tripflag; //true = after atleast one part/subclass @) before { ->ParamClassName,parameters,ClassName_Commalist , ->ClassSpec, actual_parameters,ClassSpec_Commalist} (@ throw new ParameterisationException("Detected parameterized classes"); @) before Program (@ bFirstUID = false ; bParse = true ; bBlockParse = true ; bClassDef = false ; @) before DoParse (@ if(bClassDef) bParse = true ; else bBlockParse = true ; @) before DontParse (@ if(bClassDef) bParse = false ; else bBlockParse = false ; @) before ClassDef (@ this.bFlag = true; //TRUE means const vertex ; FALSE means its alt vertex // set to TRUE before each vertex:classdef this.bOptFlag = false; this.bClassDef = true; bParse = bBlockParse ; UID uid = UniqueIDGenerator.get_NextUnique(); //if present , dont care, else introduce a UTerm temporarily. if( this.hTable.containsKey(this.dig_out().get_name())==false) this.hTable.put(this.dig_out().get_name() , new UTermConstVertex (this.dig_out().get_name() , UniqueIDGenerator.get_NextUnique() )); class_before = null; class_after = null; edge_before = null; edge_after = null; var_syntax = null; tripflag = false; @) after ClassDef (@ UID uid = UniqueIDGenerator.get_NextUnique(); //if present and UTerm,get the id, delete and add(with the old id) //else return IEdge_List incoming = null ; OEdge_List outgoing = null ; // System.out.println("after classdef -" + this.dig_out().get_name()); if( this.hTable.containsKey(this.dig_out().get_name())==true) { // System.out.println("already in hashtable as "+this.hTable.get( this.dig_out().get_name()).getClass().getName() ); if(this.hTable.get( this.dig_out().get_name()).getClass().getName().endsWith("UTermConstVertex")) { // System.out.println("UT true"); uid = ((UVertex)this.hTable.get( this.dig_out().get_name() )).get_vid(); incoming = ((UVertex)this.hTable.get( this.dig_out().get_name() )).get_incoming(); outgoing = ((UVertex)this.hTable.get( this.dig_out().get_name() )).get_outgoing(); this.hTable.remove( this.dig_out().get_name()); } else { // System.out.println("UT false"); String errMesg ="Possible redefinition of class " + this.dig_out().get_name(); System.out.println(errMesg); // the UVertex present is either UAltVertex or UConstVertex. The earlier version remains. this.bClassDef = false; //kedar throw a redefinition exception here throw new UnsupportedSyntaxException(errMesg); // return ; } } //add the vertex since it is not present. If it were, its been deleted 'cos it was a UTerm. if(this.bFlag == true) { uv = new UConstVertex(this.dig_out().get_name() , uid , bParse); class_after = var_syntax; ((UConstVertex)uv).set_beforeSyntax(class_before); ((UConstVertex)uv).set_afterSyntax(class_after);} else { uv = new UAltVertex(this.dig_out().get_name() , uid , bParse); } uv.set_incoming(incoming); uv.set_outgoing(outgoing); ScopeIdentifier_List sl = host.getClassMods(); if(!sl.isEmpty()) ((UConstOrAltVertex)uv).set_keywords(sl); else ((UConstOrAltVertex)uv).set_keywords(null); //add the vertex into hashtable | the # key being the vertex name. this.hTable.put(this.dig_out().get_name() , uv); if(! this.bFirstUID) { this.get_ugraph().set_firstuid(uv.get_vid()); bFirstUID = true; } this.bClassDef = false; @) before PlainSyntax (@ if(var_syntax != null) var_syntax += host.get_string(); else var_syntax = host.get_string(); @) before Part (@ //add vertex to hashtable if not already present // System.out.println("in Part" + host.get_classspec().get_classname().get_name()); if( this.hTable.containsKey( host.get_classspec().get_classname().get_name())==false) { // System.out.println("in Part(new) -"); this.hTable.put( host.get_classspec().get_classname().get_name() , new UTermConstVertex(host.get_classspec().get_classname().get_name() , UniqueIDGenerator.get_NextUnique())); } UVertex from_vertex = (UVertex) this.hTable.get(this.dig_out().get_name() ) ; UVertex to_vertex = (UVertex) this.hTable.get( host.get_classspec().get_classname().get_name() ) ; UID from_id = from_vertex.get_vid() ; UID to_id = to_vertex.get_vid(); if(host.get_partname() == null) { host.set_partname(new PartName(new Ident((host.get_classspec()).get_classname().get_name().toString().toLowerCase()))); } ue = new UConstEdge( from_id , to_id , new Ident(host.get_partname().toString()) ); from_vertex.add_outgoing( ue.get_eid()); to_vertex.add_incoming( ue.get_eid()); if( tripflag || bOptFlag ) edge_before = var_syntax; else class_before = var_syntax; @) after Part (@ Cardinality crdn; if(this.bOptFlag == true) { crdn = new Cardinality(new Lower(new Integer(0)) ,new Upper( new String("1"))); } else { crdn = new Cardinality(); crdn.set_lower(new Lower(new Integer(1))); } ((UConstEdge)ue).set_card(crdn); this.ugraph.add_uedge(ue); var_syntax = null; tripflag = true; ((UConstEdge)ue).set_beforeSyntax(edge_before); PartModifier_List pl = host.getPartMods(); if(!pl.isEmpty()) ((UConstEdge)ue).set_keywords(pl); else ((UConstEdge)ue).set_keywords(null); @) before Subclass (@ this.bFlag = false; //add vertex to hashtable if not already present if( this.hTable.containsKey( host.get_classspec().get_classname().get_name())==false) { this.hTable.put( host.get_classspec().get_classname().get_name() , new UTermConstVertex(host.get_classspec().get_classname().get_name() , UniqueIDGenerator.get_NextUnique())); } UVertex from_vertex = (UVertex) this.hTable.get(this.dig_out().get_name() ) ; UVertex to_vertex = (UVertex) this.hTable.get( host.get_classspec().get_classname().get_name() ) ; UID from_id = from_vertex.get_vid() ; UID to_id = to_vertex.get_vid(); ue = new UAltEdge( from_id , to_id ); from_vertex.add_outgoing( ue.get_eid()); to_vertex.add_incoming( ue.get_eid()); @) after Subclass (@ this.ugraph.add_uedge(ue); tripflag = true; @) before Superclass (@ //add vertex to hashtable if not already present if( this.hTable.containsKey( host.get_classspec().get_classname().get_name())==false) { this.hTable.put( host.get_classspec().get_classname().get_name() , new UTermConstVertex(host.get_classspec().get_classname().get_name() , UniqueIDGenerator.get_NextUnique())); } UVertex to_vertex = (UVertex) this.hTable.get(this.dig_out().get_name() ) ; UVertex from_vertex = (UVertex) this.hTable.get( host.get_classspec().get_classname().get_name() ) ; UID from_id = from_vertex.get_vid() ; UID to_id = to_vertex.get_vid(); ue = new UExtendEdge( from_id , to_id ); from_vertex.add_outgoing( ue.get_eid()); to_vertex.add_incoming( ue.get_eid()); @) before Interface (@ //add vertex to hashtable if not already present if( this.hTable.containsKey( host.get_classspec().get_classname().get_name())==false) { this.hTable.put( host.get_classspec().get_classname().get_name() , new UTermConstVertex(host.get_classspec().get_classname().get_name() , UniqueIDGenerator.get_NextUnique())); } UVertex to_vertex = (UVertex) this.hTable.get(this.dig_out().get_name() ) ; UVertex from_vertex = (UVertex) this.hTable.get( host.get_classspec().get_classname().get_name() ) ; UID from_id = from_vertex.get_vid() ; UID to_id = to_vertex.get_vid(); ue = new UImplEdge( from_id , to_id ); from_vertex.add_outgoing( ue.get_eid()); to_vertex.add_incoming( ue.get_eid()); @) after Superclass (@ this.ugraph.add_uedge(ue); //tripflag = true; @) after Interface (@ this.ugraph.add_uedge(ue); //tripflag = true; @) before OptionalPart (@ this.bOptFlag = true; if(!tripflag) class_before = var_syntax; else { edge_after = var_syntax; if(edge_after != null) //if prev edge was alt, then syntax==null ((UConstEdge)ue).set_afterSyntax(edge_after); } var_syntax = null; @) after OptionalPart (@ this.bOptFlag = false; edge_after= var_syntax; var_syntax = null; ((UConstEdge)ue).set_afterSyntax(edge_after); // System.out.println("bef str - "+ ((UConstEdge)ue).get_beforeSyntax()+" aft str -" + ((UConstEdge)ue).get_afterSyntax()); @) before RepeatedPart (@ Name first = null; Name inner = null; RepClassSpecVisitor csv = new RepClassSpecVisitor(first , inner); host.toClassSpec(csv); first = csv.get_first(); inner = csv.get_inner(); Cardinality crdn; if( first != null) { if( first.equals(inner) ) { //ue:: cardinality 1..* crdn = new Cardinality(new Lower(new Integer(1)) ,new Upper( new String("*"))); } else { //ue::cardinality 1:first //ue::cardinality 0..*:inner //first if(this.hTable.containsKey(first) == false) { this.hTable.put(first , new UTermConstVertex(first , UniqueIDGenerator.get_NextUnique())); } UVertex from_vertex = (UVertex) this.hTable.get(this.dig_out().get_name() ) ; UVertex to_vertex = (UVertex) this.hTable.get( first ) ; UID from_id = from_vertex.get_vid() ; UID to_id = to_vertex.get_vid(); ue = new UConstEdge( from_id , to_id , null ); from_vertex.add_outgoing( ue.get_eid()); to_vertex.add_incoming( ue.get_eid()); crdn = new Cardinality(); crdn.set_lower(new Lower(new Integer(1))); ((UConstEdge)ue).set_card(crdn); this.ugraph.add_uedge(ue); //inner crdn = new Cardinality(new Lower(new Integer(0)) ,new Upper( new String("*"))); } } else { //ue::cardinality 0..* crdn = new Cardinality(new Lower(new Integer(0)) ,new Upper( new String("*"))); } if(inner != null) { if(this.hTable.containsKey(inner) == false) { this.hTable.put(inner , new UTermConstVertex(inner , UniqueIDGenerator.get_NextUnique())); } UVertex from_vertex = (UVertex) this.hTable.get(this.dig_out().get_name() ) ; UVertex to_vertex = (UVertex) this.hTable.get( inner ) ; UID from_id = from_vertex.get_vid() ; UID to_id = to_vertex.get_vid(); ue = new UConstEdge( from_id , to_id , null ); from_vertex.add_outgoing( ue.get_eid()); to_vertex.add_incoming( ue.get_eid()); ((UConstEdge)ue).set_card(crdn); class_before = var_syntax; host.setSyntax((UConstEdge)ue); this.ugraph.add_uedge(ue); } @) after RepeatedPart (@ var_syntax = null; @) /* before InterfaceDef (@ UID uid = UniqueIDGenerator.get_NextUnique(); if( this.hTable.containsKey(host.get_classname().get_name())==false) { UInterface ui = new UInterface ( host.get_classname().get_name() , UniqueIDGenerator.get_NextUnique() ); ui.set_javacode( host.get_javacode() ); this.hTable.put( host.get_classname().get_name(), ui); InterfaceModifier_List il = host.getIntMods(); if (!il.isEmpty()) ui.set_keywords(il); else ui.set_keywords(null); } else { System.out.println("Possibble redefinition of " + host.get_classname().get_name() ); } @) */ before PackageDirective (@ this.ugraph.set_pkg(host.get_pkg()); @) before LocalImports (@ this.ugraph.set_imports(host.get_imports()); @) after Program (@ Enumeration e = this.hTable.keys(), e2 = this.hTable.elements(); for( ; e.hasMoreElements() ; ) // add vertices to list { e.nextElement(); uv = (UVertex)e2.nextElement(); if(uv.get_incoming() != null) if(uv.get_incoming().isEmpty()) uv.set_incoming(null); if(uv.get_outgoing() != null) if(uv.get_outgoing().isEmpty()) uv.set_outgoing(null); this.ugraph.add_uvertex(uv); } @) } //***************end class EdgeVisitor***********************************/ //***************RepClassSpecVisitor***********************************/ RepClassSpecVisitor { (@ boolean bflag = false; @) before RepeatedPart (@ bflag = true ; @) before ClassSpec_Sandwich (@ bflag = false ; @) before ClassSpec (@ if (bflag) first = host.get_classname().get_name(); else inner = host.get_classname().get_name(); @) } //*************** end class RepClassSpecVisitor***********************************/ //******************************IntModVisitor*********************************/ //IntModVisitor = InterfaceModifier_List . /*IntModVisitor { before PublicInterface (@ InterfaceModifier i = new PublicModifier(); il.addElement(i); @) }*/ //******************************end IntModVisitor*********************************/ //******************************ClassModVisitor*********************************/ //ClassModVisitor = ScopeIdentifier_List . ClassModVisitor { before PublicClass (@ ScopeIdentifier s = new PublicIdentifier(); sl.addElement(s); @) before FinalClass (@ ScopeIdentifier s = new FinalIdentifier(); sl.addElement(s); @) before { PublicClassWithStars,PublicClassWithoutStars, FinalClassWithStars,FinalClassWithoutStars } {{ }} } //******************************end ClassModVisitor*********************************/ //******************************PartModVisitor*********************************/ //PartModVisitor = PartModifier_List . PartModVisitor { before FinalPart (@ PartModifier p = new FinalMod(); pl.addElement(p); @) before StaticPart (@ PartModifier p = new StaticMod(); pl.addElement(p); @) before ReadOnlyPart (@ PartModifier p = new ReadOnlyMod(); pl.addElement(p); @) before PrivatePart (@ PartModifier p = new PrivateMod(); pl.addElement(p); @) before { FinalPartWithStars,FinalPartWithoutStars, StaticPartWithStars,StaticPartWithoutStars, ReadOnlyPartWithStars,ReadOnlyPartWithoutStars, PrivatePartWithStars,PrivatePartWithoutStars} {{ }} } //******************************end PartModVisitor*********************************/ //******************************PlacementVisitor*********************************/ //PlacementVisitor = UGraph . PlacementVisitor { traversal toUVertex(PlaceVertexVisitor pvv) { to UVertex; } traversal toAllEnds(superInitVisitor siv) { to {UVertex , UEdge}; } (@ private Hashtable vtable; private Hashtable etable; void PositionThem() { this.Init(); Coordinates pos = new Coordinates(50 , 50); PlaceVertexVisitor pvv = new PlaceVertexVisitor( pos , vtable , etable); if(this.get_ugraph().get_firstuid() != null ) { Coordinates cc = new Coordinates(pos.get_xvalue(), pos.get_yvalue()); UVertex uvert = (UVertex)vtable.get(this.get_ugraph().get_firstuid()); uvert.set_position(cc); int rightmost = pvv.place(uvert); pos = new Coordinates( (rightmost + 70 ), pos.get_yvalue()) ; //default vertex = 45-35 } pvv = new PlaceVertexVisitor( pos , vtable , etable); this.toUVertex(pvv); } void Init() //mark all as 0 (white) { superInitVisitor inv = new InitVisitor(); toAllEnds(inv); vtable = new Hashtable( (((InitVisitor)inv).get_vcount() + 10) ); etable = new Hashtable(((InitVisitor)inv).get_ecount() + 10); superInitVisitor hcv = new HashCreateVisitor(vtable , etable); toAllEnds(hcv); } @) } //***********************end class PlacementVisitor****************************/ //**********************superInitVisitor****************************/ superInitVisitor { before UGraph (@ @) before {UVertex,UInterface,UTerm,UTermInterface,UTermConstVertex}(@ @) before UEdge (@ @) before {UConstEdge,UImplEdge,UAltEdge,UExtendEdge,USuperEdge} (@ @) before {UConstOrAltVertex,UConstVertex,UAltVertex} {{ }} after UGraph (@ @) } //**********************end class superInitVisitor****************************/ //***************************PlaceVertexVisitor*********************************/ //PlaceVertexVisitor = Coordinates Hashtable Hashtable. PlaceVertexVisitor { before {UConstOrAltVertex,UAltVertex} {{ }} before UVertex (@ if( host.get_vdeco().isSet(true)) return; //for all outgoing, call place Coordinates cc = new Coordinates(pos.get_xvalue(), pos.get_yvalue()); host.set_position(cc); int rightmost = place(host); pos = new Coordinates( (rightmost + 70 ), pos.get_yvalue()) ; //default vertex = 45-35 @) (@ int place(UVertex uv) { int rightmost = uv.get_position().get_xvalue(); int x = rightmost; int y = uv.get_position().get_yvalue(); uv.get_vdeco().setMark(true); UEdge loopue; UVertex loopuv; UID loopuidv; UID loopuide; Nonempty_OEdge_List list; if(uv.get_outgoing() != null) { list = uv.get_outgoing().get_first(); while(list != null) { loopuide = list.get_it(); list = list.get_next(); loopue = (UEdge)etable.get(loopuide); loopuidv=loopue.get_toVertex(); loopuv = (UVertex)vtable.get(loopuidv); if(loopuv.get_vdeco().isSet(true) ) continue; //already marked else { loopuv.set_position(new Coordinates(rightmost , (y + 90))); loopuv.get_vdeco().setMark(true); rightmost = place(loopuv); rightmost += 50; } } // rightmost -= 50; } uv.get_position().get_x().set_x(new Integer(( x+rightmost)/2)); return rightmost; } @) } //**************************end class PlaceVertexVisitor*****************************/ //************************InitVisitor**********************/ InitVisitor { (@ private int vcount; private int ecount; int get_vcount() { return vcount; } void set_vcount(int n) { vcount = n; } int get_ecount() { return ecount; } void set_ecount(int n) { ecount = n; } @) before UGraph (@ set_vcount(0); set_ecount(0); @) before UVertex (@ set_vcount(get_vcount() + 1); if(host.get_vdeco() == null) host.set_vdeco(new Decorator( new Integer(0) , new Vector()) ); else host.get_vdeco().set_travtag(new Integer(0)); @) before UEdge (@ set_ecount(get_ecount() + 1); if(host.get_edeco() == null) host.set_edeco(new Decorator( new Integer(0) , new Vector()) ); else host.get_edeco().set_travtag(new Integer(0)); @) } //*********************end class InitVisitor*******************/ //*******************HashCreateVisitor***********************/ HashCreateVisitor { (@ private Hashtable vtable; private Hashtable etable; HashCreateVisitor ( Hashtable v , Hashtable e ) { vtable = v; etable = e; } @) before UVertex (@ vtable.put(host.get_vid() , host); @) before UEdge (@ etable.put(host.get_eid() , host); @) after UGraph (@ host.set_idToVertexTable(vtable); host.set_idToEdgeTable(etable); // System.out.println("hashtables set"); @) } //*********************end class HashCreateVisitor*****************/