aoqi@0: /* aoqi@0: * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: /* aoqi@0: * Licensed Materials - Property of IBM aoqi@0: * RMI-IIOP v1.0 aoqi@0: * Copyright IBM Corp. 1998 1999 All Rights Reserved aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: package sun.rmi.rmic.iiop; aoqi@0: aoqi@0: import java.io.File; aoqi@0: import java.io.IOException; aoqi@0: import java.text.DateFormat; aoqi@0: import java.util.Date; aoqi@0: import java.util.Enumeration; aoqi@0: import java.util.Hashtable; aoqi@0: import java.util.Locale; aoqi@0: import java.util.StringTokenizer; aoqi@0: import java.util.Vector; aoqi@0: import sun.tools.java.Identifier; aoqi@0: import sun.tools.java.ClassDefinition; aoqi@0: import sun.tools.java.CompilerError; aoqi@0: import sun.rmi.rmic.IndentingWriter; aoqi@0: import java.util.HashSet; aoqi@0: import sun.rmi.rmic.Main; aoqi@0: aoqi@0: /** aoqi@0: * An IDL generator for rmic. aoqi@0: * aoqi@0: * @author Steve Newberry, Bryan Atsatt aoqi@0: */ aoqi@0: public class IDLGenerator extends sun.rmi.rmic.iiop.Generator { aoqi@0: aoqi@0: private boolean valueMethods = true; aoqi@0: private boolean factory = true; //init==!factory aoqi@0: private Hashtable ifHash = new Hashtable(); //IDL file Hashtable aoqi@0: private Hashtable imHash = new Hashtable(); //IDL module Hashtable aoqi@0: aoqi@0: private boolean isThrown = true; //flag for writeInclude aoqi@0: private boolean isException = true; //flag for writeBanner, writeIfndef aoqi@0: private boolean isForward = true; //flag for writeIfndef aoqi@0: private boolean forValuetype = true; //flag for writeInherits aoqi@0: aoqi@0: /** aoqi@0: * Default constructor for Main to use. aoqi@0: */ aoqi@0: public IDLGenerator() { aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return true if a new instance should be created for each aoqi@0: * class on the command line. Subclasses which return true aoqi@0: * should override newInstance() to return an appropriately aoqi@0: * constructed instance. aoqi@0: */ aoqi@0: protected boolean requireNewInstance() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Return true if non-conforming types should be parsed. aoqi@0: * @param stack The context stack. aoqi@0: */ aoqi@0: protected boolean parseNonConforming(ContextStack stack) { aoqi@0: return valueMethods; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Create and return a top-level type. aoqi@0: * @param env The compiler environment. aoqi@0: * @param cdef The top-level class definition. aoqi@0: * @return An RemoteType or null if is non-conforming. aoqi@0: */ aoqi@0: protected sun.rmi.rmic.iiop.CompoundType getTopType(ClassDefinition cdef, aoqi@0: ContextStack stack) { aoqi@0: return CompoundType.forCompound(cdef,stack); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return an Identifier which contains the fully-qualified IDL filename aoqi@0: * for the given OutputType. aoqi@0: * The OutputType contains a filename string (not directory) and Type. aoqi@0: * @param ot the OutputType for which directory nesting is to be defined. aoqi@0: * @return the new identifier. aoqi@0: */ aoqi@0: protected Identifier getOutputId ( aoqi@0: OutputType ot ) { aoqi@0: Identifier id = super.getOutputId( ot ); aoqi@0: aoqi@0: Type t = ot.getType(); aoqi@0: String fName = ot.getName(); aoqi@0: aoqi@0: if ( id == idJavaLangClass ) //java.lang.Class and array of aoqi@0: if ( t.isArray() ) aoqi@0: return Identifier.lookup( aoqi@0: "org.omg.boxedRMI.javax.rmi.CORBA." + fName ); aoqi@0: else return idClassDesc; aoqi@0: aoqi@0: if ( id == idJavaLangString && //array of java.lang.String aoqi@0: t.isArray() ) aoqi@0: return Identifier.lookup( "org.omg.boxedRMI.CORBA." + fName ); aoqi@0: aoqi@0: if ( "org.omg.CORBA.Object".equals( t.getQualifiedName() ) && aoqi@0: t.isArray() ) //array of org.omg.CORBA.Object aoqi@0: return Identifier.lookup( "org.omg.boxedRMI." + fName ); aoqi@0: aoqi@0: if ( t.isArray()) { //array aoqi@0: ArrayType at = (ArrayType)t; aoqi@0: Type et = at.getElementType(); aoqi@0: if ( et.isCompound() ) { aoqi@0: CompoundType ct = (CompoundType)et; aoqi@0: String qName = ct.getQualifiedName(); aoqi@0: if ( ct.isIDLEntity() ) aoqi@0: return Identifier.lookup( getQualifiedName( at ) ); aoqi@0: } aoqi@0: return Identifier.lookup( idBoxedRMI,id ); aoqi@0: } aoqi@0: aoqi@0: if ( t.isCompound() ) { //boxed IDLEntity aoqi@0: CompoundType ct = (CompoundType)t; aoqi@0: String qName = ct.getQualifiedName(); aoqi@0: if ( ct.isBoxed() ) aoqi@0: return Identifier.lookup( getQualifiedName( ct ) ); aoqi@0: } aoqi@0: aoqi@0: return id; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return the file name extension for the given file name (e.g. ".java"). aoqi@0: * All files generated with the ".java" extension will be compiled. To aoqi@0: * change this behavior for ".java" files, override the compileJavaSourceFile aoqi@0: * method to return false. aoqi@0: * @param outputType One of the items returned by getOutputTypesFor(...) aoqi@0: */ aoqi@0: protected String getFileNameExtensionFor(OutputType outputType) { aoqi@0: return IDL_FILE_EXTENSION; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Examine and consume command line arguments. aoqi@0: * @param argv The command line arguments. Ignore null aoqi@0: * and unknown arguments. Set each consumed argument to null. aoqi@0: * @param error Report any errors using the main.error() methods. aoqi@0: * @return true if no errors, false otherwise. aoqi@0: */ aoqi@0: public boolean parseArgs(String argv[], Main main) { aoqi@0: boolean result = super.parseArgs(argv,main); aoqi@0: String idlFrom; aoqi@0: String idlTo; aoqi@0: if (result) { aoqi@0: nextArg: aoqi@0: for (int i = 0; i < argv.length; i++) { aoqi@0: if (argv[i] != null) { aoqi@0: if (argv[i].equalsIgnoreCase("-idl")) { aoqi@0: idl = true; aoqi@0: argv[i] = null; aoqi@0: } aoqi@0: else if ( argv[i].equalsIgnoreCase( "-valueMethods" ) ) { aoqi@0: valueMethods = true; aoqi@0: argv[i] = null; aoqi@0: } aoqi@0: else if ( argv[i].equalsIgnoreCase( "-noValueMethods" ) ) { aoqi@0: valueMethods = false; aoqi@0: argv[i] = null; aoqi@0: } aoqi@0: else if ( argv[i].equalsIgnoreCase( "-init" ) ) { aoqi@0: factory = false; aoqi@0: argv[i] = null; aoqi@0: } aoqi@0: else if ( argv[i].equalsIgnoreCase( "-factory" ) ) { aoqi@0: factory = true; aoqi@0: argv[i] = null; aoqi@0: } aoqi@0: else if ( argv[i].equalsIgnoreCase( "-idlfile" ) ) { aoqi@0: argv[i] = null; aoqi@0: if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) { aoqi@0: idlFrom = argv[i]; aoqi@0: argv[i] = null; aoqi@0: if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) { aoqi@0: idlTo = argv[i]; aoqi@0: argv[i] = null; aoqi@0: ifHash.put( idlFrom,idlTo ); aoqi@0: continue nextArg; aoqi@0: } aoqi@0: } aoqi@0: main.error("rmic.option.requires.argument", "-idlfile"); aoqi@0: result = false; aoqi@0: } aoqi@0: else if ( argv[i].equalsIgnoreCase( "-idlmodule" ) ) { aoqi@0: argv[i] = null; aoqi@0: if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) { aoqi@0: idlFrom = argv[i]; aoqi@0: argv[i] = null; aoqi@0: if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) { aoqi@0: idlTo = argv[i]; aoqi@0: argv[i] = null; aoqi@0: imHash.put( idlFrom,idlTo ); aoqi@0: continue nextArg; aoqi@0: } aoqi@0: } aoqi@0: main.error("rmic.option.requires.argument", "-idlmodule"); aoqi@0: result = false; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: return result; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return an array of OutputTypes for the IDL files that need to be aoqi@0: * generated for the given top-level type. aoqi@0: * OutputTypes contain filename string (not directory) and Type. aoqi@0: * @param topType The type returned by getTopType(). aoqi@0: * @param alreadyChecked A set of Types which have already been checked. aoqi@0: * @return Array of OutputTypes to generate aoqi@0: */ aoqi@0: protected OutputType[] getOutputTypesFor( aoqi@0: CompoundType topType, aoqi@0: HashSet alreadyChecked ) { aoqi@0: Vector refVec = getAllReferencesFor( topType ); aoqi@0: Vector outVec = new Vector(); aoqi@0: for ( int i1 = 0; i1 < refVec.size(); i1++ ) { //forall references aoqi@0: Type t = (Type)refVec.elementAt( i1 ); aoqi@0: if ( t.isArray() ) { aoqi@0: ArrayType at = (ArrayType)t; aoqi@0: int dim = at.getArrayDimension(); aoqi@0: Type et = at.getElementType(); aoqi@0: String fName = unEsc( et.getIDLName() ).replace( ' ','_' ); aoqi@0: for ( int i2 = 0; i2 < dim; i2++ ) { //foreach dimension aoqi@0: String fileName = "seq" + ( i2 + 1 ) + "_" + fName; aoqi@0: outVec.addElement( new OutputType( fileName,at ) ); aoqi@0: } aoqi@0: } aoqi@0: else if ( t.isCompound() ) { aoqi@0: String fName = unEsc( t.getIDLName() ); aoqi@0: outVec.addElement( new OutputType( fName.replace( ' ','_' ),t ) ); aoqi@0: if ( t.isClass() ) { aoqi@0: ClassType ct = (ClassType)t; aoqi@0: if ( ct.isException() ) { //exception file aoqi@0: fName = unEsc( ct.getIDLExceptionName() ); aoqi@0: outVec.addElement( new OutputType( fName.replace( ' ','_' ),t ) ); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: OutputType[] outArr = new OutputType[outVec.size()]; aoqi@0: outVec.copyInto( outArr ); aoqi@0: return outArr; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get all referenced types of a given tyoe for which an IDL file needs aoqi@0: * to be generated. aoqi@0: * @param ct The given type. aoqi@0: * @return Vector of Types for which IDL must be generated. aoqi@0: */ aoqi@0: protected Vector getAllReferencesFor( aoqi@0: CompoundType ct ) { aoqi@0: Hashtable refHash = new Hashtable(); aoqi@0: Hashtable spcHash = new Hashtable(); aoqi@0: Hashtable arrHash = new Hashtable(); aoqi@0: int refSize; aoqi@0: refHash.put( ct.getQualifiedName(),ct ); //put the given type aoqi@0: accumulateReferences( refHash,spcHash,arrHash ); aoqi@0: do { aoqi@0: refSize = refHash.size(); aoqi@0: accumulateReferences( refHash,spcHash,arrHash ); aoqi@0: } aoqi@0: while ( refSize < refHash.size() ); //till hashtable stays same size aoqi@0: aoqi@0: Vector outVec = new Vector(); aoqi@0: Enumeration e = refHash.elements(); //ordinary references aoqi@0: while ( e.hasMoreElements() ) { aoqi@0: CompoundType t = (CompoundType)e.nextElement(); aoqi@0: outVec.addElement( t ); aoqi@0: } aoqi@0: e = spcHash.elements(); //special references aoqi@0: while ( e.hasMoreElements() ) { aoqi@0: CompoundType t = (CompoundType)e.nextElement(); aoqi@0: outVec.addElement( t ); aoqi@0: } aoqi@0: e = arrHash.elements(); //array references aoqi@0: nextSequence: aoqi@0: while ( e.hasMoreElements() ) { aoqi@0: ArrayType at = (ArrayType)e.nextElement(); aoqi@0: int dim = at.getArrayDimension(); aoqi@0: Type et = at.getElementType(); aoqi@0: Enumeration e2 = arrHash.elements(); aoqi@0: while ( e2.hasMoreElements() ) { //eliminate duplicates aoqi@0: ArrayType at2 = (ArrayType)e2.nextElement(); aoqi@0: if ( et == at2.getElementType() && //same element type & aoqi@0: dim < at2.getArrayDimension() ) //smaller dimension? aoqi@0: continue nextSequence; //ignore this one aoqi@0: } aoqi@0: outVec.addElement( at ); aoqi@0: } aoqi@0: return outVec; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Accumulate and filter all those types that are referenced by the given aoqi@0: * referenced types. aoqi@0: * Keep only those for which IDL is to be generated. aoqi@0: * @param refHash Hashtable containing the given types aoqi@0: * @param spcHash Hashtable containing referenced specials (IDL typedefs) aoqi@0: * @param arrHash Hashtable containing referenced arrays (dimensioned) aoqi@0: */ aoqi@0: protected void accumulateReferences( aoqi@0: Hashtable refHash, aoqi@0: Hashtable spcHash, aoqi@0: Hashtable arrHash ) { aoqi@0: Enumeration e = refHash.elements(); aoqi@0: while ( e.hasMoreElements() ) { aoqi@0: CompoundType t = (CompoundType)e.nextElement(); aoqi@0: Vector datVec = getData( t ); //collect and sort data aoqi@0: Vector mthVec = getMethods( t ); //collect and filter methods aoqi@0: getInterfaces( t,refHash ); //collect interfaces aoqi@0: getInheritance( t,refHash ); //add inheritance aoqi@0: getMethodReferences( mthVec,refHash,spcHash,arrHash,refHash ); aoqi@0: getMemberReferences( datVec,refHash,spcHash,arrHash ); aoqi@0: } aoqi@0: e = arrHash.elements(); //add array element references aoqi@0: while ( e.hasMoreElements() ) { aoqi@0: ArrayType at = (ArrayType)e.nextElement(); aoqi@0: Type et = at.getElementType(); aoqi@0: addReference( et,refHash,spcHash,arrHash ); aoqi@0: } aoqi@0: e = refHash.elements(); aoqi@0: while ( e.hasMoreElements() ) { aoqi@0: CompoundType t = (CompoundType)e.nextElement(); aoqi@0: if ( !isIDLGeneratedFor( t ) ) //remove if no IDL generation aoqi@0: refHash.remove( t.getQualifiedName() ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Determine if IDL should be generated for a referenced type. aoqi@0: * Do not generate IDL for a CORBA Object reference. It gets mapped aoqi@0: * to the original IDL or to Object (if exactly org.omg.CORBA.Object) aoqi@0: * Generate (boxed) IDL for an IDL Entity unless it is an IDL user aoqi@0: * exception, a ValueBase, an AbstractBase (or a CORBA Object). aoqi@0: * Do not generate IDL for Implementation classes..unless they inherit aoqi@0: * from multiple distinct remote interfaces aoqi@0: * @param t The type to check. aoqi@0: * @return true or false aoqi@0: */ aoqi@0: protected boolean isIDLGeneratedFor( aoqi@0: CompoundType t ) { aoqi@0: if ( t.isCORBAObject() ) return false; aoqi@0: if ( t.isIDLEntity() ) aoqi@0: if ( t.isBoxed() ) return true; aoqi@0: else if ( "org.omg.CORBA.portable.IDLEntity" aoqi@0: .equals( t.getQualifiedName() ) ) return true; aoqi@0: else if ( t.isCORBAUserException() ) return true; aoqi@0: else return false; aoqi@0: Hashtable inhHash = new Hashtable(); aoqi@0: getInterfaces( t,inhHash ); aoqi@0: if ( t.getTypeCode() == TYPE_IMPLEMENTATION ) aoqi@0: if ( inhHash.size() < 2 ) return false; //no multiple inheritance aoqi@0: else return true; aoqi@0: return true; //generate IDL for this type aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write the output for the given OutputFileName into the output stream. aoqi@0: * (The IDL mapping for java.lang.Class is generated from aoqi@0: * javax.rmi.CORBA.ClassDesc in the tools workspace) aoqi@0: * @param OutputType ot One of the items returned by getOutputTypesFor(...) aoqi@0: * @param alreadyChecked A set of Types which have already been checked. aoqi@0: * Intended to be passed to Type.collectMatching(filter,alreadyChecked). aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeOutputFor( aoqi@0: OutputType ot, aoqi@0: HashSet alreadyChecked, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Type t = ot.getType(); aoqi@0: if ( t.isArray() ) { //specialcase: sequence aoqi@0: writeSequence( ot,p ); aoqi@0: return; aoqi@0: } aoqi@0: if ( isSpecialReference( t ) ) { //specialcase: IDL typecode aoqi@0: writeSpecial( t,p ); aoqi@0: return; aoqi@0: } aoqi@0: if ( t.isCompound() ) { //specialcase: boxed IDL aoqi@0: CompoundType ct = (CompoundType)t; aoqi@0: if ( ct.isIDLEntity() && ct.isBoxed() ) { aoqi@0: writeBoxedIDL( ct,p ); aoqi@0: return; aoqi@0: } aoqi@0: } aoqi@0: if ( t.isClass() ) { //specialcase: exception aoqi@0: ClassType ct = (ClassType)t; aoqi@0: if ( ct.isException() ) { aoqi@0: String eName = unEsc( ct.getIDLExceptionName() ); aoqi@0: String fName = ot.getName(); aoqi@0: if ( fName.equals( eName.replace( ' ','_' ) ) ) { aoqi@0: writeException( ct,p ); aoqi@0: return; aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: switch ( t.getTypeCode() ) { //general case aoqi@0: case TYPE_IMPLEMENTATION: aoqi@0: writeImplementation( (ImplementationType)t,p ); aoqi@0: break; aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_NC_INTERFACE: aoqi@0: writeNCType( (CompoundType)t,p ); aoqi@0: break; aoqi@0: case TYPE_ABSTRACT: //AbstractType is a RemoteType aoqi@0: case TYPE_REMOTE: aoqi@0: writeRemote( (RemoteType)t,p ); aoqi@0: break; aoqi@0: case TYPE_VALUE: aoqi@0: writeValue( (ValueType)t,p ); aoqi@0: break; aoqi@0: default: aoqi@0: throw new CompilerError( aoqi@0: "IDLGenerator got unexpected type code: " aoqi@0: + t.getTypeCode()); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL interface definition for a Java implementation class aoqi@0: * @param t The current ImplementationType aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeImplementation( aoqi@0: ImplementationType t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Hashtable inhHash = new Hashtable(); aoqi@0: Hashtable refHash = new Hashtable(); aoqi@0: getInterfaces( t,inhHash ); //collect interfaces aoqi@0: aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeInheritedIncludes( inhHash,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeIncOrb( p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.p( "interface " + t.getIDLName() ); aoqi@0: writeInherits( inhHash,!forValuetype,p ); aoqi@0: aoqi@0: p.pln( " {" ); aoqi@0: p.pln( "};" ); aoqi@0: aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEpilog( t,refHash,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL valuetype definition for aoqi@0: * 1) a nonconforming Java class aoqi@0: * 2) a nonconforming Java interface (that is not an AbstractType) aoqi@0: * @param t The current NC Type (NCClassType or NCInterfaceType) aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeNCType( aoqi@0: CompoundType t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Vector conVec = getConstants( t ); //collect constants aoqi@0: Vector mthVec = getMethods( t ); //collect methods aoqi@0: Hashtable inhHash = new Hashtable(); aoqi@0: Hashtable refHash = new Hashtable(); aoqi@0: Hashtable spcHash = new Hashtable(); aoqi@0: Hashtable arrHash = new Hashtable(); aoqi@0: Hashtable excHash = new Hashtable(); aoqi@0: getInterfaces( t,inhHash ); //collect interfaces aoqi@0: getInheritance( t,inhHash ); //add inheritance aoqi@0: getMethodReferences( mthVec,refHash,spcHash,arrHash,excHash ); aoqi@0: aoqi@0: writeProlog( t,refHash,spcHash,arrHash,excHash,inhHash,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.p( "abstract valuetype " + t.getIDLName() ); aoqi@0: writeInherits( inhHash,!forValuetype,p ); aoqi@0: aoqi@0: p.pln( " {" ); aoqi@0: if ( conVec.size() + mthVec.size() > 0 ) { //any content? aoqi@0: p.pln();p.pI(); aoqi@0: for ( int i1 = 0; i1 < conVec.size(); i1++ ) //write constants aoqi@0: writeConstant( (CompoundType.Member)conVec.elementAt( i1 ),p ); aoqi@0: for ( int i1 = 0; i1 < mthVec.size(); i1++ ) //write methods aoqi@0: writeMethod( (CompoundType.Method)mthVec.elementAt( i1 ),p ); aoqi@0: p.pO();p.pln(); aoqi@0: } aoqi@0: p.pln( "};" ); aoqi@0: aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEpilog( t,refHash,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL interface definition for either: aoqi@0: * 1) a conforming Java remote interface (RemoteType)..or aoqi@0: * 2) a non-conforming Java interface whose methods all throw aoqi@0: * java.rmi.RemoteException (AbstractType) aoqi@0: * @param t The current RemoteType aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeRemote( aoqi@0: RemoteType t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Vector conVec = getConstants( t ); //collect constants aoqi@0: Vector mthVec = getMethods( t ); //collect methods aoqi@0: Hashtable inhHash = new Hashtable(); aoqi@0: Hashtable refHash = new Hashtable(); aoqi@0: Hashtable spcHash = new Hashtable(); aoqi@0: Hashtable arrHash = new Hashtable(); aoqi@0: Hashtable excHash = new Hashtable(); aoqi@0: getInterfaces( t,inhHash ); //collect interfaces aoqi@0: getMethodReferences( mthVec,refHash,spcHash,arrHash,excHash ); aoqi@0: aoqi@0: writeProlog( t,refHash,spcHash,arrHash,excHash,inhHash,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: if ( t.getTypeCode() == TYPE_ABSTRACT ) p.p( "abstract " ); aoqi@0: p.p( "interface " + t.getIDLName() ); aoqi@0: writeInherits( inhHash,!forValuetype,p ); aoqi@0: aoqi@0: p.pln( " {" ); aoqi@0: if ( conVec.size() + mthVec.size() > 0 ) { //any constants or methods? aoqi@0: p.pln();p.pI(); aoqi@0: for ( int i1 = 0; i1 < conVec.size(); i1++ ) //constants aoqi@0: writeConstant( (CompoundType.Member)conVec.elementAt( i1 ),p ); aoqi@0: for ( int i1 = 0; i1 < mthVec.size(); i1++ ) //methods, attributes aoqi@0: writeMethod( (CompoundType.Method)mthVec.elementAt( i1 ),p ); aoqi@0: p.pO();p.pln(); aoqi@0: } aoqi@0: p.pln( "};" ); aoqi@0: aoqi@0: p.pO();p.pln(); aoqi@0: writeRepositoryID ( t,p ); aoqi@0: p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEpilog( t,refHash,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL valuetype definition for a conforming Java class. aoqi@0: * Methods and constructors are optional..controlled by -valueMethods flag aoqi@0: * @param t The current ValueType aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeValue( aoqi@0: ValueType t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Vector datVec = getData( t ); //collect and sort data aoqi@0: Vector conVec = getConstants( t ); //collect constants aoqi@0: Vector mthVec = getMethods( t ); //collect and filter methods aoqi@0: Hashtable inhHash = new Hashtable(); aoqi@0: Hashtable refHash = new Hashtable(); aoqi@0: Hashtable spcHash = new Hashtable(); aoqi@0: Hashtable arrHash = new Hashtable(); aoqi@0: Hashtable excHash = new Hashtable(); aoqi@0: getInterfaces( t,inhHash ); //collect interfaces aoqi@0: getInheritance( t,inhHash ); //add inheritance aoqi@0: getMethodReferences( mthVec,refHash,spcHash,arrHash,excHash ); aoqi@0: getMemberReferences( datVec,refHash,spcHash,arrHash ); aoqi@0: aoqi@0: writeProlog( t,refHash,spcHash,arrHash,excHash,inhHash,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: if ( t.isCustom() ) p.p( "custom " ); aoqi@0: p.p( "valuetype " + t.getIDLName() ); aoqi@0: writeInherits( inhHash,forValuetype,p ); aoqi@0: aoqi@0: p.pln( " {" ); aoqi@0: if ( conVec.size() + datVec.size() + mthVec.size() > 0 ) { //any content? aoqi@0: p.pln();p.pI(); aoqi@0: for ( int i1 = 0; i1 < conVec.size(); i1++ ) //write constants aoqi@0: writeConstant( (CompoundType.Member)conVec.elementAt( i1 ),p ); aoqi@0: for ( int i1 = 0; i1 < datVec.size(); i1++ ) { aoqi@0: CompoundType.Member mem = (CompoundType.Member)datVec.elementAt( i1 ); aoqi@0: if ( mem.getType().isPrimitive() ) aoqi@0: writeData( mem,p ); //write primitive data aoqi@0: } aoqi@0: for ( int i1 = 0; i1 < datVec.size(); i1++ ) { aoqi@0: CompoundType.Member mem = (CompoundType.Member)datVec.elementAt( i1 ); aoqi@0: if ( !mem.getType().isPrimitive() ) aoqi@0: writeData( mem,p ); //write non-primitive data aoqi@0: } aoqi@0: for ( int i1 = 0; i1 < mthVec.size(); i1++ ) //write methods aoqi@0: writeMethod( (CompoundType.Method)mthVec.elementAt( i1 ),p ); aoqi@0: p.pO();p.pln(); aoqi@0: } aoqi@0: p.pln( "};" ); aoqi@0: aoqi@0: p.pO();p.pln(); aoqi@0: writeRepositoryID ( t,p ); aoqi@0: p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEpilog( t,refHash,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write IDL prolog for a CompoundType. aoqi@0: * @param t The CompoundType. aoqi@0: * @param refHash Hashtable loaded with type references. aoqi@0: * @param spcHash Hashtable loaded with special type references. aoqi@0: * @param arrHash Hashtable loaded with array references. aoqi@0: * @param excHash Hashtable loaded with exceptions thrown. aoqi@0: * @param inhHash Hashtable loaded with inherited types. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeProlog( aoqi@0: CompoundType t, aoqi@0: Hashtable refHash, aoqi@0: Hashtable spcHash, aoqi@0: Hashtable arrHash, aoqi@0: Hashtable excHash, aoqi@0: Hashtable inhHash, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeForwardReferences( refHash,p ); aoqi@0: writeIncludes( excHash,isThrown,p ); //#includes for exceptions thrown aoqi@0: writeInheritedIncludes( inhHash,p ); aoqi@0: writeIncludes( spcHash,!isThrown,p ); //#includes for special types aoqi@0: writeBoxedRMIIncludes( arrHash,p ); aoqi@0: writeIDLEntityIncludes( refHash,p ); aoqi@0: writeIncOrb( p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write IDL epilog for a CompoundType. aoqi@0: * @param t The CompoundType. aoqi@0: * @param refHash Hashtable loaded with type references. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeEpilog( aoqi@0: CompoundType t, aoqi@0: Hashtable refHash, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeIncludes( refHash,!isThrown,p ); //#includes for forward dcl types aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write special typedef aoqi@0: * @param t A special Type. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeSpecial( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: String spcName = t.getQualifiedName(); aoqi@0: if ( "java.io.Serializable".equals( spcName ) ) aoqi@0: writeJavaIoSerializable( t,p ); aoqi@0: else if ( "java.io.Externalizable".equals( spcName ) ) aoqi@0: writeJavaIoExternalizable( t,p ); aoqi@0: else if ( "java.lang.Object".equals( spcName) ) aoqi@0: writeJavaLangObject( t,p ); aoqi@0: else if ( "java.rmi.Remote".equals( spcName) ) aoqi@0: writeJavaRmiRemote( t,p ); aoqi@0: else if ( "org.omg.CORBA.portable.IDLEntity".equals( spcName) ) aoqi@0: writeIDLEntity( t,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a hard-coded IDL typedef definition for the special case aoqi@0: * java.io.Serializable. aoqi@0: * @param t The current Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeJavaIoSerializable( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.pln( "typedef any Serializable;" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a hard-coded IDL typedef definition for the special case aoqi@0: * java.io.Externalizable. aoqi@0: * @param t The current Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeJavaIoExternalizable( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.pln( "typedef any Externalizable;" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a hard-coded IDL typedef definition for the special case aoqi@0: * java.lang.Object. aoqi@0: * @param t The current Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeJavaLangObject( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.pln( "typedef any _Object;" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a hard-coded IDL typedef definition for the special case aoqi@0: * java.rmi.Remote. aoqi@0: * @param t The current Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeJavaRmiRemote( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.pln( "typedef Object Remote;" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a hard-coded IDL typedef definition for the special case aoqi@0: * org.omg.CORBA.portable.IDLEntity aoqi@0: * @param t The current Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeIDLEntity( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.pln( "typedef any IDLEntity;" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Filter and collect non-duplicate inherited interfaces for a type aoqi@0: * @param ct The current CompoundType aoqi@0: * @param inhHash Hashtable containing the inherited interfaces aoqi@0: */ aoqi@0: protected void getInterfaces( aoqi@0: CompoundType ct, aoqi@0: Hashtable inhHash ) { aoqi@0: InterfaceType[] infs = ct.getInterfaces(); aoqi@0: nextInterface: aoqi@0: for ( int i1 = 0; i1 < infs.length; i1++ ) { //forall inherited interfaces aoqi@0: String inhName = infs[i1].getQualifiedName(); aoqi@0: switch ( ct.getTypeCode() ) { aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_VALUE: //filter for classes aoqi@0: if ( "java.io.Externalizable".equals( inhName ) || aoqi@0: "java.io.Serializable".equals( inhName ) || aoqi@0: "org.omg.CORBA.portable.IDLEntity".equals( inhName ) ) aoqi@0: continue nextInterface; aoqi@0: break; aoqi@0: default: //filter for all others aoqi@0: if ( "java.rmi.Remote".equals( inhName ) ) aoqi@0: continue nextInterface; aoqi@0: break; aoqi@0: } aoqi@0: inhHash.put( inhName,infs[i1] ); //add this one aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Filter and add base class inheritance for a class type aoqi@0: * @param ct The current CompoundType aoqi@0: * @param inhHash Hashtable containing inherited types aoqi@0: */ aoqi@0: protected void getInheritance( aoqi@0: CompoundType ct, aoqi@0: Hashtable inhHash ) { aoqi@0: ClassType par = ct.getSuperclass(); //get parent aoqi@0: if ( par == null ) return; aoqi@0: String parName = par.getQualifiedName(); aoqi@0: switch ( ct.getTypeCode() ) { aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_VALUE: aoqi@0: if ( "java.lang.Object".equals( parName ) ) //this is implicit aoqi@0: return; aoqi@0: break; aoqi@0: default: return; //ignore other types aoqi@0: } aoqi@0: inhHash.put( parName,par ); //add valid base class aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Collect and filter type and array references from methods aoqi@0: * @param mthVec Given Vector of methods aoqi@0: * @param refHash Hashtable for type references aoqi@0: * @param spcHash Hashtable for special type references aoqi@0: * @param arrHash Hashtable for array references aoqi@0: * @param excHash Hashtable for exceptions thrown aoqi@0: */ aoqi@0: protected void getMethodReferences( aoqi@0: Vector mthVec, aoqi@0: Hashtable refHash, aoqi@0: Hashtable spcHash, aoqi@0: Hashtable arrHash, aoqi@0: Hashtable excHash ) { aoqi@0: for ( int i1 = 0; i1 < mthVec.size(); i1++ ) { //forall methods aoqi@0: CompoundType.Method mth = (CompoundType.Method)mthVec.elementAt( i1 ); aoqi@0: Type[] args = mth.getArguments(); aoqi@0: Type ret = mth.getReturnType(); aoqi@0: getExceptions( mth,excHash ); //collect exceptions thrown aoqi@0: for ( int i2 = 0; i2 < args.length; i2++ ) //forall arguments aoqi@0: addReference( args[i2],refHash,spcHash,arrHash ); aoqi@0: addReference( ret,refHash,spcHash,arrHash ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Collect and filter type and array references from data members aoqi@0: * @param datVec Given Vector of data members aoqi@0: * @param refHash Hashtable for type references aoqi@0: * @param spcHash Hashtable for special type references aoqi@0: * @param arrHash Hashtable for array references aoqi@0: */ aoqi@0: protected void getMemberReferences( aoqi@0: Vector datVec, aoqi@0: Hashtable refHash, aoqi@0: Hashtable spcHash, aoqi@0: Hashtable arrHash ) { aoqi@0: for ( int i1 = 0; i1 < datVec.size(); i1++ ) { //forall datamembers aoqi@0: CompoundType.Member mem = (CompoundType.Member)datVec.elementAt( i1 ); aoqi@0: Type dat = mem.getType(); aoqi@0: addReference( dat,refHash,spcHash,arrHash ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Add reference for given type avoiding duplication. aoqi@0: * Sort into specials, arrays and regular references. aoqi@0: * Filter out types which are not required. aoqi@0: * @param t Given Type aoqi@0: * @param refHash Hashtable for type references aoqi@0: * @param spcHash Hashtable for special type references aoqi@0: * @param arrHash Hashtable for array references aoqi@0: */ aoqi@0: protected void addReference( aoqi@0: Type ref, aoqi@0: Hashtable refHash, aoqi@0: Hashtable spcHash, aoqi@0: Hashtable arrHash ) { aoqi@0: String rName = ref.getQualifiedName(); aoqi@0: switch ( ref.getTypeCode() ) { aoqi@0: case TYPE_ABSTRACT: aoqi@0: case TYPE_REMOTE: aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_NC_INTERFACE: aoqi@0: case TYPE_VALUE: aoqi@0: refHash.put( rName,ref ); aoqi@0: return; aoqi@0: case TYPE_CORBA_OBJECT: aoqi@0: if ( "org.omg.CORBA.Object".equals( rName ) ) return; //don't want aoqi@0: refHash.put( rName,ref ); aoqi@0: return; aoqi@0: case TYPE_ARRAY: //array? aoqi@0: arrHash.put( rName + ref.getArrayDimension(),ref ); aoqi@0: return; aoqi@0: default: aoqi@0: if ( isSpecialReference( ref ) ) //special IDL typedef? aoqi@0: spcHash.put( rName,ref ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Determine whether given Type is a special reference. aoqi@0: * Special cases are: java.io.Serializable, java.io.Externalizable, aoqi@0: * java.lang.Object, java.rmi.Remote and org.omg.CORBA.portable.IDLEntity aoqi@0: * They are special because they have a hard-coded typedef defined in the aoqi@0: * spec. aoqi@0: * @param ref A referenced Type aoqi@0: * @return boolean indicating whether it's a special reference aoqi@0: */ aoqi@0: protected boolean isSpecialReference( aoqi@0: Type ref ) { aoqi@0: String rName = ref.getQualifiedName(); aoqi@0: if ( "java.io.Serializable".equals( rName ) ) return true; aoqi@0: if ( "java.io.Externalizable".equals( rName ) ) return true; aoqi@0: if ( "java.lang.Object".equals( rName) ) return true; aoqi@0: if ( "java.rmi.Remote".equals( rName) ) return true; aoqi@0: if ( "org.omg.CORBA.portable.IDLEntity".equals( rName) ) return true; aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Collect and filter thrown exceptions for a given pre-filtered method. aoqi@0: * Keep only 'checked' exception classes minus java.rmi.RemoteException aoqi@0: * and its subclasses aoqi@0: * @param method The current method aoqi@0: * @param excHash Hashtable containing non-duplicate thrown exceptions aoqi@0: */ aoqi@0: protected void getExceptions( aoqi@0: CompoundType.Method mth, aoqi@0: Hashtable excHash ) { aoqi@0: ClassType[] excs = mth.getExceptions(); aoqi@0: for ( int i1 = 0; i1 < excs.length; i1++ ) { //forall exceptions aoqi@0: ClassType exc = excs[i1]; aoqi@0: if ( exc.isCheckedException() && aoqi@0: !exc.isRemoteExceptionOrSubclass() ) { aoqi@0: excHash.put( exc.getQualifiedName(),exc ); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Collect and filter methods for a type. aoqi@0: * Remove any private or inherited methods. aoqi@0: * @param ct The current CompoundType aoqi@0: * @return Vector containing the methods aoqi@0: */ aoqi@0: protected Vector getMethods( aoqi@0: CompoundType ct ) { aoqi@0: Vector vec = new Vector(); aoqi@0: int ctType = ct.getTypeCode(); aoqi@0: switch ( ctType ) { aoqi@0: case TYPE_ABSTRACT: aoqi@0: case TYPE_REMOTE: break; aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_NC_INTERFACE: aoqi@0: case TYPE_VALUE: if ( valueMethods ) break; aoqi@0: default: return vec; aoqi@0: } aoqi@0: Identifier ctId = ct.getIdentifier(); aoqi@0: CompoundType.Method[] mths = ct.getMethods(); aoqi@0: nextMethod: aoqi@0: for ( int i1 = 0; i1 < mths.length; i1++ ) { //forall methods aoqi@0: if ( mths[i1].isPrivate() || //private method? aoqi@0: mths[i1].isInherited() ) //inherited method? aoqi@0: continue nextMethod; //yes..ignore it aoqi@0: if ( ctType == TYPE_VALUE ) { aoqi@0: String mthName = mths[i1].getName(); aoqi@0: if ( "readObject" .equals( mthName ) || aoqi@0: "writeObject" .equals( mthName ) || aoqi@0: "readExternal".equals( mthName ) || aoqi@0: "writeExternal".equals( mthName ) ) aoqi@0: continue nextMethod; //ignore this one aoqi@0: } aoqi@0: if ( ( ctType == TYPE_NC_CLASS || aoqi@0: ctType == TYPE_NC_INTERFACE ) && aoqi@0: mths[i1].isConstructor() ) //init not valid for abstract valuetype aoqi@0: continue nextMethod; //ignore this one aoqi@0: vec.addElement( mths[i1] ); //add this one aoqi@0: } aoqi@0: return vec; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Collect constants for a type. aoqi@0: * A valid constant is a "public final static" field with a compile-time aoqi@0: * constant value for a primitive type or String aoqi@0: * @param ct The current CompoundType aoqi@0: * @return Vector containing the constants aoqi@0: */ aoqi@0: protected Vector getConstants( aoqi@0: CompoundType ct ) { aoqi@0: Vector vec = new Vector(); aoqi@0: CompoundType.Member[] mems = ct.getMembers(); aoqi@0: for ( int i1 = 0; i1 < mems.length; i1++ ) { //forall members aoqi@0: Type memType = mems[i1].getType(); aoqi@0: String memValue = mems[i1].getValue(); aoqi@0: if ( mems[i1].isPublic() && aoqi@0: mems[i1].isFinal() && aoqi@0: mems[i1].isStatic() && aoqi@0: ( memType.isPrimitive() || "String".equals( memType.getName() ) ) && aoqi@0: memValue != null ) aoqi@0: vec.addElement( mems[i1] ); //add this one aoqi@0: } aoqi@0: return vec; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Collect and sort data fields for a ValueType. aoqi@0: * Sort in Java (not IDL) Unicode name string lexicographic increasing aoqi@0: * order. aoqi@0: * Non-static, non-transient fields are mapped. aoqi@0: * If the type is a custom valuetype, only public fields are mapped. aoqi@0: * @param ct The current CompoundType aoqi@0: * @return Vector containing the data fields aoqi@0: */ aoqi@0: protected Vector getData( aoqi@0: CompoundType t ) { aoqi@0: Vector vec = new Vector(); aoqi@0: if ( t.getTypeCode() != TYPE_VALUE ) return vec; aoqi@0: ValueType vt = (ValueType)t; aoqi@0: CompoundType.Member[] mems = vt.getMembers(); aoqi@0: boolean notCust = !vt.isCustom(); aoqi@0: for ( int i1 = 0; i1 < mems.length; i1++ ) { //forall members aoqi@0: if ( !mems[i1].isStatic() && aoqi@0: !mems[i1].isTransient() && aoqi@0: ( mems[i1].isPublic() || notCust ) ) { aoqi@0: int i2; aoqi@0: String memName = mems[i1].getName(); aoqi@0: for ( i2 = 0; i2 < vec.size(); i2++ ) { //insert in java lex order aoqi@0: CompoundType.Member aMem = (CompoundType.Member)vec.elementAt( i2 ); aoqi@0: if ( memName.compareTo( aMem.getName() ) < 0 ) break; aoqi@0: } aoqi@0: vec.insertElementAt( mems[i1],i2 ); //insert this one aoqi@0: } aoqi@0: } aoqi@0: return vec; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write forward references for referenced interfaces and valuetypes aoqi@0: * ...but not if the reference is to a boxed IDLEntity, aoqi@0: * @param refHash Hashtable loaded with referenced types aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeForwardReferences( aoqi@0: Hashtable refHash, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Enumeration refEnum = refHash.elements(); aoqi@0: nextReference: aoqi@0: while ( refEnum.hasMoreElements() ) { aoqi@0: Type t = (Type)refEnum.nextElement(); aoqi@0: if ( t.isCompound() ) { aoqi@0: CompoundType ct = (CompoundType)t; aoqi@0: if ( ct.isIDLEntity() ) aoqi@0: continue nextReference; //ignore IDLEntity reference aoqi@0: } aoqi@0: writeForwardReference( t,p ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write forward reference for given type aoqi@0: * @param t Given type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeForwardReference( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: String qName = t.getQualifiedName(); aoqi@0: if ( "java.lang.String".equals( qName ) ) ; aoqi@0: else if ( "org.omg.CORBA.Object".equals( qName ) ) return ; //no fwd dcl aoqi@0: aoqi@0: writeIfndef( t,0,!isException,isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: switch ( t.getTypeCode() ) { aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_NC_INTERFACE: p.p( "abstract valuetype " ); break; aoqi@0: case TYPE_ABSTRACT: p.p( "abstract interface " ); break; aoqi@0: case TYPE_VALUE: p.p( "valuetype " ); break; aoqi@0: case TYPE_REMOTE: aoqi@0: case TYPE_CORBA_OBJECT: p.p( "interface " ); break; aoqi@0: default: ; //all other types were filtered aoqi@0: } aoqi@0: p.pln( t.getIDLName() + ";" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write forward reference for boxed valuetype for single dimension of IDL aoqi@0: * sequence. aoqi@0: * If the dimension is <1 and the element is a CompoundType, write a aoqi@0: * forward declare for the element aoqi@0: * @param at ArrayType for forward declare aoqi@0: * @param dim The dimension to write aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeForwardReference( aoqi@0: ArrayType at, aoqi@0: int dim, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: Type et = at.getElementType(); aoqi@0: if ( dim < 1 ) { aoqi@0: if ( et.isCompound() ) { aoqi@0: CompoundType ct = (CompoundType)et; aoqi@0: writeForwardReference( et,p); aoqi@0: } aoqi@0: return; aoqi@0: } aoqi@0: String fName = unEsc( et.getIDLName() ).replace( ' ','_' ); aoqi@0: aoqi@0: writeIfndef( at,dim,!isException,isForward,p ); aoqi@0: writeModule1( at,p ); aoqi@0: p.pln();p.pI(); aoqi@0: switch ( et.getTypeCode() ) { aoqi@0: case TYPE_NC_CLASS: aoqi@0: case TYPE_NC_INTERFACE: p.p( "abstract valuetype " ); break; aoqi@0: case TYPE_ABSTRACT: p.p( "abstract interface " ); break; aoqi@0: case TYPE_VALUE: p.p( "valuetype " ); break; aoqi@0: case TYPE_REMOTE: aoqi@0: case TYPE_CORBA_OBJECT: p.p( "interface " ); break; aoqi@0: default: ; //all other types were filtered aoqi@0: } aoqi@0: p.pln( "seq" + dim + "_" + fName + ";" ); aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( at,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #includes for boxed IDLEntity references. aoqi@0: * @param refHash Hashtable loaded with referenced types aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeIDLEntityIncludes( aoqi@0: Hashtable refHash, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Enumeration refEnum = refHash.elements(); aoqi@0: while ( refEnum.hasMoreElements() ) { aoqi@0: Type t = (Type)refEnum.nextElement(); aoqi@0: if ( t.isCompound() ) { aoqi@0: CompoundType ct = (CompoundType)t; aoqi@0: if ( ct.isIDLEntity() ) { //select IDLEntities aoqi@0: writeInclude( ct,0,!isThrown,p ); aoqi@0: refHash.remove( ct.getQualifiedName() ); //avoid another #include aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #includes aoqi@0: * @param incHash Hashtable loaded with Types to include aoqi@0: * @param isThrown true if Types are thrown exceptions aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeIncludes( aoqi@0: Hashtable incHash, aoqi@0: boolean isThrown, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Enumeration incEnum = incHash.elements(); aoqi@0: while ( incEnum.hasMoreElements() ) { aoqi@0: CompoundType t = (CompoundType)incEnum.nextElement(); aoqi@0: writeInclude( t,0,isThrown,p ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write includes for boxedRMI valuetypes for IDL sequences. aoqi@0: * Write only the maximum dimension found for an ArrayType. aoqi@0: * @param arrHash Hashtable loaded with array types aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeBoxedRMIIncludes( aoqi@0: Hashtable arrHash, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: Enumeration e1 = arrHash.elements(); aoqi@0: nextSequence: aoqi@0: while ( e1.hasMoreElements() ) { aoqi@0: ArrayType at = (ArrayType)e1.nextElement(); aoqi@0: int dim = at.getArrayDimension(); aoqi@0: Type et = at.getElementType(); aoqi@0: aoqi@0: Enumeration e2 = arrHash.elements(); aoqi@0: while ( e2.hasMoreElements() ) { //eliminate duplicates aoqi@0: ArrayType at2 = (ArrayType)e2.nextElement(); aoqi@0: if ( et == at2.getElementType() && //same element type & aoqi@0: dim < at2.getArrayDimension() ) //smaller dimension? aoqi@0: continue nextSequence; //ignore this one aoqi@0: } aoqi@0: writeInclude( at,dim,!isThrown,p ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #includes aoqi@0: * @param incHash Hashtable loaded with Types to include aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeInheritedIncludes( aoqi@0: Hashtable inhHash, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Enumeration inhEnum = inhHash.elements(); aoqi@0: while ( inhEnum.hasMoreElements() ) { aoqi@0: CompoundType t = (CompoundType)inhEnum.nextElement(); aoqi@0: writeInclude( t,0,!isThrown,p ); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a #include. aoqi@0: * @param t Type to include aoqi@0: * @param dim The dimension to write if t is an array. aoqi@0: * @param isThrown boolean indicating if include is for thrown exception. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeInclude( aoqi@0: Type t, aoqi@0: int dim, aoqi@0: boolean isThrown, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: CompoundType ct; aoqi@0: String tName; aoqi@0: String[] modNames; aoqi@0: if ( t.isCompound() ) { aoqi@0: ct = (CompoundType)t; aoqi@0: String qName = ct.getQualifiedName(); aoqi@0: if ( "java.lang.String".equals( qName ) ) { aoqi@0: writeIncOrb( p ); //#include orb.idl for String aoqi@0: return; aoqi@0: } aoqi@0: if ( "org.omg.CORBA.Object".equals( qName ) ) aoqi@0: return; //Object treated like primitive aoqi@0: modNames = getIDLModuleNames( ct ); //module name array aoqi@0: tName = unEsc( ct.getIDLName() ); //file name default aoqi@0: aoqi@0: if ( ct.isException() ) aoqi@0: if ( ct.isIDLEntityException() ) aoqi@0: if ( ct.isCORBAUserException() ) aoqi@0: if ( isThrown ) tName = unEsc( ct.getIDLExceptionName() ); aoqi@0: else ; aoqi@0: else tName = ct.getName(); //use original IDL name aoqi@0: else if ( isThrown ) aoqi@0: tName = unEsc( ct.getIDLExceptionName() ); aoqi@0: } aoqi@0: else if ( t.isArray() ) { aoqi@0: Type et = t.getElementType(); //file name for sequence aoqi@0: if ( dim > 0 ) { aoqi@0: modNames = getIDLModuleNames( t ); //module name array aoqi@0: tName = "seq" + dim + "_" + unEsc( et.getIDLName().replace( ' ','_' ) ); aoqi@0: } aoqi@0: else{ //#include element aoqi@0: if ( !et.isCompound() ) return; //no include needed for primitive aoqi@0: ct = (CompoundType) et; aoqi@0: modNames = getIDLModuleNames( ct ); //no boxedRMI for element aoqi@0: tName = unEsc( ct.getIDLName() ); aoqi@0: writeInclude( ct,modNames,tName,p ); aoqi@0: return; aoqi@0: } aoqi@0: } aoqi@0: else return; //no include needed for primitive aoqi@0: writeInclude( t,modNames,tName,p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write a #include doing user specified -idlFile translation (if any) for aoqi@0: * IDLEntities. aoqi@0: * @param t Type to include. aoqi@0: * @param modNames Preprocessed module names (default). aoqi@0: * @param tName Preprocessed Type name (default). aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeInclude( aoqi@0: Type t, aoqi@0: String[] modNames, aoqi@0: String tName, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: if ( t.isCompound() ) { aoqi@0: CompoundType it = (CompoundType)t; aoqi@0: aoqi@0: if ( ifHash.size() > 0 && //any -idlFile translation to apply aoqi@0: it.isIDLEntity() ) { //..for this IDLEntity? aoqi@0: String qName = t.getQualifiedName(); //fully qualified orig Java name aoqi@0: aoqi@0: Enumeration k = ifHash.keys(); aoqi@0: while ( k.hasMoreElements() ) { //loop thro user-defined -idlFiles aoqi@0: String from = (String)k.nextElement(); aoqi@0: if ( qName.startsWith( from ) ) { //found a match? aoqi@0: String to = (String)ifHash.get( from ); aoqi@0: p.pln( "#include \"" + to + "\"" ); //user-specified idl filename aoqi@0: return; //don't look for any more aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: else if ( t.isArray() ) ; //no -idlFile translation needed for array aoqi@0: else return; //no #include needed for primitive aoqi@0: aoqi@0: p.p( "#include \"" ); //no -idlFile translation required aoqi@0: for ( int i1 = 0; i1 < modNames.length; i1++ ) p.p( modNames[i1] + "/" ); aoqi@0: p.p( tName + ".idl\"" ); aoqi@0: p.pln(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return the fully qualified Java Name for a Type. aoqi@0: * IDLEntity preprocessing done by getIDLModuleNames(t) aoqi@0: * @param t Given Type aoqi@0: * @return Array containing the original module nesting. aoqi@0: */ aoqi@0: protected String getQualifiedName( aoqi@0: Type t ) { aoqi@0: String[] modNames = getIDLModuleNames( t ); aoqi@0: int len = modNames.length; aoqi@0: StringBuffer buf = new StringBuffer(); aoqi@0: for ( int i1 = 0; i1 < len; i1++ ) aoqi@0: buf.append( modNames[i1] + "." ); aoqi@0: buf.append( t.getIDLName() ); aoqi@0: return buf.toString(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return the global fully qualified IDL Name for a Type. aoqi@0: * IDLEntity preprocessing done by getIDLModuleNames(t) aoqi@0: * @param t Given Type aoqi@0: * @return Array containing the original module nesting. aoqi@0: */ aoqi@0: protected String getQualifiedIDLName(Type t) { aoqi@0: if ( t.isPrimitive() ) aoqi@0: return t.getIDLName(); aoqi@0: if ( !t.isArray() && aoqi@0: "org.omg.CORBA.Object".equals( t.getQualifiedName() ) ) aoqi@0: return t.getIDLName(); aoqi@0: aoqi@0: String[] modNames = getIDLModuleNames( t ); aoqi@0: int len = modNames.length; aoqi@0: if (len > 0) { aoqi@0: StringBuffer buf = new StringBuffer(); aoqi@0: for ( int i1 = 0; i1 < len; i1++ ) aoqi@0: buf.append( IDL_NAME_SEPARATOR + modNames[i1] ); aoqi@0: buf.append( IDL_NAME_SEPARATOR + t.getIDLName() ); aoqi@0: return buf.toString(); aoqi@0: } else { aoqi@0: return t.getIDLName(); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Return the IDL module nesting of the given Type. aoqi@0: * For IDLEntity CompoundTypes (or their arrays) apply any user specified aoqi@0: * -idlModule translation or, if none applicable, strip any package aoqi@0: * prefix. aoqi@0: * Add boxedIDL or boxedRMI modules if required. aoqi@0: * @param t Given Type aoqi@0: * @return Array containing the original module nesting. aoqi@0: */ aoqi@0: protected String[] getIDLModuleNames(Type t) { aoqi@0: String[] modNames = t.getIDLModuleNames(); //default module name array aoqi@0: CompoundType ct; aoqi@0: if ( t.isCompound() ) { aoqi@0: ct = (CompoundType)t; aoqi@0: if ( !ct.isIDLEntity ) return modNames; //normal (non-IDLEntity) case aoqi@0: if ( "org.omg.CORBA.portable.IDLEntity" aoqi@0: .equals( t.getQualifiedName() ) ) aoqi@0: return modNames; aoqi@0: } aoqi@0: else if ( t.isArray() ) { aoqi@0: Type et = t.getElementType(); aoqi@0: if ( et.isCompound() ) { aoqi@0: ct = (CompoundType)et; aoqi@0: if ( !ct.isIDLEntity ) return modNames; //normal (non-IDLEntity) case aoqi@0: if ( "org.omg.CORBA.portable.IDLEntity" aoqi@0: .equals( t.getQualifiedName() ) ) aoqi@0: return modNames; aoqi@0: } aoqi@0: else return modNames; aoqi@0: } aoqi@0: else return modNames; //no preprocessing needed for primitives aoqi@0: aoqi@0: //it's an IDLEntity or an array of... aoqi@0: Vector mVec = new Vector(); aoqi@0: if ( !translateJavaPackage( ct,mVec ) ) //apply -idlModule translation aoqi@0: stripJavaPackage( ct,mVec ); //..or strip prefixes (not both) aoqi@0: aoqi@0: if ( ct.isBoxed() ) { //add boxedIDL if required aoqi@0: mVec.insertElementAt( "org",0 ); aoqi@0: mVec.insertElementAt( "omg",1 ); aoqi@0: mVec.insertElementAt( "boxedIDL",2 ); aoqi@0: } aoqi@0: if ( t.isArray() ) { //add boxedRMI if required aoqi@0: mVec.insertElementAt( "org",0 ); aoqi@0: mVec.insertElementAt( "omg",1 ); aoqi@0: mVec.insertElementAt( "boxedRMI",2 ); aoqi@0: } aoqi@0: String[] outArr = new String[mVec.size()]; aoqi@0: mVec.copyInto( outArr ); aoqi@0: return outArr; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Apply user specified -idlModule translation to package names of given aoqi@0: * IDLEntity ct. Example: aoqi@0: * -idlModule foo.bar real::mod::nesting aoqi@0: * @param ct CompoundType containing given IDLEntity. aoqi@0: * @param vec Returned Vector of translated IDL module names. aoqi@0: * @return boolean true if any translation was done. aoqi@0: */ aoqi@0: protected boolean translateJavaPackage( aoqi@0: CompoundType ct, aoqi@0: Vector vec ) { aoqi@0: vec.removeAllElements(); aoqi@0: boolean ret = false; aoqi@0: String fc = null; aoqi@0: if ( ! ct.isIDLEntity() ) return ret; aoqi@0: aoqi@0: String pName = ct.getPackageName(); //start from Java package names aoqi@0: if ( pName == null ) return ret; aoqi@0: StringTokenizer pt = new StringTokenizer( pName,"." ); aoqi@0: while ( pt.hasMoreTokens() ) vec.addElement( pt.nextToken() ); aoqi@0: aoqi@0: if ( imHash.size() > 0 ) { //any -idlModule translation to apply? aoqi@0: Enumeration k = imHash.keys(); aoqi@0: aoqi@0: nextModule: aoqi@0: while ( k.hasMoreElements() ) { //loop thro user-defined -idlModules aoqi@0: String from = (String)k.nextElement(); //from String.. aoqi@0: StringTokenizer ft = new StringTokenizer( from,"." ); aoqi@0: int vecLen = vec.size(); aoqi@0: int ifr; aoqi@0: for ( ifr = 0; ifr < vecLen && ft.hasMoreTokens(); ifr++ ) aoqi@0: if ( ! vec.elementAt(ifr).equals( ft.nextToken() ) ) aoqi@0: continue nextModule; //..no match aoqi@0: aoqi@0: if ( ft.hasMoreTokens() ) { //matched so far.. aoqi@0: fc = ft.nextToken(); //a 'from' token remains aoqi@0: if ( ! ct.getName().equals( fc ) || //matches class name? aoqi@0: ft.hasMoreTokens() ) aoqi@0: continue nextModule; //..no match aoqi@0: } aoqi@0: aoqi@0: ret = true; //found a match aoqi@0: for ( int i4 = 0; i4 < ifr; i4++ ) aoqi@0: vec.removeElementAt( 0 ); //remove 'from' package aoqi@0: aoqi@0: String to = (String)imHash.get( from ); //..to String aoqi@0: StringTokenizer tt = new StringTokenizer( to,IDL_NAME_SEPARATOR ); aoqi@0: aoqi@0: int itoco = tt.countTokens(); aoqi@0: int ito = 0; aoqi@0: if ( fc != null ) itoco--; //user may have given IDL type aoqi@0: for ( ito = 0; ito < itoco; ito++ ) aoqi@0: vec.insertElementAt( tt.nextToken(),ito ); //insert 'to' modules aoqi@0: if ( fc != null ) { aoqi@0: String tc = tt.nextToken(); aoqi@0: if ( ! ct.getName().equals( tc ) ) //not the IDL type, so.. aoqi@0: vec.insertElementAt( tc,ito ); //insert final 'to' module aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: return ret; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Strip Java #pragma prefix and/or -pkgPrefix prefix package names from aoqi@0: * given IDLEntity ct. aoqi@0: * Strip any package prefix which may have been added by comparing with aoqi@0: * repository id. For example in Java package fake.omega: aoqi@0: * repid = IDL:phoney.pfix/omega/Juliet:1.0 gives { "omega" } aoqi@0: * @param ct CompoundType containing given IDLEntity. aoqi@0: * @param vec Returned Vector of stripped IDL module names. aoqi@0: */ aoqi@0: protected void stripJavaPackage( aoqi@0: CompoundType ct, aoqi@0: Vector vec ) { aoqi@0: vec.removeAllElements(); aoqi@0: if ( ! ct.isIDLEntity() ) return; aoqi@0: aoqi@0: String repID = ct.getRepositoryID().substring( 4 ); aoqi@0: StringTokenizer rept = new StringTokenizer( repID,"/" ); aoqi@0: if ( rept.countTokens() < 2 ) return; aoqi@0: aoqi@0: while ( rept.hasMoreTokens() ) aoqi@0: vec.addElement( rept.nextToken() ); aoqi@0: vec.removeElementAt( vec.size() - 1 ); aoqi@0: aoqi@0: String pName = ct.getPackageName(); //start from Java package names aoqi@0: if ( pName == null ) return; aoqi@0: Vector pVec = new Vector(); aoqi@0: StringTokenizer pt = new StringTokenizer( pName,"." ); aoqi@0: while ( pt.hasMoreTokens() ) pVec.addElement( pt.nextToken() ); aoqi@0: aoqi@0: int i1 = vec.size() - 1; aoqi@0: int i2 = pVec.size() - 1; aoqi@0: while ( i1 >= 0 && i2 >= 0 ) { //go R->L till mismatch aoqi@0: String rep = (String)( vec.elementAt( i1 ) ); aoqi@0: String pkg = (String)( pVec.elementAt( i2 ) ); aoqi@0: if ( ! pkg.equals( rep ) ) break; aoqi@0: i1--; i2--; aoqi@0: } aoqi@0: for ( int i3 = 0; i3 <= i1; i3++ ) aoqi@0: vec.removeElementAt( 0 ); //strip prefix aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write boxedRMI valuetype for a single dimension of an IDL sequence aoqi@0: * indicated by the given OutputType. aoqi@0: * The filename for the OutputType is of the form "seqn_elemName" where n aoqi@0: * is the dimension required. aoqi@0: * @param ot Given OutputType. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeSequence( aoqi@0: OutputType ot, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: ArrayType at = (ArrayType)ot.getType(); aoqi@0: Type et = at.getElementType(); aoqi@0: String fName = ot.getName(); aoqi@0: int dim = Integer.parseInt( fName.substring( 3,fName.indexOf( "_" ) ) ); aoqi@0: String idlName = unEsc( et.getIDLName() ).replace( ' ','_' ); aoqi@0: String qIdlName = getQualifiedIDLName( et ); aoqi@0: String qName = et.getQualifiedName(); aoqi@0: aoqi@0: String repID = at.getRepositoryID(); aoqi@0: int rix1 = repID.indexOf( '[' ); //edit repository id aoqi@0: int rix2 = repID.lastIndexOf( '[' ) + 1; aoqi@0: StringBuffer rid = new StringBuffer( aoqi@0: repID.substring( 0,rix1 ) + aoqi@0: repID.substring( rix2 ) ); aoqi@0: for ( int i1 = 0; i1 < dim; i1++ ) rid.insert( rix1,'[' ); aoqi@0: aoqi@0: String vtName = "seq" + dim + "_" + idlName; aoqi@0: boolean isFromIDL = false; aoqi@0: if ( et.isCompound() ) { aoqi@0: CompoundType ct = (CompoundType)et; aoqi@0: isFromIDL = ct.isIDLEntity() || ct.isCORBAObject(); aoqi@0: } aoqi@0: boolean isForwardInclude = aoqi@0: et.isCompound() && aoqi@0: !isSpecialReference( et ) && aoqi@0: dim == 1 && aoqi@0: !isFromIDL && aoqi@0: !"org.omg.CORBA.Object".equals(qName) && aoqi@0: !"java.lang.String".equals(qName); aoqi@0: aoqi@0: writeBanner( at,dim,!isException,p ); aoqi@0: if ( dim == 1 && "java.lang.String".equals(qName) ) //special case aoqi@0: writeIncOrb( p ); aoqi@0: if ( dim == 1 && "org.omg.CORBA.Object".equals(qName) ) ; aoqi@0: else if ( isSpecialReference( et ) || dim > 1 || isFromIDL ) aoqi@0: writeInclude( at,dim-1,!isThrown,p ); //"trivial" include aoqi@0: writeIfndef( at,dim,!isException,!isForward,p ); aoqi@0: if ( isForwardInclude ) aoqi@0: writeForwardReference( at,dim-1,p ); //forward declare aoqi@0: writeModule1( at,p ); aoqi@0: p.pln();p.pI(); aoqi@0: p.p( "valuetype " + vtName ); aoqi@0: p.p( " sequence<" ); aoqi@0: if ( dim == 1 ) p.p( qIdlName ); aoqi@0: else { aoqi@0: p.p( "seq" + ( dim - 1 ) + "_" ); aoqi@0: p.p( idlName ); aoqi@0: } aoqi@0: p.pln( ">;" ); aoqi@0: p.pO();p.pln(); aoqi@0: p.pln( "#pragma ID " + vtName + " \"" + rid + "\"" ); aoqi@0: p.pln(); aoqi@0: writeModule2( at,p ); aoqi@0: if ( isForwardInclude ) aoqi@0: writeInclude( at,dim-1,!isThrown,p ); //#include for forward declare aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write valuetype for a boxed IDLEntity. aoqi@0: * @param t Given CompoundType representing the IDLEntity. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeBoxedIDL( aoqi@0: CompoundType t, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: String[] boxNames = getIDLModuleNames( t ); aoqi@0: int len = boxNames.length; aoqi@0: String[] modNames = new String[len - 3]; //remove box modules aoqi@0: for ( int i1 = 0; i1 < len - 3; i1++ ) modNames[i1] = boxNames[i1 + 3]; aoqi@0: String tName = unEsc( t.getIDLName() ); aoqi@0: aoqi@0: writeBanner( t,0,!isException,p ); aoqi@0: writeInclude( t,modNames,tName,p ); aoqi@0: writeIfndef( t,0,!isException,!isForward,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: aoqi@0: p.p( "valuetype " + tName + " " ); aoqi@0: for ( int i1 = 0; i1 < modNames.length; i1++ ) aoqi@0: p.p( IDL_NAME_SEPARATOR + modNames[i1] ); aoqi@0: p.pln( IDL_NAME_SEPARATOR + tName + ";" ); aoqi@0: aoqi@0: p.pO();p.pln(); aoqi@0: writeRepositoryID( t,p ); aoqi@0: p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an exception. aoqi@0: * @param t Given ClassType representing the exception. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeException( aoqi@0: ClassType t, aoqi@0: IndentingWriter p) aoqi@0: throws IOException { aoqi@0: writeBanner( t,0,isException,p ); aoqi@0: writeIfndef( t,0,isException,!isForward,p ); aoqi@0: writeForwardReference( t,p ); aoqi@0: writeModule1( t,p ); aoqi@0: p.pln();p.pI(); aoqi@0: aoqi@0: p.pln( "exception " + t.getIDLExceptionName() + " {" ); aoqi@0: p.pln();p.pI(); aoqi@0: p.pln( t.getIDLName() + " value;" ); aoqi@0: p.pO();p.pln(); aoqi@0: p.pln( "};" ); aoqi@0: aoqi@0: p.pO();p.pln(); aoqi@0: writeModule2( t,p ); aoqi@0: writeInclude( t,0,!isThrown,p ); //include valuetype idl file aoqi@0: writeEndif( p ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #pragma to identify the repository ID of the given type aoqi@0: * @param t The given Type. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeRepositoryID( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: String repid = t.getRepositoryID(); aoqi@0: if ( t.isCompound() ) { aoqi@0: CompoundType ct = (CompoundType)t; aoqi@0: if ( ct.isBoxed() ) aoqi@0: repid = ct.getBoxedRepositoryID(); aoqi@0: } aoqi@0: aoqi@0: p.pln( "#pragma ID " + t.getIDLName() + " \"" + aoqi@0: repid + "\"" ); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Write inheritance for an IDL interface or valuetype. Any class aoqi@0: * inheritance precedes any interface inheritance. aoqi@0: * For a valutype any inheritance from abstract interfaces then aoqi@0: * follows the "supports" keyword. aoqi@0: * @param inhHash Hashtable loaded with inherited Types aoqi@0: * @param forValuetype true if writing inheritance for a valuetype aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeInherits( aoqi@0: Hashtable inhHash, aoqi@0: boolean forValuetype, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: int itot = inhHash.size(); aoqi@0: int iinh = 0; aoqi@0: int isup = 0; aoqi@0: if ( itot < 1 ) return; //any inheritance to write? aoqi@0: Enumeration inhEnum = inhHash.elements(); aoqi@0: CompoundType ct; aoqi@0: if ( forValuetype ) aoqi@0: while ( inhEnum.hasMoreElements() ) { aoqi@0: ct = (CompoundType)inhEnum.nextElement(); aoqi@0: if ( ct.getTypeCode() == TYPE_ABSTRACT ) isup++; aoqi@0: } aoqi@0: iinh = itot - isup; aoqi@0: aoqi@0: if ( iinh > 0 ) { aoqi@0: p.p( ": " ); aoqi@0: inhEnum = inhHash.elements(); aoqi@0: while ( inhEnum.hasMoreElements() ) { //write any class inheritance aoqi@0: ct = (CompoundType)inhEnum.nextElement(); aoqi@0: if ( ct.isClass() ) { aoqi@0: p.p( getQualifiedIDLName( ct ) ); aoqi@0: if ( iinh > 1 ) p.p( ", " ); //delimit them with commas aoqi@0: else if ( itot > 1 ) p.p( " " ); aoqi@0: break; //only one parent aoqi@0: } aoqi@0: } aoqi@0: int i = 0; aoqi@0: inhEnum = inhHash.elements(); aoqi@0: while ( inhEnum.hasMoreElements() ) { //write any interface inheritance aoqi@0: ct = (CompoundType)inhEnum.nextElement(); aoqi@0: if ( !ct.isClass() && aoqi@0: !( ct.getTypeCode() == TYPE_ABSTRACT ) ) { aoqi@0: if ( i++ > 0 ) p.p( ", " ); //delimit with commas aoqi@0: p.p( getQualifiedIDLName( ct ) ); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: if ( isup > 0 ) { //write abstract interface inheritance aoqi@0: p.p( " supports " ); aoqi@0: int i = 0; aoqi@0: inhEnum = inhHash.elements(); aoqi@0: while ( inhEnum.hasMoreElements() ) { aoqi@0: ct = (CompoundType)inhEnum.nextElement(); aoqi@0: if ( ct.getTypeCode() == TYPE_ABSTRACT ) { aoqi@0: if ( i++ > 0 ) p.p( ", " ); //delimit with commas aoqi@0: p.p( getQualifiedIDLName( ct ) ); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL constant aoqi@0: * @param constant The current CompoundType.Member constant aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeConstant( aoqi@0: CompoundType.Member constant, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: Type t = constant.getType(); aoqi@0: p.p( "const " ); aoqi@0: p.p( getQualifiedIDLName( t ) ); aoqi@0: p.p( " " + constant.getIDLName() + " = " + constant.getValue() ); aoqi@0: p.pln( ";" ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL data member aoqi@0: * @param data The current CompoundType.Member data member aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeData( aoqi@0: CompoundType.Member data, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: if ( data.isInnerClassDeclaration() ) return; //ignore aoqi@0: Type t = data.getType(); aoqi@0: if ( data.isPublic() ) aoqi@0: p.p( "public " ); aoqi@0: else p.p( "private " ); aoqi@0: p.pln( getQualifiedIDLName( t ) + " " + aoqi@0: data.getIDLName() + ";" ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL Attribute aoqi@0: * @param attr The current CompoundType.Method attribute aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeAttribute( aoqi@0: CompoundType.Method attr, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: if ( attr.getAttributeKind() == ATTRIBUTE_SET ) return; //use getters only aoqi@0: Type t = attr.getReturnType(); aoqi@0: if ( !attr.isReadWriteAttribute() ) p.p( "readonly " ); aoqi@0: p.p( "attribute " + getQualifiedIDLName( t ) + " " ); aoqi@0: p.pln( attr.getAttributeName() + ";" ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write an IDL method aoqi@0: * @param method The current CompoundType.Method aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeMethod( aoqi@0: CompoundType.Method method, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: if ( method.isAttribute() ) { aoqi@0: writeAttribute( method,p ); aoqi@0: return; aoqi@0: } aoqi@0: Type[] pts = method.getArguments(); aoqi@0: String[] paramNames = method.getArgumentNames(); aoqi@0: Type rt = method.getReturnType(); aoqi@0: Hashtable excHash = new Hashtable(); aoqi@0: getExceptions( method,excHash ); aoqi@0: aoqi@0: if ( method.isConstructor() ) aoqi@0: if ( factory ) p.p( "factory " + method.getIDLName() + "(" ); aoqi@0: else p.p( "init(" ); //IDL initializer aoqi@0: else { aoqi@0: p.p( getQualifiedIDLName( rt ) ); aoqi@0: p.p( " " + method.getIDLName() + "(" ); aoqi@0: } aoqi@0: p.pI(); aoqi@0: aoqi@0: for ( int i=0; i < pts.length; i++ ) { aoqi@0: if ( i > 0 ) p.pln( "," ); //delimit with comma and newline aoqi@0: else p.pln(); aoqi@0: p.p( "in " ); aoqi@0: p.p( getQualifiedIDLName( pts[i] ) ); aoqi@0: p.p( " " + paramNames[i] ); aoqi@0: } aoqi@0: p.pO(); aoqi@0: p.p( " )" ); aoqi@0: aoqi@0: if ( excHash.size() > 0 ) { //any exceptions to write? aoqi@0: p.pln( " raises (" ); aoqi@0: p.pI(); aoqi@0: int i = 0; aoqi@0: Enumeration excEnum = excHash.elements(); aoqi@0: while ( excEnum.hasMoreElements() ) { aoqi@0: ValueType exc = (ValueType)excEnum.nextElement(); aoqi@0: if ( i > 0 ) p.pln( "," ); //delimit them with commas aoqi@0: if ( exc.isIDLEntityException() ) aoqi@0: if ( exc.isCORBAUserException() ) aoqi@0: p.p( "::org::omg::CORBA::UserEx" ); aoqi@0: else { aoqi@0: String[] modNames = getIDLModuleNames( exc ); aoqi@0: for ( int i2 = 0; i2 < modNames.length; i2++ ) aoqi@0: p.p( IDL_NAME_SEPARATOR + modNames[i2] ); aoqi@0: p.p( IDL_NAME_SEPARATOR + exc.getName() ); aoqi@0: } aoqi@0: else p.p( exc.getQualifiedIDLExceptionName( true ) ); aoqi@0: i++; aoqi@0: } aoqi@0: p.pO(); aoqi@0: p.p( " )" ); aoqi@0: } aoqi@0: aoqi@0: p.pln( ";" ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Remove escape character ("_"), if any, from given String aoqi@0: * @param name Given String aoqi@0: * @return String with any escape character removed aoqi@0: */ aoqi@0: protected String unEsc( aoqi@0: String name ) { aoqi@0: if ( name.startsWith( "_" ) ) return name.substring( 1 ); aoqi@0: else return name; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write IDL banner into the output stream for a given Type aoqi@0: * @param t The given Type. aoqi@0: * @param dim The dimension required if t is an ArrayType. aoqi@0: * @param isException true if writing an exception. aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeBanner( aoqi@0: Type t, aoqi@0: int dim, aoqi@0: boolean isException, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: String[] modNames = getIDLModuleNames( t ); //module name array aoqi@0: String fName = unEsc( t.getIDLName() ); //file name default aoqi@0: if ( isException && t.isClass() ) { aoqi@0: ClassType ct = (ClassType)t; //file name for Exception aoqi@0: fName = unEsc( ct.getIDLExceptionName() ); aoqi@0: } aoqi@0: if ( dim > 0 && t.isArray() ) { aoqi@0: Type et = t.getElementType(); //file name for sequence aoqi@0: fName = "seq" + dim + "_" + unEsc( et.getIDLName().replace( ' ','_' ) ); aoqi@0: } aoqi@0: aoqi@0: p.pln( "/**" ); aoqi@0: p.p( " * " ); aoqi@0: for ( int i1 = 0; i1 < modNames.length; i1++ ) aoqi@0: p.p( modNames[i1] + "/" ); aoqi@0: p.pln( fName + ".idl" ); aoqi@0: p.pln( " * Generated by rmic -idl. Do not edit" ); aoqi@0: String d = DateFormat.getDateTimeInstance( aoqi@0: DateFormat.FULL,DateFormat.FULL,Locale.getDefault() ) aoqi@0: .format( new Date() ); aoqi@0: String ocStr = "o'clock"; aoqi@0: int ocx = d.indexOf( ocStr ); //remove unwanted o'clock, if any aoqi@0: p.p ( " * " ); aoqi@0: if ( ocx > -1 ) aoqi@0: p.pln( d.substring( 0,ocx ) + d.substring( ocx + ocStr.length() ) ); aoqi@0: else p.pln( d ); aoqi@0: p.pln( " */" ); aoqi@0: p.pln(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #include for orb.idl aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeIncOrb( aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: p.pln( "#include \"orb.idl\"" ); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #ifndef guard into the output stream for a given Type aoqi@0: * @param t The given Type. aoqi@0: * @param dim The dimension required if t is an ArrayType. aoqi@0: * @param isException true if writing an exception. aoqi@0: * @param isForward. No #define needed if it's a forward declare aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeIfndef( aoqi@0: Type t, aoqi@0: int dim, aoqi@0: boolean isException, aoqi@0: boolean isForward, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: String[] modNames = getIDLModuleNames( t ); //module name array aoqi@0: String fName = unEsc( t.getIDLName() ); //file name default aoqi@0: if ( isException && t.isClass() ) { aoqi@0: ClassType ct = (ClassType)t; //file name for Exception aoqi@0: fName = unEsc( ct.getIDLExceptionName() ); aoqi@0: } aoqi@0: if ( dim > 0 && t.isArray() ) { aoqi@0: Type et = t.getElementType(); //file name for sequence aoqi@0: fName = "seq" + dim + "_" + unEsc( et.getIDLName().replace( ' ','_' ) ); aoqi@0: } aoqi@0: p.pln(); aoqi@0: p.p( "#ifndef __" ); aoqi@0: for ( int i = 0; i < modNames.length; i++ ) p.p( modNames[i] + "_" ); aoqi@0: p.pln( fName + "__" ); aoqi@0: if ( !isForward ) { aoqi@0: p.p( "#define __" ); aoqi@0: for ( int i = 0; i < modNames.length; i++ ) p.p( modNames[i] + "_" ); aoqi@0: p.pln( fName + "__" ); aoqi@0: p.pln(); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Write #endif bracket into the output stream aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeEndif( aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: p.pln("#endif"); aoqi@0: p.pln(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Write Module start bracketing for the given type into the output stream aoqi@0: * @param t The given Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeModule1( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: aoqi@0: String[] modNames = getIDLModuleNames( t ); aoqi@0: p.pln(); aoqi@0: for ( int i = 0; i < modNames.length; i++ ) aoqi@0: p.pln( "module " + modNames[i] + " {" ); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Write Module end bracketing for the given type into the output stream aoqi@0: * @param t The given Type aoqi@0: * @param p The output stream. aoqi@0: */ aoqi@0: protected void writeModule2( aoqi@0: Type t, aoqi@0: IndentingWriter p ) aoqi@0: throws IOException { aoqi@0: String[] modNames = getIDLModuleNames( t ); aoqi@0: for ( int i=0; i < modNames.length; i++ ) p.pln( "};" ); aoqi@0: p.pln(); aoqi@0: } aoqi@0: aoqi@0: }