## defs/ClassDef.java

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

## FUNCTIONS

This source file includes following functions.

1. ClassDef
2. getNodeRawValue
3. createAttributes
4. createForeignAttrs
5. toCString
6. getName
7. getCode
8. getStatus
9. getDescription
10. getDbaseCode
11. getWidth
12. getAttributes
13. getForeignAttrs
14. getEnum
15. getTemplate
16. getTemplateV
17. getDiagram
18. toString
19. ClassDiagram
20. toString

       1 import java.util.*;
       2 import org.w3c.dom.*;
       3 import com.sun.xml.tree.*;
       4
       5 /**
       6  * RIPE class.
       7  *
       8  * @author ottrey@ripe.net
       9  * @version $Version$
      10  *
      11  */
      12 public class ClassDef {
         /* [<][>][^][v][top][bottom][index][help] */
      13
      14   public static final int EXTRA_BIT=11;
      15
      16   private String    name;
      17   private String    enum;
      18   private String    code;
      19   private String    status;
      20   private String    description;
      21   private Vector    attributes;
      22   private int       dbaseCode;
      23
      24   private int       width;        // The longest attribute name.
      25   private Hashtable foreignAttrs;
      26
      27   // -----------------oOo-----------------
      28   //              Constructors
      29   // -----------------oOo-----------------
      30   /**
      31    * Creates a RIPE class.
      32    *
      33    * @author ottrey@ripe.net
      34    * @version $Version$
      35    *
      36    * @param obj The node from which a RIPE class is made.
      37    *
      38    * NOTE: No-one has implemented a Node.getNodeValue() method yet.  ;-(
      39    *       description = tw.getNextElement("description").getNodeValue();
      40    *       So I wrote a crappy one here.
      41    * @see getNodeValue
      42    */
      43   public ClassDef(Node obj, Hashtable ripeAttributes) {
      44     width = 0;
      45     name      = obj.getAttributes().getNamedItem("name").getNodeValue();
      46     code      = obj.getAttributes().getNamedItem("code").getNodeValue();
      47     status    = obj.getAttributes().getNamedItem("status").getNodeValue();
      48     enum      = new String("C_" + code).toUpperCase();
      49     // Prepare to walk the tree.
      50     TreeWalker tw = new TreeWalker(obj);
      51
      52     // Extract the "description".
      53     description = getNodeRawValue(tw.getNextElement("description"));
      54
      55     // Create the attributes.
      56     attributes = createAttributes(tw.getNextElement("attributes"), ripeAttributes);
      57
      58     // Get the dbase_code.
      59     dbaseCode = -1;
      60     Node dcn = tw.getNextElement("dbase_code");
      61     if (dcn != null) {
      62       String dbaseCodeStr = dcn.getAttributes().getNamedItem("value").getNodeValue();
      63       try {
      64         dbaseCode = Integer.parseInt(dbaseCodeStr);
      65       }
      66       catch (NumberFormatException e) {
      67         System.err.println("Bad dbaseCode: " + dbaseCodeStr);
      68         System.err.println("\tencounterd in Object: " + obj);
      69         System.exit(-1);
      70       }
      71     }
      72
      73     // Create the foreignAttrs.
      74     foreignAttrs = createForeignAttrs();
      75
      76   } // ClassDef()
      77
      78
      79   /**
      80    * Aaaargh I shouldn't have to write this. :-(
      81    *
      82    * @param        node
      83    * @return       The value of the node.
      84    * @see          ClassDef
      85    *
      86    */
      87   private String getNodeRawValue(Node node) {
         /* [<][>][^][v][top][bottom][index][help] */
      88     String nodeStr = node.toString();
      89     int startIndex = nodeStr.indexOf('>') + 1;
      90     int endIndex = nodeStr.lastIndexOf('<') - 1;
      91
      92     return nodeStr.substring(startIndex, endIndex);
      93   } // getNodeRawValue()
      94
      95   /**
      96    * Create the attributes for this class from the attributes already created.
      97    *
      98    * @param  attrs          The head node of the attributes tree from the classes DOM.
      99    * @param  ripeAttributes The attributes created from the attributes DOM.
     100    * @return       (methods only)
     101    *
     102    */
     103   private Vector createAttributes(Node attrs, Hashtable ripeAttributes) {
         /* [<][>][^][v][top][bottom][index][help] */
     104     // Create a set of attributes for this class.
     105     Vector result = new Vector();
     106
     107     Node attrNode;
     108     AttributeDef adTmp;
     109     String attrCode=null;
     110     String status;
     111
     112     // Prepare to walk the tree.
     113     TreeWalker tw = new TreeWalker(attrs);
     114     try {
     115       // Get the attribute node from the tree.
     116       while ((attrNode = tw.getNext()) != null) {
     117         // Get the attribute code from the node.
     118         attrCode = new String(attrNode.getNodeName());
     119
     120         // Get the attribute from the ripeAttributes.
     121         adTmp = (AttributeDef)ripeAttributes.get(attrCode);
     122
     123         // Keep track of the longest attribute name.
     124         if ( adTmp.getName().length() > width ) {
     125           width = adTmp.getName().length();
     126         }
     127
     128         // If the attribute is "valid"
     129         if ((status=adTmp.getStatus()).equals("valid")) {
     130
     131           // Create a clone of the attribute.
     132           AttributeDef ad = null;
     133           try {
     134             ad = (AttributeDef)adTmp.clone();
     135           }
     136           catch (CloneNotSupportedException e) {
     137             System.err.println("Doh!");
     138           }
     139
     140           // Set the min attribute.
     141           ad.setChoice(attrNode.getAttributes().getNamedItem("choice").getNodeValue());
     142
     143           // Set the max attribute.
     144           ad.setNumber(attrNode.getAttributes().getNamedItem("number").getNodeValue());
     145
     146           // Add the attribute to this class.
     147           result.addElement(ad);
     148         }
     149         else {
     150           System.err.println("Warning: Class " + name + " contains a " +
     151                              status + " attribute: " + attrCode);
     152         }
     153       }
     154     }
     155     catch (NullPointerException e) {
     156       // We tried to do something with a null - No worries, we caught it!
     157       System.err.println("Trouble creating attributes: " + e);
     158       System.err.println("attrCode=" + attrCode);
     159       System.err.println("attrs=" + attrs);
     160     }
     161
     162     return result;
     163   } // createAttributes()
     164
     165   private Hashtable createForeignAttrs() {
         /* [<][>][^][v][top][bottom][index][help] */
     166     // Create a set of foreign attributes for this class.
     167     Hashtable result = new Hashtable();
     168
     169     Enumeration e = attributes.elements();
     170     while (e.hasMoreElements()) {
     171       AttributeDef ad = (AttributeDef)e.nextElement();
     172       String code = ad.getCode();
     173       String foreign = ad.getForeign();
     174       if (foreign.length() > 1 ) {
     175         result.put(code, foreign);
     176       }
     177     }
     178     return result;
     179   } // createAttributes()
     180
     181   private String toCString(String str) {
         /* [<][>][^][v][top][bottom][index][help] */
     182     String result = new String();
     183     char c;
     184
     185     result += "\"";
     186     for(int i=0; i < str.length(); i++) {
     187       c = str.charAt(i);
     188       switch (c) {
     189         case '\n':
     190           result += "\\n\"\n\"";
     191         break;
     192
     193         case '"':
     194           result += "\\\"";
     195         break;
     196
     197         case '&':
     198           if(str.regionMatches(true, i, "&lt;", 0, 4)) {
     199             result += "<";
     200             i += 3;
     201           } else if(str.regionMatches(true, i, "&gt;", 0, 4)) {
     202             result += ">";
     203             i += 3;
     204           }
     205           else {
     206             result += c;
     207           }
     208         break;
     209
     210         default:
     211           result += c;
     212       }
     213     }
     214     result += "\"";
     215
     216     return result;
     217   } // toCString
     218
     219   public String getName() {
         /* [<][>][^][v][top][bottom][index][help] */
     220     return name;
     221   } // getCode()
     222
     223   public String getCode() {
         /* [<][>][^][v][top][bottom][index][help] */
     224     return code;
     225   } // getCode()
     226
     227   public String getStatus() {
         /* [<][>][^][v][top][bottom][index][help] */
     228     return status;
     229   } // getStatus()
     230
     231   public String getDescription(boolean CStyle) {
         /* [<][>][^][v][top][bottom][index][help] */
     232     String result = description;
     233
     234     if (CStyle) {
     235       result = toCString(description);
     236     }
     237
     238     return result;
     239   } // getDescription()
     240
     241   public int getDbaseCode() {
         /* [<][>][^][v][top][bottom][index][help] */
     242     return dbaseCode;
     243   } // getDbaseCode()
     244
     245   public int getWidth() {
         /* [<][>][^][v][top][bottom][index][help] */
     246     return width + EXTRA_BIT;
     247   } // getWidth()
     248
     249   public Vector getAttributes() {
         /* [<][>][^][v][top][bottom][index][help] */
     250     return attributes;
     251   } // getAttributes()
     252
     253   public Hashtable getForeignAttrs() {
         /* [<][>][^][v][top][bottom][index][help] */
     254     return foreignAttrs;
     255   } // getForeignAttrs()
     256
     257   public String getEnum() {
         /* [<][>][^][v][top][bottom][index][help] */
     258     return enum;
     259   } // getEnum()
     260
     261  /**
     262   * Returns a template for the class in the form:
     263   *
     264   * boolean CStyle Returns in C style eg, with "\n\" at the end of each line.
     265   *
     266   * person:      [mandatory]  [single]     [primary/look-up key]
     267   * address:     [mandatory]  [multiple]   [ ]
     268   * phone:       [mandatory]  [multiple]   [ ]
     269   * fax-no:      [optional]   [multiple]   [ ]
     270   * e-mail:      [optional]   [multiple]   [look-up key]
     271   * nic-hdl:     [mandatory]  [single]     [primary/look-up key]
     272   * remarks:     [optional]   [multiple]   [ ]
     273   * notify:      [optional]   [multiple]   [inverse key]
     274   * mnt-by:      [optional]   [multiple]   [inverse key]
     275   * changed:     [mandatory]  [multiple]   [ ]
     276   * source:      [mandatory]  [single]     [ ]
     277   *
     278   * @return String the template.
     279   */
     280   public String getTemplate(boolean CStyle) {
         /* [<][>][^][v][top][bottom][index][help] */
     281     String result = new String();
     282
     283     String pad1 = "              "; /* XXX It is a crappy! assumption of the longest attribute name. */
     284     String pad2 = "           ";
     285     String pad3 = "           ";
     286
     287     String sofl = new String();
     288     String eofl = new String();
     289     if(CStyle) {
     290       sofl = "\"";
     291       eofl = "\\n\"\n";
     292     }
     293     else {
     294       sofl = "";
     295       eofl = "\n";
     296     }
     297
     298     AttributeDef ad;
     299     String name, choice, number, keytype;
     300     Enumeration e = attributes.elements();
     301     while (e.hasMoreElements()) {
     302       ad = (AttributeDef)e.nextElement();
     303       name = ad.getName();
     304       choice = ad.getChoice();
     305       number = ad.getNumber();
     306       keytype = ad.getKeytype2();
     307       result += (sofl + name + ":"                                 +
     308                  pad1.substring(0, pad1.length()-name.length())    +
     309                  "[" + choice + "]"                                +
     310                  pad2.substring(0, pad2.length()-choice.length())  +
     311                  "[" + number + "]"                                +
     312                  pad3.substring(0, pad3.length()-number.length())  +
     313                  "[" + keytype + "]"                               +
     314                  eofl
     315                 );
     316     }
     317
     318     return result;
     319   } // getTemplate()
     320
     321   public String getTemplateV(boolean CStyle) {
         /* [<][>][^][v][top][bottom][index][help] */
     322     String result=new String();
     323     String templ = getTemplate(CStyle);
     324
     325     String sofl = new String();
     326     String eofl = new String();
     327     if(CStyle) {
     328       sofl = "\"";
     329       eofl = "\\n\"\n";
     330     }
     331     else {
     332       sofl = "";
     333       eofl = "\n";
     334     }
     335
     336     result += (sofl + "The " + name + " class:" + eofl          +
     337                toCString(description)                           +
     338                sofl + eofl                                      +
     339                templ                                            +
     340                sofl + eofl                                      +
     341                sofl + "The content of the attributes of the "   +
     342                name + " class are defined below:" + eofl        +
     343                sofl + eofl
     344               );
     345
     346     AttributeDef ad;
     347     String name, description, format;
     348     Enumeration e = attributes.elements();
     349     while (e.hasMoreElements()) {
     350       ad = (AttributeDef)e.nextElement();
     351       name = ad.getName();
     352       if (CStyle) {
     353         description = toCString(ad.getDescription());
     354         format = toCString(ad.getFormat());
     355       }
     356       else {
     357         description = ad.getDescription();
     358         format = ad.getFormat();
     359       }
     360
     361       result += (sofl + name + eofl +
     362                  description        +
     363                  format             +
     364                  sofl + eofl
     365                 );
     366     }
     367
     368     result += (sofl + eofl                                               +
     369                sofl + "Further information may be found at:" + eofl      +
     370                sofl + eofl                                               +
     371                sofl + "http://www.ripe.net/docs/ripe-157.html" + eofl    +
     372                sofl + "ftp://ftp.ripe.net/ripe/docs/ripe-157.ps" + eofl  +
     373                sofl + "ftp://ftp.ripe.net/ripe/docs/ripe-157.txt" + eofl +
     374                sofl + eofl
     375               );
     376
     377     return result;
     378   } // getTemplateV()
     379
     380   public String getDiagram(int maxWidth, Hashtable foreigns) {
         /* [<][>][^][v][top][bottom][index][help] */
     381     ClassDiagram om = new ClassDiagram(this, maxWidth, foreigns);
     382
     383     return om.toString();
     384   } // getDiagram()
     385
     386   /*
     387   public boolean equals(ClassDef ro) {
     388     return code.equals(ro.getCode());
     389   } // equals()
     390   */
     391
     392   public String toString() {
         /* [<][>][^][v][top][bottom][index][help] */
     393     return new String("ripe class={" +
     394                          "\n\tname="         + name          +
     395                          "\n\tcode="         + code          +
     396                          "\n\tstatus="       + status        +
     397                          "\n\tdescription="  + description   +
     398                          "\n\tattributes="   + attributes    +
     399                          "\n\tdbaseCode="    + dbaseCode     +
     400                          "\n\twidth="        + width         +
     401                          "\n\tforeignAttrs=" + foreignAttrs  +
     402                          "\n}");
     403   } // toString()
     404
     405   /**
     406    * RIPE class diagram.
     407    *
     408    * @author ottrey@ripe.net
     409    * @version $Version$
     410    *
     411    */
     412   public class ClassDiagram {
         /* [<][>][^][v][top][bottom][index][help] */
     413     private Vector    diagram;
     414
     415     // -----------------oOo-----------------
     416     //              Constructors
     417     // -----------------oOo-----------------
     418     /**
     419      * Creates a RIPE class diagram.
     420      *
     421      * @author ottrey@ripe.net
     422      * @version $Version$
     423      *
     424      * @param od Definition to make diagram from.
     425      */
     426     public ClassDiagram(ClassDef od, int maxWidth, Hashtable foreigns) {
     427       diagram = new Vector();
     428       String line = new String();
     429
     430       String border = new String();
     431       border = "+-";
     432       for (int i=0; i < getWidth(); i++) {
     433         border += ("-");
     434       }
     435       border += "-+   ";
     436       for (int i=od.getWidth(); i < maxWidth; i++) {
     437         border += (" ");
     438       }
     439       Enumeration e1 = foreigns.keys();
     440       while (e1.hasMoreElements()) {
     441         String foreign = (String)e1.nextElement();
     442         if (e1.hasMoreElements()) {
     443           border += ("|--");
     444         }
     445       }
     446       border += ("|\n");
     447       diagram.addElement(border);
     448
     449       line = ("| " + od.getCode() + ": " + od.getName());
     450       for (int i=od.getName().length()+4; i < getWidth(); i++) {
     451         line += (" ");
     452       }
     453       line += (" |   ");
     454       for (int i=od.getWidth(); i < maxWidth; i++) {
     455         line += (" ");
     456       }
     457       Enumeration e3 = foreigns.keys();
     458       while (e3.hasMoreElements()) {
     459         String foreign = (String)e3.nextElement();
     460         line += (foreign + " ");
     461       }
     462       line += ("\n");
     463       diagram.addElement(line);
     464
     465       diagram.addElement(border);
     466
     467       AttributeDef ad;
     468       Enumeration e = od.getAttributes().elements();
     469       while (e.hasMoreElements()) {
     470         ad = (AttributeDef)e.nextElement();
     471         String name = ad.getName();
     472         String keytype = ad.getKeytype3();
     473         line = ("| " + ad.getCode() + ": " + name + " ");
     474         for (int i=name.length(); i < width; i++) {
     475           line += (" ");
     476         }
     477         line += (keytype + " |");
     478
     479         // The horizontal line.
     480         // Is a foreign key.
     481         boolean f = (ad.getForeign().length() > 1);
     482         // Is a referenced key.
     483         boolean p = (foreigns.contains(ad.getCode()));
     484         if (f) {
     485           line += ("->-");
     486         }
     487         else if (p) {
     488           line += ("-|-");
     489         } else {
     490           line += ("   ");
     491         }
     492         for (int i=od.getWidth(); i < maxWidth; i++) {
     493           if (f || p) {
     494             line += ("-");
     495           }
     496           else {
     497             line += (" ");
     498           }
     499         }
     500
     501         // Add the xrefs.
     502         Enumeration e2 = foreigns.keys();
     503         while (e2.hasMoreElements()) {
     504           String foreign = (String)e2.nextElement();
     505           String code = ad.getCode();
     506           if (foreign.equals(code)) {
     507             line += ("X");
     508           }
     509           else if (foreigns.get(foreign).equals(code)) {
     510             line += ("o");
     511           }
     512           else {
     513             line += ("|");
     514           }
     515           if (e2.hasMoreElements()) {
     516             line += ("--");
     517           }
     518         }
     519         line += ("\n");
     520         diagram.addElement(line);
     521       }
     522
     523       diagram.addElement(border);
     524     } // ClassDiagram()
     525
     526     public String toString() {
         /* [<][>][^][v][top][bottom][index][help] */
     527       String result = new String();
     528
     529       Enumeration e = diagram.elements();
     530       while (e.hasMoreElements()) {
     531         String line = (String)e.nextElement();
     532         result += line;
     533       }
     534
     535       return result;
     536     } // toString()
     537
     538   } // ClassDiagram
     539
     540 } // ClassDef

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