KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > coach > idltree > IdlNode


1 /***************************************************************************/
2 /* COACH: Component Based Open Source Architecture for */
3 /* Distributed Telecom Applications */
4 /* See: http://www.objectweb.org/ */
5 /* */
6 /* Copyright (C) 2003 Lucent Technologies Nederland BV */
7 /* Bell Labs Advanced Technologies - EMEA */
8 /* */
9 /* Initial developer(s): Harold Batteram */
10 /* */
11 /* This library is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public */
13 /* License as published by the Free Software Foundation; either */
14 /* version 2.1 of the License, or (at your option) any later version. */
15 /* */
16 /* This library is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
19 /* Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public */
22 /* License along with this library; if not, write to the Free Software */
23 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
24 /***************************************************************************/
25 package org.coach.idltree;
26
27 import javax.swing.tree.*;
28
29 import java.util.*;
30 import java.io.*;
31 import java.lang.reflect.*;
32
33 import org.omg.CORBA.ORB JavaDoc;
34 import org.omg.CORBA.TypeCode JavaDoc;
35 import org.omg.CORBA.Any JavaDoc;
36 import org.omg.CORBA.TCKind JavaDoc;
37
38 /**
39  * IdlNode is the abstract base class for all concrete IdlNode types.
40  * The classes in the idltree library are used to represent arbitrary complex Idl type values as a tree structure.
41  * For example an Idl struct such as:
42  * <code>
43  * <pre>
44  * struct MyStruct {
45  * string member1;
46  * short member2;
47  * };
48  * </pre>
49  * </code>
50  * is represented as an IdlStruct node with two chidren, one of type IdlString and one of type IdlShort.
51  * <pre>
52  *
53  * IdlStruct
54  * /\
55  * / \
56  * / \
57  * / \
58  * IdlString IdlShort
59  * field=member1 field=member2
60  * value="" value=0
61  *</pre>
62  * The field member variable is used to hold the struct member name.
63  * Each IdlNode which is a leaf has a value member variable to hold the current value of the node. The
64  * value is maintained as a String but can be converted to a CORBA any value.
65  * The tree structure can be constructed in several ways:
66  * <BL>
67  * <LI>From the content of a CORBA Any value.</LI>
68  * <LI>From a CORBA TypeCode value.</LI>
69  * <LI>From a XML string representation.</LI>
70  * </BL>
71  * In reverse, IdlNodes can be converted to CORBA Any and/or an XML string containing all fields and values.
72  * Value variables have proper default values. For example when a IdlString node is created, its default value is an empty string.
73  * Complex nested Idl structures can be navigated by their field values.
74  * An IdlNode tree is derived from a javax.swing.tree.DefaultMutableTreeNode and can be easily drawn as a javax.swing.JTree or
75  * interactively edited using a tree editor such as implemented by the IdlEditor class.
76  * The tree can also be navigated and controlled through this API.
77  */

