GenerateCDVisitor { {{ private Formatter f; private Hashtable allTypes; private boolean listPartPresent = false; private String attrClassParts; private String elementClassParts; private String elementClassPartsWithNoTags; private String listUnitPart; }} before CDDef {{ // Generate a list of all "type"s defined in the schema, for later use allTypes = new Hashtable(); for (Enumeration types = host.get_types().elements(); types.hasMoreElements(); ) { DataClass c = (DataClass) types.nextElement(); allTypes.put(c.get_name(), c); } // Open the output formatter to create the CD file f = new Formatter(filename, "CD", behCodeType); f.open(); f.writeTextLine("import java.util.*;"); f.writeTextLine("import java.io.*;"); if (behCodeType.equals("DJ")) f.writeTextLine("import edu.neu.ccs.demeter.dj.*;"); f.skipLine(); f.skipLine(); f.writeTextLine( "// *************************************************************************"); f.writeTextLine( "// The following section has been generated automatically by the XML to Java"); f.writeTextLine( "// conversion application."); f.writeTextLine( "// *************************************************************************"); f.skipLine(); f.writeCDClassName("XMLDoc"); f.writeTextLine("= \" String"); f.writeTextLine(f.indent() + "[ \"encoding\" \"=\" String ]"); f.writeTextLine(f.indent() + " \"?>\""); DataElement root = host.get_root_element(); if (root != null) { String rootName = root.get_name(); String rootType = root.get_type(); f.writeTextLine(f.indent() + "\"<" + rootName + "\""); f.writeTextLine(f.indent() + "[ \"xsi\" \"=\" String ]"); f.writeTextLine(f.indent() + "[ \"schemaLocation\" \"=\" String ]"); f.writeTextLine(f.indent() + "[ \"noNamespaceSchemaLocation\" \"=\" String ]"); f.writeText(f.indent()); if (getTypeCategory(rootType).equals("SIMPLE")) f.writeTextLine("\">\""); f.writeTextLine("<" + rootName + "> " + rootType + " \"\""); } f.writeText(f.indent() + " Hashtable"); f.writeTextLine("."); f.skipLine(); }} after CDDef {{ // Declare the basic classes at the end of the CD f.skipLine(); f.writeCDClassName("Main"); f.writeTextLine("= ."); f.writeCDClassName("Preprocessor"); f.writeTextLine("= ."); if (listPartPresent) { f.skipLine(); f.writeCDClassName("List(S)"); f.writeTextLine("~ {S}."); } f.skipLine(); if (behCodeType.equals("DEMETERJ")) { f.writeCDClassName("visitor InitVisitor"); f.writeTextLine("= ."); f.writeCDClassName("visitor ValidateVisitor"); f.writeTextLine("= ."); } else { f.writeCDClassName("InitVisitor"); f.writeTextLine("= extends Visitor."); f.writeCDClassName("ValidateVisitor"); f.writeTextLine("= extends Visitor."); } f.skipLine(); f.writeTextLine( "// *************************************************************************"); f.writeTextLine( "// End of automatically generated section."); f.writeTextLine( "// *************************************************************************"); // Close the output formatter f.close(); }} before DataClass {{ f.writeCDClassName(host.get_name()); if (host.get_abstract_ind()) { // Print the derived classes String subclasses = ""; for (Enumeration e = host.get_subclasses().elements(); e.hasMoreElements(); ) { subclasses = subclasses + (subclasses.equals("") ? "" : " | ") + (String) e.nextElement(); } f.writeText(": " + subclasses); } else f.writeText("= "); attrClassParts = ""; elementClassParts = ""; elementClassPartsWithNoTags = ""; listUnitPart = ""; }} after DataClass {{ if (host.get_abstract_ind()) { // FOR NOW, always flatten the hierarchy, and do not have any // common parts in abstract superclasses } else // this is a concrete class { if (host.get_category().equals("SIMPLE")) f.writeText(elementClassPartsWithNoTags); else if (host.get_category().equals("COMPLEX")) { // If this class' superclass is abstract, then add a dummy // "type" attribute to correctly identify the construction class if ((host.get_superclass_abstract_ind() != null) && (host.get_superclass_abstract_ind().booleanValue())) { if (!attrClassParts.equals("")) attrClassParts = attrClassParts + "\n" + f.indent(); attrClassParts = attrClassParts + "\"type\" \"=\" " + "\"" + host.get_name() + "\""; } f.writeText(attrClassParts); if (!attrClassParts.equals("")) { f.skipLine(); f.writeText(f.indent()); } f.writeText("\">\""); if (!elementClassParts.equals("")) { f.skipLine(); f.writeText(f.indent() + elementClassParts); } } else if ((host.get_category().equals("GROUP")) || (host.get_category().equals("ALL-GROUP")) || (host.get_category().equals("CHOICE-GROUP")) || (host.get_category().equals("SEQ-GROUP"))) { if (!elementClassParts.equals("")) { f.skipLine(); f.writeText(f.indent() + elementClassParts); } } else if (host.get_category().equals("LISTUNIT")) f.writeText(listUnitPart); } f.writeTextLine("."); f.skipLine(); }} before ElementClassPart {{ Constraint cons = host.get_constraint(); if ((cons.min_occurs == 0) && (cons.max_occurs == 0)) return; boolean optional = false, listPart = false; if ((cons.min_occurs == 0) && (cons.max_occurs == 1)) optional = true; if (cons.max_occurs > 1) { listPart = true; listPartPresent = true; } String thisElement = ""; String partName = host.get_name(); String partType = host.get_type(); listUnitPart = "\"<" + partName; if (getTypeCategory(partType).equals("SIMPLE")) listUnitPart = listUnitPart + ">"; listUnitPart = listUnitPart + "\" " + "<" + partName + "> " + partType + " \"\""; if (listPart) { thisElement = "<" + partName + "> " + "List(" + partType + ")"; if (!elementClassPartsWithNoTags.equals("")) elementClassPartsWithNoTags = elementClassPartsWithNoTags + "\n" + f.indent(); elementClassPartsWithNoTags = elementClassPartsWithNoTags + thisElement; } else { if (optional) thisElement = "[ "; else thisElement = ""; // If the class-part represents an element group, then the markup // for the element name is not needed if ((cons.group_part_flag != null) && (cons.group_part_flag.booleanValue() == true)) { thisElement = thisElement + "<" + partName + "> " + partType; } else { thisElement = thisElement + "\"<" + partName; if (getTypeCategory(partType).equals("SIMPLE")) thisElement = thisElement + ">"; thisElement = thisElement + "\" " + "<" + partName + "> " + partType + " \"\""; } if (optional) thisElement = thisElement + " ]"; if (!elementClassPartsWithNoTags.equals("")) elementClassPartsWithNoTags = elementClassPartsWithNoTags + "\n" + f.indent(); elementClassPartsWithNoTags = elementClassPartsWithNoTags + (optional ? "[ " : "") + "<" + partName + "> " + partType + (optional ? " ]" : ""); } if (!elementClassParts.equals("")) elementClassParts = elementClassParts + "\n" + f.indent(); elementClassParts = elementClassParts + thisElement; }} before AttrClassPart {{ Constraint cons = host.get_constraint(); if ((cons.min_occurs == 0) && (cons.max_occurs == 0)) return; boolean optional = false; if ((cons.min_occurs == 0) && (cons.max_occurs == 1)) optional = true; String thisAttr = ""; String partName = host.get_name(); String partType = host.get_type(); if (optional) thisAttr = thisAttr + "[ "; thisAttr = thisAttr + "\"" + partName + "\"" + " \"=\" "; thisAttr = thisAttr + "<" + partName + "> " + partType; if (optional) thisAttr = thisAttr + " ]"; if (!attrClassParts.equals("")) attrClassParts = attrClassParts + "\n" + f.indent(); attrClassParts = attrClassParts + thisAttr; }} public String getErrors() {{ if (f == null) return "\nCD Print visitor action not yet initiated"; else return f.getErrors(); }} private String getTypeCategory(String typeName) {{ // First check if it's one of the built-in XML types with a directly // corresponding Java type if (Utils.isBuiltInXMLType(typeName)) return "SIMPLE"; // If not, look at the types defined in this schema DataClass c = (DataClass) allTypes.get(typeName); if (c != null) // should always be true return c.get_category(); return "SIMPLE"; }} }