IDLGenerator.java revision 673:6b017d166ac2
1/*
2 * Copyright (c) 1998, 2007, 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 * Licensed Materials - Property of IBM
27 * RMI-IIOP v1.0
28 * Copyright IBM Corp. 1998 1999  All Rights Reserved
29 *
30 */
31
32package sun.rmi.rmic.iiop;
33
34import java.io.File;
35import java.io.IOException;
36import java.text.DateFormat;
37import java.util.Date;
38import java.util.Enumeration;
39import java.util.Hashtable;
40import java.util.Locale;
41import java.util.StringTokenizer;
42import java.util.Vector;
43import sun.tools.java.Identifier;
44import sun.tools.java.ClassDefinition;
45import sun.tools.java.CompilerError;
46import sun.rmi.rmic.IndentingWriter;
47import java.util.HashSet;
48import sun.rmi.rmic.Main;
49
50/**
51 * An IDL generator for rmic.
52 *
53 * @author  Steve Newberry, Bryan Atsatt
54 */
55public class IDLGenerator extends sun.rmi.rmic.iiop.Generator {
56
57    private boolean valueMethods = true;
58    private boolean factory = true;                              //init==!factory
59    private Hashtable ifHash = new Hashtable();              //IDL file Hashtable
60    private Hashtable imHash = new Hashtable();            //IDL module Hashtable
61
62    private boolean isThrown = true;                      //flag for writeInclude
63    private boolean isException = true;       //flag for writeBanner, writeIfndef
64    private boolean isForward = true;                      //flag for writeIfndef
65    private boolean forValuetype = true;                 //flag for writeInherits
66
67    /**
68     * Default constructor for Main to use.
69     */
70    public IDLGenerator() {
71    }
72
73
74    /**
75     * Return true if a new instance should be created for each
76     * class on the command line. Subclasses which return true
77     * should override newInstance() to return an appropriately
78     * constructed instance.
79     */
80    protected boolean requireNewInstance() {
81        return false;
82    }
83
84    /**
85     * Return true if non-conforming types should be parsed.
86     * @param stack The context stack.
87     */
88    protected boolean parseNonConforming(ContextStack stack) {
89        return valueMethods;
90    }
91
92    /**
93     * Create and return a top-level type.
94     * @param cdef The top-level class definition.
95     * @param stack The context stack.
96     * @return An RemoteType or null if is non-conforming.
97     */
98    protected sun.rmi.rmic.iiop.CompoundType getTopType(ClassDefinition cdef,
99                                                        ContextStack stack) {
100        return CompoundType.forCompound(cdef,stack);
101    }
102
103
104    /**
105     * Return an Identifier which contains the fully-qualified IDL filename
106     * for the given OutputType.
107     * The OutputType contains a filename string (not directory) and Type.
108     * @param ot the OutputType for which directory nesting is to be defined.
109     * @return the new identifier.
110     */
111    protected Identifier getOutputId (
112                                      OutputType ot ) {
113        Identifier id = super.getOutputId( ot );
114
115        Type t = ot.getType();
116        String fName = ot.getName();
117
118        if ( id == idJavaLangClass )                 //java.lang.Class and array of
119            if ( t.isArray() )
120                return Identifier.lookup(
121                                         "org.omg.boxedRMI.javax.rmi.CORBA." + fName  );
122            else return idClassDesc;
123
124        if ( id == idJavaLangString &&                  //array of java.lang.String
125             t.isArray() )
126            return Identifier.lookup( "org.omg.boxedRMI.CORBA." + fName );
127
128        if ( "org.omg.CORBA.Object".equals( t.getQualifiedName() ) &&
129             t.isArray() )                          //array of org.omg.CORBA.Object
130            return Identifier.lookup( "org.omg.boxedRMI." + fName );
131
132        if ( t.isArray()) {                                                 //array
133            ArrayType at = (ArrayType)t;
134            Type et = at.getElementType();
135            if ( et.isCompound() ) {
136                CompoundType ct = (CompoundType)et;
137                String qName = ct.getQualifiedName();
138                if ( ct.isIDLEntity() )
139                    return Identifier.lookup( getQualifiedName( at ) );
140            }
141            return Identifier.lookup( idBoxedRMI,id );
142        }
143
144        if ( t.isCompound() ) {                                   //boxed IDLEntity
145            CompoundType ct = (CompoundType)t;
146            String qName = ct.getQualifiedName();
147            if ( ct.isBoxed() )
148                return Identifier.lookup( getQualifiedName( ct ) );
149        }
150
151        return id;
152    }
153
154
155
156    /**
157     * Return the file name extension for the given file name (e.g. ".java").
158     * All files generated with the ".java" extension will be compiled. To
159     * change this behavior for ".java" files, override the compileJavaSourceFile
160     * method to return false.
161     * @param outputType One of the items returned by getOutputTypesFor(...)
162     */
163    protected String getFileNameExtensionFor(OutputType outputType) {
164        return IDL_FILE_EXTENSION;
165    }
166
167
168    /**
169     * Examine and consume command line arguments.
170     * @param argv The command line arguments. Ignore null
171     * and unknown arguments. Set each consumed argument to null.
172     * @param main Report any errors using the main.error() methods.
173     * @return true if no errors, false otherwise.
174     */
175    public boolean parseArgs(String argv[], Main main) {
176        boolean result = super.parseArgs(argv,main);
177        String idlFrom;
178        String idlTo;
179        if (result) {
180        nextArg:
181            for (int i = 0; i < argv.length; i++) {
182                if (argv[i] != null) {
183                    if (argv[i].equalsIgnoreCase("-idl")) {
184                        idl = true;
185                        argv[i] = null;
186                    }
187                    else if ( argv[i].equalsIgnoreCase( "-valueMethods" ) ) {
188                        valueMethods = true;
189                        argv[i] = null;
190                    }
191                    else if ( argv[i].equalsIgnoreCase( "-noValueMethods" ) ) {
192                        valueMethods = false;
193                        argv[i] = null;
194                    }
195                    else if ( argv[i].equalsIgnoreCase( "-init" ) ) {
196                        factory = false;
197                        argv[i] = null;
198                    }
199                    else if ( argv[i].equalsIgnoreCase( "-factory" ) ) {
200                        factory = true;
201                        argv[i] = null;
202                    }
203                    else if ( argv[i].equalsIgnoreCase( "-idlfile" ) ) {
204                        argv[i] = null;
205                        if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) {
206                            idlFrom = argv[i];
207                            argv[i] = null;
208                            if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) {
209                                idlTo = argv[i];
210                                argv[i] = null;
211                                ifHash.put( idlFrom,idlTo );
212                                continue nextArg;
213                            }
214                        }
215                        main.error("rmic.option.requires.argument", "-idlfile");
216                        result = false;
217                    }
218                    else if ( argv[i].equalsIgnoreCase( "-idlmodule" ) ) {
219                        argv[i] = null;
220                        if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) {
221                            idlFrom = argv[i];
222                            argv[i] = null;
223                            if ( ++i < argv.length && argv[i] != null && !argv[i].startsWith("-") ) {
224                                idlTo = argv[i];
225                                argv[i] = null;
226                                imHash.put( idlFrom,idlTo );
227                                continue nextArg;
228                            }
229                        }
230                        main.error("rmic.option.requires.argument", "-idlmodule");
231                        result = false;
232                    }
233
234
235                }
236            }
237        }
238        return result;
239    }
240
241
242
243    /**
244     * Return an array of OutputTypes for the IDL files that need to be
245     * generated for the given top-level type.
246     * OutputTypes contain filename string (not directory) and Type.
247     * @param topType The type returned by getTopType().
248     * @param alreadyChecked A set of Types which have already been checked.
249     * @return Array of OutputTypes to generate
250     */
251    protected OutputType[] getOutputTypesFor(
252                                             CompoundType topType,
253                                             HashSet alreadyChecked ) {
254        Vector refVec = getAllReferencesFor( topType );
255        Vector outVec = new Vector();
256        for ( int i1 = 0; i1 < refVec.size(); i1++ ) {          //forall references
257            Type t = (Type)refVec.elementAt( i1 );
258            if ( t.isArray() ) {
259                ArrayType at = (ArrayType)t;
260                int dim = at.getArrayDimension();
261                Type et = at.getElementType();
262                String fName = unEsc( et.getIDLName() ).replace( ' ','_' );
263                for ( int i2 = 0; i2 < dim; i2++ ) {                //foreach dimension
264                    String fileName = "seq" + ( i2 + 1 ) + "_" + fName;
265                    outVec.addElement( new OutputType( fileName,at ) );
266                }
267            }
268            else if ( t.isCompound() ) {
269                String fName = unEsc( t.getIDLName() );
270                outVec.addElement( new OutputType( fName.replace( ' ','_' ),t ) );
271            if ( t.isClass() ) {
272                ClassType ct = (ClassType)t;
273                    if ( ct.isException() ) {                            //exception file
274                        fName = unEsc( ct.getIDLExceptionName() );
275                        outVec.addElement( new OutputType( fName.replace( ' ','_' ),t ) );
276            }
277        }
278    }
279    }
280        OutputType[] outArr = new OutputType[outVec.size()];
281        outVec.copyInto( outArr );
282        return outArr;
283    }
284
285    /**
286     * Get all referenced types of a given tyoe for which an IDL file needs
287     * to be generated.
288     * @param ct The given type.
289     * @return Vector of Types for which IDL must be generated.
290     */
291    protected Vector getAllReferencesFor(
292                                         CompoundType ct ) {
293        Hashtable refHash = new Hashtable();
294        Hashtable spcHash = new Hashtable();
295        Hashtable arrHash = new Hashtable();
296        int refSize;
297        refHash.put( ct.getQualifiedName(),ct );               //put the given type
298        accumulateReferences( refHash,spcHash,arrHash );
299        do {
300            refSize = refHash.size();
301            accumulateReferences( refHash,spcHash,arrHash );
302        }
303        while ( refSize < refHash.size() );        //till hashtable stays same size
304
305        Vector outVec = new Vector();
306        Enumeration e = refHash.elements();                   //ordinary references
307        while ( e.hasMoreElements() ) {
308            CompoundType t = (CompoundType)e.nextElement();
309            outVec.addElement( t );
310        }
311        e = spcHash.elements();                                //special references
312        while ( e.hasMoreElements() ) {
313            CompoundType t = (CompoundType)e.nextElement();
314            outVec.addElement( t );
315    }
316        e = arrHash.elements();                                  //array references
317                                         nextSequence:
318        while ( e.hasMoreElements() ) {
319            ArrayType at = (ArrayType)e.nextElement();
320            int dim = at.getArrayDimension();
321            Type et = at.getElementType();
322            Enumeration e2 = arrHash.elements();
323            while ( e2.hasMoreElements() ) {                   //eliminate duplicates
324                ArrayType at2 = (ArrayType)e2.nextElement();
325                if ( et == at2.getElementType() &&                //same element type &
326                     dim < at2.getArrayDimension() )               //smaller dimension?
327                    continue nextSequence;                              //ignore this one
328            }
329            outVec.addElement( at );
330        }
331        return outVec;
332    }
333
334
335    /**
336     * Accumulate and filter all those types that are referenced by the given
337     * referenced types.
338     * Keep only those for which IDL is to be generated.
339     * @param refHash Hashtable containing the given types
340     * @param spcHash Hashtable containing referenced specials (IDL typedefs)
341     * @param arrHash Hashtable containing referenced arrays (dimensioned)
342     */
343    protected void accumulateReferences(
344                                        Hashtable refHash,
345                                        Hashtable spcHash,
346                                        Hashtable arrHash ) {
347        Enumeration e = refHash.elements();
348        while ( e.hasMoreElements() ) {
349            CompoundType t = (CompoundType)e.nextElement();
350            Vector datVec = getData( t );                     //collect and sort data
351            Vector mthVec = getMethods( t );             //collect and filter methods
352            getInterfaces( t,refHash );                          //collect interfaces
353            getInheritance( t,refHash );                            //add inheritance
354            getMethodReferences( mthVec,refHash,spcHash,arrHash,refHash );
355            getMemberReferences( datVec,refHash,spcHash,arrHash );
356        }
357        e = arrHash.elements();                      //add array element references
358        while ( e.hasMoreElements() ) {
359            ArrayType at = (ArrayType)e.nextElement();
360            Type et = at.getElementType();
361            addReference( et,refHash,spcHash,arrHash );
362        }
363        e = refHash.elements();
364        while ( e.hasMoreElements() ) {
365            CompoundType t = (CompoundType)e.nextElement();
366            if ( !isIDLGeneratedFor( t ) )              //remove if no IDL generation
367                refHash.remove( t.getQualifiedName() );
368    }
369    }
370
371
372
373    /**
374     * Determine if IDL should be generated for a referenced type.
375     * Do not generate IDL for a CORBA Object reference. It gets mapped
376     * to the original IDL or to Object (if exactly org.omg.CORBA.Object)
377     * Generate (boxed) IDL for an IDL Entity unless it is an IDL user
378     * exception, a ValueBase, an AbstractBase (or a CORBA Object).
379     * Do not generate IDL for Implementation classes..unless they inherit
380     * from multiple distinct remote interfaces
381     * @param t The type to check.
382     * @return true or false
383     */
384    protected boolean isIDLGeneratedFor(
385                                 CompoundType t ) {
386        if ( t.isCORBAObject() ) return false;
387        if ( t.isIDLEntity() )
388            if ( t.isBoxed() ) return true;
389            else if ( "org.omg.CORBA.portable.IDLEntity"
390                      .equals( t.getQualifiedName() ) ) return true;
391            else if ( t.isCORBAUserException() ) return true;
392            else return false;
393        Hashtable inhHash = new Hashtable();
394        getInterfaces( t,inhHash );
395        if ( t.getTypeCode() == TYPE_IMPLEMENTATION )
396            if ( inhHash.size() < 2 ) return false;         //no multiple inheritance
397            else return true;
398        return true;                                   //generate IDL for this type
399    }
400
401
402    /**
403     * Write the output for the given OutputFileName into the output stream.
404     * (The IDL mapping for java.lang.Class is generated from
405     * javax.rmi.CORBA.ClassDesc in the tools workspace)
406     * @param ot One of the items returned by getOutputTypesFor(...)
407     * @param alreadyChecked A set of Types which have already been checked.
408     *  Intended to be passed to Type.collectMatching(filter,alreadyChecked).
409     * @param p The output stream.
410     */
411    protected void writeOutputFor(
412                                  OutputType ot,
413                                  HashSet alreadyChecked,
414                                  IndentingWriter p )
415        throws IOException {
416        Type t = ot.getType();
417        if ( t.isArray() ) {                                //specialcase: sequence
418            writeSequence( ot,p );
419            return;
420        }
421        if ( isSpecialReference( t ) ) {                //specialcase: IDL typecode
422            writeSpecial( t,p );
423            return;
424        }
425        if ( t.isCompound() ) {                            //specialcase: boxed IDL
426            CompoundType ct = (CompoundType)t;
427            if ( ct.isIDLEntity() && ct.isBoxed() ) {
428                writeBoxedIDL( ct,p );
429                return;
430            }
431        }
432        if ( t.isClass() ) {                               //specialcase: exception
433            ClassType ct = (ClassType)t;
434            if ( ct.isException() ) {
435                String eName = unEsc( ct.getIDLExceptionName() );
436                String fName = ot.getName();
437                if ( fName.equals( eName.replace( ' ','_' ) ) ) {
438                    writeException( ct,p );
439                    return;
440                }
441            }
442        }
443        switch ( t.getTypeCode() ) {                                 //general case
444        case TYPE_IMPLEMENTATION:
445            writeImplementation( (ImplementationType)t,p );
446            break;
447        case TYPE_NC_CLASS:
448        case TYPE_NC_INTERFACE:
449            writeNCType( (CompoundType)t,p );
450            break;
451        case TYPE_ABSTRACT:                        //AbstractType is a RemoteType
452        case TYPE_REMOTE:
453            writeRemote( (RemoteType)t,p );
454            break;
455        case TYPE_VALUE:
456            writeValue( (ValueType)t,p );
457            break;
458        default:
459            throw new CompilerError(
460                                    "IDLGenerator got unexpected type code: "
461                                    + t.getTypeCode());
462        }
463    }
464
465
466    /**
467     * Write an IDL interface definition for a Java implementation class
468     * @param t The current ImplementationType
469     * @param p The output stream.
470     */
471    protected void writeImplementation(
472                                       ImplementationType t,
473                                       IndentingWriter p )
474        throws IOException {
475        Hashtable inhHash = new Hashtable();
476        Hashtable refHash = new Hashtable();
477        getInterfaces( t,inhHash );                            //collect interfaces
478
479        writeBanner( t,0,!isException,p );
480        writeInheritedIncludes( inhHash,p );
481        writeIfndef( t,0,!isException,!isForward,p );
482        writeIncOrb( p );
483        writeModule1( t,p );
484        p.pln();p.pI();
485        p.p( "interface " + t.getIDLName() );
486        writeInherits( inhHash,!forValuetype,p );
487
488        p.pln( " {" );
489        p.pln( "};" );
490
491        p.pO();p.pln();
492        writeModule2( t,p );
493        writeEpilog( t,refHash,p );
494    }
495
496
497    /**
498     * Write an IDL valuetype definition for
499     * 1) a nonconforming Java class
500     * 2) a nonconforming Java interface (that is not an AbstractType)
501     * @param t The current NC Type (NCClassType or NCInterfaceType)
502     * @param p The output stream.
503     */
504    protected void writeNCType(
505                               CompoundType t,
506                               IndentingWriter p )
507        throws IOException {
508        Vector conVec = getConstants( t );                      //collect constants
509        Vector mthVec = getMethods( t );                          //collect methods
510        Hashtable inhHash = new Hashtable();
511        Hashtable refHash = new Hashtable();
512        Hashtable spcHash = new Hashtable();
513        Hashtable arrHash = new Hashtable();
514        Hashtable excHash = new Hashtable();
515        getInterfaces( t,inhHash );                            //collect interfaces
516        getInheritance( t,inhHash );                              //add inheritance
517        getMethodReferences( mthVec,refHash,spcHash,arrHash,excHash );
518
519        writeProlog( t,refHash,spcHash,arrHash,excHash,inhHash,p );
520        writeModule1( t,p );
521        p.pln();p.pI();
522        p.p( "abstract valuetype " + t.getIDLName() );
523        writeInherits( inhHash,!forValuetype,p );
524
525        p.pln( " {" );
526        if ( conVec.size() + mthVec.size() > 0 ) {                   //any content?
527            p.pln();p.pI();
528            for ( int i1 = 0; i1 < conVec.size(); i1++ )            //write constants
529                writeConstant( (CompoundType.Member)conVec.elementAt( i1 ),p );
530            for ( int i1 = 0; i1 < mthVec.size(); i1++ )              //write methods
531                writeMethod( (CompoundType.Method)mthVec.elementAt( i1 ),p );
532            p.pO();p.pln();
533        }
534        p.pln( "};" );
535
536                p.pO();p.pln();
537        writeModule2( t,p );
538        writeEpilog( t,refHash,p );
539    }
540
541
542    /**
543     * Write an IDL interface definition for either:
544     * 1) a conforming Java remote interface (RemoteType)..or
545     * 2) a non-conforming Java interface whose methods all throw
546     *     java.rmi.RemoteException (AbstractType)
547     * @param t The current RemoteType
548     * @param p The output stream.
549     */
550    protected void writeRemote(
551                               RemoteType t,
552                               IndentingWriter p )
553        throws IOException {
554        Vector conVec = getConstants( t );                      //collect constants
555        Vector mthVec = getMethods( t );                          //collect methods
556        Hashtable inhHash = new Hashtable();
557        Hashtable refHash = new Hashtable();
558        Hashtable spcHash = new Hashtable();
559        Hashtable arrHash = new Hashtable();
560        Hashtable excHash = new Hashtable();
561        getInterfaces( t,inhHash );                            //collect interfaces
562        getMethodReferences( mthVec,refHash,spcHash,arrHash,excHash );
563
564        writeProlog( t,refHash,spcHash,arrHash,excHash,inhHash,p );
565        writeModule1( t,p );
566        p.pln();p.pI();
567        if ( t.getTypeCode() == TYPE_ABSTRACT ) p.p( "abstract " );
568        p.p( "interface " + t.getIDLName() );
569        writeInherits( inhHash,!forValuetype,p );
570
571        p.pln( " {" );
572        if ( conVec.size() + mthVec.size() > 0 ) {      //any constants or methods?
573            p.pln();p.pI();
574            for ( int i1 = 0; i1 < conVec.size(); i1++ )                  //constants
575                writeConstant( (CompoundType.Member)conVec.elementAt( i1 ),p );
576            for ( int i1 = 0; i1 < mthVec.size(); i1++ )        //methods, attributes
577                writeMethod( (CompoundType.Method)mthVec.elementAt( i1 ),p );
578            p.pO();p.pln();
579        }
580        p.pln( "};" );
581
582        p.pO();p.pln();
583        writeRepositoryID ( t,p );
584        p.pln();
585        writeModule2( t,p );
586        writeEpilog( t,refHash,p );
587    }
588
589
590    /**
591     * Write an IDL valuetype definition for a conforming Java class.
592     * Methods and constructors are optional..controlled by -valueMethods flag
593     * @param t The current ValueType
594     * @param p The output stream.
595     */
596    protected void writeValue(
597                              ValueType t,
598                              IndentingWriter p )
599        throws IOException {
600        Vector datVec = getData( t );                       //collect and sort data
601        Vector conVec = getConstants( t );                      //collect constants
602        Vector mthVec = getMethods( t );               //collect and filter methods
603        Hashtable inhHash = new Hashtable();
604        Hashtable refHash = new Hashtable();
605        Hashtable spcHash = new Hashtable();
606        Hashtable arrHash = new Hashtable();
607        Hashtable excHash = new Hashtable();
608        getInterfaces( t,inhHash );                            //collect interfaces
609        getInheritance( t,inhHash );                              //add inheritance
610        getMethodReferences( mthVec,refHash,spcHash,arrHash,excHash );
611        getMemberReferences( datVec,refHash,spcHash,arrHash );
612
613        writeProlog( t,refHash,spcHash,arrHash,excHash,inhHash,p );
614        writeModule1( t,p );
615        p.pln();p.pI();
616        if ( t.isCustom() ) p.p( "custom " );
617        p.p( "valuetype " + t.getIDLName() );
618        writeInherits( inhHash,forValuetype,p );
619
620        p.pln( " {" );
621        if ( conVec.size() + datVec.size() + mthVec.size() > 0 ) {   //any content?
622            p.pln();p.pI();
623            for ( int i1 = 0; i1 < conVec.size(); i1++ )            //write constants
624                writeConstant( (CompoundType.Member)conVec.elementAt( i1 ),p );
625            for ( int i1 = 0; i1 < datVec.size(); i1++ ) {
626                CompoundType.Member mem = (CompoundType.Member)datVec.elementAt( i1 );
627                if ( mem.getType().isPrimitive() )
628                    writeData( mem,p );                            //write primitive data
629            }
630            for ( int i1 = 0; i1 < datVec.size(); i1++ ) {
631                CompoundType.Member mem = (CompoundType.Member)datVec.elementAt( i1 );
632                if ( !mem.getType().isPrimitive() )
633                    writeData( mem,p );                        //write non-primitive data
634            }
635            for ( int i1 = 0; i1 < mthVec.size(); i1++ )              //write methods
636                writeMethod( (CompoundType.Method)mthVec.elementAt( i1 ),p );
637            p.pO();p.pln();
638        }
639        p.pln( "};" );
640
641        p.pO();p.pln();
642        writeRepositoryID ( t,p );
643            p.pln();
644        writeModule2( t,p );
645        writeEpilog( t,refHash,p );
646        }
647
648
649    /**
650     * Write IDL prolog for a CompoundType.
651     * @param t The CompoundType.
652     * @param refHash Hashtable loaded with type references.
653     * @param spcHash Hashtable loaded with special type references.
654     * @param arrHash Hashtable loaded with array references.
655     * @param excHash Hashtable loaded with exceptions thrown.
656     * @param inhHash Hashtable loaded with inherited types.
657     * @param p The output stream.
658     */
659    protected void writeProlog(
660                               CompoundType t,
661                               Hashtable refHash,
662                               Hashtable spcHash,
663                               Hashtable arrHash,
664                               Hashtable excHash,
665                               Hashtable inhHash,
666                               IndentingWriter p )
667        throws IOException {
668        writeBanner( t,0,!isException,p );
669        writeForwardReferences( refHash,p );
670        writeIncludes( excHash,isThrown,p );      //#includes for exceptions thrown
671        writeInheritedIncludes( inhHash,p );
672        writeIncludes( spcHash,!isThrown,p );         //#includes for special types
673        writeBoxedRMIIncludes( arrHash,p );
674        writeIDLEntityIncludes( refHash,p );
675        writeIncOrb( p );
676        writeIfndef( t,0,!isException,!isForward,p );
677    }
678
679
680    /**
681     * Write IDL epilog for a CompoundType.
682     * @param t The CompoundType.
683     * @param refHash Hashtable loaded with type references.
684     * @param p The output stream.
685     */
686    protected void writeEpilog(
687                               CompoundType t,
688                               Hashtable refHash,
689                               IndentingWriter p )
690        throws IOException {
691        writeIncludes( refHash,!isThrown,p );     //#includes for forward dcl types
692        writeEndif( p );
693    }
694
695
696
697    /**
698     * Write special typedef
699     * @param t A special Type.
700     * @param p The output stream.
701     */
702    protected void writeSpecial(
703                                Type t,
704                                IndentingWriter p )
705        throws IOException {
706        String spcName = t.getQualifiedName();
707        if ( "java.io.Serializable".equals( spcName ) )
708            writeJavaIoSerializable( t,p );
709        else if ( "java.io.Externalizable".equals( spcName ) )
710            writeJavaIoExternalizable( t,p );
711        else if ( "java.lang.Object".equals( spcName) )
712            writeJavaLangObject( t,p );
713        else if ( "java.rmi.Remote".equals( spcName) )
714            writeJavaRmiRemote( t,p );
715        else if ( "org.omg.CORBA.portable.IDLEntity".equals( spcName) )
716            writeIDLEntity( t,p );
717    }
718
719
720
721    /**
722     * Write a hard-coded IDL typedef definition for the special case
723     * java.io.Serializable.
724     * @param t The current Type
725     * @param p The output stream.
726     */
727    protected void writeJavaIoSerializable(
728                                           Type t,
729                                           IndentingWriter p )
730        throws IOException {
731        writeBanner( t,0,!isException,p );
732        writeIfndef( t,0,!isException,!isForward,p );
733        writeModule1( t,p );
734        p.pln();p.pI();
735        p.pln( "typedef any Serializable;" );
736        p.pO();p.pln();
737        writeModule2( t,p );
738        writeEndif( p );
739    }
740
741
742    /**
743     * Write a hard-coded IDL typedef definition for the special case
744     * java.io.Externalizable.
745     * @param t The current Type
746     * @param p The output stream.
747     */
748    protected void writeJavaIoExternalizable(
749                                             Type t,
750                                             IndentingWriter p )
751        throws IOException {
752        writeBanner( t,0,!isException,p );
753        writeIfndef( t,0,!isException,!isForward,p );
754        writeModule1( t,p );
755        p.pln();p.pI();
756        p.pln( "typedef any Externalizable;" );
757        p.pO();p.pln();
758        writeModule2( t,p );
759        writeEndif( p );
760    }
761
762
763    /**
764     * Write a hard-coded IDL typedef definition for the special case
765     * java.lang.Object.
766     * @param t The current Type
767     * @param p The output stream.
768     */
769    protected void writeJavaLangObject(
770                                       Type t,
771                                       IndentingWriter p )
772        throws IOException {
773        writeBanner( t,0,!isException,p );
774        writeIfndef( t,0,!isException,!isForward,p );
775        writeModule1( t,p );
776        p.pln();p.pI();
777        p.pln( "typedef any _Object;" );
778        p.pO();p.pln();
779        writeModule2( t,p );
780        writeEndif( p );
781    }
782
783
784    /**
785     * Write a hard-coded IDL typedef definition for the special case
786     * java.rmi.Remote.
787     * @param t The current Type
788     * @param p The output stream.
789     */
790    protected void writeJavaRmiRemote(
791                                      Type t,
792                                      IndentingWriter p )
793        throws IOException {
794        writeBanner( t,0,!isException,p );
795        writeIfndef( t,0,!isException,!isForward,p );
796        writeModule1( t,p );
797        p.pln();p.pI();
798        p.pln( "typedef Object Remote;" );
799        p.pO();p.pln();
800        writeModule2( t,p );
801        writeEndif( p );
802    }
803
804
805
806    /**
807     * Write a hard-coded IDL typedef definition for the special case
808     * org.omg.CORBA.portable.IDLEntity
809     * @param t The current Type
810     * @param p The output stream.
811     */
812    protected void writeIDLEntity(
813                                  Type t,
814                                  IndentingWriter p )
815        throws IOException {
816        writeBanner( t,0,!isException,p );
817        writeIfndef( t,0,!isException,!isForward,p );
818        writeModule1( t,p );
819        p.pln();p.pI();
820        p.pln( "typedef any IDLEntity;" );
821        p.pO();p.pln();
822        writeModule2( t,p );
823        writeEndif( p );
824    }
825
826
827    /**
828     * Filter and collect non-duplicate inherited interfaces for a type
829     * @param ct The current CompoundType
830     * @param inhHash Hashtable containing the inherited interfaces
831     */
832    protected void getInterfaces(
833                                 CompoundType ct,
834                                 Hashtable inhHash ) {
835        InterfaceType[] infs = ct.getInterfaces();
836                                 nextInterface:
837        for ( int i1 = 0; i1 < infs.length; i1++ ) {  //forall inherited interfaces
838            String inhName = infs[i1].getQualifiedName();
839            switch ( ct.getTypeCode() ) {
840            case TYPE_NC_CLASS:
841            case TYPE_VALUE:                                   //filter for classes
842                if ( "java.io.Externalizable".equals( inhName ) ||
843                     "java.io.Serializable".equals( inhName ) ||
844                     "org.omg.CORBA.portable.IDLEntity".equals( inhName ) )
845                    continue nextInterface;
846                break;
847            default:                                        //filter for all others
848                if ( "java.rmi.Remote".equals( inhName ) )
849                    continue nextInterface;
850                break;
851            }
852            inhHash.put( inhName,infs[i1] );                           //add this one
853        }
854    }
855
856
857    /**
858     * Filter and add base class inheritance for a class type
859     * @param ct The current CompoundType
860     * @param inhHash Hashtable containing inherited types
861     */
862    protected void getInheritance(
863                                  CompoundType ct,
864                                  Hashtable inhHash ) {
865        ClassType par = ct.getSuperclass();                            //get parent
866        if ( par == null ) return;
867        String parName = par.getQualifiedName();
868        switch ( ct.getTypeCode() ) {
869        case TYPE_NC_CLASS:
870        case TYPE_VALUE:
871            if ( "java.lang.Object".equals( parName ) )          //this is implicit
872                return;
873            break;
874        default: return;                                     //ignore other types
875        }
876        inhHash.put( parName,par );                          //add valid base class
877    }
878
879
880    /**
881     * Collect and filter type and array references from methods
882     * @param mthVec Given Vector of methods
883     * @param refHash Hashtable for type references
884     * @param spcHash Hashtable for special type references
885     * @param arrHash Hashtable for array references
886     * @param excHash Hashtable for exceptions thrown
887     */
888    protected void getMethodReferences(
889                                       Vector mthVec,
890                                       Hashtable refHash,
891                                       Hashtable spcHash,
892                                       Hashtable arrHash,
893                                       Hashtable excHash ) {
894        for ( int i1 = 0; i1 < mthVec.size(); i1++ ) {             //forall methods
895            CompoundType.Method mth = (CompoundType.Method)mthVec.elementAt( i1 );
896            Type[] args = mth.getArguments();
897            Type ret = mth.getReturnType();
898            getExceptions( mth,excHash );                 //collect exceptions thrown
899            for ( int i2 = 0; i2 < args.length; i2++ )             //forall arguments
900                addReference( args[i2],refHash,spcHash,arrHash );
901            addReference( ret,refHash,spcHash,arrHash );
902        }
903    }
904
905
906    /**
907     * Collect and filter type and array references from data members
908     * @param datVec Given Vector of data members
909     * @param refHash Hashtable for type references
910     * @param spcHash Hashtable for special type references
911     * @param arrHash Hashtable for array references
912     */
913    protected void getMemberReferences(
914                                       Vector datVec,
915                                       Hashtable refHash,
916                                       Hashtable spcHash,
917                                       Hashtable arrHash ) {
918        for ( int i1 = 0; i1 < datVec.size(); i1++ ) {         //forall datamembers
919            CompoundType.Member mem = (CompoundType.Member)datVec.elementAt( i1 );
920            Type dat = mem.getType();
921            addReference( dat,refHash,spcHash,arrHash );
922        }
923    }
924
925
926    /**
927     * Add reference for given type avoiding duplication.
928     * Sort into specials, arrays and regular references.
929     * Filter out types which are not required.
930     * @param ref Given Type
931     * @param refHash Hashtable for type references
932     * @param spcHash Hashtable for special type references
933     * @param arrHash Hashtable for array references
934     */
935    protected void addReference(
936                                Type ref,
937                                Hashtable refHash,
938                                Hashtable spcHash,
939                                Hashtable arrHash ) {
940        String rName = ref.getQualifiedName();
941        switch ( ref.getTypeCode() ) {
942        case TYPE_ABSTRACT:
943        case TYPE_REMOTE:
944        case TYPE_NC_CLASS:
945        case TYPE_NC_INTERFACE:
946        case TYPE_VALUE:
947            refHash.put( rName,ref );
948            return;
949        case TYPE_CORBA_OBJECT:
950            if ( "org.omg.CORBA.Object".equals( rName ) ) return;      //don't want
951            refHash.put( rName,ref );
952            return;
953        case TYPE_ARRAY:                                                 //array?
954            arrHash.put( rName + ref.getArrayDimension(),ref );
955            return;
956        default:
957            if ( isSpecialReference( ref ) )                 //special IDL typedef?
958                spcHash.put( rName,ref );
959        }
960    }
961
962
963
964    /**
965     * Determine whether given Type is a special reference.
966     * Special cases are: java.io.Serializable, java.io.Externalizable,
967     * java.lang.Object, java.rmi.Remote and org.omg.CORBA.portable.IDLEntity
968     * They are special because they have a hard-coded typedef defined in the
969     * spec.
970     * @param ref A referenced Type
971     * @return boolean indicating whether it's a special reference
972     */
973    protected boolean isSpecialReference(
974                                         Type ref ) {
975        String rName = ref.getQualifiedName();
976        if ( "java.io.Serializable".equals( rName ) ) return true;
977        if ( "java.io.Externalizable".equals( rName ) ) return true;
978        if ( "java.lang.Object".equals( rName) ) return true;
979        if ( "java.rmi.Remote".equals( rName) ) return true;
980        if ( "org.omg.CORBA.portable.IDLEntity".equals( rName) ) return true;
981        return false;
982    }
983
984
985    /**
986     * Collect and filter thrown exceptions for a given pre-filtered method.
987     * Keep only 'checked' exception classes minus java.rmi.RemoteException
988     * and its subclasses
989     * @param mth The current method
990     * @param excHash Hashtable containing non-duplicate thrown exceptions
991     */
992    protected void getExceptions(
993                                      CompoundType.Method mth,
994                                      Hashtable excHash ) {
995        ClassType[] excs = mth.getExceptions();
996        for ( int i1 = 0; i1 < excs.length; i1++ ) {            //forall exceptions
997            ClassType exc = excs[i1];
998            if ( exc.isCheckedException() &&
999                 !exc.isRemoteExceptionOrSubclass() ) {
1000                excHash.put( exc.getQualifiedName(),exc );
1001        }
1002    }
1003    }
1004
1005
1006    /**
1007     * Collect and filter methods for a type.
1008     * Remove any private or inherited methods.
1009     * @param ct The current CompoundType
1010     * @return Vector containing the methods
1011     */
1012    protected Vector getMethods(
1013                                CompoundType ct ) {
1014        Vector vec = new Vector();
1015        int ctType = ct.getTypeCode();
1016        switch ( ctType ) {
1017        case TYPE_ABSTRACT:
1018        case TYPE_REMOTE:       break;
1019        case TYPE_NC_CLASS:
1020        case TYPE_NC_INTERFACE:
1021        case TYPE_VALUE:        if ( valueMethods ) break;
1022        default: return vec;
1023        }
1024        Identifier ctId = ct.getIdentifier();
1025        CompoundType.Method[] mths = ct.getMethods();
1026                                nextMethod:
1027        for ( int i1 = 0; i1 < mths.length; i1++ ) {               //forall methods
1028            if ( mths[i1].isPrivate() ||                            //private method?
1029                 mths[i1].isInherited() )                         //inherited method?
1030                continue nextMethod;                                   //yes..ignore it
1031            if ( ctType == TYPE_VALUE ) {
1032                String mthName = mths[i1].getName();
1033                if ( "readObject"  .equals( mthName ) ||
1034                     "writeObject" .equals( mthName ) ||
1035                     "readExternal".equals( mthName ) ||
1036                     "writeExternal".equals( mthName ) )
1037                    continue nextMethod;                                //ignore this one
1038            }
1039            if ( ( ctType == TYPE_NC_CLASS ||
1040                   ctType == TYPE_NC_INTERFACE ) &&
1041                 mths[i1].isConstructor() )   //init not valid for abstract valuetype
1042                continue nextMethod;                                  //ignore this one
1043            vec.addElement( mths[i1] );                                //add this one
1044        }
1045        return vec;
1046    }
1047
1048
1049    /**
1050     * Collect constants for a type.
1051     * A valid constant is a "public final static" field with a compile-time
1052     * constant value for a primitive type or String
1053     * @param ct The current CompoundType
1054     * @return Vector containing the constants
1055     */
1056    protected Vector getConstants(
1057                                  CompoundType ct ) {
1058        Vector vec = new Vector();
1059        CompoundType.Member[] mems = ct.getMembers();
1060        for ( int i1 = 0; i1 < mems.length; i1++ ) {               //forall members
1061            Type   memType  = mems[i1].getType();
1062            String memValue = mems[i1].getValue();
1063            if ( mems[i1].isPublic() &&
1064                 mems[i1].isFinal()  &&
1065                 mems[i1].isStatic() &&
1066                 ( memType.isPrimitive() || "String".equals( memType.getName() ) ) &&
1067                 memValue != null )
1068                vec.addElement( mems[i1] );                              //add this one
1069        }
1070        return vec;
1071    }
1072
1073
1074    /**
1075     * Collect and sort data fields for a ValueType.
1076     * Sort in Java (not IDL) Unicode name string lexicographic increasing
1077     * order.
1078     * Non-static, non-transient fields are mapped.
1079     * If the type is a custom valuetype, only public fields are mapped.
1080     * @param t The current CompoundType
1081     * @return Vector containing the data fields
1082     */
1083    protected Vector getData(
1084                             CompoundType t ) {
1085        Vector vec = new Vector();
1086        if ( t.getTypeCode() != TYPE_VALUE ) return vec;
1087        ValueType vt = (ValueType)t;
1088        CompoundType.Member[] mems = vt.getMembers();
1089        boolean notCust = !vt.isCustom();
1090        for ( int i1 = 0; i1 < mems.length; i1++ ) {               //forall members
1091            if ( !mems[i1].isStatic()    &&
1092                 !mems[i1].isTransient() &&
1093                 (  mems[i1].isPublic() || notCust ) ) {
1094                int i2;
1095                String memName = mems[i1].getName();
1096                for ( i2 = 0; i2 < vec.size(); i2++ ) {      //insert in java lex order
1097                    CompoundType.Member aMem = (CompoundType.Member)vec.elementAt( i2 );
1098                    if ( memName.compareTo( aMem.getName() ) < 0 ) break;
1099                }
1100                vec.insertElementAt( mems[i1],i2 );                   //insert this one
1101            }
1102        }
1103        return vec;
1104    }
1105
1106
1107    /**
1108     * Write forward references for referenced interfaces and valuetypes
1109     * ...but not if the reference is to a boxed IDLEntity,
1110     * @param refHash Hashtable loaded with referenced types
1111     * @param p The output stream.
1112     */
1113    protected void writeForwardReferences(
1114                                          Hashtable refHash,
1115                                          IndentingWriter p )
1116        throws IOException {
1117        Enumeration refEnum = refHash.elements();
1118        nextReference:
1119        while ( refEnum.hasMoreElements() ) {
1120            Type t = (Type)refEnum.nextElement();
1121            if ( t.isCompound() ) {
1122                CompoundType ct = (CompoundType)t;
1123                if ( ct.isIDLEntity() )
1124                    continue nextReference;                  //ignore IDLEntity reference
1125            }
1126            writeForwardReference( t,p );
1127        }
1128    }
1129
1130
1131    /**
1132     * Write forward reference for given type
1133     * @param t Given type
1134     * @param p The output stream.
1135     */
1136    protected void writeForwardReference(
1137                                         Type t,
1138                                         IndentingWriter p )
1139        throws IOException {
1140        String qName = t.getQualifiedName();
1141        if ( "java.lang.String".equals( qName ) ) ;
1142        else if ( "org.omg.CORBA.Object".equals( qName ) ) return ;    //no fwd dcl
1143
1144        writeIfndef( t,0,!isException,isForward,p );
1145            writeModule1( t,p );
1146            p.pln();p.pI();
1147            switch ( t.getTypeCode() ) {
1148        case TYPE_NC_CLASS:
1149            case TYPE_NC_INTERFACE: p.p( "abstract valuetype " ); break;
1150            case TYPE_ABSTRACT:     p.p( "abstract interface " ); break;
1151            case TYPE_VALUE:        p.p( "valuetype " ); break;
1152        case TYPE_REMOTE:
1153        case TYPE_CORBA_OBJECT: p.p( "interface " ); break;
1154            default: ;                              //all other types were filtered
1155            }
1156            p.pln( t.getIDLName() + ";" );
1157            p.pO();p.pln();
1158            writeModule2( t,p );
1159        writeEndif( p );
1160        }
1161
1162
1163    /**
1164     * Write forward reference for boxed valuetype for single dimension of IDL
1165     * sequence.
1166     * If the dimension is {@literal < 1} and the element is a CompoundType, write a
1167     * forward declare for the element
1168     * @param at ArrayType for forward declare
1169     * @param dim The dimension to write
1170     * @param p The output stream.
1171     */
1172    protected void writeForwardReference(
1173                                         ArrayType at,
1174                                         int dim,
1175                                         IndentingWriter p)
1176        throws IOException {
1177        Type et = at.getElementType();
1178        if ( dim < 1 ) {
1179            if ( et.isCompound() ) {
1180                CompoundType ct = (CompoundType)et;
1181                writeForwardReference( et,p);
1182    }
1183            return;
1184        }
1185        String fName = unEsc( et.getIDLName() ).replace( ' ','_' );
1186
1187        writeIfndef( at,dim,!isException,isForward,p );
1188        writeModule1( at,p );
1189        p.pln();p.pI();
1190        switch ( et.getTypeCode() ) {
1191        case TYPE_NC_CLASS:
1192        case TYPE_NC_INTERFACE: p.p( "abstract valuetype " ); break;
1193        case TYPE_ABSTRACT:     p.p( "abstract interface " ); break;
1194        case TYPE_VALUE:        p.p( "valuetype " ); break;
1195        case TYPE_REMOTE:
1196        case TYPE_CORBA_OBJECT: p.p( "interface " ); break;
1197        default: ;                              //all other types were filtered
1198        }
1199        p.pln( "seq" + dim + "_" + fName + ";" );
1200        p.pO();p.pln();
1201        writeModule2( at,p );
1202        writeEndif( p );
1203    }
1204
1205
1206    /**
1207     * Write #includes for boxed IDLEntity references.
1208     * @param refHash Hashtable loaded with referenced types
1209     * @param p The output stream.
1210     */
1211    protected void writeIDLEntityIncludes(
1212                                          Hashtable refHash,
1213                                          IndentingWriter p )
1214        throws IOException {
1215        Enumeration refEnum = refHash.elements();
1216        while ( refEnum.hasMoreElements() ) {
1217            Type t = (Type)refEnum.nextElement();
1218            if ( t.isCompound() ) {
1219                CompoundType ct = (CompoundType)t;
1220                if ( ct.isIDLEntity() ) {                          //select IDLEntities
1221                    writeInclude( ct,0,!isThrown,p );
1222                    refHash.remove( ct.getQualifiedName() );     //avoid another #include
1223                }
1224            }
1225        }
1226    }
1227
1228
1229    /**
1230     * Write #includes
1231     * @param incHash Hashtable loaded with Types to include
1232     * @param isThrown true if Types are thrown exceptions
1233     * @param p The output stream.
1234     */
1235    protected void writeIncludes(
1236                                 Hashtable incHash,
1237                                 boolean isThrown,
1238                                 IndentingWriter p )
1239        throws IOException {
1240        Enumeration incEnum = incHash.elements();
1241        while ( incEnum.hasMoreElements() ) {
1242            CompoundType t = (CompoundType)incEnum.nextElement();
1243            writeInclude( t,0,isThrown,p );
1244            }
1245    }
1246
1247
1248    /**
1249     * Write includes for boxedRMI valuetypes for IDL sequences.
1250     * Write only the maximum dimension found for an ArrayType.
1251     * @param arrHash Hashtable loaded with array types
1252     * @param p The output stream.
1253     */
1254    protected void writeBoxedRMIIncludes(
1255                                         Hashtable arrHash,
1256                                         IndentingWriter p)
1257        throws IOException {
1258        Enumeration e1 = arrHash.elements();
1259        nextSequence:
1260        while ( e1.hasMoreElements() ) {
1261            ArrayType at = (ArrayType)e1.nextElement();
1262            int dim = at.getArrayDimension();
1263            Type et = at.getElementType();
1264
1265            Enumeration e2 = arrHash.elements();
1266            while ( e2.hasMoreElements() ) {                   //eliminate duplicates
1267                ArrayType at2 = (ArrayType)e2.nextElement();
1268                if ( et == at2.getElementType() &&                //same element type &
1269                     dim < at2.getArrayDimension() )               //smaller dimension?
1270                    continue nextSequence;                              //ignore this one
1271        }
1272            writeInclude( at,dim,!isThrown,p );
1273    }
1274    }
1275
1276
1277    /**
1278     * Write #includes
1279     * @param inhHash Hashtable loaded with Types to include
1280     * @param p The output stream.
1281     */
1282    protected void writeInheritedIncludes(
1283                                          Hashtable inhHash,
1284                                 IndentingWriter p )
1285        throws IOException {
1286        Enumeration inhEnum = inhHash.elements();
1287        while ( inhEnum.hasMoreElements() ) {
1288            CompoundType t = (CompoundType)inhEnum.nextElement();
1289            writeInclude( t,0,!isThrown,p );
1290        }
1291    }
1292
1293
1294    /**
1295     * Write a #include.
1296     * @param t Type to include
1297     * @param dim The dimension to write if t is an array.
1298     * @param isThrown boolean indicating if include is for thrown exception.
1299     * @param p The output stream.
1300     */
1301    protected void writeInclude(
1302                                Type t,
1303                                int dim,
1304                                boolean isThrown,
1305                                  IndentingWriter p)
1306        throws IOException {
1307        CompoundType ct;
1308        String tName;
1309        String[] modNames;
1310        if ( t.isCompound() ) {
1311            ct = (CompoundType)t;
1312            String qName = ct.getQualifiedName();
1313            if ( "java.lang.String".equals( qName ) ) {
1314                writeIncOrb( p );                         //#include orb.idl for String
1315                return;
1316            }
1317            if ( "org.omg.CORBA.Object".equals( qName ) )
1318                return;                                 //Object treated like primitive
1319            modNames = getIDLModuleNames( ct );                   //module name array
1320            tName = unEsc( ct.getIDLName() );                     //file name default
1321
1322            if ( ct.isException() )
1323                if ( ct.isIDLEntityException() )
1324                    if ( ct.isCORBAUserException() )
1325                        if ( isThrown ) tName = unEsc( ct.getIDLExceptionName() );
1326                        else ;
1327                    else tName = ct.getName();                    //use original IDL name
1328                else if ( isThrown )
1329                    tName = unEsc( ct.getIDLExceptionName() );
1330            }
1331        else if ( t.isArray() ) {
1332            Type et = t.getElementType();                    //file name for sequence
1333            if ( dim > 0 ) {
1334                modNames = getIDLModuleNames( t );                  //module name array
1335                tName = "seq" + dim + "_" + unEsc( et.getIDLName().replace( ' ','_' ) );
1336            }
1337            else{                                                  //#include element
1338                if ( !et.isCompound() ) return;       //no include needed for primitive
1339                ct = (CompoundType) et;
1340                modNames = getIDLModuleNames( ct );           //no boxedRMI for element
1341                tName = unEsc( ct.getIDLName() );
1342                writeInclude( ct,modNames,tName,p );
1343                return;
1344            }
1345        }
1346        else return;                              //no include needed for primitive
1347        writeInclude( t,modNames,tName,p );
1348    }
1349
1350
1351    /**
1352     * Write a #include doing user specified -idlFile translation (if any) for
1353     * IDLEntities.
1354     * @param t Type to include.
1355     * @param modNames Preprocessed module names (default).
1356     * @param tName Preprocessed Type name (default).
1357     * @param p The output stream.
1358     */
1359    protected void writeInclude(
1360                                Type t,
1361                                String[] modNames,
1362                                String tName,
1363                                IndentingWriter p)
1364        throws IOException {
1365        if ( t.isCompound() ) {
1366            CompoundType it = (CompoundType)t;
1367
1368            if ( ifHash.size() > 0 &&             //any -idlFile translation to apply
1369                 it.isIDLEntity() ) {                         //..for this IDLEntity?
1370                String qName = t.getQualifiedName();   //fully qualified orig Java name
1371
1372                Enumeration k = ifHash.keys();
1373                while ( k.hasMoreElements() ) {      //loop thro user-defined -idlFiles
1374                    String from = (String)k.nextElement();
1375                    if ( qName.startsWith( from ) ) {                    //found a match?
1376                        String to = (String)ifHash.get( from );
1377                        p.pln( "#include \"" + to + "\"" );   //user-specified idl filename
1378                        return;                                   //don't look for any more
1379                    }
1380                }
1381            }
1382        }
1383        else if ( t.isArray() ) ;        //no -idlFile translation needed for array
1384        else return;                             //no #include needed for primitive
1385
1386        p.p( "#include \"" );                    //no -idlFile translation required
1387        for ( int i1 = 0; i1 < modNames.length; i1++ ) p.p( modNames[i1] + "/" );
1388        p.p( tName + ".idl\"" );
1389        p.pln();
1390    }
1391
1392
1393    /**
1394     * Return the fully qualified Java Name for a Type.
1395     * IDLEntity preprocessing done by getIDLModuleNames(t)
1396     * @param t Given Type
1397     * @return Array containing the original module nesting.
1398     */
1399    protected String getQualifiedName(
1400                                      Type t ) {
1401        String[] modNames = getIDLModuleNames( t );
1402        int len = modNames.length;
1403        StringBuffer buf = new StringBuffer();
1404        for ( int i1 = 0; i1 < len; i1++ )
1405            buf.append( modNames[i1] + "." );
1406        buf.append( t.getIDLName() );
1407        return buf.toString();
1408    }
1409
1410
1411    /**
1412     * Return the global fully qualified IDL Name for a Type.
1413     * IDLEntity preprocessing done by getIDLModuleNames(t)
1414     * @param t Given Type
1415     * @return Array containing the original module nesting.
1416     */
1417    protected String getQualifiedIDLName(Type t) {
1418        if ( t.isPrimitive() )
1419            return t.getIDLName();
1420        if ( !t.isArray() &&
1421             "org.omg.CORBA.Object".equals( t.getQualifiedName() ) )
1422            return t.getIDLName();
1423
1424        String[] modNames = getIDLModuleNames( t );
1425        int len = modNames.length;
1426        if (len > 0) {
1427            StringBuffer buf = new StringBuffer();
1428            for ( int i1 = 0; i1 < len; i1++ )
1429                buf.append( IDL_NAME_SEPARATOR + modNames[i1] );
1430            buf.append( IDL_NAME_SEPARATOR + t.getIDLName() );
1431            return buf.toString();
1432        } else {
1433            return t.getIDLName();
1434        }
1435    }
1436
1437
1438    /**
1439     * Return the IDL module nesting of the given Type.
1440     * For IDLEntity CompoundTypes (or their arrays) apply any user specified
1441     * -idlModule translation or, if none applicable, strip any package
1442     * prefix.
1443     * Add boxedIDL or boxedRMI modules if required.
1444     * @param t Given Type
1445     * @return Array containing the original module nesting.
1446     */
1447    protected String[] getIDLModuleNames(Type t) {
1448        String[] modNames = t.getIDLModuleNames();      //default module name array
1449        CompoundType ct;
1450        if ( t.isCompound() ) {
1451            ct = (CompoundType)t;
1452            if ( !ct.isIDLEntity ) return modNames;     //normal (non-IDLEntity) case
1453            if ( "org.omg.CORBA.portable.IDLEntity"
1454                 .equals( t.getQualifiedName() ) )
1455                return modNames;
1456        }
1457        else if ( t.isArray() ) {
1458            Type et = t.getElementType();
1459            if ( et.isCompound() ) {
1460                ct = (CompoundType)et;
1461                if ( !ct.isIDLEntity ) return modNames;   //normal (non-IDLEntity) case
1462                if ( "org.omg.CORBA.portable.IDLEntity"
1463                     .equals( t.getQualifiedName() ) )
1464                    return modNames;
1465            }
1466            else return modNames;
1467        }
1468        else return modNames;              //no preprocessing needed for primitives
1469
1470        //it's an IDLEntity or an array of...
1471        Vector mVec = new Vector();
1472        if ( !translateJavaPackage( ct,mVec ) )      //apply -idlModule translation
1473            stripJavaPackage( ct,mVec );             //..or strip prefixes (not both)
1474
1475        if ( ct.isBoxed() ) {                            //add boxedIDL if required
1476            mVec.insertElementAt( "org",0 );
1477            mVec.insertElementAt( "omg",1 );
1478            mVec.insertElementAt( "boxedIDL",2 );
1479        }
1480        if ( t.isArray() ) {                             //add boxedRMI if required
1481            mVec.insertElementAt( "org",0 );
1482            mVec.insertElementAt( "omg",1 );
1483            mVec.insertElementAt( "boxedRMI",2 );
1484        }
1485        String[] outArr = new String[mVec.size()];
1486        mVec.copyInto( outArr );
1487        return outArr;
1488    }
1489
1490
1491    /**
1492     * Apply user specified -idlModule translation to package names of given
1493     * IDLEntity ct. Example:
1494     *   -idlModule foo.bar real::mod::nesting
1495     * @param ct CompoundType containing given IDLEntity.
1496     * @param vec Returned Vector of translated IDL module names.
1497     * @return boolean true if any translation was done.
1498     */
1499    protected boolean translateJavaPackage(
1500                                           CompoundType ct,
1501                                           Vector vec ) {
1502        vec.removeAllElements();
1503        boolean ret = false;
1504        String fc = null;
1505        if ( ! ct.isIDLEntity() ) return ret;
1506
1507        String pName = ct.getPackageName();         //start from Java package names
1508        if ( pName == null ) return ret;
1509        StringTokenizer pt = new StringTokenizer( pName,"." );
1510        while ( pt.hasMoreTokens() ) vec.addElement( pt.nextToken() );
1511
1512        if ( imHash.size() > 0 ) {           //any -idlModule translation to apply?
1513            Enumeration k = imHash.keys();
1514
1515        nextModule:
1516            while ( k.hasMoreElements() ) {      //loop thro user-defined -idlModules
1517                String from = (String)k.nextElement();                  //from String..
1518                StringTokenizer ft = new StringTokenizer( from,"." );
1519                int vecLen = vec.size();
1520                int ifr;
1521                for ( ifr = 0; ifr < vecLen && ft.hasMoreTokens(); ifr++ )
1522                    if ( ! vec.elementAt(ifr).equals( ft.nextToken() ) )
1523                        continue nextModule;                                  //..no match
1524
1525                if ( ft.hasMoreTokens() ) {                          //matched so far..
1526                    fc = ft.nextToken();                         //a 'from' token remains
1527                    if ( ! ct.getName().equals( fc ) ||             //matches class name?
1528                         ft.hasMoreTokens() )
1529                        continue nextModule;                                   //..no match
1530                }
1531
1532                ret = true;                                             //found a match
1533                for ( int i4 = 0; i4 < ifr; i4++ )
1534                    vec.removeElementAt( 0 );                     //remove 'from' package
1535
1536                String to = (String)imHash.get( from );                   //..to String
1537                StringTokenizer tt = new StringTokenizer( to,IDL_NAME_SEPARATOR );
1538
1539                int itoco = tt.countTokens();
1540                int ito = 0;
1541                if ( fc != null ) itoco--;               //user may have given IDL type
1542                for ( ito = 0; ito < itoco; ito++ )
1543                    vec.insertElementAt( tt.nextToken(),ito );      //insert 'to' modules
1544                if ( fc != null ) {
1545                    String tc = tt.nextToken();
1546                    if ( ! ct.getName().equals( tc ) )           //not the IDL type, so..
1547                        vec.insertElementAt( tc,ito );           //insert final 'to' module
1548                }
1549            }
1550        }
1551        return ret;
1552    }
1553
1554
1555    /**
1556     * Strip Java #pragma prefix and/or -pkgPrefix prefix package names from
1557     * given IDLEntity ct.
1558     * Strip any package prefix which may have been added by comparing with
1559     * repository id. For example in Java package fake.omega:
1560     *   repid = IDL:phoney.pfix/omega/Juliet:1.0 gives { "omega" }
1561     * @param ct CompoundType containing given IDLEntity.
1562     * @param vec Returned Vector of stripped IDL module names.
1563     */
1564    protected void stripJavaPackage(
1565                                    CompoundType ct,
1566                                    Vector vec ) {
1567        vec.removeAllElements();
1568        if ( ! ct.isIDLEntity() ) return;
1569
1570        String repID = ct.getRepositoryID().substring( 4 );
1571        StringTokenizer rept = new StringTokenizer( repID,"/" );
1572        if ( rept.countTokens() < 2 ) return;
1573
1574        while ( rept.hasMoreTokens() )
1575            vec.addElement( rept.nextToken() );
1576        vec.removeElementAt( vec.size() - 1 );
1577
1578        String pName = ct.getPackageName();         //start from Java package names
1579        if ( pName == null ) return;
1580        Vector pVec = new Vector();
1581        StringTokenizer pt = new StringTokenizer( pName,"." );
1582        while ( pt.hasMoreTokens() ) pVec.addElement( pt.nextToken() );
1583
1584        int i1 = vec.size() - 1;
1585        int i2 = pVec.size() - 1;
1586        while ( i1 >= 0 && i2 >= 0 ) {                      //go R->L till mismatch
1587            String rep = (String)( vec.elementAt( i1 ) );
1588            String pkg = (String)( pVec.elementAt( i2 ) );
1589            if ( ! pkg.equals( rep ) ) break;
1590            i1--; i2--;
1591        }
1592        for ( int i3 = 0; i3 <= i1; i3++ )
1593            vec.removeElementAt( 0 );                                  //strip prefix
1594    }
1595
1596
1597
1598    /**
1599     * Write boxedRMI valuetype for a single dimension of an IDL sequence
1600     * indicated by the given OutputType.
1601     * The filename for the OutputType is of the form "seqn_elemName" where n
1602     * is the dimension required.
1603     * @param ot Given OutputType.
1604     * @param p The output stream.
1605     */
1606    protected void writeSequence(
1607                                 OutputType ot,
1608                                 IndentingWriter p)
1609        throws IOException {
1610        ArrayType at = (ArrayType)ot.getType();
1611        Type et = at.getElementType();
1612        String fName = ot.getName();
1613        int dim = Integer.parseInt( fName.substring( 3,fName.indexOf( "_" ) ) );
1614        String idlName = unEsc( et.getIDLName() ).replace( ' ','_' );
1615        String qIdlName = getQualifiedIDLName( et );
1616        String qName = et.getQualifiedName();
1617
1618        String repID = at.getRepositoryID();
1619        int rix1 = repID.indexOf( '[' );                       //edit repository id
1620        int rix2 = repID.lastIndexOf( '[' ) + 1;
1621            StringBuffer rid = new StringBuffer(
1622                                            repID.substring( 0,rix1 ) +
1623                                            repID.substring( rix2 ) );
1624        for ( int i1 = 0; i1 < dim; i1++ ) rid.insert( rix1,'[' );
1625
1626        String vtName = "seq" + dim + "_" + idlName;
1627        boolean isFromIDL = false;
1628        if ( et.isCompound() ) {
1629            CompoundType ct = (CompoundType)et;
1630            isFromIDL = ct.isIDLEntity() || ct.isCORBAObject();
1631        }
1632        boolean isForwardInclude =
1633            et.isCompound() &&
1634            !isSpecialReference( et ) &&
1635            dim == 1 &&
1636            !isFromIDL &&
1637            !"org.omg.CORBA.Object".equals(qName) &&
1638            !"java.lang.String".equals(qName);
1639
1640        writeBanner( at,dim,!isException,p );
1641        if ( dim == 1 && "java.lang.String".equals(qName) )          //special case
1642            writeIncOrb( p );
1643        if ( dim == 1 && "org.omg.CORBA.Object".equals(qName) ) ;
1644        else if ( isSpecialReference( et ) || dim > 1 || isFromIDL )
1645            writeInclude( at,dim-1,!isThrown,p );               //"trivial" include
1646        writeIfndef( at,dim,!isException,!isForward,p );
1647        if ( isForwardInclude )
1648            writeForwardReference( at,dim-1,p );                    //forward declare
1649        writeModule1( at,p );
1650                p.pln();p.pI();
1651                p.p( "valuetype " + vtName );
1652                p.p( " sequence<" );
1653        if ( dim == 1 ) p.p( qIdlName );
1654                else {
1655            p.p( "seq" + ( dim - 1 ) + "_"  );
1656                    p.p( idlName );
1657                }
1658                p.pln( ">;" );
1659                p.pO();p.pln();
1660                p.pln( "#pragma ID " + vtName + " \"" + rid + "\"" );
1661                p.pln();
1662        writeModule2( at,p );
1663        if ( isForwardInclude )
1664            writeInclude( at,dim-1,!isThrown,p );      //#include for forward declare
1665                writeEndif( p );
1666            }
1667
1668
1669    /**
1670     * Write valuetype for a boxed IDLEntity.
1671     * @param t Given CompoundType representing the IDLEntity.
1672     * @param p The output stream.
1673     */
1674    protected void writeBoxedIDL(
1675                                 CompoundType t,
1676                                 IndentingWriter p)
1677        throws IOException {
1678        String[] boxNames = getIDLModuleNames( t );
1679        int len = boxNames.length;
1680        String[] modNames = new String[len - 3];               //remove box modules
1681        for ( int i1 = 0; i1 < len - 3; i1++ ) modNames[i1] = boxNames[i1 + 3];
1682        String tName = unEsc( t.getIDLName() );
1683
1684        writeBanner( t,0,!isException,p );
1685        writeInclude( t,modNames,tName,p );
1686        writeIfndef( t,0,!isException,!isForward,p );
1687        writeModule1( t,p );
1688        p.pln();p.pI();
1689
1690        p.p( "valuetype " + tName + " " );
1691        for ( int i1 = 0; i1 < modNames.length; i1++ )
1692            p.p( IDL_NAME_SEPARATOR + modNames[i1] );
1693        p.pln( IDL_NAME_SEPARATOR + tName + ";" );
1694
1695        p.pO();p.pln();
1696        writeRepositoryID( t,p );
1697        p.pln();
1698        writeModule2( t,p );
1699        writeEndif( p );
1700        }
1701
1702
1703    /**
1704     * Write an exception.
1705     * @param t Given ClassType representing the exception.
1706     * @param p The output stream.
1707     */
1708    protected void writeException(
1709                                  ClassType t,
1710                                  IndentingWriter p)
1711        throws IOException {
1712        writeBanner( t,0,isException,p );
1713        writeIfndef( t,0,isException,!isForward,p );
1714        writeForwardReference( t,p );
1715        writeModule1( t,p );
1716        p.pln();p.pI();
1717
1718        p.pln( "exception " + t.getIDLExceptionName() + " {" );
1719        p.pln();p.pI();
1720        p.pln( t.getIDLName() + " value;" );
1721        p.pO();p.pln();
1722        p.pln( "};" );
1723
1724        p.pO();p.pln();
1725        writeModule2( t,p );
1726        writeInclude( t,0,!isThrown,p );               //include valuetype idl file
1727        writeEndif( p );
1728    }
1729
1730
1731    /**
1732     * Write #pragma to identify the repository ID of the given type
1733     * @param t The given Type.
1734     * @param p The output stream.
1735     */
1736    protected void writeRepositoryID(
1737                                     Type t,
1738                                     IndentingWriter p )
1739        throws IOException {
1740        String repid = t.getRepositoryID();
1741        if ( t.isCompound() ) {
1742            CompoundType ct = (CompoundType)t;
1743            if ( ct.isBoxed() )
1744                repid = ct.getBoxedRepositoryID();
1745        }
1746
1747        p.pln( "#pragma ID " + t.getIDLName() + " \"" +
1748               repid + "\"" );
1749    }
1750
1751    /**
1752     * Write inheritance for an IDL interface or valuetype. Any class
1753     * inheritance precedes any interface inheritance.
1754     * For a valutype any inheritance from abstract interfaces then
1755     * follows the "supports" keyword.
1756     * @param inhHash Hashtable loaded with inherited Types
1757     * @param forValuetype true if writing inheritance for a valuetype
1758     * @param p The output stream.
1759     */
1760    protected void writeInherits(
1761                                 Hashtable inhHash,
1762                                 boolean forValuetype,
1763                                 IndentingWriter p )
1764        throws IOException {
1765        int itot = inhHash.size();
1766        int iinh = 0;
1767        int isup = 0;
1768        if ( itot < 1 ) return;                         //any inheritance to write?
1769        Enumeration inhEnum = inhHash.elements();
1770        CompoundType ct;
1771        if ( forValuetype )
1772            while ( inhEnum.hasMoreElements() ) {
1773                ct = (CompoundType)inhEnum.nextElement();
1774                if ( ct.getTypeCode() == TYPE_ABSTRACT ) isup++;
1775            }
1776        iinh = itot - isup;
1777
1778        if ( iinh > 0 ) {
1779        p.p( ": " );
1780            inhEnum = inhHash.elements();
1781        while ( inhEnum.hasMoreElements() ) {         //write any class inheritance
1782                ct = (CompoundType)inhEnum.nextElement();
1783                if ( ct.isClass() ) {
1784                    p.p( getQualifiedIDLName( ct ) );
1785                    if ( iinh > 1 ) p.p( ", " );               //delimit them with commas
1786                    else if ( itot > 1 ) p.p( " " );
1787                break;                                                //only one parent
1788            }
1789        }
1790            int i = 0;
1791        inhEnum = inhHash.elements();
1792        while ( inhEnum.hasMoreElements() ) {     //write any interface inheritance
1793                ct = (CompoundType)inhEnum.nextElement();
1794                if ( !ct.isClass() &&
1795                     !( ct.getTypeCode() == TYPE_ABSTRACT ) ) {
1796                    if ( i++ > 0 ) p.p( ", " );                     //delimit with commas
1797                    p.p( getQualifiedIDLName( ct ) );
1798            }
1799        }
1800    }
1801        if ( isup > 0 ) {                    //write abstract interface inheritance
1802            p.p( " supports " );
1803            int i = 0;
1804            inhEnum = inhHash.elements();
1805            while ( inhEnum.hasMoreElements() ) {
1806                ct = (CompoundType)inhEnum.nextElement();
1807                if ( ct.getTypeCode() == TYPE_ABSTRACT ) {
1808                    if ( i++ > 0 ) p.p( ", " );                     //delimit with commas
1809                    p.p( getQualifiedIDLName( ct ) );
1810                }
1811            }
1812        }
1813    }
1814
1815
1816    /**
1817     * Write an IDL constant
1818     * @param constant The current CompoundType.Member constant
1819     * @param p The output stream.
1820     */
1821    protected void writeConstant(
1822                                 CompoundType.Member constant,
1823                                 IndentingWriter p )
1824        throws IOException {
1825        Type t = constant.getType();
1826        p.p( "const " );
1827        p.p( getQualifiedIDLName( t ) );
1828        p.p( " " + constant.getIDLName() + " = " + constant.getValue() );
1829        p.pln( ";" );
1830    }
1831
1832
1833
1834    /**
1835     * Write an IDL data member
1836     * @param data The current CompoundType.Member data member
1837     * @param p The output stream.
1838     */
1839    protected void writeData(
1840                             CompoundType.Member data,
1841                             IndentingWriter p )
1842        throws IOException {
1843        if ( data.isInnerClassDeclaration() ) return;                      //ignore
1844        Type t = data.getType();
1845        if ( data.isPublic() )
1846            p.p( "public " );
1847        else p.p( "private " );
1848        p.pln( getQualifiedIDLName( t ) +  " " +
1849               data.getIDLName() + ";" );
1850    }
1851
1852
1853
1854    /**
1855     * Write an IDL Attribute
1856     * @param attr The current CompoundType.Method attribute
1857     * @param p The output stream.
1858     */
1859    protected void writeAttribute(
1860                                  CompoundType.Method attr,
1861                                  IndentingWriter p )
1862        throws IOException {
1863        if ( attr.getAttributeKind() == ATTRIBUTE_SET ) return;  //use getters only
1864        Type t = attr.getReturnType();
1865        if ( !attr.isReadWriteAttribute() ) p.p( "readonly " );
1866        p.p( "attribute " + getQualifiedIDLName( t ) + " " );
1867        p.pln( attr.getAttributeName() + ";" );
1868    }
1869
1870
1871
1872    /**
1873     * Write an IDL method
1874     * @param method The current CompoundType.Method
1875     * @param p The output stream.
1876     */
1877    protected void writeMethod(
1878                               CompoundType.Method method,
1879                               IndentingWriter p )
1880        throws IOException {
1881        if ( method.isAttribute() ) {
1882            writeAttribute( method,p );
1883            return;
1884        }
1885        Type[]    pts = method.getArguments();
1886        String[]  paramNames = method.getArgumentNames();
1887        Type      rt = method.getReturnType();
1888        Hashtable excHash = new Hashtable();
1889        getExceptions( method,excHash );
1890
1891        if ( method.isConstructor() )
1892            if ( factory ) p.p( "factory " + method.getIDLName() + "(" );
1893            else p.p( "init(" );                                    //IDL initializer
1894        else {
1895            p.p( getQualifiedIDLName( rt ) );
1896            p.p( " " + method.getIDLName() + "(" );
1897        }
1898        p.pI();
1899
1900        for ( int i=0; i < pts.length; i++ ) {
1901            if ( i > 0 ) p.pln( "," );               //delimit with comma and newline
1902            else p.pln();
1903            p.p( "in " );
1904            p.p( getQualifiedIDLName( pts[i] ) );
1905            p.p( " " + paramNames[i] );
1906        }
1907        p.pO();
1908        p.p( " )" );
1909
1910        if ( excHash.size() > 0 ) {                      //any exceptions to write?
1911            p.pln( " raises (" );
1912            p.pI();
1913            int i = 0;
1914            Enumeration excEnum = excHash.elements();
1915            while ( excEnum.hasMoreElements() ) {
1916                ValueType exc = (ValueType)excEnum.nextElement();
1917                if ( i > 0 ) p.pln( "," );                   //delimit them with commas
1918                if ( exc.isIDLEntityException() )
1919                    if ( exc.isCORBAUserException() )
1920                        p.p( "::org::omg::CORBA::UserEx" );
1921                    else {
1922                        String[] modNames = getIDLModuleNames( exc );
1923                        for ( int i2 = 0; i2 < modNames.length; i2++ )
1924                            p.p( IDL_NAME_SEPARATOR + modNames[i2] );
1925                        p.p( IDL_NAME_SEPARATOR + exc.getName() );
1926                    }
1927                else p.p( exc.getQualifiedIDLExceptionName( true ) );
1928                i++;
1929            }
1930            p.pO();
1931            p.p( " )" );
1932        }
1933
1934        p.pln( ";" );
1935    }
1936
1937
1938    /**
1939     * Remove escape character ("_"), if any, from given String
1940     * @param name Given String
1941     * @return String with any escape character removed
1942     */
1943    protected String unEsc(
1944                           String name ) {
1945        if ( name.startsWith( "_" ) ) return name.substring( 1 );
1946        else return name;
1947    }
1948
1949
1950    /**
1951     * Write IDL banner into the output stream for a given Type
1952     * @param t The given Type.
1953     * @param dim The dimension required if t is an ArrayType.
1954     * @param isException true if writing an exception.
1955     * @param p The output stream.
1956     */
1957    protected void writeBanner(
1958                               Type t,
1959                               int dim,
1960                               boolean isException,
1961                               IndentingWriter p )
1962        throws IOException {
1963        String[] modNames = getIDLModuleNames( t );             //module name array
1964        String fName = unEsc( t.getIDLName() );                 //file name default
1965        if ( isException && t.isClass() ) {
1966            ClassType ct = (ClassType)t;                    //file name for Exception
1967            fName = unEsc( ct.getIDLExceptionName() );
1968        }
1969        if ( dim > 0 && t.isArray() ) {
1970            Type et = t.getElementType();                    //file name for sequence
1971            fName = "seq" + dim + "_" + unEsc( et.getIDLName().replace( ' ','_' ) );
1972        }
1973
1974        p.pln( "/**" );
1975        p.p( " * " );
1976        for ( int i1 = 0; i1 < modNames.length; i1++ )
1977            p.p( modNames[i1] + "/" );
1978        p.pln( fName + ".idl" );
1979        p.pln( " * Generated by rmic -idl. Do not edit" );
1980        String d = DateFormat.getDateTimeInstance(
1981                                                  DateFormat.FULL,DateFormat.FULL,Locale.getDefault() )
1982            .format( new Date() );
1983        String ocStr = "o'clock";
1984        int ocx = d.indexOf( ocStr );             //remove unwanted o'clock, if any
1985        p.p ( " * " );
1986        if ( ocx > -1 )
1987            p.pln( d.substring( 0,ocx ) + d.substring( ocx + ocStr.length() ) );
1988        else p.pln( d );
1989        p.pln( " */" );
1990        p.pln();
1991    }
1992
1993
1994    /**
1995     * Write #include for orb.idl
1996     * @param p The output stream.
1997     */
1998    protected void writeIncOrb(
1999                               IndentingWriter p )
2000        throws IOException {
2001        p.pln( "#include \"orb.idl\"" );
2002    }
2003
2004
2005    /**
2006     * Write #ifndef guard into the output stream for a given Type
2007     * @param t The given Type.
2008     * @param dim The dimension required if t is an ArrayType.
2009     * @param isException true if writing an exception.
2010     * @param isForward. No #define needed if it's a forward declare
2011     * @param p The output stream.
2012     */
2013    protected void writeIfndef(
2014                               Type t,
2015                               int dim,
2016                               boolean isException,
2017                               boolean isForward,
2018                               IndentingWriter p )
2019        throws IOException {
2020        String[] modNames = getIDLModuleNames( t );             //module name array
2021        String fName = unEsc( t.getIDLName() );                 //file name default
2022        if ( isException && t.isClass() ) {
2023            ClassType ct = (ClassType)t;                    //file name for Exception
2024            fName = unEsc( ct.getIDLExceptionName() );
2025        }
2026        if ( dim > 0 && t.isArray() ) {
2027            Type et = t.getElementType();                    //file name for sequence
2028            fName = "seq" + dim + "_" + unEsc( et.getIDLName().replace( ' ','_' ) );
2029        }
2030        p.pln();
2031        p.p( "#ifndef __" );
2032        for ( int i = 0; i < modNames.length; i++ ) p.p( modNames[i] + "_" );
2033        p.pln( fName + "__" );
2034        if ( !isForward ) {
2035        p.p( "#define __" );
2036        for ( int i = 0; i < modNames.length; i++ ) p.p( modNames[i] + "_" );
2037            p.pln( fName + "__" );
2038            p.pln();
2039    }
2040    }
2041
2042
2043    /**
2044     * Write #endif bracket into the output stream
2045     * @param p The output stream.
2046     */
2047    protected void writeEndif(
2048                              IndentingWriter p )
2049        throws IOException {
2050        p.pln("#endif");
2051        p.pln();
2052    }
2053
2054    /**
2055     * Write Module start bracketing for the given type into the output stream
2056     * @param t The given Type
2057     * @param p The output stream.
2058     */
2059    protected void writeModule1(
2060                                Type t,
2061                                IndentingWriter p )
2062        throws IOException {
2063
2064        String[] modNames = getIDLModuleNames( t );
2065        p.pln();
2066        for ( int i = 0; i < modNames.length; i++ )
2067            p.pln( "module " + modNames[i] + " {" );
2068    }
2069
2070    /**
2071     * Write Module end bracketing for the given type into the output stream
2072     * @param t The given Type
2073     * @param p The output stream.
2074     */
2075    protected void writeModule2(
2076                                Type t,
2077                                IndentingWriter p )
2078        throws IOException {
2079        String[] modNames = getIDLModuleNames( t );
2080        for ( int i=0; i < modNames.length; i++ ) p.pln( "};" );
2081        p.pln();
2082    }
2083
2084}
2085