duke@1: /* ohair@158: * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@158: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@158: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@158: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@158: * or visit www.oracle.com if you need additional information or have any ohair@158: * questions. duke@1: */ duke@1: duke@1: /* duke@1: * Licensed Materials - Property of IBM duke@1: * RMI-IIOP v1.0 duke@1: * Copyright IBM Corp. 1998 1999 All Rights Reserved duke@1: * duke@1: */ duke@1: duke@1: package sun.rmi.rmic.iiop; duke@1: duke@1: import java.util.Vector; duke@1: import java.util.Hashtable; duke@1: import java.util.Enumeration; duke@1: import java.io.IOException; duke@1: import sun.tools.java.ClassDefinition; duke@1: import sun.tools.java.ClassDeclaration; duke@1: import sun.tools.java.Identifier; duke@1: import sun.tools.java.ClassNotFound; duke@1: import sun.tools.java.CompilerError; duke@1: import sun.rmi.rmic.IndentingWriter; duke@1: import java.util.HashSet; duke@1: import com.sun.corba.se.impl.util.RepositoryId; duke@1: import sun.rmi.rmic.Names; duke@1: duke@1: /** duke@1: * Type is an abstract base class for a family of types which provide duke@1: * conformance checking and name mapping as defined in the "Java to IDL duke@1: * Mapping" OMG specification. The family is composed of the following duke@1: * fixed set of types: duke@1: *
duke@1:  *
duke@1:  *                                              +- RemoteType <-- AbstractType
duke@1:  *                                              |
duke@1:  *                           +- InterfaceType <-+- SpecialInterfaceType
duke@1:  *         +- PrimitiveType  |                  |
duke@1:  *         |                 |                  +- NCInterfaceType
duke@1:  *  Type <-+- CompoundType <-|
duke@1:  *         |                 |                  +- ValueType
duke@1:  *         +- ArrayType      |                  |
duke@1:  *                           +- ClassType <-----+- ImplementationType
duke@1:  *                                              |
duke@1:  *                                              +- SpecialClassType
duke@1:  *                                              |
duke@1:  *                                              +- NCClassType
duke@1:  *
duke@1:  * 
duke@1: * PrimitiveType represents a primitive or a void type. duke@1: *

duke@1: * CompoundType is an abstract base representing any non-special class duke@1: * or interface type. duke@1: *

duke@1: * InterfaceType is an abstract base representing any non-special duke@1: * interface type. duke@1: *

duke@1: * RemoteType represents any non-special interface which inherits duke@1: * from java.rmi.Remote. duke@1: *

duke@1: * AbstractType represents any non-special interface which does not duke@1: * inherit from java.rmi.Remote, for which all methods throw RemoteException. duke@1: *

duke@1: * SpecialInterfaceType represents any one of the following types: duke@1: *

duke@1:  *    java.rmi.Remote
duke@1:  *    java.io.Serializable
duke@1:  *    java.io.Externalizable
duke@1:  * 
duke@1: * all of which are treated as special cases. duke@1: *

duke@1: * NCInterfaceType represents any non-special, non-conforming interface. duke@1: *

duke@1: * ClassType is an abstract base representing any non-special class duke@1: * type. duke@1: *

duke@1: * ValueType represents any non-special class which does inherit from duke@1: * java.io.Serializable and does not inherit from java.rmi.Remote. duke@1: *

duke@1: * ImplementationType represents any non-special class which implements duke@1: * one or more interfaces which inherit from java.rmi.Remote. duke@1: *

duke@1: * SpecialClassType represents any one of the following types: duke@1: *

duke@1:  *    java.lang.Object
duke@1:  *    java.lang.String
duke@1:  *    org.omg.CORBA.Object
duke@1:  * 
duke@1: * all of which are treated as special cases. For all but CORBA.Object, duke@1: * the type must match exactly. For CORBA.Object, the type must either be duke@1: * CORBA.Object or inherit from it. duke@1: *

duke@1: * NCClassType represents any non-special, non-conforming class. duke@1: *

duke@1: * ArrayType is a wrapper for any of the other types. The getElementType() duke@1: * method can be used to get the array element type. The getArrayDimension() duke@1: * method can be used to get the array dimension. duke@1: *

duke@1: * NOTE: None of these types is multi-thread-safe duke@1: * @author Bryan Atsatt duke@1: */ duke@1: public abstract class Type implements sun.rmi.rmic.iiop.Constants, ContextElement, Cloneable { duke@1: duke@1: private int typeCode; duke@1: private int fullTypeCode; duke@1: private Identifier id; duke@1: duke@1: private String name; duke@1: private String packageName; duke@1: private String qualifiedName; duke@1: duke@1: private String idlName; duke@1: private String[] idlModuleNames; duke@1: private String qualifiedIDLName; duke@1: duke@1: private String repositoryID; duke@1: private Class ourClass; duke@1: duke@1: private int status = STATUS_PENDING; duke@1: duke@1: protected BatchEnvironment env; // Easy access for subclasses. duke@1: protected ContextStack stack; // Easy access for subclasses. duke@1: duke@1: protected boolean destroyed = false; duke@1: duke@1: //_____________________________________________________________________ duke@1: // Public Interfaces duke@1: //_____________________________________________________________________ duke@1: duke@1: /** duke@1: * Return the unqualified name for this type (e.g. com.acme.Dynamite would duke@1: * return "Dynamite"). duke@1: */ duke@1: public String getName() { duke@1: return name; duke@1: } duke@1: duke@1: /** duke@1: * Return the package of this type (e.g. com.acme.Dynamite would duke@1: * return "com.acme"). Will return null if default package or duke@1: * if this type is a primitive. duke@1: */ duke@1: public String getPackageName() { duke@1: return packageName; duke@1: } duke@1: duke@1: /** duke@1: * Return the fully qualified name of this type (e.g. com.acme.Dynamite duke@1: * would return "com.acme.Dynamite") duke@1: */ duke@1: public String getQualifiedName() { duke@1: return qualifiedName; duke@1: } duke@1: duke@1: /** duke@1: * Return signature for this type (e.g. com.acme.Dynamite duke@1: * would return "com.acme.Dynamite", byte = "B") duke@1: */ duke@1: public abstract String getSignature(); duke@1: duke@1: /** duke@1: * IDL_Naming duke@1: * Return the unqualified IDL name of this type (e.g. com.acme.Dynamite would duke@1: * return "Dynamite"). duke@1: */ duke@1: public String getIDLName() { duke@1: return idlName; duke@1: } duke@1: duke@1: /** duke@1: * IDL_Naming duke@1: * Return the IDL module name for this type (e.g. com.acme.Dynamite would return duke@1: * a three element array of {"com","acme"). May be a zero length array if duke@1: * there is no module name. duke@1: */ duke@1: public String[] getIDLModuleNames() { duke@1: return idlModuleNames; duke@1: } duke@1: duke@1: /** duke@1: * IDL_Naming duke@1: * Return the fully qualified IDL name for this type (e.g. com.acme.Dynamite would duke@1: * return "com::acme::Dynamite"). duke@1: * @param global If true, prepends "::". duke@1: */ duke@1: public String getQualifiedIDLName(boolean global) { duke@1: if (global && getIDLModuleNames().length > 0) { duke@1: return IDL_NAME_SEPARATOR + qualifiedIDLName; duke@1: } else { duke@1: return qualifiedIDLName; duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Return the identifier for this type. May be qualified. duke@1: */ duke@1: public Identifier getIdentifier() { duke@1: return id; duke@1: } duke@1: duke@1: /** duke@1: * Return the repository ID for this type. duke@1: */ duke@1: public String getRepositoryID() { duke@1: return repositoryID; duke@1: } duke@1: duke@1: /** duke@1: * Return the repository ID for this "boxed" type. duke@1: */ duke@1: public String getBoxedRepositoryID() { duke@1: return RepositoryId.createForJavaType(ourClass); duke@1: } duke@1: duke@1: /** duke@1: * Return the Class for this type. duke@1: */ duke@1: public Class getClassInstance() { duke@1: if (ourClass == null) { duke@1: initClass(); duke@1: } duke@1: return ourClass; duke@1: } duke@1: duke@1: /** duke@1: * Return the status of this type. duke@1: */ duke@1: public int getStatus() { duke@1: return status; duke@1: } duke@1: duke@1: /** duke@1: * Set the status of this type. duke@1: */ duke@1: public void setStatus(int status) { duke@1: this.status = status; duke@1: } duke@1: duke@1: /** duke@1: * Return the compiler environment for this type. duke@1: */ duke@1: public BatchEnvironment getEnv() { duke@1: return env; duke@1: } duke@1: duke@1: /** duke@1: * Get type code, without modifiers. Type codes are defined in sun.rmi.rmic.iiop.Constants. duke@1: */ duke@1: public int getTypeCode() { duke@1: return typeCode; duke@1: } duke@1: duke@1: /** duke@1: * Get type code, with modifiers. Type codes are defined in sun.rmi.rmic.iiop.Constants. duke@1: */ duke@1: public int getFullTypeCode() { duke@1: return fullTypeCode; duke@1: } duke@1: duke@1: /** duke@1: * Get type code modifiers. Type codes are defined in sun.rmi.rmic.iiop.Constants. duke@1: */ duke@1: public int getTypeCodeModifiers() { duke@1: return fullTypeCode & TM_MASK; duke@1: } duke@1: duke@1: /** duke@1: * Check for a certain type. Type codes are defined in sun.rmi.rmic.iiop.Constants. duke@1: * Returns true if all of the bits in typeCodeMask are present in the full type code duke@1: * of this object. duke@1: */ duke@1: public boolean isType(int typeCodeMask) { duke@1: return (fullTypeCode & typeCodeMask) == typeCodeMask; duke@1: } duke@1: duke@1: /** duke@1: * Like isType(), but returns true if any of the bits in typeCodeMask are duke@1: * present in the full type code of this object. duke@1: */ duke@1: public boolean typeMatches(int typeCodeMask) { duke@1: return (fullTypeCode & typeCodeMask) > 0; duke@1: } duke@1: duke@1: duke@1: /** duke@1: * Return the fullTypeCode. If an array, returns the duke@1: * type code from the element type. duke@1: */ duke@1: public int getRootTypeCode() { duke@1: if (isArray()) { duke@1: return getElementType().getFullTypeCode(); duke@1: } else { duke@1: return fullTypeCode; duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a InterfaceType. duke@1: */ duke@1: public boolean isInterface() { duke@1: return (fullTypeCode & TM_INTERFACE) == TM_INTERFACE; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a ClassType. duke@1: */ duke@1: public boolean isClass() { duke@1: return (fullTypeCode & TM_CLASS) == TM_CLASS; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a inner class or interface. duke@1: */ duke@1: public boolean isInner() { duke@1: return (fullTypeCode & TM_INNER) == TM_INNER; duke@1: } duke@1: duke@1: duke@1: /** duke@1: * Return true if this type is-a SpecialInterfaceType. duke@1: */ duke@1: public boolean isSpecialInterface() { duke@1: return (fullTypeCode & TM_SPECIAL_INTERFACE) == TM_SPECIAL_INTERFACE; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a SpecialClassType. duke@1: */ duke@1: public boolean isSpecialClass() { duke@1: return (fullTypeCode & TM_SPECIAL_CLASS) == TM_SPECIAL_CLASS; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a CompoundType. duke@1: */ duke@1: public boolean isCompound() { duke@1: return (fullTypeCode & TM_COMPOUND) == TM_COMPOUND; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a PrimitiveType. duke@1: */ duke@1: public boolean isPrimitive() { duke@1: return (fullTypeCode & TM_PRIMITIVE) == TM_PRIMITIVE; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is-a ArrayType. duke@1: */ duke@1: public boolean isArray() { duke@1: return (fullTypeCode & TYPE_ARRAY) == TYPE_ARRAY; duke@1: } duke@1: duke@1: /** duke@1: * Return true if this type is a conforming type. duke@1: */ duke@1: public boolean isConforming() { duke@1: return (fullTypeCode & TM_NON_CONFORMING) == TM_NON_CONFORMING; duke@1: } duke@1: duke@1: /** duke@1: * Return a string representation of this type. duke@1: */ duke@1: public String toString () { duke@1: return getQualifiedName(); duke@1: } duke@1: duke@1: /** duke@1: * Get element type. Returns null if not an array. duke@1: */ duke@1: public Type getElementType () { duke@1: return null; duke@1: } duke@1: duke@1: /** duke@1: * Get array dimension. Returns zero if not an array. duke@1: */ duke@1: public int getArrayDimension () { duke@1: return 0; duke@1: } duke@1: duke@1: /** duke@1: * Get brackets string. Returns "" if not an array. duke@1: */ duke@1: public String getArrayBrackets () { duke@1: return ""; duke@1: } duke@1: duke@1: /** duke@1: * Equality check based on the string representation. duke@1: */ duke@1: public boolean equals(Object obj) { duke@1: duke@1: String us = toString(); duke@1: String them = ((Type)obj).toString(); duke@1: return us.equals(them); duke@1: } duke@1: duke@1: /** duke@1: * Collect all the matching types referenced directly or indirectly duke@1: * by this type, including itself. duke@1: * @param typeCodeFilter The typeCode to use as a filter. duke@1: */ duke@1: public Type[] collectMatching (int typeCodeFilter) { duke@1: return collectMatching(typeCodeFilter,new HashSet(env.allTypes.size())); duke@1: } duke@1: duke@1: /** duke@1: * Collect all the matching types referenced directly or indirectly duke@1: * by this type, including itself. duke@1: * @param typeCodeFilter The typeCode to use as a filter. duke@1: * @param alreadyChecked Contains types which have previously been checked duke@1: * and will be ignored. Updated during collection. duke@1: */ duke@1: public Type[] collectMatching (int typeCodeFilter, HashSet alreadyChecked) { duke@1: Vector matching = new Vector(); duke@1: duke@1: // Fill up the list... duke@1: duke@1: addTypes(typeCodeFilter,alreadyChecked,matching); duke@1: duke@1: // Copy vector contents to array and return it... duke@1: duke@1: Type[] result = new Type[matching.size()]; duke@1: matching.copyInto(result); duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Return a string describing this type. duke@1: */ duke@1: public abstract String getTypeDescription (); duke@1: duke@1: /** duke@1: * Return the name of this type. For arrays, will include "[]" if useIDLNames == false. duke@1: * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: * @param globalIDLNames If true and useIDLNames true, prepends "::". duke@1: */ duke@1: public String getTypeName ( boolean useQualifiedNames, duke@1: boolean useIDLNames, duke@1: boolean globalIDLNames) { duke@1: if (useIDLNames) { duke@1: if (useQualifiedNames) { duke@1: return getQualifiedIDLName(globalIDLNames); duke@1: } else { duke@1: return getIDLName(); duke@1: } duke@1: } else { duke@1: if (useQualifiedNames) { duke@1: return getQualifiedName(); duke@1: } else { duke@1: return getName(); duke@1: } duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Print all types referenced directly or indirectly by this type which duke@1: * match the filter. duke@1: * @param writer The stream to print to. duke@1: * @param typeCodeFilter The type codes to print. duke@1: * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: * @param globalIDLNames If true and useIDLNames true, prepends "::". duke@1: */ duke@1: public void print ( IndentingWriter writer, duke@1: int typeCodeFilter, duke@1: boolean useQualifiedNames, duke@1: boolean useIDLNames, duke@1: boolean globalIDLNames) throws IOException { duke@1: duke@1: Type[] theTypes = collectMatching(typeCodeFilter); duke@1: print(writer,theTypes,useQualifiedNames,useIDLNames,globalIDLNames); duke@1: } duke@1: duke@1: /** duke@1: * Print an array of types. duke@1: * @param writer The stream to print to. duke@1: * @param theTypes The types to print. duke@1: * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: * @param globalIDLNames If true and useIDLNames true, prepends "::". duke@1: */ duke@1: public static void print ( IndentingWriter writer, duke@1: Type[] theTypes, duke@1: boolean useQualifiedNames, duke@1: boolean useIDLNames, duke@1: boolean globalIDLNames) throws IOException { duke@1: duke@1: for (int i = 0; i < theTypes.length; i++) { duke@1: theTypes[i].println(writer,useQualifiedNames,useIDLNames,globalIDLNames); duke@1: } duke@1: } duke@1: duke@1: duke@1: /** duke@1: * Print this type. duke@1: * @param writer The stream to print to. duke@1: * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: * @param globalIDLNames If true and useIDLNames true, prepends "::". duke@1: */ duke@1: public void print ( IndentingWriter writer, duke@1: boolean useQualifiedNames, duke@1: boolean useIDLNames, duke@1: boolean globalIDLNames) throws IOException { duke@1: printTypeName(writer,useQualifiedNames,useIDLNames,globalIDLNames); duke@1: } duke@1: duke@1: /** duke@1: * Print this type, followed by a newline. duke@1: * @param writer The stream to print to. duke@1: * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: * @param globalIDLNames If true and useIDLNames true, prepends "::". duke@1: */ duke@1: public void println ( IndentingWriter writer, duke@1: boolean useQualifiedNames, duke@1: boolean useIDLNames, duke@1: boolean globalIDLNames) throws IOException { duke@1: duke@1: print(writer,useQualifiedNames,useIDLNames,globalIDLNames); duke@1: writer.pln(); duke@1: } duke@1: duke@1: duke@1: duke@1: /** duke@1: * Print the name of this type. duke@1: * @param writer The stream to print to. duke@1: * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: * @param globalIDLNames If true and useIDLNames true, prepends "::". duke@1: */ duke@1: public void printTypeName ( IndentingWriter writer, duke@1: boolean useQualifiedNames, duke@1: boolean useIDLNames, duke@1: boolean globalIDLNames) throws IOException { duke@1: duke@1: writer.p(getTypeName(useQualifiedNames,useIDLNames,globalIDLNames)); duke@1: } duke@1: duke@1: /** duke@1: * Return context element name. duke@1: */ duke@1: public String getElementName() { duke@1: return getQualifiedName(); duke@1: } duke@1: duke@1: //_____________________________________________________________________ duke@1: // Subclass Interfaces duke@1: //_____________________________________________________________________ duke@1: duke@1: /** duke@1: * Print the "opening" of the package or module of this type. duke@1: * @param writer The stream to print to. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: */ duke@1: protected void printPackageOpen ( IndentingWriter writer, duke@1: boolean useIDLNames) throws IOException { duke@1: duke@1: if (useIDLNames) { duke@1: String[] moduleNames = getIDLModuleNames(); duke@1: for (int i = 0; i < moduleNames.length; i++ ) { duke@1: writer.plnI("module " + moduleNames[i] + " {"); duke@1: } duke@1: } else { duke@1: String packageName = getPackageName(); duke@1: if (packageName != null) { duke@1: writer.pln("package " + packageName + ";"); duke@1: } duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Get a type out of the table. duke@1: */ duke@1: protected static Type getType (sun.tools.java.Type key, ContextStack stack) { duke@1: return getType(key.toString(),stack); duke@1: } duke@1: duke@1: /** duke@1: * Get a type out of the table. duke@1: */ duke@1: protected static Type getType (String key, ContextStack stack) { duke@1: Type result = (Type) stack.getEnv().allTypes.get(key); duke@1: duke@1: if (result != null) { duke@1: stack.traceExistingType(result); duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Remove a type from the table. duke@1: */ duke@1: protected static void removeType (String key, ContextStack stack) { duke@1: Type value = (Type) stack.getEnv().allTypes.remove(key); duke@1: stack.getEnv().invalidTypes.put(value,key); duke@1: } duke@1: duke@1: /** duke@1: * Remove a type from the table. duke@1: */ duke@1: protected static void removeType (sun.tools.java.Type key, ContextStack stack) { duke@1: String theKey = key.toString(); duke@1: Type old = (Type) stack.getEnv().allTypes.remove(theKey); duke@1: putInvalidType(old,theKey,stack); duke@1: } duke@1: duke@1: /** duke@1: * Put a type into the table. duke@1: */ duke@1: protected static void putType (sun.tools.java.Type key, Type value, ContextStack stack) { duke@1: stack.getEnv().allTypes.put(key.toString(),value); duke@1: } duke@1: duke@1: /** duke@1: * Put a type into the table. duke@1: */ duke@1: protected static void putType (String key, Type value, ContextStack stack) { duke@1: stack.getEnv().allTypes.put(key,value); duke@1: } duke@1: duke@1: /** duke@1: * Put an invalid type into the. duke@1: */ duke@1: protected static void putInvalidType (Type key, String value, ContextStack stack) { duke@1: stack.getEnv().invalidTypes.put(key,value); duke@1: } duke@1: duke@1: duke@1: /** duke@1: * Remove all invalid types... duke@1: */ duke@1: public void removeInvalidTypes () { duke@1: if (env.invalidTypes.size() > 0) { duke@1: env.invalidTypes.clear(); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Walk all types and tell them to update invalid types... duke@1: */ duke@1: protected static void updateAllInvalidTypes (ContextStack stack) { duke@1: BatchEnvironment env = stack.getEnv(); duke@1: if (env.invalidTypes.size() > 0) { duke@1: duke@1: // Walk all types and swap invalid... duke@1: duke@1: for (Enumeration e = env.allTypes.elements() ; e.hasMoreElements() ;) { duke@1: Type it = (Type) e.nextElement(); duke@1: it.swapInvalidTypes(); duke@1: } duke@1: duke@1: // Delete all invalidTypes... duke@1: duke@1: env.invalidTypes.clear(); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Return count of previously parsed types. duke@1: */ duke@1: protected int countTypes () { duke@1: return env.allTypes.size(); duke@1: } duke@1: duke@1: /** duke@1: * Reset types removes all previously parsed types. duke@1: */ duke@1: void resetTypes () { duke@1: env.reset(); duke@1: } duke@1: duke@1: /** duke@1: * Release all resources. duke@1: */ duke@1: protected void destroy () { duke@1: if (!destroyed) { duke@1: id = null; duke@1: name = null; duke@1: packageName = null; duke@1: qualifiedName = null; duke@1: idlName = null; duke@1: idlModuleNames = null; duke@1: qualifiedIDLName = null; duke@1: repositoryID = null; duke@1: ourClass = null; duke@1: env = null; duke@1: stack = null; duke@1: destroyed = true; duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Convert all invalid types to valid ones. duke@1: */ duke@1: protected void swapInvalidTypes () { duke@1: } duke@1: duke@1: /** duke@1: * Convert an invalid type to a valid one. duke@1: */ duke@1: protected Type getValidType (Type invalidType) { duke@1: if (invalidType.getStatus() == STATUS_VALID) { duke@1: return invalidType; duke@1: } duke@1: duke@1: String key = (String)env.invalidTypes.get(invalidType); duke@1: Type result = null; duke@1: if (key != null) { duke@1: result = (Type) env.allTypes.get(key); duke@1: } duke@1: duke@1: if (result == null) { duke@1: throw new Error("Failed to find valid type to swap for " + invalidType + " mis-identified as " + invalidType.getTypeDescription()); duke@1: } duke@1: //System.out.println("Swapped " + result + " from " + invalidType.getTypeDescription() duke@1: // + " to " + result.getTypeDescription()); duke@1: //ContextStack.dumpCallStack(); duke@1: return result; duke@1: } duke@1: duke@1: /** duke@1: * Print the "closing" of the package or module of this type. duke@1: * @param writer The stream to print to. duke@1: * @param useIDLNames If true, print IDL names; otherwise, print java names. duke@1: */ duke@1: protected void printPackageClose ( IndentingWriter writer, duke@1: boolean useIDLNames) throws IOException { duke@1: if (useIDLNames) { duke@1: String[] moduleNames = getIDLModuleNames(); duke@1: for (int i = 0; i < moduleNames.length; i++ ) { duke@1: writer.pOln("};"); duke@1: } duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Create a Type instance for the given type. Requires that duke@1: * setName(Identifier) be called afterward. duke@1: */ duke@1: protected Type(ContextStack stack, int fullTypeCode) { duke@1: this.env = stack.getEnv(); duke@1: this.stack = stack; duke@1: this.fullTypeCode = fullTypeCode; duke@1: typeCode = fullTypeCode & TYPE_MASK; duke@1: } duke@1: duke@1: /** duke@1: * Set type codes. May only be called during initialization. duke@1: */ duke@1: protected void setTypeCode(int fullTypeCode) { duke@1: this.fullTypeCode = fullTypeCode; duke@1: typeCode = fullTypeCode & TYPE_MASK; duke@1: } duke@1: duke@1: /** duke@1: * Set name and package. May only be called during initialization. duke@1: */ duke@1: protected void setNames(Identifier id, String[] idlModuleNames, String idlName) { duke@1: duke@1: this.id = id; duke@1: name = Names.mangleClass(id).getName().toString(); duke@1: packageName = null; duke@1: duke@1: if (id.isQualified()) { duke@1: packageName = id.getQualifier().toString(); duke@1: qualifiedName = packageName + NAME_SEPARATOR + name; duke@1: } else { duke@1: qualifiedName = name; duke@1: } duke@1: duke@1: setIDLNames(idlModuleNames,idlName); duke@1: } duke@1: duke@1: duke@1: /** duke@1: * Set IDL name. May only be called during initialization. duke@1: */ duke@1: protected void setIDLNames(String[] idlModuleNames, String idlName) { duke@1: this.idlName = idlName; duke@1: duke@1: if (idlModuleNames != null) { duke@1: this.idlModuleNames = idlModuleNames; duke@1: } else { duke@1: this.idlModuleNames = new String[0]; duke@1: } duke@1: qualifiedIDLName = IDLNames.getQualifiedName(idlModuleNames,idlName); duke@1: } duke@1: duke@1: /** duke@1: * Report a ClassNotFoundException thru the compiler environment. duke@1: */ duke@1: protected static void classNotFound(ContextStack stack, duke@1: ClassNotFound e) { duke@1: classNotFound(false,stack,e); duke@1: } duke@1: duke@1: /** duke@1: * Report a ClassNotFoundException thru the compiler environment. duke@1: */ duke@1: protected static void classNotFound(boolean quiet, duke@1: ContextStack stack, duke@1: ClassNotFound e) { duke@1: if (!quiet) stack.getEnv().error(0, "rmic.class.not.found", e.name); duke@1: stack.traceCallStack(); duke@1: } duke@1: duke@1: /** duke@1: * Report a constraint failure thru the compiler environment. duke@1: * @param constraintNum Used to generate a key of the form duke@1: "rmic.iiop.constraint.N", which must identify a message duke@1: in the "rmic.properties" file. duke@1: * @param quiet True if should not cause failure or message. duke@1: * @param stack The context stack. duke@1: * @param arg0 An object to substitute for {0} in the message. duke@1: * @param arg1 An object to substitute for {1} in the message. duke@1: * @param arg2 An object to substitute for {2} in the message. duke@1: * @return false. duke@1: */ duke@1: protected static boolean failedConstraint(int constraintNum, duke@1: boolean quiet, duke@1: ContextStack stack, duke@1: Object arg0, Object arg1, Object arg2) { duke@1: String message = "rmic.iiop.constraint." + constraintNum; duke@1: duke@1: if (!quiet) { duke@1: stack.getEnv().error(0,message, duke@1: (arg0 != null ? arg0.toString() : null), duke@1: (arg1 != null ? arg1.toString() : null), duke@1: (arg2 != null ? arg2.toString() : null)); duke@1: } else { duke@1: String error = stack.getEnv().errorString(message,arg0,arg1,arg2); duke@1: stack.traceln(error); duke@1: } duke@1: duke@1: return false; duke@1: } duke@1: duke@1: /** duke@1: * Report a constraint failure thru the compiler environment. duke@1: * @param constraintNum Used to generate a key of the form duke@1: "rmic.iiop.constraint.N", which must identify a message duke@1: in the "rmic.properties" file. duke@1: * @param quiet True if should not cause failure or message. duke@1: * @param stack The context stack. duke@1: * @param arg0 An object to substitute for {0} in the message. duke@1: * @param arg1 An object to substitute for {1} in the message. duke@1: * @return false. duke@1: */ duke@1: protected static boolean failedConstraint(int constraintNum, duke@1: boolean quiet, duke@1: ContextStack stack, duke@1: Object arg0, Object arg1) { duke@1: return failedConstraint(constraintNum,quiet,stack,arg0,arg1,null); duke@1: } duke@1: duke@1: duke@1: /** duke@1: * Report a constraint failure thru the compiler environment. duke@1: * @param constraintNum Used to generate a key of the form duke@1: "rmic.iiop.constraint.N", which must identify a message duke@1: in the "rmic.properties" file. duke@1: * @param quiet True if should not cause failure or message. duke@1: * @param stack The context stack. duke@1: * @param arg0 An object to substitute for {0} in the message. duke@1: * @return false. duke@1: */ duke@1: protected static boolean failedConstraint(int constraintNum, duke@1: boolean quiet, duke@1: ContextStack stack, duke@1: Object arg0) { duke@1: return failedConstraint(constraintNum,quiet,stack,arg0,null,null); duke@1: } duke@1: duke@1: /** duke@1: * Report a constraint failure thru the compiler environment. duke@1: * @param quiet True if should not cause failure or message. duke@1: * @param stack The context stack. duke@1: * @param constraintNum Used to generate a key of the form duke@1: "rmic.iiop.constraint.N", which must identify a message duke@1: in the "rmic.properties" file. duke@1: * @return false. duke@1: */ duke@1: protected static boolean failedConstraint(int constraintNum, duke@1: boolean quiet, duke@1: ContextStack stack) { duke@1: return failedConstraint(constraintNum,quiet,stack,null,null,null); duke@1: } duke@1: duke@1: /** duke@1: * Cloning is supported by returning a shallow copy of this object. duke@1: */ duke@1: protected Object clone() { duke@1: try { duke@1: return super.clone(); duke@1: } catch (CloneNotSupportedException e) { duke@1: throw new Error("clone failed"); duke@1: } duke@1: } duke@1: duke@1: /* duke@1: * Add matching types to list. Return true if this type has not duke@1: * been previously checked, false otherwise. duke@1: */ duke@1: protected boolean addTypes (int typeCodeFilter, duke@1: HashSet checked, duke@1: Vector matching) { duke@1: duke@1: boolean result; duke@1: duke@1: // Have we already checked this type? duke@1: duke@1: if (checked.contains(this)) { duke@1: duke@1: // Yes, so return false. duke@1: duke@1: result = false; duke@1: duke@1: } else { duke@1: duke@1: // Nope, so add it... duke@1: duke@1: checked.add(this); duke@1: duke@1: // Do we match the filter? duke@1: duke@1: if (typeMatches(typeCodeFilter)) { duke@1: duke@1: // Yep. so add it and set result to true... duke@1: duke@1: matching.addElement(this); duke@1: } duke@1: duke@1: // Return true. duke@1: duke@1: result = true; duke@1: } duke@1: duke@1: return result; duke@1: } duke@1: duke@1: /* duke@1: * Load a Class instance. Return null if fail. duke@1: */ duke@1: protected abstract Class loadClass(); duke@1: duke@1: private boolean initClass() { duke@1: if (ourClass == null) { duke@1: ourClass = loadClass(); duke@1: if (ourClass == null) { duke@1: failedConstraint(27,false,stack,getQualifiedName()); duke@1: return false; duke@1: } duke@1: } duke@1: return true; duke@1: } duke@1: duke@1: /* duke@1: * Set the clz and repositoryID fields. Reports error duke@1: * and returns false if fails, returns true if succeeds. duke@1: */ duke@1: protected boolean setRepositoryID() { duke@1: duke@1: // First, load the class... duke@1: duke@1: if (!initClass()) { duke@1: return false; duke@1: } duke@1: duke@1: // Now make the repositoryID and return success... duke@1: duke@1: repositoryID = RepositoryId.createForAnyType(ourClass); duke@1: return true; duke@1: } duke@1: duke@1: duke@1: //_____________________________________________________________________ duke@1: // Internal Interfaces duke@1: //_____________________________________________________________________ duke@1: duke@1: private Type () {} // Disallowed. duke@1: }