SpecialInterfaceType.java revision 608:7e06bf1dcb09
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
33package sun.rmi.rmic.iiop;
34
35import sun.tools.java.ClassNotFound;
36import sun.tools.java.CompilerError;
37import sun.tools.java.Identifier;
38import sun.tools.java.ClassDeclaration;
39import sun.tools.java.ClassDefinition;
40
41/**
42 * SpecialInterfaceType represents any one of the following types:
43 * <pre>
44 *    java.rmi.Remote
45 *    java.io.Serializable
46 *    java.io.Externalizable
47 *    org.omg.CORBA.Object
48 *    org.omg.CORBA.portable.IDLEntity
49 * </pre>
50 * all of which are treated as special cases. For all but CORBA.Object,
51 * the type must match exactly. For CORBA.Object, the type must either be
52 * CORBA.Object or inherit from it.
53 * <p>
54 * The static forSpecial(...) method must be used to obtain an instance, and
55 * will return null if the type is non-conforming.
56 *
57 * @author  Bryan Atsatt
58 */
59public class SpecialInterfaceType extends InterfaceType {
60
61    //_____________________________________________________________________
62    // Public Interfaces
63    //_____________________________________________________________________
64
65    /**
66     * Create a SpecialInterfaceType object for the given class.
67     *
68     * If the class is not a properly formed or if some other error occurs, the
69     * return value will be null, and errors will have been reported to the
70     * supplied BatchEnvironment.
71     */
72    public static SpecialInterfaceType forSpecial ( ClassDefinition theClass,
73                                                    ContextStack stack) {
74
75        if (stack.anyErrors()) return null;
76
77        // Do we already have it?
78
79        sun.tools.java.Type type = theClass.getType();
80        Type existing = getType(type,stack);
81
82        if (existing != null) {
83
84            if (!(existing instanceof SpecialInterfaceType)) return null; // False hit.
85
86            // Yep, so return it...
87
88            return (SpecialInterfaceType) existing;
89        }
90
91        // Is it special?
92
93        if (isSpecial(type,theClass,stack)) {
94
95            // Yes...
96
97            SpecialInterfaceType result = new SpecialInterfaceType(stack,0,theClass);
98            putType(type,result,stack);
99            stack.push(result);
100
101            if (result.initialize(type,stack)) {
102                stack.pop(true);
103                return result;
104            } else {
105                removeType(type,stack);
106                stack.pop(false);
107                return null;
108            }
109        }
110        return null;
111    }
112
113    /**
114     * Return a string describing this type.
115     */
116    public String getTypeDescription () {
117        return "Special interface";
118    }
119
120    //_____________________________________________________________________
121    // Subclass/Internal Interfaces
122    //_____________________________________________________________________
123
124    /**
125     * Create an SpecialInterfaceType instance for the given class.
126     */
127    private SpecialInterfaceType(ContextStack stack, int typeCode,
128                                 ClassDefinition theClass) {
129        super(stack,typeCode | TM_SPECIAL_INTERFACE | TM_INTERFACE | TM_COMPOUND, theClass);
130        setNames(theClass.getName(),null,null); // Fixed in initialize.
131    }
132
133    private static boolean isSpecial(sun.tools.java.Type type,
134                                     ClassDefinition theClass,
135                                     ContextStack stack) {
136        if (type.isType(TC_CLASS)) {
137            Identifier id = type.getClassName();
138
139            if (id.equals(idRemote)) return true;
140            if (id == idJavaIoSerializable) return true;
141            if (id == idJavaIoExternalizable) return true;
142            if (id == idCorbaObject) return true;
143            if (id == idIDLEntity) return true;
144            BatchEnvironment env = stack.getEnv();
145            try {
146                if (env.defCorbaObject.implementedBy(env,theClass.getClassDeclaration())) return true;
147            } catch (ClassNotFound e) {
148                classNotFound(stack,e);
149            }
150        }
151        return false;
152    }
153
154    private boolean initialize(sun.tools.java.Type type, ContextStack stack) {
155
156        int typeCode = TYPE_NONE;
157        Identifier id = null;
158        String idlName = null;
159        String[] idlModuleName = null;
160        boolean constant = stack.size() > 0 && stack.getContext().isConstant();
161
162        if (type.isType(TC_CLASS)) {
163            id = type.getClassName();
164
165            if (id.equals(idRemote)) {
166                typeCode = TYPE_JAVA_RMI_REMOTE;
167                idlName = IDL_JAVA_RMI_REMOTE;
168                idlModuleName = IDL_JAVA_RMI_MODULE;
169            } else if (id == idJavaIoSerializable) {
170                typeCode = TYPE_ANY;
171                idlName = IDL_SERIALIZABLE;
172                idlModuleName = IDL_JAVA_IO_MODULE;
173            } else if (id == idJavaIoExternalizable) {
174                typeCode = TYPE_ANY;
175                idlName = IDL_EXTERNALIZABLE;
176                idlModuleName = IDL_JAVA_IO_MODULE;
177            } else if (id == idIDLEntity) {
178                typeCode = TYPE_ANY;
179                idlName = IDL_IDLENTITY;
180                idlModuleName = IDL_ORG_OMG_CORBA_PORTABLE_MODULE;
181            } else {
182
183                typeCode = TYPE_CORBA_OBJECT;
184
185                // Is it exactly org.omg.CORBA.Object?
186
187                if (id == idCorbaObject) {
188
189                    // Yes, so special case...
190
191                    idlName = IDLNames.getTypeName(typeCode,constant);
192                    idlModuleName = null;
193
194                } else {
195
196                    // No, so get the correct names...
197
198                    try {
199
200                        // These can fail if we get case-sensitive name matches...
201
202                        idlName = IDLNames.getClassOrInterfaceName(id,env);
203                        idlModuleName = IDLNames.getModuleNames(id,isBoxed(),env);
204
205                    } catch (Exception e) {
206                        failedConstraint(7,false,stack,id.toString(),e.getMessage());
207                        throw new CompilerError("");
208                    }
209                }
210            }
211        }
212
213        if (typeCode == TYPE_NONE) {
214            return false;
215        }
216
217        // Reset type code...
218
219        setTypeCode(typeCode | TM_SPECIAL_INTERFACE | TM_INTERFACE | TM_COMPOUND);
220
221        // Set names
222
223        if (idlName == null) {
224            throw new CompilerError("Not a special type");
225        }
226
227        setNames(id,idlModuleName,idlName);
228
229        // Initialize CompoundType...
230
231        return initialize(null,null,null,stack,false);
232    }
233}
234