SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
Introspection.java
1/*
2 * Class: Introspection
3 * Description: Methods for introspection using Java Reflection API.
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.util;
26
27import java.lang.reflect.Field;
28import java.lang.reflect.Method;
29import java.lang.reflect.Modifier;
30import java.util.ArrayList;
31import java.util.HashSet;
32import java.util.List;
33import java.util.ListIterator;
34import java.util.Set;
35
41public class Introspection {
42 private Introspection() {
43 }
44
59 public static Method[] getMethods(Class<?> c) {
60 // Creates the set of methods for the class.
61 List<Method> lst = internalGetMethods(c);
62
63 // Copy the methods to the array that will be returned.
64 return lst.toArray(new Method[lst.size()]);
65 }
66
67 private static List<Method> internalGetMethods(Class<?> c) {
68 // Inspired from java.lang.Class
69 List<Method> methods = new ArrayList<Method>();
70 Method[] mt = c.getDeclaredMethods();
71 for (int i = 0; i < mt.length; i++)
72 methods.add(mt[i]);
73
74 List<Method> inheritedMethods = new ArrayList<Method>();
75 Class<?>[] iface = c.getInterfaces();
76 for (int i = 0; i < iface.length; i++)
77 inheritedMethods.addAll(internalGetMethods(iface[i]));
78 if (!c.isInterface()) {
79 Class<?> s = c.getSuperclass();
80 if (s != null) {
81 List<Method> supers = internalGetMethods(s);
82 for (Method m : supers) {
83 // Filter out concrete implementations of any interface
84 // methods.
85 if (m != null && !Modifier.isAbstract(m.getModifiers()))
86 removeByNameAndSignature(inheritedMethods, m);
87 }
88 supers.addAll(inheritedMethods);
89 inheritedMethods = supers;
90 }
91 }
92
93 // Filter out all local methods from inherited ones
94 for (Method m : methods)
95 removeByNameAndSignature(inheritedMethods, m);
96
97 for (Method m : inheritedMethods) {
98 if (m == null)
99 continue;
100 if (!methods.contains(m))
101 methods.add(m);
102 }
103 return methods;
104 }
105
106 private static void removeByNameAndSignature(List<Method> methods, Method m) {
107 for (ListIterator<Method> it = methods.listIterator(); it.hasNext();) {
108 Method tst = it.next();
109 if (tst == null)
110 continue;
111 if (tst.getName().equals(m.getName()) && tst.getReturnType() == m.getReturnType() && sameSignature(tst, m))
112 it.set(null);
113 }
114 }
115
125 public static boolean sameSignature(Method m1, Method m2) {
126 Class<?>[] pt1 = m1.getParameterTypes();
127 Class<?>[] pt2 = m2.getParameterTypes();
128 if (pt1.length != pt2.length)
129 return false;
130 for (int i = 0; i < pt1.length; i++)
131 if (pt1[i] != pt2[i])
132 return false;
133 return true;
134 }
135
149 public static Field[] getFields(Class<?> c) {
150 // Creates the set of fields for the class.
151 List<Field> lst = new ArrayList<Field>();
152 processFields(c, lst);
153 Set<Class<?>> traversedInterfaces = new HashSet<Class<?>>();
154 processInterfaceFields(c, lst, traversedInterfaces);
155
156 if (!c.isInterface()) {
157 Class<?> s = c.getSuperclass();
158 while (s != null) {
159 processFields(s, lst);
160 processInterfaceFields(s, lst, traversedInterfaces);
161 s = s.getSuperclass();
162 }
163 }
164
165 // Copy the fields to the array that will be returned.
166 return lst.toArray(new Field[lst.size()]);
167 }
168
169 private static void processFields(final Class<?> c, final List<Field> lst) {
170 Field[] f = c.getDeclaredFields();
171 for (int i = 0; i < f.length; i++)
172 lst.add(f[i]);
173 }
174
175 private static void processInterfaceFields(final Class<?> c, final List<Field> lst,
176 final Set<Class<?>> traversedInterfaces) {
177 Class<?>[] iface = c.getInterfaces();
178 for (int i = 0; i < iface.length; i++) {
179 if (traversedInterfaces.contains(iface[i]))
180 continue;
181 traversedInterfaces.add(iface[i]);
182 processFields(iface[i], lst);
183 processInterfaceFields(iface[i], lst, traversedInterfaces);
184 }
185 }
186
196 public static Method getMethod(Class<?> c, String name, Class[] pt) throws NoSuchMethodException {
197 try {
198 return c.getDeclaredMethod(name, pt);
199 } catch (NoSuchMethodException nme) {
200 }
201 if (!c.isInterface())
202 try {
203 Class<?> s = c.getSuperclass();
204 if (s != null)
205 return getMethod(s, name, pt);
206 } catch (NoSuchMethodException nme) {
207 }
208 Class[] iface = c.getInterfaces();
209 for (int i = 0; i < iface.length; i++)
210 try {
211 return getMethod(iface[i], name, pt);
212 } catch (NoSuchMethodException nme) {
213 }
214 throw new NoSuchMethodException("Cannot find method " + name + " in class " + c.getName());
215 }
216
228 public static Field getField(Class<?> c, String name) throws NoSuchFieldException {
229 try {
230 return c.getDeclaredField(name);
231 } catch (NoSuchFieldException nfe) {
232 }
233 Class[] iface = c.getInterfaces();
234 for (int i = 0; i < iface.length; i++)
235 try {
236 return getField(iface[i], name);
237 } catch (NoSuchFieldException nme) {
238 }
239 if (!c.isInterface())
240 try {
241 Class s = c.getSuperclass();
242 if (s != null)
243 return getField(s, name);
244 } catch (NoSuchFieldException nfe) {
245 }
246 throw new NoSuchFieldException("Cannot find field " + name + " in " + c.getName());
247 }
248
258 public static String getFieldName(Object val) {
259 Class<?> enumType = val.getClass();
260 Field[] f = enumType.getFields();
261 for (int i = 0; i < f.length; i++) {
262 if (Modifier.isPublic(f[i].getModifiers()) && Modifier.isStatic(f[i].getModifiers())
263 && Modifier.isFinal(f[i].getModifiers())) {
264 try {
265 if (f[i].get(null) == val)
266 return f[i].getName();
267 } catch (IllegalAccessException iae) {
268 }
269 }
270 }
271 return null;
272 }
273
287 public static <T> T valueOf(Class<T> cls, String name) {
288 try {
289 Field field = cls.getField(name);
290 if (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())
291 && cls.isAssignableFrom(field.getType()))
292 return (T) field.get(null);
293 } catch (NoSuchFieldException nfe) {
294 } catch (IllegalAccessException iae) {
295 }
296 throw new IllegalArgumentException("Invalid field name: " + name);
297 }
298
312 public static <T> T valueOfIgnoreCase(Class<T> cls, String name) {
313 Field[] fields = cls.getFields();
314 T res = null;
315 for (int i = 0; i < fields.length; i++) {
316 Field field = fields[i];
317 if (field.getName().equalsIgnoreCase(name) && Modifier.isStatic(field.getModifiers())
318 && Modifier.isFinal(field.getModifiers()) && cls.isAssignableFrom(field.getType()))
319 try {
320 T res2 = (T) field.get(null);
321 if (res != null && res2 != null)
322 throw new IllegalArgumentException("Found more than one field with the same name in class "
323 + cls.getName() + " if case is ignored");
324 res = res2;
325 } catch (IllegalAccessException iae) {
326 }
327 }
328 if (res == null)
329 throw new IllegalArgumentException("Invalid field name: " + name);
330 return res;
331 }
332}
static< T > T valueOfIgnoreCase(Class< T > cls, String name)
Similar to valueOf(Class<T>,String), with case insensitive field name look-up.
static< T > T valueOf(Class< T > cls, String name)
Returns the field of class cls corresponding to the name name.
static boolean sameSignature(Method m1, Method m2)
Determines if two methods m1 and m2 share the same signature.
static String getFieldName(Object val)
Returns the field name corresponding to the value of an enumerated type val.
static Method getMethod(Class<?> c, String name, Class[] pt)
This is like java.lang.Class.getMethod, except that it can return non-public methods.
static Field[] getFields(Class<?> c)
Returns all the fields declared and inherited by a class.
static Field getField(Class<?> c, String name)
This is like java.lang.Class.getField, except that it can return non-public fields.
static Method[] getMethods(Class<?> c)
Returns all the methods declared and inherited by a class.