Source code: com/simscomputing/testbed/ClearBox.java
1 // Copyright 2000 Sims Computing, Inc.
2 // Licensed under the GNU Lesser General Public License.
3
4 package com.simscomputing.testbed;
5
6 import com.simscomputing.SoftwareFaultException;
7
8 import java.lang.reflect.Constructor;
9 import java.lang.reflect.Field;
10 import java.lang.reflect.Method;
11 import java.lang.reflect.InvocationTargetException;
12
13 /**
14 Provides access to private and protected constructors, methods, and
15 fields in arbitrary classes. Inspired by a similar class written by
16 Creig Smith <creigs@acm.org>.
17
18 @author David Sims
19 @version $Revision: 1.1.1.1 $ $Date: 2000/02/21 21:22:33 $ */
20 public class ClearBox {
21 /**
22 This class is just a collection of static methods. No need to instantiate it.
23 */
24 private ClearBox() {
25 } // constructor
26
27 /**
28 Helper method for recursively finding private and protected fields.
29 */
30 private static Field findField(final Class c, final String fieldName)
31 throws NoSuchFieldException {
32
33 // make sure the class is still legitimate
34 if (c == null) {
35 throw new NoSuchFieldException();
36 } // if
37
38 try {
39 return c.getDeclaredField(fieldName);
40 } // try
41 catch (NoSuchFieldException e) {
42 // try again on the parent
43 return findField(c.getSuperclass(), fieldName);
44 } // catch
45 } // findField()
46
47 /**
48 Finds a private, protected, or public field in the specified object.
49 */
50 public static Object getField(Object object, String fieldName) throws NoSuchFieldException {
51 try {
52 final Class c = object.getClass();
53 final Field field = findField(c, fieldName);
54
55 // the following call skirts private/protected access
56 // protection unless the security manager prevents it
57 field.setAccessible(true);
58
59 return field.get(object);
60 } // try
61 catch (IllegalAccessException e) {
62 // due to the setAccessible() call above, should not reach here
63 throw new SoftwareFaultException("access should be legal", e);
64 } // catch
65 } // getField()
66
67 /**
68 Finds the class for a private, protected, or public field in the
69 specified object.
70 */
71 public static Class getFieldClass(Object object, String fieldName)
72 throws NoSuchFieldException {
73 final Class c = object.getClass();
74 final Field field = findField(c, fieldName);
75
76 // the following call skirts private/protected access
77 // protection unless the security manager prevents it
78 field.setAccessible(true);
79
80 return field.getType();
81 } // getFieldClass()
82
83 /**
84 Sets a private, protected, or public field in the specified object.
85
86 @param object the object whose field is being set
87 @param fieldName the name of the field to set
88 @param newValue the value that the field receives
89 @throws NoSuchFieldException if fieldName does not exist
90 */
91 public static void setField(final Object object,
92 final String fieldName,
93 final Object newValue)
94 throws NoSuchFieldException {
95 try {
96 final Field field = findField(object.getClass(), fieldName);
97
98 // the following call skirts private/protected access
99 // protection unless the security manager prevents it
100 field.setAccessible(true);
101
102 field.set(object, newValue);
103 } // try
104 catch (final IllegalAccessException e) {
105 // due to the setAccessible() call above, should not reach here
106 throw new SoftwareFaultException("access should be legal", e);
107 } // catch
108 } // setField()
109
110 /**
111 Instantiates an object with a private or protected constructor.
112 */
113 public static Object createNewInstance(String className, Class[] constructorParameterTypes,
114 Object[] constructorParameters)
115 throws ClassNotFoundException, NoSuchMethodException,
116 SecurityException, InstantiationException, InvocationTargetException,
117 IllegalAccessException {
118 Class newClass = ClearBox.class.getClassLoader().loadClass(className);
119 Constructor constructor = newClass.getDeclaredConstructor(constructorParameterTypes);
120
121 // the following call skirts private/protected access
122 // protection unless the security manager prevents it
123 constructor.setAccessible(true);
124
125 return constructor.newInstance(constructorParameters);
126 } // createNewInstance()
127
128 /**
129 Helper method for recursively finding private, protected,
130 and public methods.
131 */
132 private static Method findMethod(final Class c, final String methodName,
133 final Class[] methodParameterTypes)
134 throws NoSuchMethodException {
135 try {
136 return c.getDeclaredMethod(methodName, methodParameterTypes);
137 } // try
138 catch (NoSuchMethodException e) {
139 // try again on the parent
140 return findMethod(c.getSuperclass(), methodName, methodParameterTypes);
141 } // catch
142 } // findMethod()
143
144 /**
145 Finds a private, protected, or public method in the specified object.
146 */
147 public static Method getMethod(Object object, String methodName, Class[] methodParameterTypes)
148 throws ClassNotFoundException, NoSuchMethodException,
149 SecurityException, InstantiationException, InvocationTargetException, IllegalAccessException {
150 // try {
151 final Class c = object.getClass();
152 final Method method = findMethod(c, methodName, methodParameterTypes);
153
154 // the following call skirts private/protected access
155 // protection unless the security manager prevents it
156 method.setAccessible(true);
157
158 return method;
159 // } // try
160 // catch (IllegalAccessException e) {
161 // // due to the setAccessible() call above, should not reach here
162 // throw new SoftwareFaultException("access should be legal", e);
163 // } // catch
164 } // getMethod()
165 } // class ClearBox