rlm@10
|
1 /**
|
rlm@10
|
2 * Copyright (c) Rich Hickey. All rights reserved.
|
rlm@10
|
3 * The use and distribution terms for this software are covered by the
|
rlm@10
|
4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
rlm@10
|
5 * which can be found in the file epl-v10.html at the root of this distribution.
|
rlm@10
|
6 * By using this software in any fashion, you are agreeing to be bound by
|
rlm@10
|
7 * the terms of this license.
|
rlm@10
|
8 * You must not remove this notice, or any other, from this software.
|
rlm@10
|
9 **/
|
rlm@10
|
10
|
rlm@10
|
11 /* rich Apr 19, 2006 */
|
rlm@10
|
12
|
rlm@10
|
13 package clojure.lang;
|
rlm@10
|
14
|
rlm@10
|
15 import java.lang.reflect.*;
|
rlm@10
|
16 import java.util.ArrayList;
|
rlm@10
|
17 import java.util.Iterator;
|
rlm@10
|
18 import java.util.List;
|
rlm@10
|
19 import java.util.Arrays;
|
rlm@10
|
20
|
rlm@10
|
21 public class Reflector{
|
rlm@10
|
22
|
rlm@10
|
23 public static Object invokeInstanceMethod(Object target, String methodName, Object[] args) throws Exception{
|
rlm@10
|
24 try
|
rlm@10
|
25 {
|
rlm@10
|
26 Class c = target.getClass();
|
rlm@10
|
27 List methods = getMethods(c, args.length, methodName, false);
|
rlm@10
|
28 return invokeMatchingMethod(methodName, methods, target, args);
|
rlm@10
|
29 }
|
rlm@10
|
30 catch(InvocationTargetException e)
|
rlm@10
|
31 {
|
rlm@10
|
32 if(e.getCause() instanceof Exception)
|
rlm@10
|
33 throw (Exception) e.getCause();
|
rlm@10
|
34 else if(e.getCause() instanceof Error)
|
rlm@10
|
35 throw (Error) e.getCause();
|
rlm@10
|
36 throw e;
|
rlm@10
|
37 }
|
rlm@10
|
38 }
|
rlm@10
|
39
|
rlm@10
|
40 private static String noMethodReport(String methodName, Object target){
|
rlm@10
|
41 return "No matching method found: " + methodName
|
rlm@10
|
42 + (target==null?"":" for " + target.getClass());
|
rlm@10
|
43 }
|
rlm@10
|
44 static Object invokeMatchingMethod(String methodName, List methods, Object target, Object[] args)
|
rlm@10
|
45 throws Exception{
|
rlm@10
|
46 Method m = null;
|
rlm@10
|
47 Object[] boxedArgs = null;
|
rlm@10
|
48 if(methods.isEmpty())
|
rlm@10
|
49 {
|
rlm@10
|
50 throw new IllegalArgumentException(noMethodReport(methodName,target));
|
rlm@10
|
51 }
|
rlm@10
|
52 else if(methods.size() == 1)
|
rlm@10
|
53 {
|
rlm@10
|
54 m = (Method) methods.get(0);
|
rlm@10
|
55 boxedArgs = boxArgs(m.getParameterTypes(), args);
|
rlm@10
|
56 }
|
rlm@10
|
57 else //overloaded w/same arity
|
rlm@10
|
58 {
|
rlm@10
|
59 Method foundm = null;
|
rlm@10
|
60 for(Iterator i = methods.iterator(); i.hasNext();)
|
rlm@10
|
61 {
|
rlm@10
|
62 m = (Method) i.next();
|
rlm@10
|
63
|
rlm@10
|
64 Class[] params = m.getParameterTypes();
|
rlm@10
|
65 if(isCongruent(params, args))
|
rlm@10
|
66 {
|
rlm@10
|
67 if(foundm == null || Compiler.subsumes(params, foundm.getParameterTypes()))
|
rlm@10
|
68 {
|
rlm@10
|
69 foundm = m;
|
rlm@10
|
70 boxedArgs = boxArgs(params, args);
|
rlm@10
|
71 }
|
rlm@10
|
72 }
|
rlm@10
|
73 }
|
rlm@10
|
74 m = foundm;
|
rlm@10
|
75 }
|
rlm@10
|
76 if(m == null)
|
rlm@10
|
77 throw new IllegalArgumentException(noMethodReport(methodName,target));
|
rlm@10
|
78
|
rlm@10
|
79 if(!Modifier.isPublic(m.getDeclaringClass().getModifiers()))
|
rlm@10
|
80 {
|
rlm@10
|
81 //public method of non-public class, try to find it in hierarchy
|
rlm@10
|
82 Method oldm = m;
|
rlm@10
|
83 m = getAsMethodOfPublicBase(m.getDeclaringClass(), m);
|
rlm@10
|
84 if(m == null)
|
rlm@10
|
85 throw new IllegalArgumentException("Can't call public method of non-public class: " +
|
rlm@10
|
86 oldm.toString());
|
rlm@10
|
87 }
|
rlm@10
|
88 try
|
rlm@10
|
89 {
|
rlm@10
|
90 return prepRet(m.invoke(target, boxedArgs));
|
rlm@10
|
91 }
|
rlm@10
|
92 catch(InvocationTargetException e)
|
rlm@10
|
93 {
|
rlm@10
|
94 if(e.getCause() instanceof Exception)
|
rlm@10
|
95 throw (Exception) e.getCause();
|
rlm@10
|
96 else if(e.getCause() instanceof Error)
|
rlm@10
|
97 throw (Error) e.getCause();
|
rlm@10
|
98 throw e;
|
rlm@10
|
99 }
|
rlm@10
|
100
|
rlm@10
|
101 }
|
rlm@10
|
102
|
rlm@10
|
103 public static Method getAsMethodOfPublicBase(Class c, Method m){
|
rlm@10
|
104 for(Class iface : c.getInterfaces())
|
rlm@10
|
105 {
|
rlm@10
|
106 for(Method im : iface.getMethods())
|
rlm@10
|
107 {
|
rlm@10
|
108 if(im.getName().equals(m.getName())
|
rlm@10
|
109 && Arrays.equals(m.getParameterTypes(), im.getParameterTypes()))
|
rlm@10
|
110 {
|
rlm@10
|
111 return im;
|
rlm@10
|
112 }
|
rlm@10
|
113 }
|
rlm@10
|
114 }
|
rlm@10
|
115 Class sc = c.getSuperclass();
|
rlm@10
|
116 if(sc == null)
|
rlm@10
|
117 return null;
|
rlm@10
|
118 for(Method scm : sc.getMethods())
|
rlm@10
|
119 {
|
rlm@10
|
120 if(scm.getName().equals(m.getName())
|
rlm@10
|
121 && Arrays.equals(m.getParameterTypes(), scm.getParameterTypes())
|
rlm@10
|
122 && Modifier.isPublic(scm.getDeclaringClass().getModifiers()))
|
rlm@10
|
123 {
|
rlm@10
|
124 return scm;
|
rlm@10
|
125 }
|
rlm@10
|
126 }
|
rlm@10
|
127 return getAsMethodOfPublicBase(sc, m);
|
rlm@10
|
128 }
|
rlm@10
|
129
|
rlm@10
|
130 public static Object invokeConstructor(Class c, Object[] args) throws Exception{
|
rlm@10
|
131 try
|
rlm@10
|
132 {
|
rlm@10
|
133 Constructor[] allctors = c.getConstructors();
|
rlm@10
|
134 ArrayList ctors = new ArrayList();
|
rlm@10
|
135 for(int i = 0; i < allctors.length; i++)
|
rlm@10
|
136 {
|
rlm@10
|
137 Constructor ctor = allctors[i];
|
rlm@10
|
138 if(ctor.getParameterTypes().length == args.length)
|
rlm@10
|
139 ctors.add(ctor);
|
rlm@10
|
140 }
|
rlm@10
|
141 if(ctors.isEmpty())
|
rlm@10
|
142 {
|
rlm@10
|
143 throw new IllegalArgumentException("No matching ctor found"
|
rlm@10
|
144 + " for " + c);
|
rlm@10
|
145 }
|
rlm@10
|
146 else if(ctors.size() == 1)
|
rlm@10
|
147 {
|
rlm@10
|
148 Constructor ctor = (Constructor) ctors.get(0);
|
rlm@10
|
149 return ctor.newInstance(boxArgs(ctor.getParameterTypes(), args));
|
rlm@10
|
150 }
|
rlm@10
|
151 else //overloaded w/same arity
|
rlm@10
|
152 {
|
rlm@10
|
153 for(Iterator iterator = ctors.iterator(); iterator.hasNext();)
|
rlm@10
|
154 {
|
rlm@10
|
155 Constructor ctor = (Constructor) iterator.next();
|
rlm@10
|
156 Class[] params = ctor.getParameterTypes();
|
rlm@10
|
157 if(isCongruent(params, args))
|
rlm@10
|
158 {
|
rlm@10
|
159 Object[] boxedArgs = boxArgs(params, args);
|
rlm@10
|
160 return ctor.newInstance(boxedArgs);
|
rlm@10
|
161 }
|
rlm@10
|
162 }
|
rlm@10
|
163 throw new IllegalArgumentException("No matching ctor found"
|
rlm@10
|
164 + " for " + c);
|
rlm@10
|
165 }
|
rlm@10
|
166 }
|
rlm@10
|
167 catch(InvocationTargetException e)
|
rlm@10
|
168 {
|
rlm@10
|
169 if(e.getCause() instanceof Exception)
|
rlm@10
|
170 throw (Exception) e.getCause();
|
rlm@10
|
171 else if(e.getCause() instanceof Error)
|
rlm@10
|
172 throw (Error) e.getCause();
|
rlm@10
|
173 throw e;
|
rlm@10
|
174 }
|
rlm@10
|
175 }
|
rlm@10
|
176
|
rlm@10
|
177 public static Object invokeStaticMethodVariadic(String className, String methodName, Object... args) throws Exception{
|
rlm@10
|
178 return invokeStaticMethod(className, methodName, args);
|
rlm@10
|
179
|
rlm@10
|
180 }
|
rlm@10
|
181
|
rlm@10
|
182 public static Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception{
|
rlm@10
|
183 Class c = RT.classForName(className);
|
rlm@10
|
184 try
|
rlm@10
|
185 {
|
rlm@10
|
186 return invokeStaticMethod(c, methodName, args);
|
rlm@10
|
187 }
|
rlm@10
|
188 catch(InvocationTargetException e)
|
rlm@10
|
189 {
|
rlm@10
|
190 if(e.getCause() instanceof Exception)
|
rlm@10
|
191 throw (Exception) e.getCause();
|
rlm@10
|
192 else if(e.getCause() instanceof Error)
|
rlm@10
|
193 throw (Error) e.getCause();
|
rlm@10
|
194 throw e;
|
rlm@10
|
195 }
|
rlm@10
|
196 }
|
rlm@10
|
197
|
rlm@10
|
198 public static Object invokeStaticMethod(Class c, String methodName, Object[] args) throws Exception{
|
rlm@10
|
199 if(methodName.equals("new"))
|
rlm@10
|
200 return invokeConstructor(c, args);
|
rlm@10
|
201 List methods = getMethods(c, args.length, methodName, true);
|
rlm@10
|
202 return invokeMatchingMethod(methodName, methods, null, args);
|
rlm@10
|
203 }
|
rlm@10
|
204
|
rlm@10
|
205 public static Object getStaticField(String className, String fieldName) throws Exception{
|
rlm@10
|
206 Class c = RT.classForName(className);
|
rlm@10
|
207 return getStaticField(c, fieldName);
|
rlm@10
|
208 }
|
rlm@10
|
209
|
rlm@10
|
210 public static Object getStaticField(Class c, String fieldName) throws Exception{
|
rlm@10
|
211 // if(fieldName.equals("class"))
|
rlm@10
|
212 // return c;
|
rlm@10
|
213 Field f = getField(c, fieldName, true);
|
rlm@10
|
214 if(f != null)
|
rlm@10
|
215 {
|
rlm@10
|
216 return prepRet(f.get(null));
|
rlm@10
|
217 }
|
rlm@10
|
218 throw new IllegalArgumentException("No matching field found: " + fieldName
|
rlm@10
|
219 + " for " + c);
|
rlm@10
|
220 }
|
rlm@10
|
221
|
rlm@10
|
222 public static Object setStaticField(String className, String fieldName, Object val) throws Exception{
|
rlm@10
|
223 Class c = RT.classForName(className);
|
rlm@10
|
224 return setStaticField(c, fieldName, val);
|
rlm@10
|
225 }
|
rlm@10
|
226
|
rlm@10
|
227 public static Object setStaticField(Class c, String fieldName, Object val) throws Exception{
|
rlm@10
|
228 Field f = getField(c, fieldName, true);
|
rlm@10
|
229 if(f != null)
|
rlm@10
|
230 {
|
rlm@10
|
231 f.set(null, boxArg(f.getType(), val));
|
rlm@10
|
232 return val;
|
rlm@10
|
233 }
|
rlm@10
|
234 throw new IllegalArgumentException("No matching field found: " + fieldName
|
rlm@10
|
235 + " for " + c);
|
rlm@10
|
236 }
|
rlm@10
|
237
|
rlm@10
|
238 public static Object getInstanceField(Object target, String fieldName) throws Exception{
|
rlm@10
|
239 Class c = target.getClass();
|
rlm@10
|
240 Field f = getField(c, fieldName, false);
|
rlm@10
|
241 if(f != null)
|
rlm@10
|
242 {
|
rlm@10
|
243 return prepRet(f.get(target));
|
rlm@10
|
244 }
|
rlm@10
|
245 throw new IllegalArgumentException("No matching field found: " + fieldName
|
rlm@10
|
246 + " for " + target.getClass());
|
rlm@10
|
247 }
|
rlm@10
|
248
|
rlm@10
|
249 public static Object setInstanceField(Object target, String fieldName, Object val) throws Exception{
|
rlm@10
|
250 Class c = target.getClass();
|
rlm@10
|
251 Field f = getField(c, fieldName, false);
|
rlm@10
|
252 if(f != null)
|
rlm@10
|
253 {
|
rlm@10
|
254 f.set(target, boxArg(f.getType(), val));
|
rlm@10
|
255 return val;
|
rlm@10
|
256 }
|
rlm@10
|
257 throw new IllegalArgumentException("No matching field found: " + fieldName
|
rlm@10
|
258 + " for " + target.getClass());
|
rlm@10
|
259 }
|
rlm@10
|
260
|
rlm@10
|
261 public static Object invokeNoArgInstanceMember(Object target, String name) throws Exception{
|
rlm@10
|
262 //favor method over field
|
rlm@10
|
263 List meths = getMethods(target.getClass(), 0, name, false);
|
rlm@10
|
264 if(meths.size() > 0)
|
rlm@10
|
265 return invokeMatchingMethod(name, meths, target, RT.EMPTY_ARRAY);
|
rlm@10
|
266 else
|
rlm@10
|
267 return getInstanceField(target, name);
|
rlm@10
|
268 }
|
rlm@10
|
269
|
rlm@10
|
270 public static Object invokeInstanceMember(Object target, String name) throws Exception{
|
rlm@10
|
271 //check for field first
|
rlm@10
|
272 Class c = target.getClass();
|
rlm@10
|
273 Field f = getField(c, name, false);
|
rlm@10
|
274 if(f != null) //field get
|
rlm@10
|
275 {
|
rlm@10
|
276 return prepRet(f.get(target));
|
rlm@10
|
277 }
|
rlm@10
|
278 return invokeInstanceMethod(target, name, RT.EMPTY_ARRAY);
|
rlm@10
|
279 }
|
rlm@10
|
280
|
rlm@10
|
281 public static Object invokeInstanceMember(String name, Object target, Object arg1) throws Exception{
|
rlm@10
|
282 //check for field first
|
rlm@10
|
283 Class c = target.getClass();
|
rlm@10
|
284 Field f = getField(c, name, false);
|
rlm@10
|
285 if(f != null) //field set
|
rlm@10
|
286 {
|
rlm@10
|
287 f.set(target, boxArg(f.getType(), arg1));
|
rlm@10
|
288 return arg1;
|
rlm@10
|
289 }
|
rlm@10
|
290 return invokeInstanceMethod(target, name, new Object[]{arg1});
|
rlm@10
|
291 }
|
rlm@10
|
292
|
rlm@10
|
293 public static Object invokeInstanceMember(String name, Object target, Object... args) throws Exception{
|
rlm@10
|
294 return invokeInstanceMethod(target, name, args);
|
rlm@10
|
295 }
|
rlm@10
|
296
|
rlm@10
|
297
|
rlm@10
|
298 static public Field getField(Class c, String name, boolean getStatics){
|
rlm@10
|
299 Field[] allfields = c.getFields();
|
rlm@10
|
300 for(int i = 0; i < allfields.length; i++)
|
rlm@10
|
301 {
|
rlm@10
|
302 if(name.equals(allfields[i].getName())
|
rlm@10
|
303 && Modifier.isStatic(allfields[i].getModifiers()) == getStatics)
|
rlm@10
|
304 return allfields[i];
|
rlm@10
|
305 }
|
rlm@10
|
306 return null;
|
rlm@10
|
307 }
|
rlm@10
|
308
|
rlm@10
|
309 static public List getMethods(Class c, int arity, String name, boolean getStatics){
|
rlm@10
|
310 Method[] allmethods = c.getMethods();
|
rlm@10
|
311 ArrayList methods = new ArrayList();
|
rlm@10
|
312 ArrayList bridgeMethods = new ArrayList();
|
rlm@10
|
313 for(int i = 0; i < allmethods.length; i++)
|
rlm@10
|
314 {
|
rlm@10
|
315 Method method = allmethods[i];
|
rlm@10
|
316 if(name.equals(method.getName())
|
rlm@10
|
317 && Modifier.isStatic(method.getModifiers()) == getStatics
|
rlm@10
|
318 && method.getParameterTypes().length == arity)
|
rlm@10
|
319 {
|
rlm@10
|
320 try
|
rlm@10
|
321 {
|
rlm@10
|
322 if(method.isBridge()
|
rlm@10
|
323 && c.getMethod(method.getName(), method.getParameterTypes())
|
rlm@10
|
324 .equals(method))
|
rlm@10
|
325 bridgeMethods.add(method);
|
rlm@10
|
326 else
|
rlm@10
|
327 methods.add(method);
|
rlm@10
|
328 }
|
rlm@10
|
329 catch(NoSuchMethodException e)
|
rlm@10
|
330 {
|
rlm@10
|
331 }
|
rlm@10
|
332 }
|
rlm@10
|
333 // && (!method.isBridge()
|
rlm@10
|
334 // || (c == StringBuilder.class &&
|
rlm@10
|
335 // c.getMethod(method.getName(), method.getParameterTypes())
|
rlm@10
|
336 // .equals(method))))
|
rlm@10
|
337 // {
|
rlm@10
|
338 // methods.add(allmethods[i]);
|
rlm@10
|
339 // }
|
rlm@10
|
340 }
|
rlm@10
|
341
|
rlm@10
|
342 if(methods.isEmpty())
|
rlm@10
|
343 methods.addAll(bridgeMethods);
|
rlm@10
|
344
|
rlm@10
|
345 if(!getStatics && c.isInterface())
|
rlm@10
|
346 {
|
rlm@10
|
347 allmethods = Object.class.getMethods();
|
rlm@10
|
348 for(int i = 0; i < allmethods.length; i++)
|
rlm@10
|
349 {
|
rlm@10
|
350 if(name.equals(allmethods[i].getName())
|
rlm@10
|
351 && Modifier.isStatic(allmethods[i].getModifiers()) == getStatics
|
rlm@10
|
352 && allmethods[i].getParameterTypes().length == arity)
|
rlm@10
|
353 {
|
rlm@10
|
354 methods.add(allmethods[i]);
|
rlm@10
|
355 }
|
rlm@10
|
356 }
|
rlm@10
|
357 }
|
rlm@10
|
358 return methods;
|
rlm@10
|
359 }
|
rlm@10
|
360
|
rlm@10
|
361
|
rlm@10
|
362 static Object boxArg(Class paramType, Object arg){
|
rlm@10
|
363 if(!paramType.isPrimitive())
|
rlm@10
|
364 return paramType.cast(arg);
|
rlm@10
|
365 else if(paramType == boolean.class)
|
rlm@10
|
366 return Boolean.class.cast(arg);
|
rlm@10
|
367 else if(paramType == char.class)
|
rlm@10
|
368 return Character.class.cast(arg);
|
rlm@10
|
369 else if(arg instanceof Number)
|
rlm@10
|
370 {
|
rlm@10
|
371 Number n = (Number) arg;
|
rlm@10
|
372 if(paramType == int.class)
|
rlm@10
|
373 return n.intValue();
|
rlm@10
|
374 else if(paramType == float.class)
|
rlm@10
|
375 return n.floatValue();
|
rlm@10
|
376 else if(paramType == double.class)
|
rlm@10
|
377 return n.doubleValue();
|
rlm@10
|
378 else if(paramType == long.class)
|
rlm@10
|
379 return n.longValue();
|
rlm@10
|
380 else if(paramType == short.class)
|
rlm@10
|
381 return n.shortValue();
|
rlm@10
|
382 else if(paramType == byte.class)
|
rlm@10
|
383 return n.byteValue();
|
rlm@10
|
384 }
|
rlm@10
|
385 throw new IllegalArgumentException("Unexpected param type, expected: " + paramType +
|
rlm@10
|
386 ", given: " + arg.getClass().getName());
|
rlm@10
|
387 }
|
rlm@10
|
388
|
rlm@10
|
389 static Object[] boxArgs(Class[] params, Object[] args){
|
rlm@10
|
390 if(params.length == 0)
|
rlm@10
|
391 return null;
|
rlm@10
|
392 Object[] ret = new Object[params.length];
|
rlm@10
|
393 for(int i = 0; i < params.length; i++)
|
rlm@10
|
394 {
|
rlm@10
|
395 Object arg = args[i];
|
rlm@10
|
396 Class paramType = params[i];
|
rlm@10
|
397 ret[i] = boxArg(paramType, arg);
|
rlm@10
|
398 }
|
rlm@10
|
399 return ret;
|
rlm@10
|
400 }
|
rlm@10
|
401
|
rlm@10
|
402 static public boolean paramArgTypeMatch(Class paramType, Class argType){
|
rlm@10
|
403 if(argType == null)
|
rlm@10
|
404 return !paramType.isPrimitive();
|
rlm@10
|
405 if(paramType == argType || paramType.isAssignableFrom(argType))
|
rlm@10
|
406 return true;
|
rlm@10
|
407 if(paramType == int.class)
|
rlm@10
|
408 return argType == Integer.class;// || argType == FixNum.class;
|
rlm@10
|
409 else if(paramType == float.class)
|
rlm@10
|
410 return argType == Float.class;
|
rlm@10
|
411 else if(paramType == double.class)
|
rlm@10
|
412 return argType == Double.class;// || argType == DoubleNum.class;
|
rlm@10
|
413 else if(paramType == long.class)
|
rlm@10
|
414 return argType == Long.class;// || argType == BigNum.class;
|
rlm@10
|
415 else if(paramType == char.class)
|
rlm@10
|
416 return argType == Character.class;
|
rlm@10
|
417 else if(paramType == short.class)
|
rlm@10
|
418 return argType == Short.class;
|
rlm@10
|
419 else if(paramType == byte.class)
|
rlm@10
|
420 return argType == Byte.class;
|
rlm@10
|
421 else if(paramType == boolean.class)
|
rlm@10
|
422 return argType == Boolean.class;
|
rlm@10
|
423 return false;
|
rlm@10
|
424 }
|
rlm@10
|
425
|
rlm@10
|
426 static boolean isCongruent(Class[] params, Object[] args){
|
rlm@10
|
427 boolean ret = false;
|
rlm@10
|
428 if(args == null)
|
rlm@10
|
429 return params.length == 0;
|
rlm@10
|
430 if(params.length == args.length)
|
rlm@10
|
431 {
|
rlm@10
|
432 ret = true;
|
rlm@10
|
433 for(int i = 0; ret && i < params.length; i++)
|
rlm@10
|
434 {
|
rlm@10
|
435 Object arg = args[i];
|
rlm@10
|
436 Class argType = (arg == null) ? null : arg.getClass();
|
rlm@10
|
437 Class paramType = params[i];
|
rlm@10
|
438 ret = paramArgTypeMatch(paramType, argType);
|
rlm@10
|
439 }
|
rlm@10
|
440 }
|
rlm@10
|
441 return ret;
|
rlm@10
|
442 }
|
rlm@10
|
443
|
rlm@10
|
444 public static Object prepRet(Object x){
|
rlm@10
|
445 // if(c == boolean.class)
|
rlm@10
|
446 // return ((Boolean) x).booleanValue() ? RT.T : null;
|
rlm@10
|
447 if(x instanceof Boolean)
|
rlm@10
|
448 return ((Boolean) x)?Boolean.TRUE:Boolean.FALSE;
|
rlm@10
|
449 return x;
|
rlm@10
|
450 }
|
rlm@10
|
451 }
|