Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package junit.extensions

File PA.java

 

Coverage histogram

../../img/srcFileCovDistChart2.png
51% of files have more coverage

Code metrics

6
32
14
1
331
73
24
0.75
2.29
14
1.71

Classes

Class Line # Actions
PA 61 32 24 43
0.1730769317.3%
 

Contributing tests

This file is covered by 24 tests. .

Source view

1    /*
2    * Copyright 2004-2012 Sebastian Dietrich (Sebastian.Dietrich@e-movimento.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package junit.extensions;
17   
18    import java.util.Collection;
19   
20    /**
21    * This class is used to access a method or field of an object no matter what the access modifier of the method or field. The syntax
22    * for accessing fields and methods is out of the ordinary because this class uses reflection to peel away protection.
23    * <p>
24    * a.k.a. The "ObjectMolester"
25    * <p>
26    * Here is an example of using this to access a private member: <br>
27    * Given the following class <code>MyClass</code>: <br>
28    *
29    * <pre>
30    * public class MyClass {
31    * private String name; // private attribute
32    *
33    * // private constructor
34    * private MyClass() {
35    * super();
36    * }
37    *
38    * // private method
39    * private void setName(String newName) {
40    * this.name = newName;
41    * }
42    * }
43    * </pre>
44    *
45    * We now want to access the class: <br>
46    *
47    * <pre>
48    * MyClass myObj = PA.instantiate(MyClass.class);
49    * PA.invokeMethod(myObj, &quot;setName(java.lang.String)&quot;, &quot;myNewName&quot;);
50    * String name = PA.getValue(myObj, &quot;name&quot;);
51    * </pre>
52    *
53    * This class extends {@link PrivilegedAccessor} by re-throwing checked {@link Exception}s as {@link RuntimeException}s.
54    *
55    *
56    * @see PrivilegedAccessor
57    *
58    * @author Sebastian Dietrich (sebastian.dietrich@e-movimento.com)
59    * @author Lubos Bistak (lubos@bistak.sk)
60    */
 
