KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > junitx > util > PrivateAccessor


1 /*
2  * The JUnit-addons Software License, Version 1.0
3  * (based on the Apache Software License, Version 1.1)
4  *
5  * Copyright (c) 2002-2003 Vladimir R. Bossicard. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by Vladimir R.
22  * Bossicard as well as other contributors
23  * (http://junit-addons.sourceforge.net/)."
24  * Alternately, this acknowlegement may appear in the software itself,
25  * if and wherever such third-party acknowlegements normally appear.
26  *
27  * 4. The name "JUnit-addons" must not be used to endorse or promote
28  * products derived from this software without prior written
29  * permission. For written permission, please contact
30  * vbossica@users.sourceforge.net.
31  *
32  * 5. Products derived from this software may not be called "JUnit-addons"
33  * nor may "JUnit-addons" appear in their names without prior written
34  * permission of the project managers.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ======================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals. For more information on the JUnit-addons Project, please
52  * see <http://junit-addons.sourceforge.net/>.
53  */

54
55 package junitx.util;
56
57 import java.lang.reflect.Field JavaDoc;
58 import java.lang.reflect.InvocationTargetException JavaDoc;
59 import java.lang.reflect.Method JavaDoc;
60
61 /**
62  * Utility class to bypass the Java modifiers security and access protected and
63  * private fields and methods.
64  *
65  * <h4>Note</h4>
66  *
67  * When specifying parameter types, use <code>int.class</>,
68  * <code>double.class</>, <code>short.class</>, <code>long.class</>,
69  * <code>float.class</> and <code>char.class</> for primitive types.<p>
70  *
71  * Example: To set the value of an object <code>obj</> to 100 via the method
72  * <code>setValue()</>:
73  * <pre>
74  * PrivateAccessor.invoke( obj, "setValue", new Class[]{int.class}, new Object[]{new Integer( 100 )} );
75  * </pre>
76  *
77  * @version $Revision: 1.5 $ $Date: 2003/03/21 06:13:49 $
78  * @author <a HREF="mailto:vbossica@users.sourceforge.net">Vladimir R. Bossicard</a>
79  */

