defs/ClassDef.java
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- ClassDef
- getNodeRawValue
- createAttributes
- createForeignAttrs
- toCString
- getName
- getCode
- getStatus
- getDescription
- getDbaseCode
- getWidth
- getAttributes
- getForeignAttrs
- getEnum
- getTemplate
- getTemplateV
- getDiagram
- toString
- ClassDiagram
- 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, "<", 0, 4)) {
199 result += "<";
200 i += 3;
201 } else if(str.regionMatches(true, i, ">", 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