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

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