80 public class PrivateAccessor {
81
82     private PrivateAccessor() {
83     }
84
85     /**
86      * Returns the value of the field on the specified object. The name
87      * parameter is a <code>String</code> specifying the simple name of the
88      * desired field.<p>
89      *
90      * The object is first searched for any matching field. If no matching
91      * field is found, the superclasses are recursively searched.
92      *
93      * @exception NoSuchFieldException if a field with the specified name is
94      * not found.
95      */

96     public static Object JavaDoc getField(Object JavaDoc object,
97                                   String JavaDoc name)
98             throws NoSuchFieldException JavaDoc {
99         if (object == null) {
100             throw new IllegalArgumentException JavaDoc("Invalid null object argument");
101         }
102         for (Class JavaDoc cls = object.getClass();
103              cls != null;
104              cls = cls.getSuperclass()) {
105             try {
106                 Field JavaDoc field = cls.getDeclaredField(name);
107                 field.setAccessible(true);
108                 return field.get(object);
109             } catch (Exception JavaDoc ex) {
110                 /* in case of an exception, we will throw a new
111                  * NoSuchFieldException object */

112                 ;
113             }
114         }
115         throw new NoSuchFieldException JavaDoc("Could get value for field " +
116                 object.getClass().getName() + "." + name);
117     }
118
119     /**
120      * Returns the value of the field on the specified class. The name
121      * parameter is a <code>String</code> specifying the simple name of the
122      * desired field.<p>
123      *
124      * The class is first searched for any matching field. If no matching
125      * field is found, the superclasses are recursively searched.
126      *
127      * @exception NoSuchFieldException if a field with the specified name is
128      * not found.
129      */

130     public static Object JavaDoc getField(Class JavaDoc cls,
131                                   String JavaDoc name)
132             throws NoSuchFieldException JavaDoc {
133         if (cls == null) {
134             throw new IllegalArgumentException JavaDoc("Invalid null cls argument");
135         }
136         Class JavaDoc base = cls;
137         while (base != null) {
138             try {
139                 Field JavaDoc field = base.getDeclaredField(name);
140                 field.setAccessible(true);
141                 return field.get(base);
142             } catch (Exception JavaDoc ex) {
143                 /* in case of an exception, we will throw a new
144                  * NoSuchFieldException object */

145                 ;
146             }
147             base = base.getSuperclass();
148         }
149         throw new NoSuchFieldException JavaDoc("Could get value for static field " +
150                 cls.getName() + "." + name);
151     }
152
153     /**
154      * Sets the field represented by the name value on the specified object
155      * argument to the specified new value. The new value is automatically
156      * unwrapped if the underlying field has a primitive type.<p>
157      *
158      * The object is first searched for any matching field. If no matching
159      * field is found, the superclasses are recursively searched.
160      *
161      * @exception NoSuchFieldException if a field with the specified name is
162      * not found.
163      */

164     public static void setField(Object JavaDoc object,
165                                 String JavaDoc name,
166                                 Object JavaDoc value)
167             throws NoSuchFieldException JavaDoc {
168         if (object == null) {
169             throw new IllegalArgumentException JavaDoc("Invalid null object argument");
170         }
171         for (Class JavaDoc cls = object.getClass();
172              cls != null;
173              cls = cls.getSuperclass()) {
174             try {
175                 Field JavaDoc field = cls.getDeclaredField(name);
176                 field.setAccessible(true);
177                 field.set(object, value);
178                 return;
179             } catch (Exception JavaDoc ex) {
180                 /* in case of an exception, we will throw a new
181                  * NoSuchFieldException object */

182                 ;
183             }
184         }
185         throw new NoSuchFieldException JavaDoc("Could set value for field " +
186                 object.getClass().getName() + "." + name);
187     }
188
189     /**
190      * Sets the field represented by the name value on the specified class
191      * argument to the specified new value. The new value is automatically
192      * unwrapped if the underlying field has a primitive type.<p>
193      *
194      * The class is first searched for any matching field. If no matching
195      * field is found, the superclasses are recursively searched.
196      *
197      * @exception NoSuchFieldException if a field with the specified name is
198      * not found.
199      */

200     public static void setField(Class JavaDoc cls,
201                                 String JavaDoc name,
202                                 Object JavaDoc value)
203             throws NoSuchFieldException JavaDoc {
204         if (cls == null) {
205             throw new IllegalArgumentException JavaDoc("Invalid null cls argument");
206         }
207         Class JavaDoc base = cls;
208         while (base != null) {
209             try {
210                 Field JavaDoc field = base.getDeclaredField(name);
211                 field.setAccessible(true);
212                 field.set(base, value);
213                 return;
214             } catch (Exception JavaDoc ex) {
215                 /* in case of an exception, we will throw a new
216                  * NoSuchFieldException object */

217                 ;
218             }
219             base = base.getSuperclass();
220         }
221         throw new NoSuchFieldException JavaDoc("Could set value for static field " +
222                 cls.getName() + "." + name);
223     }
224
225     /**
226      * Invokes the method represented by the name value on the specified object
227      * with the specified parameters. Individual parameters are automatically
228      * unwrapped to match primitive formal parameters, and both primitive and
229      * reference parameters are subject to widening conversions as necessary.
230      * The value returned by the method is automatically wrapped in an object
231      * if it has a primitive type.<p>
232      *
233      * The object is first searched for any matching method. If no matching
234      * method is found, the superclasses are recursively searched.
235      *
236      * @exception NoSuchMethodException if a matching method is not found or
237      * if the name is "<init>"or "<clinit>".
238      */

239     public static Object JavaDoc invoke(Object JavaDoc object,
240                                 String JavaDoc name,
241                                 Class JavaDoc parameterTypes[],
242                                 Object JavaDoc args[])
243             throws Throwable JavaDoc {
244         if (object == null) {
245             throw new IllegalArgumentException JavaDoc("Invalid null object argument");
246         }
247         Class JavaDoc cls = object.getClass();
248         while (cls != null) {
249             try {
250                 Method JavaDoc method = cls.getDeclaredMethod(name,
251                         parameterTypes);
252                 method.setAccessible(true);
253                 return method.invoke(object, args);
254             } catch (InvocationTargetException JavaDoc e) {
255                 /* if the method throws an exception, it is embedded into an
256                  * InvocationTargetException. */

257                 throw e.getTargetException();
258             } catch (Exception JavaDoc ex) {
259                 /* in case of an exception, we will throw a new
260                  * NoSuchFieldException object */

261                 ;
262             }
263             cls = cls.getSuperclass();
264         }
265         throw new NoSuchMethodException JavaDoc("Failed method invocation: " +
266                 object.getClass().getName() + "." + name + "()");
267     }
268
269     /**
270      * Invokes the method represented by the name value on the specified class
271      * with the specified parameters. Individual parameters are automatically
272      * unwrapped to match primitive formal parameters, and both primitive and
273      * reference parameters are subject to widening conversions as necessary.
274      * The value returned by the method is automatically wrapped in an object
275      * if it has a primitive type.<p>
276      *
277      * The class is first searched for any matching method. If no matching
278      * class is found, the superclasses are recursively searched.
279      *
280      * @exception NoSuchMethodException if a matching method is not found or
281      * if the name is "<init>"or "<clinit>".
282      */

283     public static Object JavaDoc invoke(Class JavaDoc cls,
284                                 String JavaDoc name,
285                                 Class JavaDoc parameterTypes[],
286                                 Object JavaDoc args[])
287             throws Throwable JavaDoc {
288         if (cls == null) {
289             throw new IllegalArgumentException JavaDoc("Invalid null cls argument");
290         }
291         Class JavaDoc base = cls;
292         while (base != null) {
293             try {
294                 Method JavaDoc method = base.getDeclaredMethod(name,
295                         parameterTypes);
296                 method.setAccessible(true);
297                 return method.invoke(base, args);
298             } catch (InvocationTargetException JavaDoc e) {
299                 /* if the method throws an exception, it is embedded into an
300                  * InvocationTargetException. */

301                 throw (Exception JavaDoc) e.getTargetException();
302             } catch (Exception JavaDoc ex) {
303                 /* in case of an exception, we will throw a new
304                  * NoSuchFieldException object */

305                 ;
306             }
307             base = base.getSuperclass();
308         }
309         throw new NoSuchMethodException JavaDoc("Failed static method invocation: " +
310                 cls.getName() + "." + name + "()");
311     }
312
313 }
314
Popular Tags