001: /*
002: * CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
003: * NETSCAPE COMMUNICATIONS CORPORATION
004: *
005: * Copyright (c) 1996 Netscape Communications Corporation.
006: * All Rights Reserved.
007: * Use of this Source Code is subject to the terms of the applicable
008: * license agreement from Netscape Communications Corporation.
009: */
010:
011: package soif;
012:
013: import util.BinaryTree;
014: import util.BTreeNode;
015: import util.ReportError;
016:
017: import java.util.Date;
018:
019: /**
020: Schema is used to manage schema meta data.
021: Uses a tree w/ next pointing to subsequent peers and child
022: pointing to subtrees. Assumes the schema described is
023: heirarchical.
024: <p>
025: The schema is represented as a binary tree,
026: the nodes of which carry either a table (SchemaTblNode)
027: or a column (SchemaColNode).
028: The table nodes are invented on the fly as a convenience,
029: the SOIF representation revolves
030: around columns.
031: Data associated with different columns is
032: represented by multi-value SOIF,
033: the data associated with a column is
034: grouped on by the multi-value.
035: The schema eliminates the multi-value
036: during construction,
037: grouping on the SchemaColNode class.
038: When the toSOIF() method is used,
039: the numbering is created by that method
040: as it traverses the nodes.
041: Removing the multi-value makes the
042: nodes easier to work with in a general way.
043: Also, if the schema is edited, adding or
044: deleting columns, the tree doesn't have
045: to be traversed for unused multi-values.
046: <p>
047: Interestingly, the actual schema is not a tree,
048: but rather a graph with no duplicate tables.
049: A table can have multiple parents,
050: all tables up the graph from it qualify as parents.
051: The schema is constructed and managed with the
052: expectation that at any given level, the
053: attributes are followed by the subtable
054: references.
055: When the schema is dumped toSOIF,
056: duplicate tables are eliminated
057: in order to create the graph.
058: When editing a given instance
059: of a table in the hierarchy,
060: it is necessary to synch it with other
061: instances of the table in the hierarchy.
062: This is accomplished by maintaining an array
063: of columns which are pointed back to by the
064: binary tree - only one copy per column.
065: This stick of dynamite is lit, baby.
066: <p>
067: Mercifully, the hierarchy issue is now also moot,
068: since we're flattening the tree for now.
069: Currently, only attributes in the root table
070: are supported.
071: This issue may be revisited in future releases,
072: but note that toSOIF()'s current incarnation will
073: not produce correct "unduplicated graph" SOIF.
074: <p>
075: Note that some methods were created before the current
076: paradigm was established and will be reviewed for
077: efficiency in future releases.
078: *
079: */
080: public class Schema implements Cloneable {
081: /*-----------*/
082: /* variables */
083: /*-----------*/
084:
085: /**
086: * Schema name
087: */
088: public String schemaName;
089: /**
090: * SOIF Schema name
091: */
092: public String SOIFschemaName;
093: /**
094: * URL
095: */
096: public String url;
097: /**
098: * Binary tree representation of the schema
099: */
100: public BinaryTree binaryTree;
101: /**
102: * List of av pairs about the schema.
103: */
104: public AVPairs list;
105:
106: private boolean valid;
107:
108: private SchemaTblNode stnRoot;
109: private SchemaTblNode stn[];
110: private String stName[];
111: private int stnSCN[];
112: private int columnCount;
113: private SchemaColNode columnList[];
114: private int tableCount;
115:
116: /*--------------*/
117: /* constructors */
118: /*--------------*/
119:
120: /**
121: * Constructor.
122: */
123: public Schema() {
124: valid = false;
125: schemaName = "";
126: SOIFschemaName = "SCHEMA";
127: binaryTree = null;
128: list = null;
129: }
130:
131: private boolean addNode(String s, Object o, boolean first) {
132: if (first) {
133: binaryTree.createChild(s, o);
134: } else {
135: binaryTree.createNext(s, o);
136: }
137:
138: return false;
139: }
140:
141: private void buildTable(SchemaTblNode stnode) {
142: boolean first = true;
143: String sSTN;
144: String sFKSTN;
145:
146: // loop through the columns
147: for (int scnI = 0; scnI < columnCount; scnI++) {
148: // if the column is not null (accounting for gaps)
149: if (columnList[scnI] != null) {
150: // get the column's table
151: sSTN = columnList[scnI].getValue("system-table-name");
152: // if the column's table is this
153: // table, attach it
154: if (sSTN.compareTo(stnode.name) == 0) {
155: first = addNode(columnList[scnI].getLabel(),
156: columnList[scnI], first);
157: }
158:
159: // get the foreign ref
160: sFKSTN = columnList[scnI]
161: .getValue("foreign-key-system-table-name");
162: if (sFKSTN != null) {
163: // if the ref is not to ourselves (SGP?)
164: if (sFKSTN.compareTo(stnode.name) == 0) {
165: // loop through the table list
166: for (int stnI = 0; stnI < tableCount; stnI++) {
167: // if there's a match
168: // SGP: even to selves?
169: if (stn[stnI].name.compareTo(sSTN) == 0) {
170: // add the table and create it's subtree
171: first = addNode(stn[stnI].label,
172: stn[stnI], first);
173: BTreeNode btn = binaryTree.getCurrent();
174: buildTable(stn[stnI]);
175: // and then come back
176: binaryTree.setEnumeration(btn);
177: }
178: }
179:
180: }
181: }
182: }
183: }
184: }
185:
186: /**
187: * Constructor.
188: */
189: public Schema(SOIF soif) {
190: this ();
191:
192: if (soif == null) {
193: return;
194: }
195:
196: // note that random order and gaps in the schema
197: // multivalues are accounted for
198:
199: AVPairs avp;
200: int i;
201:
202: valid = true;
203: schemaName = soif.getValue("Schema-Name");
204: SOIFschemaName = soif.schemaName;
205: binaryTree = new BinaryTree(BinaryTree.DEPTHFIRST);
206:
207: // create the SchemaColNodes
208: columnCount = soif.getMaxAttributeIndex() + 1;
209: columnList = new SchemaColNode[columnCount];
210: for (i = 0; i < columnCount; i++) {
211: // get the list of av pairs for a particular multival
212: avp = soif.getAVPairsByMV(i);
213: if (avp != null) {
214: // remove the multival
215: avp.setIndices(AVPairs.NOMULTIVALUE);
216: // create a col node based on the list
217: columnList[i] = new SchemaColNode(avp);
218: }
219: }
220:
221: // get the list of av pairs that pertain to the schema
222: list = soif.getSingleValuePairs();
223:
224: // get a list of tables (w/ duplicates)
225: avp = soif.getAVPairsByAttribute("system-table-name");
226: if (avp != null) {
227: // unduplicate the list of tables
228: avp = avp.unduplicateValues();
229: }
230:
231: SchemaTblNode stnRoot = null;
232:
233: tableCount = (avp == null) ? 0 : avp.count();
234: stn = new SchemaTblNode[tableCount];
235: stnSCN = new int[tableCount];
236:
237: // build an array of tables and find the root table for
238: // the tree
239: i = 0;
240: for (AVPairs avpi = avp; avpi != null; avpi = avpi.next) {
241: stnSCN[i] = avpi.getAttributeIndex();
242:
243: stn[i] = new SchemaTblNode(avpi.value,
244: columnList[stnSCN[i]].getValue("table-name"));
245:
246: if (columnList[stnSCN[i]].getValue("in-root-table") != null) {
247: stnRoot = stn[i];
248: }
249:
250: i++;
251: }
252:
253: if (stnRoot == null) {
254: return;
255: }
256:
257: // build the tree
258: // binaryTree.createChild( schemaName, stnRoot );
259: binaryTree.createChild(stnRoot.label, stnRoot);
260: buildTable(stnRoot);
261: binaryTree.resetEnumeration();
262:
263: stn = null;
264: stnSCN = null;
265:
266: if (binaryTree.getRoot() == null) {
267: ReportError.reportError(ReportError.INTERNAL,
268: "SchemaGetter", "getSchema",
269: Messages.EMPTYSCHEMAFOUND);
270: }
271:
272: // clears the list, bad for graph collapse
273: columnList = new SchemaColNode[0];
274: }
275:
276: public Object clone() {
277: try {
278: Schema schema = (Schema) super .clone();
279:
280: schema.binaryTree = (BinaryTree) binaryTree.clone();
281:
282: return schema;
283:
284: } catch (CloneNotSupportedException e) {
285: throw new InternalError();
286: }
287: }
288:
289: /**
290: * Return whether or not the schema is valid.
291: */
292: public boolean isValid() {
293: return valid;
294: }
295:
296: /*---------------*/
297: /* set tree data */
298: /*---------------*/
299:
300: /**
301: * Hide unindexed attributes by marking the display flag false.
302: */
303: public void hideUnIndexed() {
304: Object o;
305: String s;
306:
307: binaryTree.currentBackup();
308: binaryTree.resetEnumeration();
309:
310: while (binaryTree.hasMoreElements(true)) {
311: binaryTree.nextElement(true);
312: o = binaryTree.getValue();
313: if (o instanceof SchemaColNode) {
314: s = ((SchemaColNode) o).getValue("Index-Attribute");
315: if (s == null) {
316: binaryTree.getCurrent().display = false;
317: }
318: }
319: }
320: binaryTree.currentRestore();
321: }
322:
323: /**
324: * Hide internal attributes by marking the display flag false.
325: */
326: public void hideInternal() {
327: Object o;
328: String s;
329:
330: binaryTree.currentBackup();
331: binaryTree.resetEnumeration();
332:
333: while (binaryTree.hasMoreElements(true)) {
334: binaryTree.nextElement(true);
335: o = binaryTree.getValue();
336: if (o instanceof SchemaColNode) {
337: s = ((SchemaColNode) o).getValue("Is-Internal");
338: if (s != null) {
339: binaryTree.getCurrent().display = false;
340: }
341: }
342: }
343: binaryTree.currentRestore();
344: }
345:
346: /**
347: * Hide both unindexed and internal attributes by marking
348: * the display flag false.
349: */
350: public void hideInternalOrUnIndexed() {
351: Object o;
352: String s;
353:
354: binaryTree.currentBackup();
355: binaryTree.resetEnumeration();
356:
357: while (binaryTree.hasMoreElements(true)) {
358: binaryTree.nextElement(true);
359: o = binaryTree.getValue();
360: if (o instanceof SchemaColNode) {
361: s = ((SchemaColNode) o).getValue("Index-Attribute");
362: if (s == null) {
363: binaryTree.getCurrent().display = false;
364: } else {
365: s = ((SchemaColNode) o).getValue("Is-Internal");
366: if (s != null) {
367: binaryTree.getCurrent().display = false;
368: }
369: }
370: }
371: }
372: binaryTree.currentRestore();
373: }
374:
375: private void hTWAH(BTreeNode btn) {
376: boolean b = false;
377: Object o = btn.getValue();
378:
379: if (btn.getValue() instanceof SchemaTblNode) {
380: for (BTreeNode btnI = btn.getChild(); btnI != null; btnI = btnI
381: .getNext()) {
382: if (btnI.getValue() instanceof SchemaTblNode) {
383: hTWAH(btnI);
384: }
385:
386: if (btnI.display == true) {
387: b = true;
388: }
389: }
390:
391: btn.display = b;
392: }
393: }
394:
395: /**
396: * Hide tables where all the attributes are themselves all hidden.
397: */
398: public void hideTablesWithAllHidden() {
399: if (binaryTree.getRoot() != null) {
400: hTWAH(binaryTree.getRoot());
401: }
402: }
403:
404: private String stringifyArray(String sarr[]) {
405: if (sarr == null) {
406: return null;
407: }
408:
409: StringBuffer sb = new StringBuffer(sarr[0]);
410: for (int i = 1; i < sarr.length; i++) {
411: sb.append(",");
412: sb.append(sarr[i]);
413: }
414:
415: return sb.toString();
416: }
417:
418: private String[] undupnstuff(String stmp[], int max) {
419: int n = 0;
420: for (int i = 0; i < max; i++) {
421: if (stmp[i] != null) {
422: n++;
423: }
424: }
425:
426: String s[] = new String[n];
427: int j = 0;
428: for (int i = 0; i < max; i++) {
429: if (stmp[i] != null) {
430: s[j] = stmp[i];
431: j++;
432: }
433: }
434:
435: return s;
436: }
437:
438: /**
439: * Get the list of attributes to be displayed
440: * in a comma seperated string.
441: */
442: public String getDisplayString() {
443: return stringifyArray(getDisplay());
444: }
445:
446: /**
447: * Get the list of attributes to be displayed
448: * in an array format.
449: */
450: public String[] getDisplay() {
451: Object o;
452: int maxI = 0;
453:
454: binaryTree.currentBackup();
455: binaryTree.resetEnumeration();
456: while (binaryTree.hasMoreElements(true)) {
457: binaryTree.nextElement(true);
458: o = binaryTree.getValue();
459: if (o instanceof SchemaColNode) {
460: SchemaColNode scn = ((SchemaColNode) o);
461: if (scn.display != SchemaColNode.ZIPPO) {
462: maxI = Math.max(maxI, scn.display);
463: }
464: }
465: }
466:
467: String stmp[] = new String[maxI + 1];
468: binaryTree.resetEnumeration();
469: while (binaryTree.hasMoreElements(true)) {
470: binaryTree.nextElement(true);
471: o = binaryTree.getValue();
472: if (o instanceof SchemaColNode) {
473: SchemaColNode scn = ((SchemaColNode) o);
474: if (scn.display != SchemaColNode.ZIPPO) {
475: stmp[scn.display] = scn.soifAttribute;
476: }
477: }
478: }
479:
480: binaryTree.currentRestore();
481: return undupnstuff(stmp, maxI);
482: }
483:
484: /**
485: * Get the list of attributes to be sorted by
486: * in a comma seperated string.
487: */
488: public String getSortString() {
489: return stringifyArray(getSort());
490: }
491:
492: /**
493: * Get the list of attributes to be sorted by
494: * in an array format.
495: */
496: public String[] getSort() {
497: Object o;
498: int maxI = 0;
499:
500: binaryTree.currentBackup();
501: binaryTree.resetEnumeration();
502: while (binaryTree.hasMoreElements(true)) {
503: binaryTree.nextElement(true);
504: o = binaryTree.getValue();
505: if (o instanceof SchemaColNode) {
506: SchemaColNode scn = ((SchemaColNode) o);
507: if (scn.sort != SchemaColNode.ZIPPO) {
508: maxI = Math.max(maxI, scn.sort);
509: }
510: }
511: }
512:
513: String stmp[] = new String[maxI + 1];
514: binaryTree.resetEnumeration();
515: while (binaryTree.hasMoreElements(true)) {
516: binaryTree.nextElement(true);
517: o = binaryTree.getValue();
518: if (o instanceof SchemaColNode) {
519: SchemaColNode scn = ((SchemaColNode) o);
520: if (scn.sort != SchemaColNode.ZIPPO) {
521: stmp[scn.sort] = scn.soifAttribute;
522: }
523: }
524: }
525:
526: binaryTree.currentRestore();
527: return undupnstuff(stmp, maxI);
528: }
529:
530: private int countEditable(boolean editable) {
531: Object o;
532: int i = 0;
533:
534: binaryTree.currentBackup();
535: binaryTree.resetEnumeration();
536: while (binaryTree.hasMoreElements(true)) {
537: binaryTree.nextElement(true);
538: o = binaryTree.getValue();
539: if (o instanceof SchemaColNode) {
540: SchemaColNode scn = ((SchemaColNode) o);
541: if ((scn.editable != SchemaColNode.ZIPPO) == editable) {
542: i++;
543: }
544: }
545: }
546: binaryTree.currentRestore();
547: return i;
548: }
549:
550: /**
551: * Get the list of attributes that are editable
552: * in a comma seperated string.
553: */
554: public String getEditableString() {
555: return stringifyArray(getEditable(true));
556: }
557:
558: /**
559: * Get the list of attributes that are editable
560: * in an array format.
561: */
562: public String[] getEditable() {
563: return getEditable(true);
564: }
565:
566: /**
567: * Get the list of attributes that are editable
568: * in a comma seperated string.
569: */
570: public String getNonEditableString() {
571: return stringifyArray(getEditable(false));
572: }
573:
574: /**
575: * Get the list of attributes that are editable
576: * in an array format.
577: */
578: public String[] getNonEditable() {
579: return getEditable(false);
580: }
581:
582: private String[] getEditable(boolean editable) {
583: Object o;
584: int i = 0;
585:
586: String stmp[] = new String[countEditable(editable)];
587: binaryTree.currentBackup();
588: binaryTree.resetEnumeration();
589: while (binaryTree.hasMoreElements(true)) {
590: binaryTree.nextElement(true);
591: o = binaryTree.getValue();
592: if (o instanceof SchemaColNode) {
593: SchemaColNode scn = ((SchemaColNode) o);
594: if ((scn.editable != SchemaColNode.ZIPPO) == editable) {
595: stmp[i++] = scn.soifAttribute;
596: }
597: }
598: }
599:
600: binaryTree.currentRestore();
601: return undupnstuff(stmp, i);
602: }
603:
604: private int countIndexable(boolean indexable) {
605: Object o;
606: int i = 0;
607:
608: binaryTree.currentBackup();
609: binaryTree.resetEnumeration();
610: while (binaryTree.hasMoreElements(true)) {
611: binaryTree.nextElement(true);
612: o = binaryTree.getValue();
613: if (o instanceof SchemaColNode) {
614: SchemaColNode scn = ((SchemaColNode) o);
615: if ((scn.indexable != SchemaColNode.ZIPPO) == indexable) {
616: i++;
617: }
618: }
619: }
620: binaryTree.currentRestore();
621: return i;
622: }
623:
624: /**
625: * Get the list of attributes that are indexable
626: * in a comma seperated string.
627: */
628: public String getIndexableString() {
629: return stringifyArray(getIndexable(true));
630: }
631:
632: /**
633: * Get the list of attributes that are indexable
634: * in an array format.
635: */
636: private String[] getIndexable() {
637: return getIndexable(true);
638: }
639:
640: private String[] getIndexable(boolean indexable) {
641: Object o;
642: int i = 0;
643:
644: String stmp[] = new String[countIndexable(indexable)];
645: binaryTree.currentBackup();
646: binaryTree.resetEnumeration();
647: while (binaryTree.hasMoreElements(true)) {
648: binaryTree.nextElement(true);
649: o = binaryTree.getValue();
650: if (o instanceof SchemaColNode) {
651: SchemaColNode scn = ((SchemaColNode) o);
652: if ((scn.indexable != SchemaColNode.ZIPPO) == indexable) {
653: stmp[i++] = scn.soifAttribute;
654: }
655: }
656: }
657:
658: binaryTree.currentRestore();
659: return undupnstuff(stmp, i);
660: }
661:
662: /**
663: * Get the list of attributes that are editable
664: * in a comma seperated string.
665: */
666: public String getAllString() {
667: return stringifyArray(getAll());
668: }
669:
670: /**
671: * Get the list of attributes that are editable
672: * in an array format.
673: */
674: public String[] getAll() {
675: Object o;
676: int maxI = 0;
677:
678: binaryTree.currentBackup();
679: binaryTree.resetEnumeration();
680: while (binaryTree.hasMoreElements(true)) {
681: binaryTree.nextElement(true);
682: o = binaryTree.getValue();
683: if (o instanceof SchemaColNode) {
684: maxI++;
685: }
686: }
687:
688: String stmp[] = new String[maxI + 1];
689: binaryTree.resetEnumeration();
690: for (int i = 0; binaryTree.hasMoreElements(true);) {
691: binaryTree.nextElement(true);
692: o = binaryTree.getValue();
693: if (o instanceof SchemaColNode) {
694: SchemaColNode scn = ((SchemaColNode) o);
695: stmp[i] = scn.soifAttribute;
696: i++;
697: }
698: }
699:
700: binaryTree.currentRestore();
701: return undupnstuff(stmp, maxI);
702: }
703:
704: /**
705: * Reset display flags to the default in the schema.
706: */
707: public void setDefaultDisplay() {
708: Object o;
709:
710: binaryTree.currentBackup();
711: binaryTree.resetEnumeration();
712: while (binaryTree.hasMoreElements(true)) {
713: binaryTree.nextElement(true);
714: o = binaryTree.getValue();
715: if (o instanceof SchemaColNode) {
716: ((SchemaColNode) o).setDefaultDisplay();
717: }
718: }
719: binaryTree.currentRestore();
720: }
721:
722: /**
723: * Reset sort flags to the default in the schema.
724: */
725: public void setDefaultSort() {
726: Object o;
727:
728: binaryTree.currentBackup();
729: binaryTree.resetEnumeration();
730: while (binaryTree.hasMoreElements(true)) {
731: binaryTree.nextElement(true);
732: o = binaryTree.getValue();
733: if (o instanceof SchemaColNode) {
734: ((SchemaColNode) o).setDefaultSort();
735: }
736: }
737: binaryTree.currentRestore();
738: }
739:
740: /**
741: * Clear all the display flags.
742: */
743: public void clearDisplay() {
744: Object o;
745:
746: binaryTree.currentBackup();
747: binaryTree.resetEnumeration();
748: while (binaryTree.hasMoreElements(true)) {
749: binaryTree.nextElement(true);
750: o = binaryTree.getValue();
751: if (o instanceof SchemaColNode) {
752: ((SchemaColNode) o).display = SchemaColNode.ZIPPO;
753: }
754: }
755: binaryTree.currentRestore();
756: }
757:
758: /**
759: * Clear all the sort flags.
760: */
761: public void clearSort() {
762: Object o;
763:
764: binaryTree.currentBackup();
765: binaryTree.resetEnumeration();
766: while (binaryTree.hasMoreElements(true)) {
767: binaryTree.nextElement(true);
768: o = binaryTree.getValue();
769: if (o instanceof SchemaColNode) {
770: ((SchemaColNode) o).sort = SchemaColNode.ZIPPO;
771: }
772: }
773: binaryTree.currentRestore();
774: }
775:
776: /**
777: * SOIFify SOIF list.
778: */
779: public String toSOIF() {
780: StringBuffer sb = new StringBuffer();
781:
782: list.setValue("Last-Modified", (new Date()).toLocaleString());
783: list.setValue("Number-of-Entries", ""
784: + (binaryTree.count(true) - 1));
785:
786: sb.append("@" + SOIFschemaName + " { -\n");
787: sb.append(list.toSOIFList() + "\n");
788:
789: int i = 1;
790: binaryTree.currentBackup();
791: binaryTree.resetEnumeration();
792: while (binaryTree.hasMoreElements(true)) {
793: binaryTree.nextElement(true);
794: Object o = binaryTree.getValue();
795: if (o instanceof SchemaColNode) {
796: sb.append(((SchemaColNode) o).toSOIF(i++) + "\n");
797: }
798: }
799: binaryTree.currentRestore();
800:
801: /* this and not nulling the columnList let you print
802: ** the schema w/ the flat graph business. kept for
803: ** novelty, moot for now.
804: for ( int scnI = 0; scnI < columnCount; scnI++ )
805: {
806: if ( columnList[ scnI ] != null )
807: {
808: sb.append(
809: columnList[ scnI ].toSOIF( scnI + 1 )
810: + "\n"
811: );
812: }
813: }
814: */
815:
816: sb.append("}\n");
817:
818: return sb.toString();
819: }
820:
821: public String toString() {
822: return "Schema instance: (" + Header.VERSION + ")\n"
823: + "\tvalid = [" + valid + "]\n" + "\tschemaName = ["
824: + schemaName + "]\n" + "\turl = [" + url + "]\n"
825: + "\tbinaryTree = ["
826: + ((binaryTree == null) ? "null" : "not null") + "]\n";
827: }
828:
829: /**
830: * Dump the tree out in a couple of different ways.
831: * @param fullnode dump the info in the node
832: * @param tree dump the tree structure
833: */
834: public String toStringTree(boolean fullnode, boolean tree) {
835: StringBuffer sb = new StringBuffer(toString());
836: Object o;
837:
838: binaryTree.currentBackup();
839: binaryTree.resetEnumeration();
840: if (binaryTree.isEmpty()) {
841: return sb.toString();
842: }
843:
844: if (fullnode) {
845: sb.append("---< full node >-----\n");
846:
847: binaryTree.resetEnumeration();
848:
849: while (binaryTree.hasMoreElements(true)) {
850: binaryTree.nextElement(true);
851: BTreeNode btn = binaryTree.getCurrent();
852: sb.append(btn.toString() + "\n");
853: sb.append("---" + "\n");
854: }
855:
856: sb.append("---------------------\n");
857: }
858:
859: if (tree) {
860: sb.append("---< tree >----------\n");
861:
862: binaryTree.resetEnumeration();
863:
864: while (binaryTree.hasMoreElements(true)) {
865: binaryTree.nextElement(true);
866: o = binaryTree.getValue();
867: StringBuffer indent = new StringBuffer();
868: for (int i = 0; i <= binaryTree.getUnaryDepth(); i++) {
869: indent.append(" ");
870: }
871: if (o instanceof SchemaTblNode) {
872: sb.append(indent.toString() + "<"
873: + ((SchemaTblNode) o).label + "><"
874: + ((SchemaTblNode) o).name + ">\n");
875: } else {
876: sb.append(indent.toString()
877: + ((SchemaColNode) o).getLabel() + " -- "
878: + ((SchemaColNode) o).sysTblName + "\n");
879: }
880: }
881:
882: sb.append("---------------------\n");
883: }
884:
885: binaryTree.currentRestore();
886: return sb.toString();
887: }
888: }
|