defs/ClassDef.java
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- ClassDef
- getNodeValue
- createAttributes
- createForeignAttrs
- toCString
- getName
- getCode
- getStatus
- getDescription
- getDbaseCode
- getWidth
- getAttributes
- getForeignAttrs
- getEnum
- getTemplate
- getTemplateV
- getDiagram
- toString
- ClassDiagram
- toString
import java.util.*;
import org.w3c.dom.*;
import com.sun.xml.tree.*;
/**
* RIPE class.
*
* @author ottrey@ripe.net
* @version $Version$
*
*/
public class ClassDef {
/* [<][>][^][v][top][bottom][index][help] */
public static final int EXTRA_BIT=11;
private String name;
private String code;
private String status;
private String description;
private Vector attributes;
private int dbaseCode;
private int width; // The longest attribute name.
private Hashtable foreignAttrs;
// -----------------oOo-----------------
// Constructors
// -----------------oOo-----------------
/**
* Creates a RIPE class.
*
* @author ottrey@ripe.net
* @version $Version$
*
* @param obj The node from which a RIPE class is made.
*
* NOTE: No-one has implemented a Node.getNodeValue() method yet. ;-(
* description = tw.getNextElement("description").getNodeValue();
* So I wrote a crappy one here.
* @see getNodeValue
*/
public ClassDef(Node obj, Hashtable ripeAttributes) {
width = 0;
name = obj.getAttributes().getNamedItem("name").getNodeValue();
code = obj.getAttributes().getNamedItem("code").getNodeValue();
status = obj.getAttributes().getNamedItem("status").getNodeValue();
// Prepare to walk the tree.
TreeWalker tw = new TreeWalker(obj);
// Extract the "description".
description = getNodeValue(tw.getNextElement("description"));
// Create the attributes.
attributes = createAttributes(tw.getNextElement("attributes"), ripeAttributes);
// Get the dbase_code.
dbaseCode = -1;
Node dcn = tw.getNextElement("dbase_code");
if (dcn != null) {
String dbaseCodeStr = dcn.getAttributes().getNamedItem("value").getNodeValue();
try {
dbaseCode = Integer.parseInt(dbaseCodeStr);
}
catch (NumberFormatException e) {
System.err.println("Bad dbaseCode: " + dbaseCodeStr);
System.err.println("\tencounterd in Object: " + obj);
System.exit(-1);
}
}
// Create the foreignAttrs.
foreignAttrs = createForeignAttrs();
} // ClassDef()
/**
* Aaaargh I shouldn't have to write this. :-(
*
* @param node
* @return The value of the node.
* @see ClassDef
*
*/
private String getNodeValue(Node node) {
/* [<][>][^][v][top][bottom][index][help] */
String nodeStr = node.toString();
int startIndex = nodeStr.indexOf('>') + 1;
int endIndex = nodeStr.lastIndexOf('<') - 1;
return nodeStr.substring(startIndex, endIndex);
} // getNodeValue()
/**
* Create the attributes for this class from the attributes already created.
*
* @param attrs The head node of the attributes tree from the classes DOM.
* @param ripeAttributes The attributes created from the attributes DOM.
* @return (methods only)
*
*/
private Vector createAttributes(Node attrs, Hashtable ripeAttributes) {
/* [<][>][^][v][top][bottom][index][help] */
// Create a set of attributes for this class.
Vector result = new Vector();
Node attrNode;
AttributeDef adTmp;
String attrCode=null;
String status;
// Prepare to walk the tree.
TreeWalker tw = new TreeWalker(attrs);
try {
// Get the attribute node from the tree.
while ((attrNode = tw.getNext()) != null) {
// Get the attribute code from the node.
attrCode = new String(attrNode.getNodeName());
// Get the attribute from the ripeAttributes.
adTmp = (AttributeDef)ripeAttributes.get(attrCode);
// Keep track of the longest attribute name.
if ( adTmp.getName().length() > width ) {
width = adTmp.getName().length();
}
// If the attribute is "valid"
if ((status=adTmp.getStatus()).equals("valid")) {
// Create a clone of the attribute.
AttributeDef ad = null;
try {
ad = (AttributeDef)adTmp.clone();
}
catch (CloneNotSupportedException e) {
System.err.println("Doh!");
}
// Set the min attribute.
ad.setChoice(attrNode.getAttributes().getNamedItem("choice").getNodeValue());
// Set the max attribute.
ad.setNumber(attrNode.getAttributes().getNamedItem("number").getNodeValue());
// Add the attribute to this class.
result.addElement(ad);
}
else {
System.err.println("Warning: Class " + name + " contains a " +
status + " attribute: " + attrCode);
}
}
}
catch (NullPointerException e) {
// We tried to do something with a null - No worries, we caught it!
System.err.println("Trouble creating attributes: " + e);
System.err.println("attrCode=" + attrCode);
System.err.println("attrs=" + attrs);
}
return result;
} // createAttributes()
private Hashtable createForeignAttrs() {
/* [<][>][^][v][top][bottom][index][help] */
// Create a set of foreign attributes for this class.
Hashtable result = new Hashtable();
Enumeration e = attributes.elements();
while (e.hasMoreElements()) {
AttributeDef ad = (AttributeDef)e.nextElement();
String code = ad.getCode();
String foreign = ad.getForeign();
if (foreign.length() > 1 ) {
result.put(code, foreign);
}
}
return result;
} // createAttributes()
private String toCString(String str) {
/* [<][>][^][v][top][bottom][index][help] */
String result = new String();
char c;
result += "\"";
for(int i=0; i < str.length(); i++) {
c = str.charAt(i);
switch (c) {
case '\n':
result += "\\n\"\n\"";
break;
case '"':
result += "\\\"";
break;
case '&':
if(str.regionMatches(true, i, "<", 0, 4)) {
result += "<";
i += 3;
} else if(str.regionMatches(true, i, ">", 0, 4)) {
result += ">";
i += 3;
}
else {
result += c;
}
break;
default:
result += c;
}
}
result += "\"";
return result;
} // toCString
public String getName() {
/* [<][>][^][v][top][bottom][index][help] */
return name;
} // getCode()
public String getCode() {
/* [<][>][^][v][top][bottom][index][help] */
return code;
} // getCode()
public String getStatus() {
/* [<][>][^][v][top][bottom][index][help] */
return status;
} // getStatus()
public String getDescription(boolean CStyle) {
/* [<][>][^][v][top][bottom][index][help] */
String result = description;
if (CStyle) {
result = toCString(description);
}
return result;
} // getDescription()
public int getDbaseCode() {
/* [<][>][^][v][top][bottom][index][help] */
return dbaseCode;
} // getDbaseCode()
public int getWidth() {
/* [<][>][^][v][top][bottom][index][help] */
return width + EXTRA_BIT;
} // getWidth()
public Vector getAttributes() {
/* [<][>][^][v][top][bottom][index][help] */
return attributes;
} // getAttributes()
public Hashtable getForeignAttrs() {
/* [<][>][^][v][top][bottom][index][help] */
return foreignAttrs;
} // getForeignAttrs()
public String getEnum() {
/* [<][>][^][v][top][bottom][index][help] */
return new String("C_" + code).toUpperCase();
} // getEnum()
/**
* Returns a template for the class in the form:
*
* boolean CStyle Returns in C style eg, with "\n\" at the end of each line.
*
* person: [mandatory] [single] [primary/look-up key]
* address: [mandatory] [multiple] [ ]
* phone: [mandatory] [multiple] [ ]
* fax-no: [optional] [multiple] [ ]
* e-mail: [optional] [multiple] [look-up key]
* nic-hdl: [mandatory] [single] [primary/look-up key]
* remarks: [optional] [multiple] [ ]
* notify: [optional] [multiple] [inverse key]
* mnt-by: [optional] [multiple] [inverse key]
* changed: [mandatory] [multiple] [ ]
* source: [mandatory] [single] [ ]
*
* @return String the template.
*/
public String getTemplate(boolean CStyle) {
/* [<][>][^][v][top][bottom][index][help] */
String result = new String();
String pad1 = " "; /* XXX It is a crappy! assumption of the longest attribute name. */
String pad2 = " ";
String pad3 = " ";
String sofl = new String();
String eofl = new String();
if(CStyle) {
sofl = "\"";
eofl = "\\n\"\n";
}
else {
sofl = "";
eofl = "\n";
}
AttributeDef ad;
String name, choice, number, keytype;
Enumeration e = attributes.elements();
while (e.hasMoreElements()) {
ad = (AttributeDef)e.nextElement();
name = ad.getName();
choice = ad.getChoice();
number = ad.getNumber();
keytype = ad.getKeytype2();
result += (sofl + name + ":" +
pad1.substring(0, pad1.length()-name.length()) +
"[" + choice + "]" +
pad2.substring(0, pad2.length()-choice.length()) +
"[" + number + "]" +
pad3.substring(0, pad3.length()-number.length()) +
"[" + keytype + "]" +
eofl
);
}
return result;
} // getTemplate()
public String getTemplateV(boolean CStyle) {
/* [<][>][^][v][top][bottom][index][help] */
String result=new String();
String templ = getTemplate(CStyle);
String sofl = new String();
String eofl = new String();
if(CStyle) {
sofl = "\"";
eofl = "\\n\"\n";
}
else {
sofl = "";
eofl = "\n";
}
result += (sofl + "The " + name + " class:" + eofl +
toCString(description) +
sofl + eofl +
templ +
sofl + eofl +
sofl + "The content of the attributes of the " +
name + " class are defined below:" + eofl +
sofl + eofl
);
AttributeDef ad;
String name, description, format;
Enumeration e = attributes.elements();
while (e.hasMoreElements()) {
ad = (AttributeDef)e.nextElement();
name = ad.getName();
if (CStyle) {
description = toCString(ad.getDescription());
format = toCString(ad.getFormat());
}
else {
description = ad.getDescription();
format = ad.getFormat();
}
result += (sofl + name + eofl +
description +
format +
sofl + eofl
);
}
result += (sofl + eofl +
sofl + "Further information may be found at:" + eofl +
sofl + eofl +
sofl + "http://www.ripe.net/docs/ripe-157.html" + eofl +
sofl + "ftp://ftp.ripe.net/ripe/docs/ripe-157.ps" + eofl +
sofl + "ftp://ftp.ripe.net/ripe/docs/ripe-157.txt" + eofl +
sofl + eofl
);
return result;
} // getTemplateV()
public String getDiagram(int maxWidth, Hashtable foreigns) {
/* [<][>][^][v][top][bottom][index][help] */
ClassDiagram om = new ClassDiagram(this, maxWidth, foreigns);
return om.toString();
} // getDiagram()
/*
public boolean equals(ClassDef ro) {
return code.equals(ro.getCode());
} // equals()
*/
public String toString() {
/* [<][>][^][v][top][bottom][index][help] */
return new String("ripe class={" +
"\n\tname=" + name +
"\n\tcode=" + code +
"\n\tstatus=" + status +
"\n\tdescription=" + description +
"\n\tattributes=" + attributes +
"\n\tdbaseCode=" + dbaseCode +
"\n\twidth=" + width +
"\n\tforeignAttrs=" + foreignAttrs +
"\n}");
} // toString()
/**
* RIPE class diagram.
*
* @author ottrey@ripe.net
* @version $Version$
*
*/
public class ClassDiagram {
/* [<][>][^][v][top][bottom][index][help] */
private Vector diagram;
// -----------------oOo-----------------
// Constructors
// -----------------oOo-----------------
/**
* Creates a RIPE class diagram.
*
* @author ottrey@ripe.net
* @version $Version$
*
* @param od Definition to make diagram from.
*/
public ClassDiagram(ClassDef od, int maxWidth, Hashtable foreigns) {
diagram = new Vector();
String line = new String();
String border = new String();
border = "+-";
for (int i=0; i < getWidth(); i++) {
border += ("-");
}
border += "-+ ";
for (int i=od.getWidth(); i < maxWidth; i++) {
border += (" ");
}
Enumeration e1 = foreigns.keys();
while (e1.hasMoreElements()) {
String foreign = (String)e1.nextElement();
if (e1.hasMoreElements()) {
border += ("|--");
}
}
border += ("|\n");
diagram.addElement(border);
line = ("| " + od.getCode() + ": " + od.getName());
for (int i=od.getName().length()+4; i < getWidth(); i++) {
line += (" ");
}
line += (" | ");
for (int i=od.getWidth(); i < maxWidth; i++) {
line += (" ");
}
Enumeration e3 = foreigns.keys();
while (e3.hasMoreElements()) {
String foreign = (String)e3.nextElement();
line += (foreign + " ");
}
line += ("\n");
diagram.addElement(line);
diagram.addElement(border);
AttributeDef ad;
Enumeration e = od.getAttributes().elements();
while (e.hasMoreElements()) {
ad = (AttributeDef)e.nextElement();
String name = ad.getName();
String keytype = ad.getKeytype3();
line = ("| " + ad.getCode() + ": " + name + " ");
for (int i=name.length(); i < width; i++) {
line += (" ");
}
line += (keytype + " |");
// The horizontal line.
// Is a foreign key.
boolean f = (ad.getForeign().length() > 1);
// Is a referenced key.
boolean p = (foreigns.contains(ad.getCode()));
if (f) {
line += ("->-");
}
else if (p) {
line += ("-|-");
} else {
line += (" ");
}
for (int i=od.getWidth(); i < maxWidth; i++) {
if (f || p) {
line += ("-");
}
else {
line += (" ");
}
}
// Add the xrefs.
Enumeration e2 = foreigns.keys();
while (e2.hasMoreElements()) {
String foreign = (String)e2.nextElement();
String code = ad.getCode();
if (foreign.equals(code)) {
line += ("X");
}
else if (foreigns.get(foreign).equals(code)) {
line += ("o");
}
else {
line += ("|");
}
if (e2.hasMoreElements()) {
line += ("--");
}
}
line += ("\n");
diagram.addElement(line);
}
diagram.addElement(border);
} // ClassDiagram()
public String toString() {
/* [<][>][^][v][top][bottom][index][help] */
String result = new String();
Enumeration e = diagram.elements();
while (e.hasMoreElements()) {
String line = (String)e.nextElement();
result += line;
}
return result;
} // toString()
} // ClassDiagram
} // ClassDef