78
79 public abstract class IdlNode extends DefaultMutableTreeNode {
80     // In order to save the tree structure as serialized data non
81
// serializable fields are transient.
82
protected static transient ORB JavaDoc orb = null;
83     // The CORBA type code associated with the IDL node.
84
protected transient TypeCode JavaDoc tc;
85     // Indicator if this node is an end leaf.
86
protected boolean isLeaf = true;
87     // Only mutable nodes values can be edited with an editor.
88
protected boolean isMutable = true;
89     // Field is used to add additional information to name a node.
90
// For example if a node represents a member of a struct or union, the field variable will hold the
91
// member name. If a node is an element in an arrays or sequences, the field variable will hold the index number.
92
protected String JavaDoc field = "";
93     // The IDL type name of a node.
94
protected String JavaDoc type = "";
95     // The CORBA repository ID
96
protected String JavaDoc id = "";
97     // The content of the node represented as a string.
98
protected String JavaDoc value = "";
99
100     static {
101         try {
102             if ( orb == null )
103             {
104                 orb = org.objectweb.openccm.corba.TheORB.getORB();
105             }
106         }
107         catch (Error JavaDoc e) {
108         }
109     }
110
111     protected IdlNode() {
112     }
113
114     public static void setOrb(ORB JavaDoc ob) {
115         orb = ob;
116     }
117
118     /**
119      * Sets the TypeCode for this node.
120      *
121      * @param tc The TypeCode value to set.
122      */

123     protected void setNode(TypeCode JavaDoc tc) {
124         this.tc = tc;
125         if (tc.kind().value() == TCKind._tk_alias) {
126             try {
127                 type = tc.id();
128                 id = tc.id();
129             } catch (Exception JavaDoc ex) {
130             }
131         }
132     }
133
134     /**
135      * Factory method to create a new IdlNode instance from a TypeCode value.
136      *
137      * @param tc The TypeCode value from which to create a new instance.
138      *
139      * @return A new IdlNode instance for the given TypeCode.
140      */

141     public static IdlNode create(TypeCode JavaDoc tc) {
142         try {
143             switch (tc.kind().value()) {
144                 case TCKind._tk_struct: {
145                     return new IdlStruct(tc);
146                 }
147                 case TCKind._tk_except: {
148                     return new IdlException(tc);
149                 }
150                 case TCKind._tk_union: {
151                     return new IdlUnion(tc);
152                 }
153                 case TCKind._tk_array: {
154                     return new IdlArray(tc);
155                 }
156                 case TCKind._tk_sequence: {
157                     return new IdlSequence(tc);
158                 }
159                 case TCKind._tk_enum: {
160                     return new IdlEnum(tc);
161                 }
162                 case TCKind._tk_any: {
163                     return new IdlAny(tc);
164                 }
165                 case TCKind._tk_octet: {
166                     return new IdlOctet(tc);
167                 }
168                 case TCKind._tk_short: {
169                     return new IdlShort(tc);
170                 }
171                 case TCKind._tk_ushort: {
172                     return new IdlUshort(tc);
173                 }
174                 case TCKind._tk_long: {
175                     return new IdlLong(tc);
176                 }
177                 case TCKind._tk_ulong: {
178                     return new IdlUlong(tc);
179                 }
180                 case TCKind._tk_longlong: {
181                     return new IdlLonglong(tc);
182                 }
183                 case TCKind._tk_ulonglong: {
184                     return new IdlUlonglong(tc);
185                 }
186                 case TCKind._tk_float: {
187                     return new IdlFloat(tc);
188                 }
189                 case TCKind._tk_double: {
190                     return new IdlDouble(tc);
191                 }
192                 case TCKind._tk_longdouble: {
193                     return new IdlLongdouble(tc);
194                 }
195                 case TCKind._tk_boolean: {
196                     return new IdlBoolean(tc);
197                 }
198                 case TCKind._tk_char: {
199                     return new IdlChar(tc);
200                 }
201                 case TCKind._tk_wchar: {
202                     return new IdlWchar(tc);
203                 }
204                 case TCKind._tk_objref: {
205                     return new IdlObject(tc);
206                 }
207                 case TCKind._tk_value: {
208                     return new IdlValue(tc);
209                 }
210                 case TCKind._tk_string: {
211                     return new IdlString(tc);
212                 }
213                 case TCKind._tk_wstring: {
214                     return new IdlWstring(tc);
215                 }
216                 case TCKind._tk_fixed: {
217                     return new IdlFixed(tc);
218                 }
219                 case TCKind._tk_alias: {
220                     return create(tc.content_type(), tc);
221                 }
222                 default: {
223                     throw new RuntimeException JavaDoc("Unexpected type: " + tc.kind().value());
224                 }
225             }
226         } catch (Exception JavaDoc e) {
227             e.printStackTrace();
228         }
229         return null;
230     }
231
232     /**
233      * Factory method to create a new IdlNode instance from an aliased TypeCode value.
234      *
235      * @param alias The original TypeCode value.
236      * @param tc The alias content TypeCode value from which to create a new instance.
237      *
238      * @return A new IdlNode instance for the given TypeCode.
239      */

240     private static IdlNode create(TypeCode JavaDoc alias, TypeCode JavaDoc tc) {
241         try {
242             switch (alias.kind().value()) {
243                 case TCKind._tk_struct: {
244                     return new IdlStruct(tc);
245                 }
246                 case TCKind._tk_except: {
247                     return new IdlException(tc);
248                 }
249                 case TCKind._tk_union: {
250                     return new IdlUnion(tc);
251                 }
252                 case TCKind._tk_array: {
253                     return new IdlArray(tc);
254                 }
255                 case TCKind._tk_sequence: {
256                     return new IdlSequence(tc);
257                 }
258                 case TCKind._tk_enum: {
259                     return new IdlEnum(tc);
260                 }
261                 case TCKind._tk_any: {
262                     return new IdlAny(tc);
263                 }
264                 case TCKind._tk_octet: {
265                     return new IdlOctet(tc);
266                 }
267                 case TCKind._tk_short: {
268                     return new IdlShort(tc);
269                 }
270                 case TCKind._tk_ushort: {
271                     return new IdlUshort(tc);
272                 }
273                 case TCKind._tk_long: {
274                     return new IdlLong(tc);
275                 }
276                 case TCKind._tk_ulong: {
277                     return new IdlUlong(tc);
278                 }
279                 case TCKind._tk_longlong: {
280                     return new IdlLonglong(tc);
281                 }
282                 case TCKind._tk_ulonglong: {
283                     return new IdlUlonglong(tc);
284                 }
285                 case TCKind._tk_float: {
286                     return new IdlFloat(tc);
287                 }
288                 case TCKind._tk_double: {
289                     return new IdlDouble(tc);
290                 }
291                 case TCKind._tk_longdouble: {
292                     return new IdlLongdouble(tc);
293                 }
294                 case TCKind._tk_boolean: {
295                     return new IdlBoolean(tc);
296                 }
297                 case TCKind._tk_char: {
298                     return new IdlChar(tc);
299                 }
300                 case TCKind._tk_wchar: {
301                     return new IdlWchar(tc);
302                 }
303                 case TCKind._tk_objref: {
304                     return new IdlObject(tc);
305                 }
306                 case TCKind._tk_value: {
307                     return new IdlValue(tc);
308                 }
309                 case TCKind._tk_string: {
310                     return new IdlString(tc);
311                 }
312                 case TCKind._tk_wstring: {
313                     return new IdlWstring(tc);
314                 }
315                 case TCKind._tk_fixed: {
316                     return new IdlFixed(tc);
317                 }
318                 case TCKind._tk_alias: {
319                     return create(alias.content_type(), tc);
320                 }
321                 default: {
322                     throw new RuntimeException JavaDoc("Unexpected type: " + tc.kind().value());
323                 }
324             }
325         } catch (Exception JavaDoc e) {
326             e.printStackTrace();
327         }
328         return null;
329     }
330
331     /**
332      * Factory method to create a new IdlNode instance from the content of an Any value.
333      *
334      * @param any The Any value from which to create a new instance.
335      *
336      * @return A new IdlNode instance for the given Any.
337      */

338     public static IdlNode create(Any JavaDoc any) {
339         return create(any.type(), any);
340     }
341
342     /**
343      * Write the current value to an IdlWriter object.
344      *
345      * @param w The IdlWriter object to write the current value to.
346      */

347     public void write(IdlWriter w) {
348     }
349
350     /**
351      * Writes the value to a CORBA outputstream.
352      *
353      * @param is The outputstream to write to.
354      */

355     public void write(org.omg.CORBA.portable.OutputStream JavaDoc os) {
356     }
357
358     /**
359      * Reads the value from a CORBA inputstream.
360      *
361      * @param is The inputstream to read from.
362      */

363     public void read(org.omg.CORBA.portable.InputStream JavaDoc is) {
364     }
365
366     /**
367      * Factory method to create a new IdlNode instance from an aliased Any value.
368      *
369      * @param tc The content TypeCode value.
370      * @param any The any value from which to create a new instance.
371      *
372      * @return A new IdlNode instance for the given TypeCode.
373      */

374     private static IdlNode create(TypeCode JavaDoc tc, Any JavaDoc any) {
375         try {
376             switch (tc.kind().value()) {
377                 case TCKind._tk_struct: {
378                     return new IdlStruct(any);
379                 }
380                 case TCKind._tk_except: {
381                     return new IdlException(any);
382                 }
383                 case TCKind._tk_union: {
384                     return new IdlUnion(any);
385                 }
386                 case TCKind._tk_any: {
387                     return new IdlAny(any);
388                 }
389                 case TCKind._tk_sequence: {
390                     return new IdlSequence(any);
391                 }
392                 case TCKind._tk_array: {
393                     return new IdlArray(any);
394                 }
395                 case TCKind._tk_enum: {
396                     return new IdlEnum(any);
397                 }
398                 case TCKind._tk_short: {
399                     return new IdlShort(any);
400                 }
401                 case TCKind._tk_ushort: {
402                     return new IdlUshort(any);
403                 }
404                 case TCKind._tk_char: {
405                     return new IdlChar(any);
406                 }
407                 case TCKind._tk_wchar: {
408                     return new IdlWchar(any);
409                 }
410                 case TCKind._tk_string: {
411                     return new IdlString(any);
412                 }
413                 case TCKind._tk_wstring: {
414                     return new IdlWstring(any);
415                 }
416                  case TCKind._tk_long: {
417                     return new IdlLong(any);
418                 }
419                 case TCKind._tk_ulong: {
420                     return new IdlUlong(any);
421                 }
422                 case TCKind._tk_longlong: {
423                     return new IdlLonglong(any);
424                 }
425                 case TCKind._tk_ulonglong: {
426                     return new IdlUlonglong(any);
427                 }
428                 case TCKind._tk_octet: {
429                     return new IdlOctet(any);
430                 }
431                 case TCKind._tk_longdouble: {
432                     return new IdlLongdouble(any);
433                 }
434                 case TCKind._tk_objref: {
435                     return new IdlObject(any);
436                 }
437                 case TCKind._tk_value: {
438                     return new IdlValue(any);
439                 }
440                 case TCKind._tk_float: {
441                     return new IdlFloat(any);
442                 }
443                 case TCKind._tk_double: {
444                     return new IdlDouble(any);
445                 }
446                 case TCKind._tk_boolean: {
447                     return new IdlBoolean(any);
448                 }
449                 case TCKind._tk_fixed: {
450                     return new IdlFixed(any);
451                 }
452                 case TCKind._tk_alias: {
453                     return create(tc.content_type(), any);
454                 }
455                 default: {
456                     throw new RuntimeException JavaDoc("Unexpected type: " + any.type().kind());
457                 }
458             }
459         } catch (Exception JavaDoc e) {
460             e.printStackTrace();
461         }
462         return null;
463     }
464
465     /**
466      * Returns a String representation of the node.
467      *
468      * @return A String representation of the node.
469      */

470     public String JavaDoc toString() {
471         if (field.equals("")) {
472             return (type + " " + value).trim();
473         } else {
474             return (field + " " + type + " " + value).trim();
475         }
476     }
477
478     /**
479      * Returns the child IdlNode which matches the given field path.
480      *
481      * Search through the node tree for a node that maches the
482      * node path. The node path is in the form a.b.c where a, b and c are
483      * the field names of child nodes.
484      * If no matching path is found, null is returned.
485      * This method can be used for example from a scriping environment to
486      * retrieve and manipulate IdlNodes.
487      *
488      * @param path The field path used for the search.
489      *
490      * @return The child IdlNode for the given field path or null.
491      */

492     public IdlNode getNode(String JavaDoc path) {
493         if (path == null || path.equals("")) {
494             return this;
495         }
496         String JavaDoc current = path;
497         int idx = path.indexOf(".");
498         if (idx > 0) {
499             // set the current field and subtract the current field from the path.
500
current = path.substring(0, idx);
501             path = path.substring(idx + 1);
502         } else {
503             // the end of path is reached.
504
path = null;
505         }
506         int cc = getChildCount();
507         for (int i = 0; i < cc; i++) {
508             IdlNode n = (IdlNode)getChildAt(i);
509             if (n instanceof IdlParameter) {
510                 n = ((IdlParameter)n).getParameter();
511             }
512             // strip brackets from arrays and sequences
513
String JavaDoc f = (n.field.replace('[', ' ').replace(']', ' ')).trim();
514             if (f.equals(current)) {
515                 if (path != null) {
516                     // the current fiels matched, continue with the next field.
517
return n.getNode(path);
518                 } else {
519                     // the current field maches and this is the last field
520
return n;
521                 }
522             }
523         }
524         throw new RuntimeException JavaDoc("No such field '" + current + "' in node type: " + type);
525     }
526
527     /**
528      * Returns a String with all field names of all child nodes.
529      *
530      * The field names are separated by a newline character.
531      * If the values flag is true, the node value is added to the field name, separated by a space.
532      *
533      * @param values Boolean flag to indicate if node values must be added to the output.
534      *
535      * @return A String with field names (with values if requested) for all child nodes.
536      */

537     public String JavaDoc printFields(boolean values) {
538         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
539
540         for(Enumeration e = depthFirstEnumeration(); e.hasMoreElements();) {
541             IdlNode n = (IdlNode)e.nextElement();
542             if (!(n instanceof IdlParameter) && n != this) {
543                 TreeNode[] nn = n.getPath();
544                 String JavaDoc path = "";
545                 String JavaDoc dot = "";
546                 for(int i = getLevel() + 1; i < nn.length; i++) {
547                     if (!(nn[i] instanceof IdlParameter)) {
548                         path += dot + (((IdlNode)nn[i]).field.replace('[', ' ').replace(']', ' ')).trim();
549                         dot = ".";
550                     }
551                 }
552                 if (values) {
553                     sb.append(path + ":" + n.getValue() + "\n");
554                 } else {
555                     sb.append(path + "\n");
556                 }
557             }
558         }
559
560         return sb.toString();
561     }
562
563     /**
564      * Returns a String with all node values for all child nodes.
565      *
566      * The values are separated by a newline character.
567      *
568      * @return A String with values for all child nodes.
569      */

570     public String JavaDoc printValues() {
571         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
572
573         for(Enumeration e =depthFirstEnumeration(); e.hasMoreElements();) {
574             IdlNode n = (IdlNode)e.nextElement();
575             if (!(n instanceof IdlParameter) && n != this) {
576                 sb.append(n.getValue() + "\n");
577             }
578         }
579
580         return sb.toString();
581     }
582
583     public void setField(String JavaDoc f) {
584         field = f;
585     }
586
587     /**
588      * Replace it self with the parent with the new node.
589      *
590      * This method is used to replace a whole subtree of the IdlNode tree.
591      *
592      * @param n the root of the subtree node which replaces the current node.
593      */

594     public void replace(IdlNode n) {
595         // replace only if type and id match
596
if (n.getType().equals(getType()) && n.getId().equals(getId())) {
597             n.field = field;
598             IdlNode p = (IdlNode)getParent();
599             if (p != null) {
600                 int idx = p.getIndex(this);
601                 if (idx >= 0) {
602                     p.insert(n, idx);
603                     return;
604                 }
605                 throw new RuntimeException JavaDoc("No such child node.");
606             } else {
607                 throw new RuntimeException JavaDoc("Can't replace root in IdlNode.");
608             }
609         } else {
610             throw new RuntimeException JavaDoc("Unmatching types for IdlNode replacement. Expected: " + getType());
611         }
612     }
613
614     /**
615      * Sets the node value.
616      *
617      * @param v The assigned value.
618      */

619     public void setValue(String JavaDoc v) {
620         value = v;
621     }
622
623     /**
624      * Returns the node type string.
625      *
626      * @return The node type.
627      */

628     public String JavaDoc getType() {
629         return type;
630     }
631
632     /**
633      * Returns the node value.
634      *
635      * @return The node value.
636      */

637     public String JavaDoc getValue() {
638         return value;
639     }
640
641     /**
642      * Returns the repository id for the node.
643      *
644      * @return The repositiry id.
645      */

646     public String JavaDoc getId() {
647         return id;
648     }
649
650     /**
651      * Returns the CORBA TypeCode for the node.
652      *
653      * @return The TypeCode.
654      */

655     public TypeCode JavaDoc getTypeCode() {
656         return tc;
657     }
658
659
660     /**
661      * Returns the current value as a CORBA Any value.
662      *
663      * @return The current value as a CORBA Any.
664      */

665     public Any JavaDoc toAny() {
666         return toDynAny().to_any();
667     }
668
669     public org.omg.DynamicAny.DynAny JavaDoc toDynAny() {
670         throw new RuntimeException JavaDoc("Illegal operation on this nodetype: " + this.getClass().getName());
671     }
672
673     /**
674      * Returns true if this node allows subnodes.
675      *
676      * @return true if this node allows subnodes
677      */

678     public boolean getAllowsChildren() {
679         // overwrite DefaultMutableTreeNode methods
680
return !isLeaf;
681     }
682
683     /**
684      * Returns true if this node is a leaf node.
685      *
686      * @return true if this node is a leaf node
687      */

688     public boolean isLeaf() {
689         return isLeaf;
690     }
691
692     /**
693      * Returns true if a value can be assigned to this node.
694      *
695      * @return true if a value can be assigned to this node
696      */

697     public boolean isMutable() {
698         return isMutable;
699     }
700
701     /**
702      * Makes a copy of the current node.
703      *
704      * @return a copy of this node
705      */

706     public Object JavaDoc clone() {
707         try {
708             IdlNode t = (IdlNode)super.clone();
709             t.parent = null;
710             t.children = null;
711             t.userObject = t;
712             // clone all children
713
return t;
714         } catch (Exception JavaDoc e) {
715             e.printStackTrace();
716         }
717         return null;
718     }
719
720     /**
721      * Makes a copy of the current node.
722      *
723      * @return a copy of this node
724      */

725     public IdlNode copy() {
726         return (IdlNode)clone();
727     }
728
729     /**
730      * Determine if type t is allowed to be pasted into
731      * this type.
732      *
733      * @return true if the types are compatible
734      **/

735     public boolean canPaste(IdlNode t) {
736         return false;
737     }
738
739     /**
740      * Copies values from the the given node.
741      *
742      * @param t - the node to copy values from
743      */

744     void paste(IdlNode t) {
745         // initialize all relevant fields
746
type = t.type;
747         field = t.field;
748         children = null;
749         allowsChildren = t.allowsChildren;
750         userObject = this;
751
752         // copy the value and children
753
}
754
755     static protected String JavaDoc[] splitName(String JavaDoc name, String JavaDoc separator) {
756         if (name == null) {
757             return new String JavaDoc[0];
758         }
759         StringTokenizer st = new StringTokenizer(name, separator);
760         Vector v = new Vector();
761         if (name.startsWith(separator)) {
762             v.addElement("");
763         }
764         while (st.hasMoreTokens()) {
765             v.addElement(st.nextToken());
766         }
767         String JavaDoc[] s = new String JavaDoc[v.size()];
768         v.copyInto(s);
769         return s;
770     }
771 }
Popular Tags