## defs/Defs.java

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. Defs
2. getDOM
3. validate
4. printDF_attribute_aliases
5. printDF_attribute_aliases_map
6. printDF_attribute_codes
7. printDF_attribute_enum
8. printDF_attribute_inv_attr_mask
9. printDF_attribute_names
10. printDF_class_aliases
11. printDF_class_aliases_map
12. printDF_class_codes
13. printDF_class_dbase_code_map
14. printDF_class_enum
15. printDF_class_mask
16. printDF_class_names
17. printQI_queries
18. printUD_updates
19. printTemplates
20. printTemplatesV
21. printDiagrams
22. main

    import java.io.*;
    import java.util.*;
    import com.sun.xml.parser.*;
    import com.sun.xml.tree.*;
    import org.xml.sax.*;
    import org.w3c.dom.*;

    /**
     * RIPE classes generated from Data Object Models.
     *
     * @author ottrey@ripe.net
     * @version $Version$
     *
     */
    public class Defs {
    /* [<][>][^][v][top][bottom][index][help] */

      private Hashtable ripeAttributes;
      private Vector ripeAttributeCodes;
      private Vector ripeClasses;
      private Vector ripeAttributeAliases;
      private Vector ripeAttributeAliasesMap;
      private Vector ripeClassAliases;
      private Vector ripeClassAliasesMap;
      private Vector ripeQueries;

      // -----------------oOo-----------------
      //              Constructors
      // -----------------oOo-----------------
      public Defs(boolean normalize) {
        // Create a normalized DOM from the xml file for the attributes.
        XmlDocument attrDOM = getDOM("attributes.xml", "ripe_attribute", normalize);

        // Initialize.
        ripeAttributes = new Hashtable();
        ripeAttributeCodes = new Vector();
        ripeAttributeAliases = new Vector();
        ripeAttributeAliasesMap = new Vector();
        ripeClassAliases = new Vector();
        ripeClassAliasesMap = new Vector();
        ripeQueries = new Vector();

        // Recurse through node tree
        NodeList attrNodes = attrDOM.getElementsByTagName("ripe_attribute");
        for (int i=0; i < attrNodes.getLength(); i++) {
          // (Checking if the attribute is valid)
          if (validate("attribute", attrNodes.item(i))) {
            AttributeDef ad = new AttributeDef(attrNodes.item(i));

            // and each attribute,
            ripeAttributes.put(ad.getCode(), ad);

            // and it's code.
            ripeAttributeCodes.addElement(ad.getCode());

            // and it's aliases.
            // also map the alias to the attribute index.

            // set the index to map to.
            Integer mapIndex = new Integer(ripeAttributeCodes.size()-1);

            //  first the code.
            ripeAttributeAliases.addElement(ad.getCode());
            ripeAttributeAliasesMap.addElement(mapIndex);

            //  then the name.
            ripeAttributeAliases.addElement(ad.getName());
            ripeAttributeAliasesMap.addElement(mapIndex);

            if (ad.getAltName().length() > 1) {
              //  then the altName.
              ripeAttributeAliases.addElement(ad.getAltName());
              ripeAttributeAliasesMap.addElement(mapIndex);
            }
          }
        }

        // Create a normalized DOM from the xml file for the classes.
        XmlDocument objDOM = getDOM("classes.xml", "ripe_class", normalize);

        // Create a vector to store the classes.
        ripeClasses = new Vector();

        // Recurse through node tree
        NodeList objNodes = objDOM.getElementsByTagName("ripe_class");
        for (int i=0; i < objNodes.getLength(); i++) {
          // Check if the class is valid
          if (validate("class", objNodes.item(i))) {
            ClassDef od = new ClassDef(objNodes.item(i), ripeAttributes);

            // Add the class.
            ripeClasses.addElement(od);

            // set the index to map to.
            Integer mapIndex = new Integer(ripeClasses.size()-1);

            //  first the code.
            ripeClassAliases.addElement(od.getCode());
            ripeClassAliasesMap.addElement(mapIndex);

            //  then the name.
            ripeClassAliases.addElement(od.getName());
            ripeClassAliasesMap.addElement(mapIndex);

          }
        }
      } // Defs()

      /**
       * Creates a Data Object Model from the RIPE classes defined
       * in the XML document.
       *
       * @author ottrey@ripe.net
       * @version $Version$
       *
       * @param xmlDocName The URI of the XML document.
       * @param ripeClass  The class to be created from.
       * @param normalize  Return a normalized DOM.
       *
       */
      private XmlDocument getDOM(String xmlDocName, String ripeClass, boolean normalize) {
    /* [<][>][^][v][top][bottom][index][help] */

        // Convert filename to an input source.
        InputSource inSrc= new InputSource();
        try {
          inSrc = Resolver.createInputSource(new File(xmlDocName));
        }
        catch (IOException e) {
          System.err.println("Failed to convert filename: " + xmlDocName +
                             "to an input source" + e);
          e.printStackTrace();  System.exit(-1);
        }

        // Create and validate a DOM.
        XmlDocument dom=null;
        try {
          dom = XmlDocument.createXmlDocument(inSrc, true);
        }
        catch (SAXException e) {
          System.err.println("Failed to create DOM & validate." + e);
          e.printStackTrace();  System.exit(-1);
        }
        catch (IOException e) {
          System.err.println("Failed to create DOM & validate." + e);
          e.printStackTrace();  System.exit(-1);
        }

        // Normalize the document.
        if (normalize) {
          dom.getDocumentElement().normalize();
        }

        return dom;

      } // getDOM()

      private boolean validate(String type, Node obj) {
    /* [<][>][^][v][top][bottom][index][help] */
        boolean result=false;
        String status = obj.getAttributes().getNamedItem("status").getNodeValue();
        String name   = obj.getAttributes().getNamedItem("name").getNodeValue();

        if (status.equals("valid")) {
          result=true;
        }
        else {
          System.err.println("Warning: " + type + " " + name + " is " + status);
        }

        return result;
      } // validClass()

      // -----------------oOo-----------------
      //              Print Methods
      // -----------------oOo-----------------
      private void printDF_attribute_aliases() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Attribute_aliases[] = {");
        Enumeration e = ripeAttributeAliases.elements();
        while (e.hasMoreElements()) {
          String a = (String)e.nextElement();
          System.out.println("  \"" + a + "\",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Attribute_aliases */");
      } // printDF_attribute_aliases()

      private void printDF_attribute_aliases_map() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("int const Attribute_aliases_map[] = {");
        Enumeration e = ripeAttributeAliasesMap.elements();
        while (e.hasMoreElements()) {
          Integer am = (Integer)e.nextElement();
          System.out.println("  " + am + ",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Attribute_aliases_map */");
      } // printDF_attribute_aliases_map()

      private void printDF_attribute_codes() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Attribute_codes[] = {");
        Enumeration e = ripeAttributeCodes.elements();
        while (e.hasMoreElements()) {
          String ac = (String)e.nextElement();
          AttributeDef ad = (AttributeDef)ripeAttributes.get(ac);

          // If the attribute has status="valid".
          if (ad.getStatus().equals("valid")) {
            // Output the attribute code.
            System.out.println("  \"" + ad.getCode() + "\",");
          }
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Attribute_codes */");
      } // printDF_attribute_codes()

      private void printDF_attribute_enum() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("typedef enum _A_Type_t {");

        // Enumerate through the attribute codes.
        Enumeration e = ripeAttributeCodes.elements();
        while (e.hasMoreElements()) {
          String ac = (String)e.nextElement();
          AttributeDef ad = (AttributeDef)ripeAttributes.get(ac);

          // If the attribute has status="valid".
          if (ad.getStatus().equals("valid")) {
            // Output the attribute enum.
            System.out.println("  " + ad.getEnum() + ",");
          }
        }

        System.out.println("  " + "A_END" + "\n" + "} A_Type_t;");
      } // printDF_attribute_enum()

      private void printDF_attribute_inv_attr_mask() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.print("#define INV_ATTR_MASK ");

        // Enumerate through the attribute codes.
        Enumeration e = ripeAttributeCodes.elements();
        while (e.hasMoreElements()) {
          String ac = (String)e.nextElement();
          AttributeDef ad = (AttributeDef)ripeAttributes.get(ac);

          // If the attribute has status="valid".
          if (ad.getStatus().equals("valid") && ad.getInverse()) {
            // Output the attribute enum.
            System.out.print(ad.getEnum() + ", ");
          }
        }

        System.out.println("MA_END");
      } // printDF_attribute_inv_attr_mask()

      private void printDF_attribute_names() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Attribute_names[] = {");
        Enumeration e = ripeAttributeCodes.elements();
        while (e.hasMoreElements()) {
          String ac = (String)e.nextElement();
          AttributeDef ad = (AttributeDef)ripeAttributes.get(ac);

          // If the attribute has status="valid".
          if (ad.getStatus().equals("valid")) {
            // Output the attribute name.
            System.out.println("  \"" + ad.getName() + "\",");
          }
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Attribute_names */");
      } // printDF_attribute_names()

      private void printDF_class_aliases() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Class_aliases[] = {");
        Enumeration e = ripeClassAliases.elements();
        while (e.hasMoreElements()) {
          String a = (String)e.nextElement();
          System.out.println("  \"" + a + "\",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Class_aliases */");
      } // printDF_class_aliases()

      private void printDF_class_aliases_map() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("int const Class_aliases_map[] = {");
        Enumeration e = ripeClassAliasesMap.elements();
        while (e.hasMoreElements()) {
          Integer am = (Integer)e.nextElement();
          System.out.println("  " + am + ",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Class_aliases_map */");
      } // printDF_class_aliases_map()

      private void printDF_class_codes() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Class_codes[] = {");
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          ClassDef od = (ClassDef)e.nextElement();
          System.out.println("  \"" + od.getCode() + "\",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Class_codes */");
      } // printDF_class_codes()

      private void printDF_class_dbase_code_map() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("int const Class_dbase_code_map[] = {");
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          ClassDef cd = (ClassDef)e.nextElement();
          System.out.println("  " + cd.getDbaseCode() + ",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Class_dbase_code_map */");
      } // printDF_class_dbase_code_map()

      private void printDF_class_enum() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("typedef enum _C_Type_t {");
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          ClassDef od = (ClassDef)e.nextElement();
          System.out.println("  " + od.getEnum() + ",");
        }
        System.out.println("  " + "C_END" + "\n" + "} C_Type_t;");
      } // printDF_class_enum()

      private void printDF_class_mask() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.print("#define CLASS_MASK ");
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          ClassDef cd = (ClassDef)e.nextElement();
          System.out.print(cd.getEnum() + ", ");
        }
        System.out.println("MA_END");
      } // printDF_class_mask()

      private void printDF_class_names() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Class_names[] = {");
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          String a = ((ClassDef)e.nextElement()).getName();
          System.out.println("  \"" + a + "\",");
        }
        System.out.println("  " + "NULL" + "\n" + "}; /* Class_names */");
      } // printDF_class_names()

      private void printQI_queries() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println(Query.startDoc());
        Enumeration e1 = ripeAttributes.elements();
        while (e1.hasMoreElements()) {
          AttributeDef ad = (AttributeDef)e1.nextElement();
          Enumeration e2 = ad.getQueries().elements();
          while (e2.hasMoreElements()) {
            Query q = (Query)e2.nextElement();
            System.out.println(q.getStruct("  "));
          }
        }
        System.out.println(Query.endDoc());
      } // printQI_queries()

      private void printUD_updates() {
    /* [<][>][^][v][top][bottom][index][help] */
        System.out.println("char * const Update[] = {");

        Enumeration e = ripeAttributeCodes.elements();
        while (e.hasMoreElements()) {
          String ac = (String)e.nextElement();
          AttributeDef ad = (AttributeDef)ripeAttributes.get(ac);
          System.out.println("  \"" + ad.getUpdate() + "\",");
        }

        System.out.println("  " + "NULL" + "\n" + "}; /* Update */");
      } // printUD_updates()

      private void printTemplates() {
    /* [<][>][^][v][top][bottom][index][help] */
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          ClassDef od = (ClassDef)e.nextElement();
          System.out.println(od.getName() + "\n");
          System.out.println(od.getTemplate() + "\n");
        }
      } // printTemplates()

      private void printTemplatesV() {
    /* [<][>][^][v][top][bottom][index][help] */
        Enumeration e = ripeClasses.elements();
        while (e.hasMoreElements()) {
          ClassDef od = (ClassDef)e.nextElement();
          System.out.println(od.getName() + "\n");
          System.out.println(od.getTemplateV() + "\n");
        }
      } // printTemplatesV()

      private void printDiagrams() {
    /* [<][>][^][v][top][bottom][index][help] */
        int maxWidth=0;  // Widest diagram
        Hashtable foreigns = new Hashtable();

        Enumeration e1 = ripeClasses.elements();
        while (e1.hasMoreElements()) {
          ClassDef od = (ClassDef)e1.nextElement();
          if (maxWidth < od.getWidth()) {
            maxWidth = od.getWidth();
          }

          Hashtable foriegnAttrs = od.getForeignAttrs();
          if (foriegnAttrs != null) {
            Enumeration e2 = foriegnAttrs.keys();
            while (e2.hasMoreElements()) {
              String key = (String)e2.nextElement();
              if (!foreigns.containsKey(key)) {
                foreigns.put(key, foriegnAttrs.get(key));
              }
            }
          }
        }

        System.out.print("Classes:");
        for (int i=0; i < maxWidth; i++) {
          System.out.print(" ");
        }
        System.out.println("Foreign keys:");

        Enumeration e3 = ripeClasses.elements();
        while (e3.hasMoreElements()) {
          ClassDef od = (ClassDef)e3.nextElement();
          System.out.print(od.getDiagram(maxWidth, foreigns));
        }
      } // printDiagrams()

      // -----------------oOo-----------------
      //            Unit test driver
      // -----------------oOo-----------------
      public static void main (String argv[]) {
    /* [<][>][^][v][top][bottom][index][help] */
        int n=0;
        boolean err=true;
        boolean normalize=false;

        if (argv.length > 0) {
          try {
            n = Integer.parseInt(argv[0]);
            err=false;
          }
          catch (NumberFormatException e) {
          }
          if (argv.length == 2) {
            if (argv[1].equals("normalize")) {
              normalize = true;
            }
          }
        }

        if (!err) {
          Defs rc = new Defs(normalize);

          switch (n) {
            case  1: rc.printDF_attribute_aliases();          break;
            case  2: rc.printDF_attribute_aliases_map();      break;
            case  3: rc.printDF_attribute_codes();            break;
            case  4: rc.printDF_attribute_enum();             break;
            case  5: rc.printDF_attribute_inv_attr_mask();    break;
            case  6: rc.printDF_attribute_names();            break;
            case  7: rc.printDF_class_aliases();              break;
            case  8: rc.printDF_class_aliases_map();          break;
            case  9: rc.printDF_class_codes();                break;
            case 10: rc.printDF_class_dbase_code_map();       break;
            case 11: rc.printDF_class_enum();                 break;
            case 12: rc.printDF_class_mask();                 break;
            case 13: rc.printDF_class_names();                break;
            case 14: rc.printQI_queries();                    break;
            case 15: rc.printUD_updates();                    break;
            case 16: rc.printTemplates();                     break;
            case 17: rc.printTemplatesV();                    break;
            case 18: rc.printDiagrams();                      break;
            default:
              err=true;
          }
        }

        if (err) {
          System.err.println("Usage: makedefs n (Where n = a number 1..18)");
        }

      } // main()
      // -----------------oOo-----------------

    } // Defs

/* [<][>][^][v][top][bottom][index][help] */