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 /*
  27  * Licensed Materials - Property of IBM
  28  * RMI-IIOP v1.0
  29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
  30  *
  31  */
  32 
  33 package sun.rmi.rmic.iiop;
  34 
  35 import sun.tools.java.CompilerError;
  36 import sun.tools.java.ClassNotFound;
  37 import sun.tools.java.ClassDeclaration;
  38 import sun.tools.java.ClassDefinition;
  39 import sun.rmi.rmic.IndentingWriter;
  40 import java.io.IOException;
  41 
  42 /**
  43  * ClassType is an abstract base representing any non-special class
  44  * type.
  45  *
  46  * @author      Bryan Atsatt
  47  */
  48 public abstract class ClassType extends CompoundType {
  49 
  50     private ClassType parent;
  51 
  52     //_____________________________________________________________________
  53     // Public Interfaces
  54     //_____________________________________________________________________
  55 
  56     /**
  57      * Return the parent class of this type. Returns null if this
  58      * type is an interface or if there is no parent.
  59      */
  60     public ClassType getSuperclass() {
  61         return parent;
  62     }
  63 
  64 
  65     /**
  66      * Print this type.
  67      * @param writer The stream to print to.
  68      * @param useQualifiedNames If true, print qualified names; otherwise, print unqualified names.
  69      * @param useIDLNames If true, print IDL names; otherwise, print java names.
  70      * @param globalIDLNames If true and useIDLNames true, prepends "::".
  71      */
  72     public void print ( IndentingWriter writer,
  73                         boolean useQualifiedNames,
  74                         boolean useIDLNames,
  75                         boolean globalIDLNames) throws IOException {
  76 
  77         if (isInner()) {
  78             writer.p("// " + getTypeDescription() + " (INNER)");
  79         } else {
  80             writer.p("// " + getTypeDescription());
  81         }
  82         writer.pln(" (" + getRepositoryID() + ")\n");
  83 
  84         printPackageOpen(writer,useIDLNames);
  85 
  86         if (!useIDLNames) {
  87             writer.p("public ");
  88         }
  89 
  90         String prefix = "";
  91         writer.p("class " + getTypeName(false,useIDLNames,false));
  92         if (printExtends(writer,useQualifiedNames,useIDLNames,globalIDLNames)) {
  93             prefix = ",";
  94         }
  95         printImplements(writer,prefix,useQualifiedNames,useIDLNames,globalIDLNames);
  96         writer.plnI(" {");
  97         printMembers(writer,useQualifiedNames,useIDLNames,globalIDLNames);
  98         writer.pln();
  99         printMethods(writer,useQualifiedNames,useIDLNames,globalIDLNames);
 100 
 101         if (useIDLNames) {
 102             writer.pOln("};");
 103         } else {
 104             writer.pOln("}");
 105         }
 106 
 107         printPackageClose(writer,useIDLNames);
 108     }
 109 
 110 
 111     //_____________________________________________________________________
 112     // Subclass/Internal Interfaces
 113     //_____________________________________________________________________
 114 
 115     protected void destroy () {
 116         if (!destroyed) {
 117             super.destroy();
 118             if (parent != null) {
 119                 parent.destroy();
 120                 parent = null;
 121     }
 122     }
 123         }
 124 
 125     /**
 126      * Create a ClassType instance for the given class. NOTE: This constructor
 127      * is ONLY for SpecialClassType.
 128      */
 129     protected ClassType(ContextStack stack, int typeCode, ClassDefinition classDef) {
 130         super(stack,typeCode,classDef); // Call special parent constructor.
 131         if ((typeCode & TM_CLASS) == 0 && classDef.isInterface()) {
 132             throw new CompilerError("Not a class");
 133         }
 134         parent = null;
 135     }
 136 
 137     /**
 138      * Create a ClassType instance for the given class. NOTE: This constructor
 139      * is ONLY for ImplementationType. It does not walk the parent chain.
 140      */
 141     protected ClassType(int typeCode, ClassDefinition classDef,ContextStack stack) {
 142         super(stack,classDef,typeCode);
 143 
 144         if ((typeCode & TM_CLASS) == 0 && classDef.isInterface()) {
 145             throw new CompilerError("Not a class");
 146         }
 147         parent = null;
 148     }
 149 
 150     /**
 151      * Create an ClassType instance for the given class.  The resulting
 152      * object is not yet completely initialized. Subclasses must call
 153      * initialize(directInterfaces,directInterfaces,directConstants);
 154      */
 155     protected ClassType(ContextStack stack,
 156                         ClassDefinition classDef,
 157                         int typeCode) {
 158         super(stack,classDef,typeCode);
 159         if ((typeCode & TM_CLASS) == 0 && classDef.isInterface()) {
 160             throw new CompilerError("Not a class");
 161         }
 162         parent = null;
 163     }
 164 
 165     /**
 166      * Convert all invalid types to valid ones.
 167      */
 168     protected void swapInvalidTypes () {
 169         super.swapInvalidTypes();
 170         if (parent != null && parent.getStatus() != STATUS_VALID) {
 171             parent = (ClassType) getValidType(parent);
 172         }
 173     }
 174 
 175     /**
 176      * Modify the type description with exception info.
 177      */
 178     public String addExceptionDescription (String typeDesc) {
 179         if (isException) {
 180             if (isCheckedException) {
 181                 typeDesc = typeDesc + " - Checked Exception";
 182             } else {
 183                 typeDesc = typeDesc + " - Unchecked Exception";
 184             }
 185         }
 186         return typeDesc;
 187     }
 188 
 189 
 190     protected boolean initParents(ContextStack stack) {
 191 
 192         stack.setNewContextCode(ContextStack.EXTENDS);
 193         BatchEnvironment env = stack.getEnv();
 194 
 195         // Init parent...
 196 
 197         boolean result = true;
 198 
 199         try {
 200             ClassDeclaration parentDecl = getClassDefinition().getSuperClass(env);
 201             if (parentDecl != null) {
 202                 ClassDefinition parentDef = parentDecl.getClassDefinition(env);
 203                 parent = (ClassType) makeType(parentDef.getType(),parentDef,stack);
 204                 if (parent == null) {
 205                     result = false;
 206                 }
 207             }
 208         } catch (ClassNotFound e) {
 209             classNotFound(stack,e);
 210             throw new CompilerError("ClassType constructor");
 211         }
 212 
 213         return result;
 214     }
 215 }