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