KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > idl > StructType


1 package org.jacorb.idl;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23
24 import java.io.File JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.util.*;
27
28 /**
29  * @author Gerald Brose
30  * @version $Id: StructType.java,v 1.45 2004/05/06 12:39:58 nicolas Exp $
31  */

32
33 public class StructType
34     extends TypeDeclaration
35     implements Scope
36 {
37     private boolean written = false;
38     public boolean exc;
39     public MemberList memberlist = null;
40     private boolean parsed = false;
41     private ScopeData scopeData;
42
43     public StructType(int num)
44     {
45         super(num);
46         pack_name = "";
47     }
48
49
50     public void setScopeData(ScopeData data)
51     {
52         scopeData = data;
53     }
54
55     public ScopeData getScopeData()
56     {
57         return scopeData;
58     }
59
60     /**
61      * @return true if this struct represents an IDL exception
62      */

63
64     public boolean isException()
65     {
66         return exc;
67     }
68
69     public Object JavaDoc clone()
70     {
71         StructType st = new StructType(new_num());
72         st.pack_name = this.pack_name;
73         st.name = this.name;
74         st.memberlist = this.memberlist;
75         st.included = this.included;
76         st.token = this.token;
77         st.exc = this.exc;
78         st.scopeData = this.scopeData;
79         st.enclosing_symbol = this.enclosing_symbol;
80         return st;
81     }
82
83     public TypeDeclaration declaration()
84     {
85         return this;
86     };
87
88     public String JavaDoc typeName()
89     {
90         if (typeName == null)
91             setPrintPhaseNames();
92         return typeName;
93     }
94
95     /**
96      * get this types's mapped Java name
97      */

98
99     public String JavaDoc getJavaTypeName()
100     {
101         if (typeName == null)
102             setPrintPhaseNames();
103         return typeName;
104     }
105
106
107     /**
108      * get this symbol's IDL type name
109      */

110
111     public String JavaDoc getIDLTypeName()
112     {
113         return getJavaTypeName(); // TODO
114
}
115
116
117     public boolean basic()
118     {
119         return false;
120     }
121
122     public void set_memberlist(MemberList m)
123     {
124         m.setContainingType(this);
125         memberlist = m;
126         memberlist.setPackage(name);
127         if (memberlist != null)
128             memberlist.setEnclosingSymbol(this);
129     }
130
131     public void set_included(boolean i)
132     {
133         included = i;
134     }
135
136
137     public void setPackage(String JavaDoc s)
138     {
139         s = parser.pack_replace(s);
140         if (pack_name.length() > 0)
141             pack_name = s + "." + pack_name;
142         else
143             pack_name = s;
144
145         if (memberlist != null)
146             memberlist.setPackage(s);
147     }
148
149     public void setEnclosingSymbol(IdlSymbol s)
150     {
151         if (enclosing_symbol != null && enclosing_symbol != s)
152         {
153             logger.error("was " + enclosing_symbol.getClass().getName() +
154                                 " now: " + s.getClass().getName());
155             throw new RuntimeException JavaDoc("Compiler Error: trying to reassign container for " + name);
156         }
157         enclosing_symbol = s;
158         if (memberlist != null)
159             memberlist.setEnclosingSymbol(this);
160     }
161
162     public String JavaDoc toString()
163     {
164         return typeName();
165     }
166
167     public void parse()
168     {
169         boolean justAnotherOne = false;
170
171         if (parsed)
172         {
173             // there are occasions where the compiler may try to parse
174
// a struct type spec for a second time, viz if the struct is
175
// referred to through a scoped name in another struct member.
176
// that's not a problem, but we have to skip parsing again!
177
// (Gerald: introduced together with the fix for bug #84).
178
return;
179         }
180
181         if (logger.isDebugEnabled())
182             logger.debug("Parsing Struct " + name);
183
184         escapeName();
185
186         ConstrTypeSpec ctspec = new ConstrTypeSpec(new_num());
187         try
188         {
189             // important: typeName must be set _before_ a new scope is introduced,
190
// otherwise the typeName for this struct class will be the same
191
// as the package name for the new pseudo scope!
192

193             ScopedName.definePseudoScope(full_name());
194
195             ctspec.c_type_spec = this;
196
197             NameTable.define(full_name(), "type-struct");
198             TypeMap.typedef(full_name(), ctspec);
199         }
200         catch (NameAlreadyDefined nad)
201         {
202             if (exc)
203             {
204                 parser.error("Struct " + getJavaTypeName() + " already defined", token);
205             }
206             else
207             {
208                 if (parser.get_pending (full_name ()) != null)
209                 {
210                     if (memberlist != null)
211                     {
212                         justAnotherOne = true;
213                     }
214
215                     if (!full_name().equals("org.omg.CORBA.TypeCode") && memberlist != null)
216                     {
217                         TypeMap.replaceForwardDeclaration(full_name(), ctspec);
218                     }
219                 }
220                 else
221                 {
222                     parser.error("Struct " + getJavaTypeName() + " already defined", token);
223                 }
224             }
225         }
226         if (memberlist != null)
227         {
228             ScopedName.addRecursionScope(getJavaTypeName());
229             memberlist.parse();
230             ScopedName.removeRecursionScope(getJavaTypeName());
231
232             if (exc == false)
233             {
234                 NameTable.parsed_interfaces.put(full_name(), "");
235                 parser.remove_pending(full_name());
236             }
237         }
238         else if (!justAnotherOne && exc == false)
239         {
240             // i am forward declared, must set myself as
241
// pending further parsing
242
parser.set_pending(full_name());
243         }
244
245         parsed = true;
246     }
247
248     public String JavaDoc className()
249     {
250         String JavaDoc fullName = getJavaTypeName();
251         if (fullName.indexOf('.') > 0)
252         {
253             return fullName.substring(fullName.lastIndexOf('.') + 1);
254         }
255         else
256         {
257             return fullName;
258         }
259     }
260
261     public String JavaDoc printReadExpression(String JavaDoc Streamname)
262     {
263         return toString() + "Helper.read(" + Streamname + ")";
264     }
265
266     public String JavaDoc printWriteStatement(String JavaDoc var_name, String JavaDoc streamname)
267     {
268         return toString() + "Helper.write(" + streamname + "," + var_name + ");";
269     }
270
271     public String JavaDoc holderName()
272     {
273         return getJavaTypeName() + "Holder";
274     }
275
276     /**
277      * @return a string for an expression of type TypeCode that
278      * describes this type
279      */

280
281     public String JavaDoc getTypeCodeExpression()
282     {
283         return full_name() + "Helper.type()";
284     }
285
286     public String JavaDoc getTypeCodeExpression(Set knownTypes)
287     {
288         if (knownTypes.contains(this))
289         {
290             return this.getRecursiveTypeCodeExpression();
291         }
292         else
293         {
294             return this.getTypeCodeExpression();
295         }
296     }
297
298
299     private void printClassComment(String JavaDoc className, PrintWriter JavaDoc ps)
300     {
301         ps.println("/**");
302         ps.println(" *\tGenerated from IDL definition of " +
303                 (exc ? "exception " : "struct ") + "\"" +
304                 className + "\"");
305         ps.println(" *\t@author JacORB IDL compiler ");
306         ps.println(" */\n");
307     }
308
309     private void printHolderClass(String JavaDoc className, PrintWriter JavaDoc ps)
310     {
311         if (Environment.JAVA14 && pack_name.equals(""))
312             lexer.emit_warn
313                 ("No package defined for " + className + " - illegal in JDK1.4", token);
314         if (!pack_name.equals(""))
315             ps.println("package " + pack_name + ";");
316
317         printImport(ps);
318
319         printClassComment(className, ps);
320
321         ps.println("public" + parser.getFinalString() + " class " + className + "Holder");
322         ps.println("\timplements org.omg.CORBA.portable.Streamable");
323         ps.println("{");
324
325         ps.println("\tpublic " + getJavaTypeName() + " value;\n");
326
327         ps.println("\tpublic " + className + "Holder ()");
328         ps.println("\t{");
329         ps.println("\t}");
330
331         ps.println("\tpublic " + className + "Holder(final " + getJavaTypeName() + " initial)");
332         ps.println("\t{");
333         ps.println("\t\tvalue = initial;");
334         ps.println("\t}");
335
336         ps.println("\tpublic org.omg.CORBA.TypeCode _type ()");
337         ps.println("\t{");
338         ps.println("\t\treturn " + getJavaTypeName() + "Helper.type ();");
339         ps.println("\t}");
340
341         ps.println("\tpublic void _read(final org.omg.CORBA.portable.InputStream _in)");
342         ps.println("\t{");
343         ps.println("\t\tvalue = " + getJavaTypeName() + "Helper.read(_in);");
344         ps.println("\t}");
345
346         ps.println("\tpublic void _write(final org.omg.CORBA.portable.OutputStream _out)");
347         ps.println("\t{");
348         ps.println("\t\t" + getJavaTypeName() + "Helper.write(_out, value);");
349         ps.println("\t}");
350
351         ps.println("}");
352     }
353
354
355     private void printHelperClass(String JavaDoc className, PrintWriter JavaDoc ps)
356     {
357         if (Environment.JAVA14 && pack_name.equals(""))
358             lexer.emit_warn
359                 ("No package defined for " + className + " - illegal in JDK1.4", token);
360         if (!pack_name.equals(""))
361             ps.println("package " + pack_name + ";\n");
362
363         printImport(ps);
364
365         printClassComment(className, ps);
366
367         ps.println("public" + parser.getFinalString() + " class " + className + "Helper");
368         ps.println("{");
369         ps.println("\tprivate static org.omg.CORBA.TypeCode _type = null;");
370
371         /* type() method */
372         ps.println("\tpublic static org.omg.CORBA.TypeCode type ()");
373         ps.println("\t{");
374         ps.println("\t\tif (_type == null)");
375         ps.println("\t\t{");
376
377         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
378         sb.append("org.omg.CORBA.ORB.init().create_" +
379                 (exc ? "exception" : "struct") + "_tc(" +
380                 getJavaTypeName() + "Helper.id(),\"" + className() + "\",");
381
382         if (memberlist != null)
383         {
384             sb.append("new org.omg.CORBA.StructMember[]{");
385             for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
386             {
387                 Member m = (Member)e.nextElement();
388                 Declarator d = m.declarator;
389                 sb.append("new org.omg.CORBA.StructMember(\"" + d.name() + "\", ");
390                 sb.append(m.type_spec.typeSpec().getTypeCodeExpression());
391                 sb.append(", null)");
392                 if (e.hasMoreElements())
393                     sb.append(",");
394             }
395             sb.append("}");
396         }
397         else
398         {
399             sb.append("new org.omg.CORBA.StructMember[0]");
400         }
401         sb.append(")");
402
403         ps.println("\t\t\t_type = " + sb.toString() + ";");
404
405         ps.println("\t\t}");
406         ps.println("\t\treturn _type;");
407         ps.println("\t}\n");
408
409         String JavaDoc type = getJavaTypeName();
410         TypeSpec.printInsertExtractMethods(ps, type);
411
412         printIdMethod(ps); // inherited from IdlSymbol
413

414         /* read */
415         ps.println("\tpublic static " + type +
416                     " read (final org.omg.CORBA.portable.InputStream in)");
417         ps.println("\t{");
418         ps.println("\t\t" + type + " result = new " + type + "();");
419         if (exc)
420         {
421             ps.println("\t\tif (!in.read_string().equals(id())) throw new org.omg.CORBA.MARSHAL(\"wrong id\");");
422         }
423         if (memberlist != null)
424         {
425             for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
426             {
427                 Member m = (Member)e.nextElement();
428                 Declarator d = m.declarator;
429                 ps.println("\t\t" + m.type_spec.typeSpec().printReadStatement("result." + d.name(), "in"));
430             }
431         }
432         ps.println("\t\treturn result;");
433         ps.println("\t}");
434
435         /* write */
436         ps.println("\tpublic static void write (final org.omg.CORBA.portable.OutputStream out, final " + type + " s)");
437         ps.println("\t{");
438
439         if (exc)
440         {
441             ps.println("\t\tout.write_string(id());");
442         }
443
444         if (memberlist != null)
445         {
446             for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
447             {
448                 Member m = (Member)e.nextElement();
449                 Declarator d = m.declarator;
450                 ps.println("\t\t" + m.type_spec.typeSpec().printWriteStatement("s." + d.name(), "out"));
451             }
452         }
453         ps.println("\t}");
454         ps.println("}");
455     }
456
457     private void printStructClass(String JavaDoc className, PrintWriter JavaDoc ps)
458     {
459         if (Environment.JAVA14 && pack_name.equals(""))
460             lexer.emit_warn
461                 ("No package defined for " + className + " - illegal in JDK1.4", token);
462         String JavaDoc fullClassName = className;
463
464         if (!pack_name.equals(""))
465         {
466             fullClassName = pack_name + "." + className;
467
468             ps.println("package " + pack_name + ";");
469         }
470
471         printImport(ps);
472
473         printClassComment(className, ps);
474
475         ps.println("public" + parser.getFinalString() + " class " + className);
476         if (exc)
477             ps.println("\textends org.omg.CORBA.UserException");
478         else
479             ps.println("\timplements org.omg.CORBA.portable.IDLEntity");
480
481         ps.println("{");
482
483         // print an empty constructor
484

485         if (exc)
486         {
487             ps.println("\tpublic " + className + "()");
488             ps.println("\t{");
489             ps.println("\t\tsuper(" + fullClassName + "Helper.id());");
490             ps.println("\t}");
491             ps.println();
492
493             if (memberlist == null)
494             {
495                 ps.println("\tpublic " + className + "(String value)");
496                 ps.println("\t{");
497                 ps.println("\t\tsuper(value);");
498                 ps.println("\t}");
499             }
500         }
501         else
502         {
503             ps.println("\tpublic " + className + "(){}");
504         }
505
506         if (memberlist != null)
507         {
508             // print member declarations
509

510             for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
511             {
512                 ((Member)e.nextElement()).member_print(ps, "\tpublic ");
513                 ps.println();
514             }
515
516             // print a constructor for class member initialization
517

518             if (exc)
519             {
520                 // print a constructor for class member initialization
521
// with additional first string parameter
522

523                 ps.print("\tpublic " + className + "(");
524                 ps.print("java.lang.String _reason,");
525                 for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
526                 {
527                     Member m = (Member)e.nextElement();
528                     Declarator d = m.declarator;
529                     ps.print(m.type_spec.toString() + " " + d.toString());
530                     if (e.hasMoreElements())
531                         ps.print(", ");
532                 }
533                 ps.println(")");
534
535                 ps.println("\t{");
536                 ps.println("\t\tsuper(" + fullClassName + "Helper.id()+ \" \" + _reason);");
537                 for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
538                 {
539                     Member m = (Member)e.nextElement();
540                     Declarator d = m.declarator;
541                     ps.print("\t\tthis.");
542                     ps.print(d.name());
543                     ps.print(" = ");
544                     ps.println(d.name() + ";");
545                 }
546                 ps.println("\t}");
547             }
548
549             ps.print("\tpublic " + className + "(");
550             for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
551             {
552                 Member m = (Member)e.nextElement();
553                 Declarator d = m.declarator;
554                 ps.print(m.type_spec.toString() + " " + d.name());
555                 if (e.hasMoreElements())
556                     ps.print(", ");
557             }
558             ps.println(")");
559
560             ps.println("\t{");
561
562             if (exc) // fixes #462
563
ps.println("\t\tsuper(" + fullClassName + "Helper.id());");
564
565             for (Enumeration e = memberlist.v.elements(); e.hasMoreElements();)
566             {
567                 Member m = (Member)e.nextElement();
568                 Declarator d = m.declarator;
569                 ps.print("\t\tthis.");
570                 ps.print(d.name());
571                 ps.print(" = ");
572                 ps.println(d.name() + ";");
573             }
574             ps.println("\t}");
575
576         }
577         ps.println("}");
578     }
579
580     /**
581      * Generates code from this AST class
582      *
583      * @param ps not used, the necessary output streams to classes
584      * that receive code (e.g., helper and holder classes for the
585      * IDL/Java mapping, are created inside this method.
586      */

587
588     public void print(PrintWriter JavaDoc ps)
589     {
590         setPrintPhaseNames();
591
592         if (!parsed)
593         {
594             throw new ParseException ("Unparsed Struct!");
595         }
596
597         // no code generation for included definitions
598
if (included && !generateIncluded())
599         {
600             return;
601         }
602
603         // only generate code once
604

605         if (!written)
606         {
607             // guard against recursive entries, which can happen due to
608
// containments, e.g., an alias within an interface that refers
609
// back to the interface
610
written = true;
611
612             try
613             {
614                 String JavaDoc className = className();
615
616                 String JavaDoc path = parser.out_dir + fileSeparator +
617                     pack_name.replace('.', fileSeparator);
618
619                 File JavaDoc dir = new File JavaDoc(path);
620                 if (!dir.exists())
621                 {
622                     if (!dir.mkdirs())
623                     {
624                         org.jacorb.idl.parser.fatal_error("Unable to create " + path, null);
625                     }
626                 }
627
628                 String JavaDoc fname = className + ".java";
629                 File JavaDoc f = new File JavaDoc(dir, fname);
630
631                 if (GlobalInputStream.isMoreRecentThan(f))
632                 {
633                     // print the mapped java class
634
PrintWriter JavaDoc printWriter = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
635                     printStructClass(className, printWriter);
636                     printWriter.close();
637                 }
638
639                 fname = className + "Holder.java";
640                 f = new File JavaDoc(dir, fname);
641
642                 if (GlobalInputStream.isMoreRecentThan(f))
643                 {
644                     // print the mapped holder class
645
PrintWriter JavaDoc printWriter = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
646                     printHolderClass(className, printWriter);
647                     printWriter.close();
648                 }
649
650                 fname = className + "Helper.java";
651                 f = new File JavaDoc(dir, fname);
652
653                 if (GlobalInputStream.isMoreRecentThan(f))
654                 {
655                     // print the mapped helper class
656
PrintWriter JavaDoc printWriter = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
657                     printHelperClass(className, printWriter);
658                     printWriter.close();
659                 }
660             }
661             catch (java.io.IOException JavaDoc i)
662             {
663                 throw new RuntimeException JavaDoc("File IO error" + i);
664             }
665         }
666     }
667
668     public void accept(IDLTreeVisitor visitor)
669     {
670         visitor.visitStruct(this);
671     }
672 }
673
Popular Tags