KickJava   Java API By Example, From Geeks To Geeks.

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


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

20
21 package org.jacorb.idl;
22
23 import java.io.File JavaDoc;
24 import java.io.PrintWriter JavaDoc;
25
26 /**
27  * IDL sequences.
28  *
29  *
30  * @author Gerald Brose
31  * @version $Id: SequenceType.java,v 1.36 2004/05/06 12:39:58 nicolas Exp $
32  */

33
34 public class SequenceType
35     extends VectorType
36 {
37     private boolean written = false;
38
39     /** used to generate unique name vor local variables */
40     private static int idxNum = 0;
41
42     /** markers for recursive sequences */
43     private boolean recursive = false;
44
45     public ConstExpr max = null;
46     int length = 0;
47
48     public SequenceType(int num)
49     {
50         super(num);
51         name = null;
52         typedefd = false;
53     }
54
55     public Object JavaDoc clone()
56     {
57         SequenceType st = new SequenceType(IdlSymbol.new_num());
58         st.type_spec = this.type_spec;
59         st.max = this.max;
60         st.length = this.length;
61         st.name = this.name;
62         st.pack_name = this.pack_name;
63         st.included = this.included;
64         st.typedefd = this.typedefd;
65         st.recursive = this.recursive;
66         st.set_token(this.get_token());
67         st.setEnclosingSymbol(this.getEnclosingSymbol());
68         return st;
69     }
70
71
72     public void setEnclosingSymbol(IdlSymbol s)
73     {
74         if (enclosing_symbol != null && enclosing_symbol != s)
75             throw new RuntimeException JavaDoc("Compiler Error: trying to reassign container for " + name);
76         enclosing_symbol = s;
77     }
78
79
80     /**
81      * since the sequence type's name depends on a declarator
82      * given in the typedef, the name varilabe has to be set explicitly
83      * by the TypeDef object before this sequence type can
84      * be used.
85      */

86
87     public TypeSpec typeSpec()
88     {
89         return this;
90     }
91
92     public void setPackage(String JavaDoc s)
93     {
94         s = parser.pack_replace(s);
95         if (pack_name.length() > 0)
96             pack_name = s + "." + pack_name;
97         else
98             pack_name = s;
99         type_spec.setPackage(s);
100         if (max != null)
101             max.setPackage(s);
102     }
103
104     /**
105      */

106
107     public int length()
108     {
109         return length;
110     }
111
112
113
114     void setRecursive()
115     {
116         if (logger.isWarnEnabled())
117             logger.warn("Sequence " + typeName +
118                         " set recursive ------- this: " + this);
119         recursive = true;
120     }
121
122     /**
123      * @return a string for an expression of type TypeCode that describes this type
124      */

125
126     public String JavaDoc getTypeCodeExpression()
127     {
128         if (logger.isDebugEnabled())
129             logger.debug("Sequence getTypeCodeExpression " + name);
130
131         String JavaDoc originalType = null;
132
133         if (recursive)
134         {
135             originalType = "org.omg.CORBA.ORB.init().create_sequence_tc(" +
136                 length + ", org.omg.CORBA.ORB.init().create_recursive_tc(\"" +
137                 elementTypeSpec().id() + "\"))";
138         }
139         else
140         {
141             originalType = "org.omg.CORBA.ORB.init().create_sequence_tc(" +
142                 length + ", " + elementTypeExpression() + ")";
143         }
144         return originalType;
145     }
146
147     public static int getNumber()
148     {
149         return idxNum++;
150     }
151
152     /**
153      * We have to distinguish between sequence types that have been
154      * explicitly declared as types with a typedef and those that
155      * are declared as anonymous types in structs or unions. In
156      * the latter case, we have to generate marshalling code in-line
157      * because there are no helpers for anonymous types
158      */

159
160     public String JavaDoc printReadStatement(String JavaDoc var_name, String JavaDoc streamname)
161     {
162         if (logger.isDebugEnabled())
163             logger.debug("Sequence printReadStatement for " + typeName());
164
165         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
166         String JavaDoc type = typeName();
167         String JavaDoc lgt = "_l" + var_name.replace('.', '_');
168
169         // if [i] is part of the name, trim that off
170
if (lgt.indexOf("[") > 0)
171             lgt = lgt.substring(0, lgt.indexOf("[")) + "_";
172
173         // make local variable name unique
174
lgt = lgt + getNumber();
175
176         sb.append("int " + lgt + " = " + streamname + ".read_long();\n");
177         if (length != 0)
178         {
179             sb.append("\t\tif (" + lgt + " > " + length + ")\n");
180             sb.append("\t\t\tthrow new org.omg.CORBA.MARSHAL(\"Sequence length incorrect!\");\n");
181         }
182         sb.append("\t\t" + var_name + " = new " + type.substring(0, type.indexOf("[")) +
183                   "[" + lgt + "]" + type.substring(type.indexOf("]") + 1) + ";\n");
184
185         if (elementTypeSpec() instanceof BaseType &&
186             !(elementTypeSpec() instanceof AnyType))
187         {
188             String JavaDoc _tmp = elementTypeSpec().printReadExpression(streamname);
189             sb.append("\t" + _tmp.substring(0, _tmp.indexOf("(")) +
190                       "_array(" + var_name + ",0," + lgt + ");");
191         }
192         else
193         {
194             char idx_variable = 'i';
195             String JavaDoc indent = "";
196             if (var_name.endsWith("]"))
197             {
198                 idx_variable = (char)(var_name.charAt(var_name.length() - 2) + 1);
199                 indent = " ";
200             }
201             sb.append("\t\t" + indent + "for (int " + idx_variable + "=0;" +
202                       idx_variable + "<" + var_name + ".length;" + idx_variable + "++)\n\t\t" + indent + "{\n");
203
204             sb.append("\t\t\t" + indent +
205                       elementTypeSpec().printReadStatement(var_name +
206                                                            "[" + idx_variable + "]",
207                                                            streamname)
208                       + "\n");
209
210             sb.append("\t\t" + indent + "}\n");
211
212         }
213         return sb.toString();
214     }
215
216
217     public String JavaDoc printWriteStatement(String JavaDoc var_name, String JavaDoc streamname)
218     {
219         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
220         String JavaDoc type = typeName();
221         if (length != 0)
222         {
223             sb.append("\t\tif (" + var_name + ".length > " + length + ")\n");
224             sb.append("\t\t\tthrow new org.omg.CORBA.MARSHAL(\"Incorrect sequence length\");");
225         }
226         sb.append("\n\t\t" + streamname + ".write_long(" + var_name + ".length);\n");
227
228         if (elementTypeSpec() instanceof BaseType &&
229             !(elementTypeSpec() instanceof AnyType))
230         {
231             String JavaDoc _tmp = elementTypeSpec().printWriteStatement(var_name, streamname);
232             sb.append("\t\t" + _tmp.substring(0, _tmp.indexOf("(")) + "_array(" +
233                       var_name + ",0," + var_name + ".length);");
234         }
235         else
236         {
237             char idx_variable = 'i';
238             String JavaDoc indent = "";
239             if (var_name.endsWith("]"))
240             {
241                 idx_variable = (char)(var_name.charAt(var_name.length() - 2) + 1);
242                 indent = " ";
243             }
244             sb.append("\t\t" + indent + "for (int " + idx_variable + "=0; " +
245                       idx_variable + "<" + var_name + ".length;" +
246                       idx_variable + "++)\n\t\t" + indent + "{\n");
247
248             sb.append("\t\t\t" + indent +
249                       elementTypeSpec().printWriteStatement(var_name
250                                                             + "[" + idx_variable + "]",
251                                                             streamname) + "\n");
252             sb.append("\t\t" + indent + "}\n");
253         }
254         return sb.toString();
255     }
256
257
258     public String JavaDoc holderName()
259     {
260         if (!typedefd)
261             throw new RuntimeException JavaDoc("Compiler Error: should not be called (helpername on not typedef'd SequenceType " + name + ")");
262
263         String JavaDoc s = full_name();
264         if (pack_name.length() > 0)
265         {
266             if (!s.startsWith("org.omg"))
267             {
268                 s = omg_package_prefix + s;
269             }
270         }
271
272         return s + "Holder";
273     }
274
275
276     public String JavaDoc helperName()
277     {
278         if (!typedefd)
279             throw new RuntimeException JavaDoc("Compiler Error: should not be called (helperName() on not typedef'd SequenceType)");
280
281         String JavaDoc s = full_name();
282         if (pack_name.length() > 0)
283         {
284             if (!s.startsWith("org.omg"))
285             {
286                 s = omg_package_prefix + s;
287             }
288         }
289
290         return s + "Helper";
291     }
292
293     public String JavaDoc className()
294     {
295         String JavaDoc fullName = full_name();
296         String JavaDoc cName;
297         if (fullName.indexOf('.') > 0)
298         {
299             pack_name = fullName.substring(0, fullName.lastIndexOf('.'));
300             cName = fullName.substring(fullName.lastIndexOf('.') + 1);
301         }
302         else
303         {
304             pack_name = "";
305             cName = fullName;
306         }
307         return cName;
308
309     }
310
311     /**
312      * The parsing phase.
313      */

314
315     public void parse()
316     {
317         if (max != null)
318         {
319             max.parse();
320             length = Integer.parseInt(max.value());
321
322         }
323
324         if (type_spec.typeSpec() instanceof ScopedName)
325         {
326             TypeSpec ts =
327                 ((ScopedName)type_spec.typeSpec()).resolvedTypeSpec();
328             if (ts != null)
329                 type_spec = ts;
330
331             if (type_spec instanceof AliasTypeSpec)
332                 addImportedAlias(type_spec.full_name());
333             else
334                 addImportedName(type_spec.typeName());
335
336             addImportedName(type_spec.typeSpec().typeName());
337         }
338         try
339         {
340             NameTable.define(full_name(), "type");
341         }
342         catch (NameAlreadyDefined n)
343         {
344             // ignore, sequence types can be defined a number
345
// of times under different names
346
}
347     }
348
349     public String JavaDoc full_name()
350     {
351         if (name == null)
352         {
353             return "<" + pack_name + ".anon>";
354         }
355         if (pack_name.length() > 0)
356             return ScopedName.unPseudoName(pack_name + "." + name);
357         else
358             return ScopedName.unPseudoName(name);
359     }
360
361
362     private void printClassComment(String JavaDoc className, PrintWriter JavaDoc ps)
363     {
364         ps.println("/**");
365         ps.println(" *\tGenerated from IDL definition of sequence" +
366                    "\"" + className + "\"");
367         ps.println(" *\t@author JacORB IDL compiler ");
368         ps.println(" */\n");
369     }
370
371     private void printHolderClass(String JavaDoc className, PrintWriter JavaDoc ps)
372     {
373         if (Environment.JAVA14 && pack_name.equals(""))
374             lexer.emit_warn
375                 ("No package defined for " + className + " - illegal in JDK1.4", token);
376         if (!pack_name.equals(""))
377             ps.println("package " + pack_name + ";\n");
378
379         String JavaDoc type = typeName();
380
381         printImport(ps);
382
383         printClassComment(className, ps);
384
385         ps.println("public" + parser.getFinalString() + " class " + className + "Holder");
386         ps.println("\timplements org.omg.CORBA.portable.Streamable");
387
388         ps.println("{");
389         ps.println("\tpublic " + type + " value;");
390         ps.println("\tpublic " + className + "Holder ()");
391         ps.println("\t{");
392         ps.println("\t}");
393
394         ps.println("\tpublic " + className + "Holder (final " + type + " initial)\n\t{");
395         ps.println("\t\tvalue = initial;");
396         ps.println("\t}");
397
398         ps.println("\tpublic org.omg.CORBA.TypeCode _type ()");
399         ps.println("\t{");
400         ps.println("\t\treturn " + className + "Helper.type ();");
401         ps.println("\t}");
402
403         ps.println("\tpublic void _read (final org.omg.CORBA.portable.InputStream _in)");
404         ps.println("\t{");
405         ps.println("\t\tvalue = " + className + "Helper.read (_in);");
406         ps.println("\t}");
407
408         ps.println("\tpublic void _write (final org.omg.CORBA.portable.OutputStream _out)");
409         ps.println("\t{");
410         ps.println("\t\t" + className + "Helper.write (_out,value);");
411         ps.println("\t}");
412
413         ps.println("}");
414     }
415
416
417     private void printHelperClass(String JavaDoc className, PrintWriter JavaDoc ps)
418     {
419         if (Environment.JAVA14 && pack_name.equals(""))
420             lexer.emit_warn
421                 ("No package defined for " + className + " - illegal in JDK1.4", token);
422         if (!pack_name.equals(""))
423             ps.println("package " + pack_name + ";");
424
425         String JavaDoc type = typeName();
426         printImport(ps);
427
428         printClassComment(className, ps);
429
430         ps.println("public" + parser.getFinalString() + " class " + className + "Helper");
431         ps.println("{");
432         ps.println("\tprivate static org.omg.CORBA.TypeCode _type = " +
433                    getTypeCodeExpression() + ";");
434
435         TypeSpec.printHelperClassMethods(ps, type);
436         printIdMethod(ps); // from IdlSymbol
437

438         /** read */
439
440         ps.println("\tpublic static " + type +
441                    " read (final org.omg.CORBA.portable.InputStream in)");
442
443         ps.println("\t{");
444         ps.println("\t\tint l = in.read_long();");
445
446         if (length != 0)
447         {
448             ps.println("\t\tif (l > " + length + ")");
449             ps.println("\t\t\tthrow new org.omg.CORBA.MARSHAL();");
450         }
451
452         ps.println("\t\t" + type + " result = new " +
453                    type.substring(0, type.indexOf("[")) + "[l]" +
454                    type.substring(type.indexOf("]") + 1) + ";");
455
456         if (elementTypeSpec() instanceof BaseType &&
457             !(elementTypeSpec() instanceof AnyType))
458         {
459             String JavaDoc _tmp = elementTypeSpec().printReadExpression("in");
460             ps.println("\t\t" + _tmp.substring(0, _tmp.indexOf("(")) +
461                        "_array(result,0,result.length);");
462         }
463         else
464         {
465             ps.println("\t\tfor (int i = 0; i < l; i++)");
466             ps.println("\t\t{");
467             ps.println("\t\t\t" + elementTypeSpec().printReadStatement("result[i]", "in"));
468             ps.println("\t\t}");
469         }
470
471         ps.println("\t\treturn result;");
472         ps.println("\t}");
473
474         /* write */
475
476         ps.println("\tpublic static void write (final org.omg.CORBA.portable.OutputStream out, "
477                    + "final " + type + " s)");
478         ps.println("\t{");
479         if (length != 0)
480         {
481             ps.println("\t\tif (s.length > " + length + ")");
482             ps.println("\t\t\tthrow new org.omg.CORBA.MARSHAL();");
483         }
484         ps.println("\t\tout.write_long(s.length);");
485
486         if (elementTypeSpec() instanceof BaseType &&
487             !(elementTypeSpec() instanceof AnyType))
488         {
489             String JavaDoc _tmp = elementTypeSpec().printWriteStatement("s", "out");
490             ps.println(_tmp.substring(0, _tmp.indexOf("(")) + "_array(s,0,s.length);");
491         }
492         else
493         {
494             ps.println("\t\tfor (int i = 0; i < s.length; i++)");
495             ps.println("\t\t\t" + elementTypeSpec().printWriteStatement("s[i]", "out"));
496         }
497
498         ps.println("\t}");
499         ps.println("}");
500     }
501
502
503     public void print(PrintWriter JavaDoc _ps)
504     {
505         try
506         {
507             // only generate class files for explicitly
508
// defined sequence types, i.e. for typedef'd ones
509

510             if ((!written) && typedefd)
511             {
512
513                 // write holder file
514

515                 String JavaDoc fullName = full_name();
516                 String JavaDoc className;
517                 if (fullName.indexOf('.') > 0)
518                 {
519                     pack_name = fullName.substring(0, fullName.lastIndexOf('.'));
520                     className = fullName.substring(fullName.lastIndexOf('.') + 1);
521                 }
522                 else
523                 {
524                     pack_name = "";
525                     className = fullName;
526                 }
527
528                 String JavaDoc path = parser.out_dir + fileSeparator +
529                     pack_name.replace('.', fileSeparator);
530
531                 File JavaDoc dir = new File JavaDoc(path);
532                 if (!dir.exists())
533                 {
534                     if (!dir.mkdirs())
535                     {
536                         org.jacorb.idl.parser.fatal_error("Unable to create " +
537                                                           path, null);
538                     }
539                 }
540
541                 String JavaDoc fname = className + "Holder.java";
542                 File JavaDoc f = new File JavaDoc(dir, fname);
543
544                 if (GlobalInputStream.isMoreRecentThan(f))
545                 {
546                     // print the mapped java class
547
PrintWriter JavaDoc ps = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
548                     printHolderClass(className, ps);
549                     ps.close();
550                 }
551
552                 fname = className + "Helper.java";
553                 f = new File JavaDoc(dir, fname);
554
555                 if (GlobalInputStream.isMoreRecentThan(f))
556                 {
557                     // print the mapped java class
558
PrintWriter JavaDoc ps = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
559                     printHelperClass(className, ps);
560                     ps.close();
561                 }
562
563                 written = true;
564             }
565         }
566         catch (java.io.IOException JavaDoc i)
567         {
568             throw new RuntimeException JavaDoc("File IO error" + i);
569         }
570     }
571 }
572
Popular Tags