View Javadoc
1   /*
2    * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  /*
26   * COMPONENT_NAME: idl.toJava
27   *
28   * ORIGINS: 27
29   *
30   * Licensed Materials - Property of IBM
31   * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
32   * RMI-IIOP v1.0
33   *
34   */
35  
36  package com.sun.tools.corba.se.idl.toJavaPortable;
37  
38  // NOTES:
39  // -09/23/98 KLR Ported -m updates (F46838.1-3)
40  // -f46082.51<daz> Transferred makefile list generation (for ODE delta-builds,
41  //  see f46838) to toJava; cleaned-out dead code.
42  // -D58319<daz> Display version info. for -version option.
43  // -D58951<daz> Modify to allow QuickTest to build.
44  // -D49526<daz> Remove "TypeCode" symbol from preParse().
45  // -D58591<daz> Publicise _factories and compile for QuickTest.  Need to revert
46  //  t0 private and add accessor methods.
47  // -D59437<daz> Fill typename information for value boxes.
48  
49  import java.io.File;
50  import java.io.IOException;
51  import java.io.BufferedWriter;
52  import java.io.FileWriter;
53  import java.io.PrintWriter;
54  
55  import java.util.Enumeration;
56  import java.util.Hashtable;
57  import java.util.Vector;
58  
59  import com.sun.tools.corba.se.idl.GenFileStream;
60  import com.sun.tools.corba.se.idl.SymtabFactory;
61  import com.sun.tools.corba.se.idl.IncludeEntry;
62  import com.sun.tools.corba.se.idl.InterfaceEntry;
63  import com.sun.tools.corba.se.idl.InterfaceState;
64  import com.sun.tools.corba.se.idl.ModuleEntry;
65  import com.sun.tools.corba.se.idl.PrimitiveEntry;
66  import com.sun.tools.corba.se.idl.SequenceEntry;
67  import com.sun.tools.corba.se.idl.StructEntry;
68  import com.sun.tools.corba.se.idl.SymtabEntry;
69  import com.sun.tools.corba.se.idl.TypedefEntry;
70  import com.sun.tools.corba.se.idl.UnionBranch;
71  import com.sun.tools.corba.se.idl.UnionEntry;
72  import com.sun.tools.corba.se.idl.ValueEntry;
73  import com.sun.tools.corba.se.idl.ValueBoxEntry;
74  import com.sun.tools.corba.se.idl.InvalidArgument;
75  
76  /**
77   * Compiler usage:
78   * <br><br>
79   *
80   * java com.sun.tools.corba.se.idl.toJavaPortable.Compile [options] &lt;idl file&gt;
81   * <br><br>
82   *
83   * where &lt;idl file&gt; is the name of a file containing IDL definitions,
84   * and [options] is any combination of the options listed below.  The options
85   * may appear in any order.
86   * <br><br>
87   *
88   * Options:
89   * <dl>
90   *   <dt>-i &lt;include path&gt;
91   *   <dd>By default, the current directory is scanned for included files.
92   *   This option adds another directory.  See also the note below.
93   *
94   *   <dt>-d &lt;symbol&gt;
95   *   <dd>This is equivalent to the following line in an IDL file:
96   *   #define &lt;symbol&gt;
97   *
98   *   <dt>-f<side>
99   *   <dd>Defines what bindings to emit.  <side> is one of client, server, all,
100  *   serverTIE, allTIE.  serverTIE and allTIE cause delegate model skeletons
101  *   to be emitted. If this flag is not used, -fclient is assumed.
102  *   allPOA has the same effect as all, except for generation POA type skeletons.
103  *
104  *   <dt>-keep
105  *   <dd>If a file to be generated already exists, do not overwrite it. By
106  *   default it is overwritten.
107  *
108  *   <dt>-sep <string>
109  *   <dd>Only valid with -m.  Replace the file separator character with
110  *     <string> in the file names listed in the .u file.
111  *
112  *   <dt>-emitAll
113  *   <dd>Emit all types, including those found in #included files.
114  *
115  *   <dt>-v
116  *   <dd>Verbose mode.
117  *
118  *   <dt>-pkgPrefix <type> <package>
119  *   <dd>Whereever <type> is encountered, make sure it resides within
120  *   &lt;package&gt; in all generated files.  &lt;type&gt; is a fully
121  *   qualified, java-style name.
122  * </dl>
123  *
124  * <B>Note:</B> If you have an include path or paths that you will always
125  * be using, it can get tedious putting these on the command with the -i
126  * option all the time.  Instead, these can be placed into a config file
127  * called idl.config.  This file must be in the CLASSPATH.  The format of
128  * the includes line is:
129  *
130  * <pre>
131  * includes=<path1>;<path2>;...;<pathN>
132  * </pre>
133  *
134  * Note that the path separator character, here shown as a semicolon,
135  * is machine dependent.  For instance, on Windows 95 this character
136  * is a semicolon, on UNIX it is a colon.
137  **/
138 public class Compile extends com.sun.tools.corba.se.idl.Compile
139 {
140  /**
141   *
142   **/
143   public static void main (String[] args)
144   {
145     compiler = new Compile ();
146     compiler.start (args);
147   } // main
148 
149  /**
150   *
151   **/
152   public void start (String[] args)
153   {
154     try
155     {
156       // <f46082.51> Use generator-specific messages file.
157       //Util.registerMessageFile ("com/sun/corba/se/idl/toJavaPortable/toJava.prp");
158       Util.registerMessageFile ("com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp");
159       init (args);
160       if (arguments.versionRequest)
161         displayVersion ();
162       else
163       {
164         preParse ();
165         Enumeration e = parse ();
166         if (e != null)
167         {
168           preEmit (e);
169           generate ();
170           // <f46082.03> Move ODE delta-build support to toJava
171           //if (((Arguments)arguments).genMakefileLists)
172           //  generateMakefileLists ();
173         }
174       }
175     }
176     catch (InvalidArgument e)
177     {
178       System.err.println (e);
179     }
180     catch (IOException e)
181     {
182       System.err.println (e);
183     }
184   } // start
185 
186   /**
187    *
188    **/
189   protected Compile ()
190   {
191     factory = factories ().symtabFactory ();
192   } // ctor
193 
194   // <d58591> _factories was made public for QuickTest to operate correctly,
195   // but the code needs to be changed to this:
196   //private Factories _factories = null;
197   //protected com.sun.tools.corba.se.idl.Factories factories ()
198   //{
199   //  if (_factories == null)
200   //    _factories = new Factories ();
201   //  return _factories;
202   //} // factories
203 
204   public Factories _factories = new Factories ();  // 58974 - changed for quicktest
205   protected com.sun.tools.corba.se.idl.Factories factories ()
206   {
207     return _factories;
208   } // factories
209 
210 
211   ModuleEntry org;
212   ModuleEntry omg;
213   ModuleEntry corba;
214   InterfaceEntry object;
215 
216   /**
217    *
218    **/
219   protected void preParse ()
220   {
221     Util.setSymbolTable (symbolTable);
222     Util.setPackageTranslation( ((Arguments)arguments).packageTranslation ) ;
223 
224     // Need modules for the predefined objects
225     org = factory.moduleEntry ();
226     // <d61919> Suppress generation of this module.  If the parser reopens it
227     // while parsing the main IDL source, any definitions appearing in the module
228     // -- and not appearing in a global-scope include file -- will be added to
229     // the emit list with emit=true for eventual generation.
230     org.emit (false);
231     org.name ("org");
232     org.container (null);
233     omg = factory.moduleEntry ();
234     omg.emit (false); // <d61919>
235     omg.name ("omg");
236     omg.module ("org");
237     omg.container (org);
238     org.addContained (omg);
239     corba = factory.moduleEntry ();
240     corba.emit (false); // <d61919>
241     corba.name ("CORBA");
242     corba.module ("org/omg");
243     corba.container (omg);
244     omg.addContained (corba);
245     symbolTable.put ("org", org);
246     symbolTable.put ("org/omg", omg);
247     symbolTable.put ("org/omg/CORBA", corba);
248 
249     // Add CORBA::Object to symbol table.
250     object = (InterfaceEntry)symbolTable.get ("Object");
251     object.module ("org/omg/CORBA");
252     object.container (corba);
253     symbolTable.put ("org/omg/CORBA/Object", object);
254 
255     // <d61961> Add PIDL type (primitive) CORBA::TypeCode to symbol table.
256     PrimitiveEntry pEntry = factory.primitiveEntry ();
257     pEntry.name ("TypeCode");
258     pEntry.module ("org/omg/CORBA");
259     pEntry.container (corba);
260     symbolTable.put ("org/omg/CORBA/TypeCode", pEntry);
261     symbolTable.put ("CORBA/TypeCode", pEntry);                      // <d55699>
262     overrideNames.put ("CORBA/TypeCode", "org/omg/CORBA/TypeCode");  // <d55699>
263     overrideNames.put ("org/omg/CORBA/TypeCode", "CORBA/TypeCode");  // <d55699>
264     // <d49526> Allow user to specify types named "TypeCode"
265     //symbolTable.put ("TypeCode", pEntry);
266     //overrideNames.put ("TypeCode", "org/omg/CORBA/TypeCode");
267 
268     // CORBA::Principal is deprecated!
269     // <d61961> Add PIDL type (primitive) CORBA::Principal to symbol table.
270     pEntry = factory.primitiveEntry ();
271     pEntry.name ("Principal");
272     pEntry.module ("org/omg/CORBA");
273     pEntry.container (corba);
274     symbolTable.put ("org/omg/CORBA/Principle", pEntry);
275     symbolTable.put ("CORBA/Principal", pEntry);
276     overrideNames.put ("CORBA/Principal", "org/omg/CORBA/Principal");
277     overrideNames.put ("org/omg/CORBA/Principal", "CORBA/Principal");
278 
279     // <d61961> Add PIDL type (interface) CORBA::Current to symbol table.
280     //InterfaceEntry iEntry = factory.interfaceEntry ();
281     //iEntry.name ("Current");
282     //iEntry.module ("org/omg/CORBA");
283     //iEntry.container (corba);
284     //symbolTable.put ("org/omg/CORBA/Current", iEntry);
285     //symbolTable.put ("CORBA/Current", iEntry);
286     //overrideNames.put ("CORBA/Current", "org/omg/CORBA/Current");
287     //overrideNames.put ("org/omg/CORBA/Current", "CORBA/Current");
288 
289     overrideNames.put ("TRUE", "true");
290     overrideNames.put ("FALSE", "false");
291     //overrideNames.put ("any", "org/omg/CORBA/Any");
292 
293     // Add CORBA module to symbol table
294     symbolTable.put ("CORBA", corba);  // 55699
295     overrideNames.put ("CORBA", "org/omg/CORBA");  // <d55699>
296     overrideNames.put ("org/omg/CORBA", "CORBA");  // <d55699>
297   } // preParse
298 
299 
300   protected void preEmit (Enumeration emitList)
301   {
302     typedefInfo = SymtabEntry.getVariableKey ();
303     Hashtable tempST = (Hashtable)symbolTable.clone ();
304 
305     for (Enumeration e = tempST.elements (); e.hasMoreElements ();)
306     {
307       SymtabEntry element = (SymtabEntry)e.nextElement ();
308 
309       // Any other symbolTable processing?
310       preEmitSTElement (element);
311     }
312 
313     // Do this processing AFTER any other processing to get the
314     // correct names.
315     Enumeration elements = symbolTable.elements ();
316     while (elements.hasMoreElements ())
317     {
318       // Find all TypedefEntry's and fill in the SymtabEntry.info
319       // field with it's real type , including [][]... with const
320       // exprs.
321       SymtabEntry element = (SymtabEntry)elements.nextElement ();
322       if (element instanceof TypedefEntry || element instanceof SequenceEntry)
323         Util.fillInfo (element);
324 
325       // <d59437> Members of constructed types may now be value boxes, and value
326       // boxes may contain types that are directly defined rather than typedef-ed
327       // (e.g., "valuetype vb sequence <long, 5>;").  If member resolves to a value
328       // box, then check and fillInfo() for value box and its content type BEFORE
329       // doing fillInfo() on member; otherwise, could get an exception.  There's
330       // code in fillInfo() that performs this check, so it does not appear here.
331 
332       else if (element instanceof StructEntry)
333       {
334         Enumeration members = ((StructEntry)element).members ().elements ();
335         while (members.hasMoreElements ())
336           Util.fillInfo ((SymtabEntry)members.nextElement ());
337       }
338       else if (element instanceof InterfaceEntry && ((InterfaceEntry)element).state () != null)
339       {
340         Enumeration members = ((InterfaceEntry)element).state ().elements ();
341         while (members.hasMoreElements ())
342           Util.fillInfo (((InterfaceState)members.nextElement ()).entry);
343       }
344       else if (element instanceof UnionEntry)
345       {
346         Enumeration branches = ((UnionEntry)element).branches ().elements ();
347         while (branches.hasMoreElements ())
348           Util.fillInfo (((UnionBranch)branches.nextElement ()).typedef);
349       }
350 
351       // For each type that is at the top level that is NOT a module
352       // or IncludeEntry, add it to the imports list.  If there are
353       // types within modules which refer to these, their types must
354       // be explicitly stated in an import statement.
355       if (element.module ().equals ("") && !(element instanceof ModuleEntry || element instanceof IncludeEntry || element instanceof PrimitiveEntry))
356         importTypes.addElement (element);
357     }
358 
359     while (emitList.hasMoreElements ())
360     {
361       SymtabEntry entry = (SymtabEntry)emitList.nextElement ();
362 
363       // Any other emitList processing:
364       preEmitELElement (entry);
365     }
366   } // preEmit
367 
368   /**
369    * This method is called by preEmit once for each symbol table entry.
370    * It can be called by extenders.
371    **/
372   protected void preEmitSTElement (SymtabEntry entry)
373   {
374     // If the -package argument was used, search the packages list
375     // for the given type name and prepend the package to it.
376     Hashtable packages = ((Arguments)arguments).packages;
377     if (packages.size () > 0)
378     {
379       String substr = (String)packages.get (entry.fullName ());
380       if (substr != null)
381       {
382         String pkg = null;
383         ModuleEntry mod = null;
384         ModuleEntry prev = null;
385         while (substr != null)
386         {
387           int dot = substr.indexOf ('.');
388           if (dot < 0)
389           {
390             pkg = substr;
391             substr = null;
392           }
393           else
394           {
395             pkg = substr.substring (0, dot);
396             substr = substr.substring (dot + 1);
397           }
398 
399           String fullName = prev == null ? pkg : prev.fullName () + '/' + pkg;
400           mod = (ModuleEntry)symbolTable.get (fullName);
401           if (mod == null)
402           {
403             mod = factory.moduleEntry ();
404             mod.name (pkg);
405             mod.container (prev);
406             if (prev != null) mod.module (prev.fullName ());
407             symbolTable.put (pkg, mod);
408           }
409           prev = mod;
410         }
411         entry.module (mod.fullName ());
412         entry.container (mod);
413       }
414     }
415   } // preEmitSTElement
416 
417   /**
418    * This method is called by preEmit once for each emitList entry.
419    * It can be called by extenders.
420    **/
421   protected void preEmitELElement (SymtabEntry entry)
422   {
423   } // preEmitELElement
424 
425   public        Vector        importTypes  = new Vector ();
426   public        SymtabFactory factory;
427   public static int           typedefInfo;
428   public        Hashtable     list         = new Hashtable ();
429   public static Compile       compiler     = null;  // <d58591>
430 } // class Compile