CDPrintVisitor { {{ private BufferedWriter file; private int indentLength = 16; private boolean listPartPresent = false; private Hashtable allTypes; private String attrClassParts; private String elementClassParts; private String elementClassPartsWithNoTags; private String listUnitPart; }} public void before(CDDef host) throws Exception {{ // Open the output file for writing the CD try { file = new BufferedWriter(new FileWriter(filename)); } catch (IOException e) { throw new Exception("Error in opening the CD file for writing."); } // Save a reference to the 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); } write(formattedClassName("XMLDoc")); write("= \" String \"?>\""); DataElement root = host.get_root_element(); if (root != null) { String rootName = root.get_name(); String rootType = root.get_type(); writeln(""); write(indent() + "\"<" + rootName); if (getTypeCategory(rootType).equals("SIMPLE")) write(">"); write("\" <" + rootName + "> " + rootType + " \"\""); } writeln("."); writeln(""); }} public void after(CDDef host) throws Exception {{ // Declare the basic classes at the end of the CD writeln(""); writeln(formattedClassName("Main") + "= ."); writeln(formattedClassName("Preprocessor") + "= ."); if (listPartPresent) { writeln(""); writeln(formattedClassName("List(S)") + "~ {S}."); } writeln(""); writeln(formattedClassName("ValidateVisitor") + "= extends Visitor."); // Close the output file try { file.close(); } catch (IOException e) { throw new Exception("Error in closing the CD file after writing."); } }} public void before(DataClass host) throws Exception {{ write(formattedClassName(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(); } writeln(": " + subclasses); } else write("= "); attrClassParts = ""; elementClassParts = ""; elementClassPartsWithNoTags = ""; listUnitPart = ""; }} public void after(DataClass host) throws Exception {{ if (host.get_abstract_ind()) { // TO BE COMPLETED LATER } else if (host.get_category().equals("SIMPLE")) write(elementClassPartsWithNoTags); else if (host.get_category().equals("COMPLEX")) { write(attrClassParts); if (!attrClassParts.equals("")) write("\n" + indent()); write("\">\""); if (!elementClassParts.equals("")) write("\n" + indent() + elementClassParts); } else if (host.get_category().equals("LISTUNIT")) write(listUnitPart); writeln("."); writeln(""); }} public void before(ElementClassPart host) throws Exception {{ boolean optional = false, listPart = false; if ((host.get_constraint().min_occurs == 0) && (host.get_constraint().max_occurs == 1)) optional = true; if (host.get_constraint().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 = "List(" + partType + ")"; else { if (optional) thisElement = "[ "; else thisElement = ""; thisElement = thisElement + "\"<" + partName; if (getTypeCategory(partType).equals("SIMPLE")) thisElement = thisElement + ">"; thisElement = thisElement + "\" " + "<" + partName + "> " + partType + " \"\""; if (optional) thisElement = thisElement + " ]"; if (!elementClassPartsWithNoTags.equals("")) elementClassPartsWithNoTags = elementClassPartsWithNoTags + "\n" + indent(); elementClassPartsWithNoTags = elementClassPartsWithNoTags + "<" + partName + "> " + partType; } if (!elementClassParts.equals("")) elementClassParts = elementClassParts + "\n" + indent(); elementClassParts = elementClassParts + thisElement; }} public void before(AttrClassPart host) throws Exception {{ boolean optional = false; if ((host.get_constraint().min_occurs == 0) && (host.get_constraint().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" + indent(); attrClassParts = attrClassParts + thisAttr; }} // Private methods used for formatting text, etc. private void write(String text) throws Exception {{ try { file.write(text); } catch (IOException e) { throw new Exception("Error in writing to CD file."); } }} private void writeln(String text) throws Exception {{ write(text + "\n"); }} private String formattedClassName(String className) throws Exception {{ String text = className; int noOfTabs = new Double(Math.ceil( (indentLength - className.length()) / 8.0)).intValue(); for (int i = 0; i < noOfTabs; i++) text = text + "\t"; if (noOfTabs <= 0) text = text + " "; return text; }} private String indent() throws Exception {{ String text = ""; for (int i = 0; i < (indentLength/8); i++) text = text + "\t"; return text + " "; }} private String getTypeCategory(String typeName) {{ // First check if it's one of the built-in XML types with a directly // corresponding Java type if (Lookup.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"; }} }