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 java.util.Vector;
36 import sun.tools.java.CompilerError;
37 import sun.tools.java.ClassNotFound;
38 import sun.tools.java.ClassDefinition;
39 
40 /**
41  * AbstractType represents any non-special interface which does not
42  * inherit from java.rmi.Remote, for which all methods throw RemoteException.
43  * <p>
44  * The static forAbstract(...) method must be used to obtain an instance, and will
45  * return null if the ClassDefinition is non-conforming.
46  * @author      Bryan Atsatt
47  */
48 public class AbstractType extends RemoteType {
49 
50     //_____________________________________________________________________
51     // Public Interfaces
52     //_____________________________________________________________________
53 
54     /**
55      * Create an AbstractType for the given class.
56      *
57      * If the class is not a properly formed or if some other error occurs, the
58      * return value will be null, and errors will have been reported to the
59      * supplied BatchEnvironment.
60      */
forAbstract(ClassDefinition classDef, ContextStack stack, boolean quiet)61     public static AbstractType forAbstract(ClassDefinition classDef,
62                                            ContextStack stack,
63                                            boolean quiet)
64     {
65         boolean doPop = false;
66         AbstractType result = null;
67 
68         try {
69 
70             // Do we already have it?
71 
72             sun.tools.java.Type theType = classDef.getType();
73             Type existing = getType(theType,stack);
74 
75             if (existing != null) {
76 
77                 if (!(existing instanceof AbstractType)) return null; // False hit.
78 
79                                 // Yep, so return it...
80 
81                 return (AbstractType) existing;
82 
83             }
84 
85             // Could this be an abstract?
86 
87             if (couldBeAbstract(stack,classDef,quiet)) {
88 
89                 // Yes, so try it...
90 
91                 AbstractType it = new AbstractType(stack, classDef);
92                 putType(theType,it,stack);
93                 stack.push(it);
94                 doPop = true;
95 
96                 if (it.initialize(quiet,stack)) {
97                     stack.pop(true);
98                     result = it;
99                 } else {
100                     removeType(theType,stack);
101                     stack.pop(false);
102                 }
103             }
104         } catch (CompilerError e) {
105             if (doPop) stack.pop(false);
106         }
107 
108         return result;
109     }
110 
111     /**
112      * Return a string describing this type.
113      */
getTypeDescription()114     public String getTypeDescription () {
115         return "Abstract interface";
116     }
117 
118     //_____________________________________________________________________
119     // Internal/Subclass Interfaces
120     //_____________________________________________________________________
121 
122     /**
123      * Create a AbstractType instance for the given class.  The resulting
124      * object is not yet completely initialized.
125      */
AbstractType(ContextStack stack, ClassDefinition classDef)126     private AbstractType(ContextStack stack, ClassDefinition classDef) {
127         super(stack,classDef,TYPE_ABSTRACT | TM_INTERFACE | TM_COMPOUND);
128     }
129 
130     //_____________________________________________________________________
131     // Internal Interfaces
132     //_____________________________________________________________________
133 
134 
couldBeAbstract(ContextStack stack, ClassDefinition classDef, boolean quiet)135     private static boolean couldBeAbstract(ContextStack stack, ClassDefinition classDef,
136                                            boolean quiet) {
137 
138         // Return true if interface and not remote...
139 
140         boolean result = false;
141 
142         if (classDef.isInterface()) {
143             BatchEnvironment env = stack.getEnv();
144 
145             try {
146                 result = ! env.defRemote.implementedBy(env, classDef.getClassDeclaration());
147                 if (!result) failedConstraint(15,quiet,stack,classDef.getName());
148             } catch (ClassNotFound e) {
149                 classNotFound(stack,e);
150             }
151         } else {
152             failedConstraint(14,quiet,stack,classDef.getName());
153         }
154 
155 
156         return result;
157     }
158 
159 
160     /**
161      * Initialize this instance.
162      */
initialize(boolean quiet,ContextStack stack)163     private boolean initialize (boolean quiet,ContextStack stack) {
164 
165         boolean result = false;
166         ClassDefinition self = getClassDefinition();
167 
168         try {
169 
170             // Get methods...
171 
172             Vector directMethods = new Vector();
173 
174             if (addAllMethods(self,directMethods,true,quiet,stack) != null) {
175 
176                 // Do we have any methods?
177 
178                 boolean validMethods = true;
179 
180                 if (directMethods.size() > 0) {
181 
182                                 // Yes. Walk 'em, ensuring each is a valid remote method...
183 
184                     for (int i = 0; i < directMethods.size(); i++) {
185 
186                         if (! isConformingRemoteMethod((Method) directMethods.elementAt(i),true)) {
187                             validMethods = false;
188                         }
189                     }
190                 }
191 
192                 if (validMethods) {
193 
194                     // We're ok, so pass 'em up...
195 
196                     result = initialize(null,directMethods,null,stack,quiet);
197                 }
198             }
199         } catch (ClassNotFound e) {
200             classNotFound(stack,e);
201         }
202 
203         return result;
204     }
205 }
206