61    public class PA {
62    private final Object instanceOrClass;
63   
64    /**
65    * Private constructor to make it impossible to instantiate this class from outside of PA.
66    *
67    * @param instanceOrClass
68    */
 
69  18 toggle private PA(Object instanceOrClass) {
70  18 this.instanceOrClass = instanceOrClass;
71    }
72   
73    /**
74    * Returns a string representation of the given object. The string has the following format: "<classname> {<attributes and values>}"
75    * whereas <attributes and values> is a comma separated list with <attributeName>=<attributeValue> <atributes and values> includes
76    * all attributes of the objects class followed by the attributes of its superclass (if any) and so on.
77    *
78    * @param instanceOrClass the object or class to get a string representation of
79    * @return a string representation of the given object
80    *
81    * @see PrivilegedAccessor#toString(Object)
82    */
 
83  0 toggle public static String toString(final Object instanceOrClass) {
84  0 return PrivilegedAccessor.toString(instanceOrClass);
85    }
86   
87    /**
88    * Gets the name of all fields (public, private, protected, default) of the given instance or class. This includes as well all
89    * fields (public, private, protected, default) of all its super classes.
90    *
91    * @param instanceOrClass the instance or class to get the fields of
92    * @return the collection of field names of the given instance or class
93    *
94    * @see PrivilegedAccessor#getFieldNames(Object)
95    */
 
96  0 toggle public static Collection<String> getFieldNames(final Object instanceOrClass) {
97  0 return PrivilegedAccessor.getFieldNames(instanceOrClass);
98    }
99   
100    /**
101    * Gets the signatures of all methods (public, private, protected, default) of the given instance or class. This includes as well
102    * all methods (public, private, protected, default) of all its super classes. This does not include constructors.
103    *
104    * @param instanceOrClass the instance or class to get the method signatures of
105    * @return the collection of method signatures of the given instance or class
106    *
107    * @see PrivilegedAccessor#getMethodSignatures(Object)
108    */
 
109  0 toggle public static Collection<String> getMethodSignatures(final Object instanceOrClass) {
110  0 return PrivilegedAccessor.getMethodSignatures(instanceOrClass);
111    }
112   
113    /**
114    * Gets the value of the named field and returns it as an object. If instanceOrClass is a class then a static field is returned.
115    *
116    * @param instanceOrClass the instance or class to get the field from
117    * @param fieldName the name of the field
118    * @return an object representing the value of the field
119    * @throws IllegalArgumentException if the field does not exist
120    *
121    * @see PrivilegedAccessor#getValue(Object,String)
122    */
 
123  126 toggle public static Object getValue(final Object instanceOrClass, final String fieldName) {
124  126 try {
125  126 return PrivilegedAccessor.getValue(instanceOrClass, fieldName);
126    } catch (Exception e) {
127  0 throw new IllegalArgumentException("Can't get value of " + fieldName + " from " + instanceOrClass, e);
128    }
129    }
130   
131    /**
132    * Gets the value of the named field and returns it as an object.
133    *
134    * @param fieldName the name of the field
135    * @return an object representing the value of the field
136    * @throws IllegalArgumentException if the field does not exist
137    *
138    * @see PA#getValue(Object,String)
139    */
 
140  0 toggle public Object getValue(final String fieldName) {
141  0 return PA.getValue(instanceOrClass, fieldName);
142    }
143   
144    /**
145    * Instantiates an object of the given class with the given arguments and the given argument types. If you want to instantiate a
146    * member class, you must provide the object it is a member of as first argument.
147    *
148    * @param fromClass the class to instantiate an object from
149    * @param arguments the arguments to pass to the constructor
150    * @param argumentTypes the fully qualified types of the arguments of the constructor
151    * @return an object of the given type
152    * @throws IllegalArgumentException if the class can't be instantiated. This could be the case if the number of actual and formal
153    * parameters differ; if an unwrapping conversion for primitive arguments fails; if, after possible unwrapping, a
154    * parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion; if
155    * this Constructor object enforces Java language access control and the underlying constructor is inaccessible; if the
156    * underlying constructor throws an exception; if the constructor could not be found; or if the class that declares the
157    * underlying constructor represents an abstract class.
158    *
159    * @see PrivilegedAccessor#instantiate(Class,Class[],Object[])
160    */
 
161  0 toggle public static <T> T instantiate(final Class<? extends T> fromClass, final Class<?>[] argumentTypes, final Object... arguments) {
162  0 try {
163  0 return PrivilegedAccessor.instantiate(fromClass, argumentTypes, correctVarargs(arguments));
164    } catch (Exception e) {
165  0 throw new IllegalArgumentException("Can't instantiate class " + fromClass + " with arguments " + arguments, e);
166    }
167    }
168   
169    /**
170    * Instantiates an object of the given class with the given arguments. If you want to instantiate a member class, you must provide
171    * the object it is a member of as first argument.
172    *
173    * @param fromClass the class to instantiate an object from
174    * @param arguments the arguments to pass to the constructor
175    * @return an object of the given type
176    * @throws IllegalArgumentException if the class can't be instantiated. This could be the case if the number of actual and formal
177    * parameters differ; if an unwrapping conversion for primitive arguments fails; or if, after possible unwrapping, a
178    * parameter value cannot be converted to the corresponding formal parameter type by a method invocation conversion; if
179    * this Constructor object enforces Java language access control and the underlying constructor is inaccessible; if the
180    * underlying constructor throws an exception; if the constructor could not be found; or if the class that declares the
181    * underlying constructor represents an abstract class.
182    *
183    * @see PrivilegedAccessor#instantiate(Class,Object[])
184    */
 
185  0 toggle public static <T> T instantiate(final Class<? extends T> fromClass, final Object... arguments) {
186  0 try {
187  0 return PrivilegedAccessor.instantiate(fromClass, correctVarargs(arguments));
188    } catch (Exception e) {
189  0 throw new IllegalArgumentException("Can't instantiate class " + fromClass + " with arguments " + arguments, e);
190    }
191    }
192   
193    /**
194    * Calls a method on the given object instance with the given arguments. Arguments can be object types or representations for
195    * primitives.
196    *
197    * @param instanceOrClass the instance or class to invoke the method on
198    * @param methodSignature the name of the method and the parameters <br>
199    * (e.g. "myMethod(java.lang.String, com.company.project.MyObject)")
200    * @param arguments an array of objects to pass as arguments
201    * @return the return value of this method or null if void
202    * @throws IllegalArgumentException if the method could not be invoked. This could be the case if the method is inaccessible; if the
203    * underlying method throws an exception; if no method with the given <code>methodSignature</code> could be found; or if
204    * an argument couldn't be converted to match the expected type
205    *
206    * @see PrivilegedAccessor#invokeMethod(Object,String,Object[])
207    */
 
208  0 toggle public static Object invokeMethod(final Object instanceOrClass, final String methodSignature, final Object... arguments) {
209  0 try {
210  0 return PrivilegedAccessor.invokeMethod(instanceOrClass, methodSignature, correctVarargs(arguments));
211    } catch (Exception e) {
212  0 throw new IllegalArgumentException("Can't invoke method " + methodSignature + " on " + instanceOrClass + " with arguments "
213    + arguments, e);
214    }
215    }
216   
217    /**
218    * Calls a method with the given arguments. Arguments can be object types or representations for primitives.
219    *
220    * @param methodSignature the name of the method and the parameters <br>
221    * (e.g. "myMethod(java.lang.String, com.company.project.MyObject)")
222    * @param arguments an array of objects to pass as arguments
223    * @return the return value of this method or null if void
224    * @throws IllegalArgumentException if the method could not be invoked. This could be the case if the method is inaccessible; if the
225    * underlying method throws an exception; if no method with the given <code>methodSignature</code> could be found; or if
226    * an argument couldn't be converted to match the expected type
227    * @see PA#invokeMethod(Object, String, Object...)
228    */
 
229  0 toggle public Object invokeMethod(final String methodSignature, final Object... arguments) {
230  0 return PA.invokeMethod(instanceOrClass, methodSignature, arguments);
231    }
232   
233    /**
234    * Corrects varargs to their initial form. If you call a method with an object-array as last argument the Java varargs mechanism
235    * converts this array in single arguments. This method returns an object array if the arguments are all of the same type.
236    *
237    * @param arguments the possibly converted arguments of a vararg method
238    * @return arguments possibly converted
239    */
 
240  0 toggle private static Object[] correctVarargs(final Object... arguments) {
241  0 if ((arguments == null) || changedByVararg(arguments)) return new Object[] {arguments};
242  0 return arguments;
243    }
244   
245    /**
246    * Tests if the arguments were changed by vararg. Arguments are changed by vararg if they are of a non primitive array type. E.g.
247    * arguments[] = Object[String[]] is converted to String[] while e.g. arguments[] = Object[int[]] is not converted and stays
248    * Object[int[]]
249    *
250    * Unfortunately we can't detect the difference for arg = Object[primitive] since arguments[] = Object[Object[primitive]] which is
251    * converted to Object[primitive] and arguments[] = Object[primitive] which stays Object[primitive]
252    *
253    * and we can't detect the difference for arg = Object[non primitive] since arguments[] = Object[Object[non primitive]] is converted
254    * to Object[non primitive] and arguments[] = Object[non primitive] stays Object[non primitive]
255    *
256    * @param parameters the parameters
257    * @return true if parameters were changes by varargs, false otherwise
258    */
 
259  0 toggle private static boolean changedByVararg(final Object[] parameters) {
260  0 if ((parameters.length == 0) || (parameters[0] == null)) return false;
261   
262  0 if (parameters.getClass() == Object[].class) return false;
263   
264  0 return true;
265    }
266   
267    /**
268    * Sets the value of the named field. If fieldName denotes a static field, provide a class, otherwise provide an instance. If the
269    * fieldName denotes a final field, this method could fail with an IllegalAccessException, since setting the value of final fields
270    * at other times than instantiation can have unpredictable effects.<br/>
271    * <br/>
272    * Example:<br/>
273    * <br/>
274    * <code>
275    * String myString = "Test"; <br/>
276    * <br/>
277    * //setting the private field value<br/>
278    * PrivilegedAccessor.setValue(myString, "value", new char[] {'T', 'e', 's', 't'});<br/>
279    * <br/>
280    * //setting the static final field serialVersionUID - MIGHT FAIL<br/>
281    * PrivilegedAccessor.setValue(myString.getClass(), "serialVersionUID", 1);<br/>
282    * <br/>
283    * </code>
284    *
285    * @param instanceOrClass the instance or class to set the field
286    * @param fieldName the name of the field
287    * @param value the new value of the field
288    * @throws IllegalArgumentException if the value could not be set. This could be the case if no field with the given
289    * <code>fieldName</code> can be found; or if the field was final
290    *
291    * @see PrivilegedAccessor.setValue(Object,String,Object)
292    */
 
293  18 toggle public static PA setValue(final Object instanceOrClass, final String fieldName, final Object value) {
294  18 try {
295  18 PrivilegedAccessor.setValue(instanceOrClass, fieldName, value);
296    } catch (Exception e) {
297  0 throw new IllegalArgumentException("Can't set value " + value + " at " + fieldName + " in " + instanceOrClass, e);
298    }
299  18 return new PA(instanceOrClass);
300    }
301   
302    /**
303    * Sets the value of the named field. If fieldName denotes a static field, provide a class, otherwise provide an instance. If the
304    * fieldName denotes a final field, this method could fail with an IllegalAccessException, since setting the value of final fields
305    * at other times than instantiation can have unpredictable effects.<br/>
306    * <br/>
307    * Example:<br/>
308    * <br/>
309    * <code>
310    * String myString = "Test"; <br/>
311    * <br/>
312    * //setting the private field value<br/>
313    * PrivilegedAccessor.setValue(myString, "value", new char[] {'T', 'e', 's', 't'});<br/>
314    * <br/>
315    * //setting the static final field serialVersionUID - MIGHT FAIL<br/>
316    * PrivilegedAccessor.setValue(myString.getClass(), "serialVersionUID", 1);<br/>
317    * <br/>
318    * </code>
319    *
320    * @param fieldName the name of the field
321    * @param value the new value of the field
322    * @throws IllegalArgumentException if the value could not be set. This could be the case if no field with the given
323    * <code>fieldName</code> can be found; or if the field was final
324    *
325    * @see PA.setValue(Object,String,Object)
326    */
 
327  0 toggle public PA setValue(final String fieldName, final Object value) {
328  0 PA.setValue(instanceOrClass, fieldName, value);
329  0 return this;
330    }
331    }