Cd_graph { {{ public HashMap parents = new HashMap(); // Map of key: Part (string) and value: Parent (string) /* Gets the parent associated with the vertex name key */ public String getParent(String vname) { return (String) parents.get(String.valueOf(vname)); } public void validateParts(final ClassGraph cg) { Strategy sg = new Strategy("from Cd_graph through Neighbors to Vertex"); /* Traverse to all vertices that are not Adjacency sources 1. if a vertex is a Terminal Buffer class with siblings or inside a parameter class, then produce a TBR error. 2. if a vertex is undefined then produce an undefined error 3. if a subclass inherits from multiple classes, then produce a multiple inheritance error */ cg.traverse( this, sg, new Visitor() { public Ident currentAdj; // The current adjacency being examined public Integer numberOfParts; // The current adjacency's part count public boolean insideParamClass; // True if inside a param class public boolean isSubClass; // True if is a subclass public void start() { insideParamClass = false; isSubClass = false; } public void before(Adjacency host){ currentAdj = host.get_source().get_vertex_name(); numberOfParts = new Integer(0); } public void before(Vertex host) { Ident vname = host.get_vertex_name(); /* Check for TBR violation */ if ( (numberOfParts.intValue() > 1 || insideParamClass) && host.isTerminalClass()) System.out.println(" *** ERROR: Class "+currentAdj.toString()+" violates TBR. Class " + vname.toString() + " is not the only part class." ); /* Check for undefined classes */ if(!definedClasses.contains(vname)) { // Show undefined error only once if (!undefinedClasses.contains(vname)) System.out.println(" *** ERROR: Class " + vname + " is not defined in the class dictionary."); undefinedClasses.add(vname); } /* Check for multiple inheritance */ /* if (isSubClass) { // get the parent of this host String the_parent = getParent( host.get_vertex_name().toString() ); if ( the_parent == null ) { // No parent specified so add the entry to the HashMap parents.put( host.get_vertex_name().toString(), currentAdj.toString() ); } else { // Check for multiple inheritance if( the_parent != currentAdj.toString() ) System.out.println(" *** ERROR: Class "+ host.get_vertex_name().toString() + " has two super classes: " + the_parent + ", " + currentAdj.toString() + "." ); } } */ } public void before(Any_vertex_List host){ // Set number of parts for this adjacency numberOfParts = new Integer(host.size()); } public void before(Term_Comma_list host) {insideParamClass = true;} public void after(Term_Comma_list host) {insideParamClass = false;} public void before(Term_Bar_list host) {isSubClass = true;} public void after(Term_Bar_list host) {isSubClass = false;} }); // end traversal } // end of method }} } /// /// The following terminal class code is reused from: /// http://www.ccs.neu.edu/research/demeter/DemeterJava/use/latest-demjava/aplib/cd/utils.beh /// Vertex { {{ private static String terminalClasses[] = { // from java.lang.*: "Boolean", "Character", "Integer", "Long", "Float", "Double", "Number", "String", "StringBuffer", // from demeter.*: "Ident", "Text", "Line", "Word" }; }} boolean isTerminalClass() {{ String s = vertex_name.toString(); for (int i = 0; i < terminalClasses.length; i++) { if (terminalClasses[i].equals(s)) return true; } return false; }} }