|
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.ClassDefinition; |
|
38 import sun.tools.java.ClassNotFound; |
|
39 |
|
40 /** |
|
41 * RemoteType represents any non-special interface which inherits |
|
42 * from java.rmi.Remote. |
|
43 * <p> |
|
44 * The static forRemote(...) 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 RemoteType extends InterfaceType { |
|
49 |
|
50 //_____________________________________________________________________ |
|
51 // Public Interfaces |
|
52 //_____________________________________________________________________ |
|
53 |
|
54 /** |
|
55 * Create an RemoteType 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 */ |
|
61 public static RemoteType forRemote(ClassDefinition classDef, |
|
62 ContextStack stack, |
|
63 boolean quiet) { |
|
64 |
|
65 if (stack.anyErrors()) return null; |
|
66 |
|
67 boolean doPop = false; |
|
68 RemoteType result = null; |
|
69 |
|
70 try { |
|
71 // Do we already have it? |
|
72 |
|
73 sun.tools.java.Type theType = classDef.getType(); |
|
74 Type existing = getType(theType,stack); |
|
75 |
|
76 if (existing != null) { |
|
77 |
|
78 if (!(existing instanceof RemoteType)) return null; // False hit. |
|
79 |
|
80 // Yep, so return it... |
|
81 |
|
82 return (RemoteType) existing; |
|
83 } |
|
84 |
|
85 // Could this be a remote type? |
|
86 |
|
87 if (couldBeRemote(quiet,stack,classDef)) { |
|
88 |
|
89 // Yes, so check it... |
|
90 |
|
91 RemoteType it = new RemoteType(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 */ |
|
114 public String getTypeDescription () { |
|
115 return "Remote interface"; |
|
116 } |
|
117 |
|
118 //_____________________________________________________________________ |
|
119 // Internal/Subclass Interfaces |
|
120 //_____________________________________________________________________ |
|
121 |
|
122 /** |
|
123 * Create a RemoteType instance for the given class. The resulting |
|
124 * object is not yet completely initialized. |
|
125 */ |
|
126 protected RemoteType(ContextStack stack, ClassDefinition classDef) { |
|
127 super(stack,classDef,TYPE_REMOTE | TM_INTERFACE | TM_COMPOUND); |
|
128 } |
|
129 |
|
130 /** |
|
131 * Create a RemoteType instance for the given class. The resulting |
|
132 * object is not yet completely initialized. |
|
133 */ |
|
134 protected RemoteType(ContextStack stack, ClassDefinition classDef, int typeCode) { |
|
135 super(stack,classDef,typeCode); |
|
136 } |
|
137 |
|
138 //_____________________________________________________________________ |
|
139 // Internal Interfaces |
|
140 //_____________________________________________________________________ |
|
141 |
|
142 |
|
143 private static boolean couldBeRemote (boolean quiet, ContextStack stack, |
|
144 ClassDefinition classDef) { |
|
145 |
|
146 boolean result = false; |
|
147 BatchEnvironment env = stack.getEnv(); |
|
148 |
|
149 try { |
|
150 if (!classDef.isInterface()) { |
|
151 failedConstraint(16,quiet,stack,classDef.getName()); |
|
152 } else { |
|
153 result = env.defRemote.implementedBy(env,classDef.getClassDeclaration()); |
|
154 if (!result) failedConstraint(1,quiet,stack,classDef.getName()); |
|
155 } |
|
156 } catch (ClassNotFound e) { |
|
157 classNotFound(stack,e); |
|
158 } |
|
159 |
|
160 return result; |
|
161 } |
|
162 |
|
163 |
|
164 /** |
|
165 * Initialize this instance. |
|
166 */ |
|
167 private boolean initialize (boolean quiet,ContextStack stack) { |
|
168 |
|
169 boolean result = false; |
|
170 |
|
171 // Go check it out and gather up the info we need... |
|
172 |
|
173 Vector directInterfaces = new Vector(); |
|
174 Vector directMethods = new Vector(); |
|
175 Vector directConstants = new Vector(); |
|
176 |
|
177 if (isConformingRemoteInterface(directInterfaces, |
|
178 directMethods, |
|
179 directConstants, |
|
180 quiet, |
|
181 stack)){ |
|
182 |
|
183 // We're ok, so pass 'em up... |
|
184 |
|
185 result = initialize(directInterfaces,directMethods,directConstants,stack,quiet); |
|
186 } |
|
187 |
|
188 return result; |
|
189 } |
|
190 |
|
191 /** |
|
192 * Check to ensure that the interface and all it's methods and arguments |
|
193 * conforms to the RMI/IDL java subset for remote interfaces as defined |
|
194 * by the "Java to IDL Mapping" specification, section 4. |
|
195 * @param directInterfaces All directly implmented interfaces will be |
|
196 * added to this list. |
|
197 * @param directMethods All directly implemented methods (other than |
|
198 * constructors and initializers) will be added to this list. |
|
199 * @param directConstants All constants defined by theInterface will be |
|
200 * added to this list. |
|
201 * @param quiet True if should not report constraint failures. |
|
202 * @return true if constraints satisfied, false otherwise. |
|
203 */ |
|
204 private boolean isConformingRemoteInterface ( Vector directInterfaces, |
|
205 Vector directMethods, |
|
206 Vector directConstants, |
|
207 boolean quiet, |
|
208 ContextStack stack) { |
|
209 |
|
210 ClassDefinition theInterface = getClassDefinition(); |
|
211 |
|
212 try { |
|
213 |
|
214 // Get all remote interfaces... |
|
215 |
|
216 if (addRemoteInterfaces(directInterfaces,false,stack) == null ) { |
|
217 return false; |
|
218 } |
|
219 |
|
220 // Make sure all constants are conforming... |
|
221 |
|
222 if (!addAllMembers(directConstants,true,quiet,stack)) { |
|
223 return false; |
|
224 } |
|
225 |
|
226 // Now, collect up all methods... |
|
227 |
|
228 if (addAllMethods(theInterface,directMethods,true,quiet,stack) == null) { |
|
229 // Failed a constraint check... |
|
230 return false; |
|
231 } |
|
232 |
|
233 // Now walk 'em, ensuring each is a valid remote method... |
|
234 |
|
235 boolean methodsConform = true; |
|
236 for (int i = 0; i < directMethods.size(); i++) { |
|
237 if (! isConformingRemoteMethod((Method) directMethods.elementAt(i),quiet)) { |
|
238 methodsConform = false; |
|
239 } |
|
240 } |
|
241 if (!methodsConform) { |
|
242 return false; |
|
243 } |
|
244 } catch (ClassNotFound e) { |
|
245 classNotFound(stack,e); |
|
246 return false; |
|
247 } |
|
248 |
|
249 return true; |
|
250 } |
|
251 } |