KickJava   Java API By Example, From Geeks To Geeks.

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


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  * @author Gerald Brose <mailto:gerald.brose@acm.org>
28  * @version $Id: ArrayTypeSpec.java,v 1.30 2005/03/28 19:58:29 brose Exp $
29  *
30  */

31
32 public class ArrayTypeSpec
33     extends VectorType
34 {
35     ArrayDeclarator declarator = null;
36     String JavaDoc typename = null;
37     String JavaDoc dimensionStr = "";
38     int[] dims = null;
39     int my_dim = 0;
40     String JavaDoc typeSig;
41
42     private boolean written = false;
43
44     public ArrayTypeSpec(int num, TypeSpec elem,
45                          ArrayDeclarator ad, String JavaDoc pack_name)
46     {
47         super(num);
48         declarator = ad;
49         name = declarator.name();
50         set_token(ad.get_token());
51         setEnclosingSymbol(ad.getEnclosingSymbol());
52         this.pack_name = pack_name;
53         type_spec = elem;
54
55         if (logger.isDebugEnabled())
56             logger.debug("ArrayTypeSpec with declarator " + ad.name());
57
58     }
59
60     /**
61      * private constructor, only to be called from public constructor for
62      * multi-dimensional arrays, i.e. nested arrays. Used to create
63      * nested ArrayTypeSpecs
64      */

65
66     private ArrayTypeSpec(int num,
67                           TypeSpec elem,
68                           ArrayDeclarator ad,
69                           String JavaDoc pack_name,
70                           int my_dim)
71     {
72         super(num);
73         declarator = ad;
74         name = declarator.name();
75         dims = declarator.dimensions();
76         set_token(ad.get_token());
77         setEnclosingSymbol(ad.getEnclosingSymbol());
78         this.pack_name = pack_name;
79         this.my_dim = my_dim;
80         if (dims.length > my_dim + 1)
81         {
82             type_spec =
83                 new ArrayTypeSpec(new_num(), elem, ad, pack_name, my_dim + 1);
84         }
85         else
86             type_spec = elem;
87
88         // needs to be done here because nested array type specs are not parsed
89
StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
90         for (int i = my_dim; i < dims.length; i++)
91         {
92             sb.append("[]");
93         }
94         dimensionStr = sb.toString();
95     }
96
97     /**
98      * clone this ArrayTypeSpec. The cloned object will not be parsed again.
99      */

100
101     public Object JavaDoc clone()
102     {
103         ArrayTypeSpec st =
104             new ArrayTypeSpec(new_num(), type_spec, declarator, pack_name);
105         st.dims = this.dims;
106         st.included = this.included;
107         st.typedefd = this.typedefd;
108         st.inhibitionFlag = this.inhibitionFlag;
109         st.dims = dims;
110         st.my_dim = my_dim;
111         st.dimensionStr = this.dimensionStr;
112         st.set_token(get_token());
113         st.setEnclosingSymbol(getEnclosingSymbol());
114         return st;
115     }
116
117     public void setEnclosingSymbol(IdlSymbol s)
118     {
119         if (enclosing_symbol != null && enclosing_symbol != s)
120             throw new RuntimeException JavaDoc("Compiler Error: trying to reassign container for " + name);
121         enclosing_symbol = s;
122     }
123
124
125     public TypeSpec typeSpec()
126     {
127         return this;
128     }
129
130     public void setPackage(String JavaDoc s)
131     {
132         s = parser.pack_replace(s);
133         throw new RuntimeException JavaDoc("ArrayTypeSpec.setPackage should never be called!");
134     }
135
136     /**
137      * we have to be able to distinguish between explicitly typedef'd
138      * type names and anonymously defined type names
139      */

140
141     public void markTypeDefd()
142     {
143         typedefd = true;
144     }
145
146     public void parse()
147         throws ParseException
148     {
149         if (logger.isDebugEnabled())
150             logger.debug("ArrayTypeSpec.parse " + declarator.name());
151
152         dims = declarator.dimensions();
153         if (dims.length > 1)
154         {
155             type_spec =
156                 new ArrayTypeSpec(new_num(), type_spec, declarator, pack_name, 1);
157         }
158         else if (type_spec.typeSpec() instanceof ConstrTypeSpec)
159         {
160             // locally defined, nested structs must be parsed (fixes
161
// bug #84) This will also result in an attempt to parse
162
// structs referred to through a scoped name in struct
163
// members, which have been inlined earlier in
164
// Member.java. Not a problem, structs will skip a second
165
// parse attempt.
166
type_spec.parse();
167         }
168         else if (type_spec.typeSpec() instanceof ScopedName)
169         {
170             TypeSpec ts = ((ScopedName)type_spec.typeSpec()).resolvedTypeSpec();
171             if (ts != null)
172                 type_spec = ts;
173         }
174
175         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
176
177         for (int i = my_dim; i < dims.length; i++)
178             sb.append("[]");
179
180         dimensionStr = sb.toString();
181
182         try
183         {
184             if (!typedefd)
185                 NameTable.define(full_name(), "type");
186
187             if (!NameTable.isDefined(typeName(), "type"))
188                 NameTable.define(typeName(), "type");
189         }
190         catch (NameAlreadyDefined n)
191         {
192             parser.fatal_error("Name " + full_name() + " already defined.", null);
193         }
194     }
195
196     /**
197      * @return a string for an expression of type TypeCode that
198      * describes this type
199      *
200      * Array and sequence types always have this expression inlined in
201      * their containing classes because arrays and sequences can be
202      * locally defined (e,g, in a struct) without there being helper
203      * classes (so Helper.type() is not an option)
204      */

205
206     public String JavaDoc getTypeCodeExpression()
207     {
208         String JavaDoc originalType =
209             "org.omg.CORBA.ORB.init().create_array_tc(" + dims[ my_dim ] + ","
210             + elementTypeSpec().getTypeCodeExpression() + ")";
211
212         return originalType;
213     }
214
215     public String JavaDoc helperName()
216     {
217         return ScopedName.unPseudoName(full_name()) + "Helper";
218     }
219
220     public String JavaDoc holderName()
221     {
222         return ScopedName.unPseudoName(full_name()) + "Holder";
223     }
224
225     public String JavaDoc className()
226     {
227         String JavaDoc fullName;
228
229         if (pack_name.length() > 0)
230             fullName = ScopedName.unPseudoName(pack_name + "." + name);
231         else
232             fullName = ScopedName.unPseudoName(name);
233
234         String JavaDoc cName;
235         if (fullName.indexOf('.') > 0)
236         {
237             pack_name = fullName.substring(0, fullName.lastIndexOf('.'));
238             cName = fullName.substring(fullName.lastIndexOf('.') + 1);
239         }
240         else
241         {
242             pack_name = "";
243             cName = fullName;
244         }
245         return cName;
246
247     }
248
249     /**
250      */

251
252     public int length()
253     {
254         return dims[ my_dim ];
255     }
256
257
258     public String JavaDoc printReadStatement(String JavaDoc var_name, String JavaDoc streamname)
259     {
260         if (logger.isWarnEnabled())
261             logger.warn("Array printReadStatement");
262
263         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
264         String JavaDoc type = typeName();
265
266         sb.append(var_name + " = new " + type.substring(0, type.indexOf("[")));
267         sb.append("[" + length() + "]");
268
269         sb.append(type.substring(type.indexOf(']') + 1) + ";\n");
270
271
272         if (elementTypeSpec() instanceof BaseType &&
273             !(elementTypeSpec() instanceof AnyType))
274         {
275             String JavaDoc _tmp = elementTypeSpec().printReadExpression(streamname);
276             sb.append("\t\t" + _tmp.substring(0, _tmp.indexOf("(")) +
277                       "_array(" + var_name + ",0," + length() + ");");
278         }
279         else
280         {
281             char idx_variable = 'i';
282             String JavaDoc indent = "";
283             if (var_name.endsWith("]"))
284             {
285                 idx_variable = (char)(var_name.charAt(var_name.length() - 2) + 1);
286                 indent = " ";
287             }
288             sb.append("\t\t" + indent + "for (int " + idx_variable + "=0;" +
289                       idx_variable + "<" + length() + ";" + idx_variable + "++)\n\t\t" + indent + "{\n");
290
291             sb.append("\t\t\t" + indent +
292                       elementTypeSpec().printReadStatement(var_name +
293                                                            "[" + idx_variable + "]", streamname) + "\n");
294             sb.append("\t\t" + indent + "}\n");
295         }
296         return sb.toString();
297     }
298
299     public String JavaDoc printWriteStatement(String JavaDoc var_name, String JavaDoc streamname)
300     {
301         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
302         String JavaDoc type = typeName();
303         sb.append("\t\tif (" + var_name + ".length<" + length() +
304                   ")\n\t\t\tthrow new org.omg.CORBA.MARSHAL(\"Incorrect array size \"+" +
305                   var_name + ".length+\", expecting " + length() + "\");\n");
306
307         if (elementTypeSpec() instanceof BaseType &&
308             !(elementTypeSpec() instanceof AnyType))
309         {
310             String JavaDoc _tmp = elementTypeSpec().printWriteStatement(var_name, streamname);
311             sb.append("\t\t" + _tmp.substring(0, _tmp.indexOf("(")) +
312                       "_array(" + var_name + ",0," + length() + ");");
313         }
314         else
315         {
316             char idx_variable = 'i';
317             String JavaDoc indent = "";
318             if (var_name.endsWith("]"))
319             {
320                 idx_variable = (char)(var_name.charAt(var_name.length() - 2) + 1);
321                 indent = " ";
322             }
323             sb.append("\t\t" + indent + "for (int " + idx_variable + "=0; " + idx_variable + "<" + length() + ";" + idx_variable + "++)\n\t\t" + indent + "{\n");
324             sb.append("\t\t\t" + indent + elementTypeSpec().printWriteStatement(var_name
325                                                                                 + "[" + idx_variable + "]", streamname) + "\n");
326             sb.append("\t\t" + indent + "}\n");
327         }
328         return sb.toString();
329     }
330
331
332     private void printHolderClass(String JavaDoc className, PrintWriter JavaDoc ps)
333     {
334         if (Environment.JAVA14 && pack_name.equals(""))
335             lexer.emit_warn
336                 ("No package defined for " + className + " - illegal in JDK1.4", token);
337         if (!pack_name.equals(""))
338             ps.println("package " + pack_name + ";\n");
339
340         String JavaDoc type = typeName();
341
342         ps.println("public" + parser.getFinalString() + " class " + className + "Holder");
343         ps.println("\timplements org.omg.CORBA.portable.Streamable");
344
345         ps.println("{");
346         ps.println("\tpublic " + type + " value;");
347         ps.println("\tpublic " + className + "Holder ()");
348         ps.println("\t{");
349         ps.println("\t}");
350
351         ps.println("\tpublic " + className + "Holder (final " + type + " initial)\n\t{");
352         ps.println("\t\tvalue = initial;");
353         ps.println("\t}");
354
355         ps.println("\tpublic org.omg.CORBA.TypeCode _type ()");
356         ps.println("\t{");
357         ps.println("\t\treturn " + className + "Helper.type ();");
358         ps.println("\t}");
359
360         TypeSpec m = type_spec;
361
362         ps.println("\tpublic void _read (final org.omg.CORBA.portable.InputStream _in)");
363         ps.println("\t{");
364         ps.println("\t\tvalue = " + className + "Helper.read (_in);");
365         ps.println("\t}");
366
367         ps.println("\tpublic void _write (final org.omg.CORBA.portable.OutputStream _out)");
368         ps.println("\t{");
369         ps.println("\t\t" + className + "Helper.write (_out,value);");
370         ps.println("\t}");
371
372         ps.println("}");
373     }
374
375
376     private void printHelperClass(String JavaDoc className, PrintWriter JavaDoc ps)
377     {
378         if (Environment.JAVA14 && pack_name.equals(""))
379             lexer.emit_warn
380                 ("No package defined for " + className + " - illegal in JDK1.4", token);
381         if (!pack_name.equals(""))
382             ps.println("package " + pack_name + ";");
383
384         String JavaDoc type = typeName();
385
386         ps.println("public" + parser.getFinalString() + " class " + className + "Helper");
387         ps.println("{");
388
389         ps.println("\tprivate static org.omg.CORBA.TypeCode _type = " +
390                    getTypeCodeExpression() + ";");
391         TypeSpec.printHelperClassMethods(ps, type);
392         printIdMethod(ps);
393
394         /* read */
395
396         ps.println("\tpublic static " + type +
397                    " read (final org.omg.CORBA.portable.InputStream _in)");
398         ps.println("\t{");
399
400         ps.print("\t\t" + type + " result = new " +
401                  type.substring(0, type.indexOf('[')) + "[" + length() + "]");
402
403         ps.println(type.substring(type.indexOf(']')+1) + "; // " + type);
404
405
406         if (elementTypeSpec() instanceof BaseType &&
407             !(elementTypeSpec() instanceof AnyType))
408         {
409             String JavaDoc _tmp = elementTypeSpec().printReadExpression("_in");
410             ps.println("\t\t" + _tmp.substring(0, _tmp.indexOf("(")) +
411                        "_array(result,0," + length() + ");");
412         }
413         else
414         {
415             ps.println("\t\tfor (int i = 0; i < " + length() + "; i++)\n\t\t{");
416             ps.println("\t\t\t" + elementTypeSpec().printReadStatement("result[i]", "_in") + "\n\t\t}");
417         }
418         ps.println("\t\treturn result;");
419         ps.println("\t}");
420
421         /* write */
422
423         ps.println("\tpublic static void write (final org.omg.CORBA.portable.OutputStream out, final " + type + " s)");
424         ps.println("\t{");
425         if (declarator.dimensions()[ 0 ] != 0)
426         {
427             ps.println("\t\tif (s.length != " + declarator.dimensions()[ 0 ] + ")");
428             ps.println("\t\t\tthrow new org.omg.CORBA.MARSHAL(\"Incorrect array size\");");
429         }
430         if (elementTypeSpec() instanceof BaseType &&
431             !(elementTypeSpec() instanceof AnyType))
432         {
433             String JavaDoc _tmp = elementTypeSpec().printWriteStatement("s", "out");
434             ps.println("\t\t" + _tmp.substring(0, _tmp.indexOf("(")) + "_array(s,0," + length() + ");");
435         }
436         else
437         {
438             ps.println("\t\tfor (int i = 0; i < s.length; i++)\n\t\t{");
439             ps.println("\t\t\t" + elementTypeSpec().printWriteStatement("s[i]", "out") + "\n\t\t}");
440         }
441         ps.println("\t}");
442         ps.println("}");
443     }
444
445
446     public void print(PrintWriter JavaDoc _ps)
447     {
448         if (included && !generateIncluded())
449             return; // no code generation
450

451         try
452         {
453             // print the element type, may be a locally defined member type, e.g.
454
// a struct member type
455
type_spec.print(_ps);
456
457             // only generate class files for explicitly
458
// defined sequence types, i.e. for typedef'd ones
459

460             if ((!written) && typedefd)
461             {
462                 // write holder file
463

464                 String JavaDoc className = className();
465                 String JavaDoc path = parser.out_dir + fileSeparator + pack_name.replace('.', fileSeparator);
466                 File JavaDoc dir = new File JavaDoc(path);
467                 if (!dir.exists())
468                 {
469                     if (!dir.mkdirs())
470                     {
471                         org.jacorb.idl.parser.fatal_error("Unable to create " + path, null);
472                     }
473                 }
474
475                 String JavaDoc fname = className + "Holder.java";
476                 File JavaDoc f = new File JavaDoc(dir, fname);
477
478                 if (GlobalInputStream.isMoreRecentThan(f))
479                 {
480                     // print the mapped java class
481
PrintWriter JavaDoc ps = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
482                     printHolderClass(className, ps);
483                     ps.close();
484                 }
485
486                 fname = className + "Helper.java";
487                 f = new File JavaDoc(dir, fname);
488
489                 if (GlobalInputStream.isMoreRecentThan(f))
490                 {
491                     // print the mapped java class
492
PrintWriter JavaDoc ps = new PrintWriter JavaDoc(new java.io.FileWriter JavaDoc(f));
493                     printHelperClass(className, ps);
494                     ps.close();
495                 }
496
497                 written = true;
498             }
499         }
500         catch (java.io.IOException JavaDoc i)
501         {
502             throw new RuntimeException JavaDoc("File IO error" + i);
503         }
504     }
505 }
506
Popular Tags