src/share/classes/sun/rmi/rmic/iiop/ImplementationType.java

changeset 1
55540e827aef
child 158
91006f157c46
equal deleted inserted replaced
-1:000000000000 1:55540e827aef
1 /*
2 * Portions Copyright 1998-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 import sun.tools.java.MemberDefinition;
40
41 /**
42 * ImplementationType represents any non-special class which implements
43 * one or more interfaces which inherit from java.rmi.Remote.
44 * <p>
45 * The static forImplementation(...) method must be used to obtain an instance,
46 * and will return null if the ClassDefinition is non-conforming.
47 *
48 * @author Bryan Atsatt
49 */
50 public class ImplementationType extends ClassType {
51
52 //_____________________________________________________________________
53 // Public Interfaces
54 //_____________________________________________________________________
55
56 /**
57 * Create an ImplementationType for the given class.
58 *
59 * If the class is not a properly formed or if some other error occurs, the
60 * return value will be null, and errors will have been reported to the
61 * supplied BatchEnvironment.
62 */
63 public static ImplementationType forImplementation(ClassDefinition classDef,
64 ContextStack stack,
65 boolean quiet) {
66 if (stack.anyErrors()) return null;
67
68 boolean doPop = false;
69 ImplementationType result = null;
70
71 try {
72 // Do we already have it?
73
74 sun.tools.java.Type theType = classDef.getType();
75 Type existing = getType(theType,stack);
76
77 if (existing != null) {
78
79 if (!(existing instanceof ImplementationType)) return null; // False hit.
80
81 // Yep, so return it...
82
83 return (ImplementationType) existing;
84
85 }
86
87 // Could this be an implementation?
88
89 if (couldBeImplementation(quiet,stack,classDef)) {
90
91 // Yes, so check it...
92
93 ImplementationType it = new ImplementationType(stack, classDef);
94 putType(theType,it,stack);
95 stack.push(it);
96 doPop = true;
97
98 if (it.initialize(stack,quiet)) {
99 stack.pop(true);
100 result = it;
101 } else {
102 removeType(theType,stack);
103 stack.pop(false);
104 }
105 }
106 } catch (CompilerError e) {
107 if (doPop) stack.pop(false);
108 }
109
110 return result;
111 }
112
113 /**
114 * Return a string describing this type.
115 */
116 public String getTypeDescription () {
117 return "Implementation";
118 }
119
120
121 //_____________________________________________________________________
122 // Internal Interfaces
123 //_____________________________________________________________________
124
125 /**
126 * Create a ImplementationType instance for the given class. The resulting
127 * object is not yet completely initialized.
128 */
129 private ImplementationType(ContextStack stack, ClassDefinition classDef) {
130 super(TYPE_IMPLEMENTATION | TM_CLASS | TM_COMPOUND,classDef,stack); // Use special constructor.
131 }
132
133
134 private static boolean couldBeImplementation(boolean quiet, ContextStack stack,
135 ClassDefinition classDef) {
136 boolean result = false;
137 BatchEnvironment env = stack.getEnv();
138
139 try {
140 if (!classDef.isClass()) {
141 failedConstraint(17,quiet,stack,classDef.getName());
142 } else {
143 result = env.defRemote.implementedBy(env, classDef.getClassDeclaration());
144 if (!result) failedConstraint(8,quiet,stack,classDef.getName());
145 }
146 } catch (ClassNotFound e) {
147 classNotFound(stack,e);
148 }
149
150 return result;
151 }
152
153
154 /**
155 * Initialize this instance.
156 */
157 private boolean initialize (ContextStack stack, boolean quiet) {
158
159 boolean result = false;
160 ClassDefinition theClass = getClassDefinition();
161
162 if (initParents(stack)) {
163
164 // Make up our collections...
165
166 Vector directInterfaces = new Vector();
167 Vector directMethods = new Vector();
168
169 // Check interfaces...
170
171 try {
172 if (addRemoteInterfaces(directInterfaces,true,stack) != null) {
173
174 boolean haveRemote = false;
175
176 // Get methods from all interfaces...
177
178 for (int i = 0; i < directInterfaces.size(); i++) {
179 InterfaceType theInt = (InterfaceType) directInterfaces.elementAt(i);
180 if (theInt.isType(TYPE_REMOTE) ||
181 theInt.isType(TYPE_JAVA_RMI_REMOTE)) {
182 haveRemote = true;
183 }
184
185 copyRemoteMethods(theInt,directMethods);
186 }
187
188 // Make sure we have at least one remote interface...
189
190 if (!haveRemote) {
191 failedConstraint(8,quiet,stack,getQualifiedName());
192 return false;
193 }
194
195 // Now check the methods to ensure we have the
196 // correct throws clauses...
197
198 if (checkMethods(theClass,directMethods,stack,quiet)) {
199
200 // We're ok, so pass 'em up...
201
202 result = initialize(directInterfaces,directMethods,null,stack,quiet);
203 }
204 }
205 } catch (ClassNotFound e) {
206 classNotFound(stack,e);
207 }
208 }
209
210 return result;
211 }
212
213 private static void copyRemoteMethods(InterfaceType type, Vector list) {
214
215 if (type.isType(TYPE_REMOTE)) {
216
217 // Copy all the unique methods from type...
218
219 Method[] allMethods = type.getMethods();
220
221 for (int i = 0; i < allMethods.length; i++) {
222 Method theMethod = allMethods[i];
223
224 if (!list.contains(theMethod)) {
225 list.addElement(theMethod);
226 }
227 }
228
229 // Now recurse thru all inherited interfaces...
230
231 InterfaceType[] allInterfaces = type.getInterfaces();
232
233 for (int i = 0; i < allInterfaces.length; i++) {
234 copyRemoteMethods(allInterfaces[i],list);
235 }
236 }
237 }
238
239 // Walk all methods of the class, and for each that is already in
240 // the list, call setImplExceptions()...
241
242 private boolean checkMethods(ClassDefinition theClass, Vector list,
243 ContextStack stack, boolean quiet) {
244
245 // Convert vector to array...
246
247 Method[] methods = new Method[list.size()];
248 list.copyInto(methods);
249
250 for (MemberDefinition member = theClass.getFirstMember();
251 member != null;
252 member = member.getNextMember()) {
253
254 if (member.isMethod() && !member.isConstructor()
255 && !member.isInitializer()) {
256
257 // It's a method...
258
259 if (!updateExceptions(member,methods,stack,quiet)) {
260 return false;
261 }
262 }
263 }
264 return true;
265 }
266
267 private boolean updateExceptions (MemberDefinition implMethod, Method[] list,
268 ContextStack stack, boolean quiet) {
269 int length = list.length;
270 String implMethodSig = implMethod.toString();
271
272 for (int i = 0; i < length; i++) {
273 Method existingMethod = list[i];
274 MemberDefinition existing = existingMethod.getMemberDefinition();
275
276 // Do we have a matching method?
277
278 if (implMethodSig.equals(existing.toString())) {
279
280 // Yes, so create exception list...
281
282 try {
283 ValueType[] implExcept = getMethodExceptions(implMethod,quiet,stack);
284 existingMethod.setImplExceptions(implExcept);
285 } catch (Exception e) {
286 return false;
287 }
288 }
289 }
290 return true;
291 }
292 }

mercurial