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] */