- return getClass(instanceOrClass).getName();
- }
-
- StringBuffer stringBuffer = new StringBuffer();
-
- stringBuffer.append(getClass(instanceOrClass).getName() + " {");
-
- for (String fieldName : fields) {
- try {
- stringBuffer.append(fieldName + "=" + getValue(instanceOrClass, fieldName) + ", ");
- } catch (NoSuchFieldException e) {
- assert false : "It should always be possible to get a field that was just here";
- }
- }
-
- stringBuffer.replace(stringBuffer.lastIndexOf(", "), stringBuffer.length(), "}");
- return stringBuffer.toString();
- }
-
- /**
- * Gets the name of all fields (public, private, protected, default) of the given instance or class. This includes as well all
- * fields (public, private, protected, default) of all its super classes.
- *
- * @param instanceOrClass the instance or class to get the fields of
- * @return the collection of field names of the given instance or class
- */
- public static Collection<String> getFieldNames(final Object instanceOrClass) {
- if (instanceOrClass == null)
- {
- return Collections.EMPTY_LIST;
- }
-
- Class<?> clazz = getClass(instanceOrClass);
- Field[] fields = clazz.getDeclaredFields();
- Collection<String> fieldNames = new ArrayList<String>(fields.length);
-
- for (Field field : fields) {
- fieldNames.add(field.getName());
- }
- fieldNames.addAll(getFieldNames(clazz.getSuperclass()));
-
- return fieldNames;
- }
-
- /**
- * Gets the signatures of all methods (public, private, protected, default) of the given instance or class. This includes as well
- * all methods (public, private, protected, default) of all its super classes. This does not include constructors.
- *
- * @param instanceOrClass the instance or class to get the method signatures of
- * @return the collection of method signatures of the given instance or class
- */
- public static Collection<String> getMethodSignatures(final Object instanceOrClass) {
- if (instanceOrClass == null)
- {
- return Collections.EMPTY_LIST;
- }
-
- Class<?> clazz = getClass(instanceOrClass);
- Method[] methods = clazz.getDeclaredMethods();
- Collection<String> methodSignatures = new ArrayList<String>(methods.length + Object.class.getDeclaredMethods().length);
-
- for (Method method : methods) {
- methodSignatures.add(method.getName() + "(" + getParameterTypesAsString(method.getParameterTypes()) + ")");
- }
- methodSignatures.addAll(getMethodSignatures(clazz.getSuperclass()));
-
- return methodSignatures;
- }
-
- /**
- * Gets the value of the named field and returns it as an object. If instanceOrClass is a class then a static field is returned.
- *
- * @param instanceOrClass the instance or class to get the field from
- * @param fieldName the name of the field
- * @return an object representing the value of the field
- * @throws NoSuchFieldException if the field does not exist
- */
- public static Object getValue(final Object instanceOrClass, final String fieldName) throws NoSuchFieldException {
- Field field = getField(instanceOrClass, fieldName);
- try {
- return field.get(instanceOrClass);
- } catch (IllegalAccessException e) {
- assert false : "getField() should have setAccessible(true), so an IllegalAccessException should not occur in this place";
- return null;
- }
- }
-
- /**
- * Instantiates an object of the given class with the given arguments. If you want to instantiate a member class, you must provide
- * the object it is a member of as first argument.
- *
- * @param fromClass the class to instantiate an object from
- * @param args the arguments to pass to the constructor
- * @return an object of the given type
- * @throws IllegalArgumentException if the number of actual and formal parameters differ; if an unwrapping conversion for primitive
- * arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
- * parameter type by a method invocation conversion.
- * @throws IllegalAccessException if this Constructor object enforces Java language access control and the underlying constructor is
- * inaccessible.
- * @throws InvocationTargetException if the underlying constructor throws an exception.
- * @throws NoSuchMethodException if the constructor could not be found
- * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class.
- *
- * @see PrivilegedAccessor#instantiate(Class,Class[],Object[])
- */
- public static <T> T instantiate(final Class<? extends T> fromClass, final Object[] args) throws IllegalArgumentException,
- InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- return instantiate(fromClass, getParameterTypes(args), args);
- }
-
- /**
- * Instantiates an object of the given class with the given arguments and the given argument types. If you want to instantiate a
- * member class, you must provide the object it is a member of as first argument.
- *
- *
- * @param fromClass the class to instantiate an object from
- * @param args the arguments to pass to the constructor
- * @param argumentTypes the fully qualified types of the arguments of the constructor
- * @return an object of the given type
- * @throws IllegalArgumentException if the number of actual and formal parameters differ; if an unwrapping conversion for primitive
- * arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
- * parameter type by a method invocation conversion.
- * @throws IllegalAccessException if this Constructor object enforces Java language access control and the underlying constructor is
- * inaccessible.
- * @throws InvocationTargetException if the underlying constructor throws an exception.
- * @throws NoSuchMethodException if the constructor could not be found
- * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class.
- *
- * @see PrivilegedAccessor#instantiate(Class,Object[])
- */
- public static <T> T instantiate(final Class<? extends T> fromClass, final Class<?>[] argumentTypes, final Object[] args)
- throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException,
- NoSuchMethodException {
- return getConstructor(fromClass, argumentTypes).newInstance(args);
- }
-
- /**
- * Calls a method on the given object instance with the given arguments. Arguments can be object types or representations for
- * primitives.
- *
- * @param instanceOrClass the instance or class to invoke the method on
- * @param methodSignature the name of the method and the parameters <br>
- * (e.g. "myMethod(java.lang.String, com.company.project.MyObject)")
- * @param arguments an array of objects to pass as arguments
- * @return the return value of this method or null if void
- * @throws IllegalAccessException if the method is inaccessible
- * @throws InvocationTargetException if the underlying method throws an exception.
- * @throws NoSuchMethodException if no method with the given <code>methodSignature</code> could be found
- * @throws IllegalArgumentException if an argument couldn't be converted to match the expected type
- */
- public static Object invokeMethod(final Object instanceOrClass, final String methodSignature, final Object[] arguments)
- throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- if ((methodSignature.indexOf('(') == -1) || (methodSignature.indexOf('(') >= methodSignature.indexOf(')')))
- {
- throw new NoSuchMethodException(methodSignature);
- }
- Class<?>[] parameterTypes = getParameterTypes(methodSignature);
- return getMethod(instanceOrClass, getMethodName(methodSignature), parameterTypes).invoke(instanceOrClass,
- getCorrectedArguments(parameterTypes, arguments));
- }
-
- /**
- * Gets the given arguments corrected to match the given methodSignature. Correction is necessary for array arguments not to be
- * mistaken by varargs.
- *
- * @param parameterTypes the method signatue the given arguments should match
- * @param arguments the arguments that should be corrected
- * @return the corrected arguments
- */
- private static Object[] getCorrectedArguments(Class<?>[] parameterTypes, Object[] arguments) {
- if (arguments == null)
- {
- return arguments;
- }
- if (parameterTypes.length > arguments.length)
- {
- return arguments;
- }
- if (parameterTypes.length < arguments.length)
- {
- return getCorrectedArguments(parameterTypes, new Object[] {arguments});
- }
-
- Object[] correctedArguments = new Object[arguments.length];
- int currentArgument = 0;
- for (Class<?> parameterType : parameterTypes) {
- correctedArguments[currentArgument] = getCorrectedArgument(parameterType, arguments[currentArgument]);
- currentArgument++;
- }
- return correctedArguments;
- }
-
- /**
- * Gets the given argument corrected to match the given parameterType. Correction is necessary for array arguments not to be
- * mistaken by varargs.
- *
- * @param parameterType the type to match the given argument upon
- * @param argument the argument to match the given parameterType
- * @return the corrected argument
- */
- private static Object getCorrectedArgument(Class<?> parameterType, Object argument) {
- if (!parameterType.isArray() || (argument == null)) {
- return argument; // normal argument for normal parameterType
- }
-
- if (!argument.getClass().isArray()) {
- return new Object[] {argument};
- }
-
- if (parameterType.equals(argument.getClass()))
- {
- return argument; // no need to cast
- }
-
- // (typed) array argument for (object) array parameterType, elements need to be casted
- Object correctedArrayArgument = Array.newInstance(parameterType.getComponentType(), Array.getLength(argument));
- for (int index = 0; index < Array.getLength(argument); index++) {
- if (parameterType.getComponentType().isPrimitive()) { // rely on autoboxing
- Array.set(correctedArrayArgument, index, Array.get(argument, index));
- } else { // cast to expected type
- try {
- Array.set(correctedArrayArgument, index, parameterType.getComponentType().cast(Array.get(argument, index)));
- } catch (ClassCastException e) {
- throw new IllegalArgumentException("Argument " + argument + " of type " + argument.getClass()
- + " does not match expected argument type " + parameterType + ".");
- }
- }
- }
- return correctedArrayArgument;
- }
-
- /**
- * Sets the value of the named field. If fieldName denotes a static field, provide a class, otherwise provide an instance. If the
- * fieldName denotes a final field, this method could fail with an IllegalAccessException, since setting the value of final fields
- * at other times than instantiation can have unpredictable effects.<br/>
- * <br/>
- * Example:<br/>
- * <br/>
- * <code>
- * String myString = "Test"; <br/>
- * <br/>
- * //setting the private field value<br/>
- * PrivilegedAccessor.setValue(myString, "value", new char[] {'T', 'e', 's', 't'});<br/>
- * <br/>
- * //setting the static final field serialVersionUID - MIGHT FAIL<br/>
- * PrivilegedAccessor.setValue(myString.getClass(), "serialVersionUID", 1);<br/>
- * <br/>
- * </code>
- *
- * @param instanceOrClass the instance or class to set the field
- * @param fieldName the name of the field
- * @param value the new value of the field
- * @throws NoSuchFieldException if no field with the given <code>fieldName</code> can be found
- * @throws IllegalAccessException possibly if the field was final
- */
- public static void setValue(final Object instanceOrClass, final String fieldName, final Object value) throws NoSuchFieldException,
- IllegalAccessException {
- Field field = getField(instanceOrClass, fieldName);
- if (Modifier.isFinal(field.getModifiers())) {
- PrivilegedAccessor.setValue(field, "modifiers", field.getModifiers() ^ Modifier.FINAL);
- }
- field.set(instanceOrClass, value);
- }
-
- /**
- * Gets the class with the given className.
- *
- * @param className the name of the class to get
- * @return the class for the given className
- * @throws ClassNotFoundException if the class could not be found
- */
- private static Class<?> getClassForName(final String className) throws ClassNotFoundException {
- if (className.indexOf('[') > -1) {
- Class<?> clazz = getClassForName(className.substring(0, className.indexOf('[')));
- return Array.newInstance(clazz, 0).getClass();
- }
-
- if (className.indexOf("...") > -1) {
- Class<?> clazz = getClassForName(className.substring(0, className.indexOf("...")));
- return Array.newInstance(clazz, 0).getClass();
- }
-
- try {
- return Class.forName(className, false, Thread.currentThread().getContextClassLoader());
- } catch (ClassNotFoundException e) {
- return getSpecialClassForName(className);
- }
- }
-
- /**
- * Maps string representation of primitives to their corresponding classes.
- */
- private static final Map<String, Class<?>> PRIMITIVE_MAPPER = new HashMap<String, Class<?>>(8);
-
- /**
- * Fills the map with all java primitives and their corresponding classes.
- */
- static {
- PRIMITIVE_MAPPER.put("int", Integer.TYPE);
- PRIMITIVE_MAPPER.put("float", Float.TYPE);
- PRIMITIVE_MAPPER.put("double", Double.TYPE);
- PRIMITIVE_MAPPER.put("short", Short.TYPE);
- PRIMITIVE_MAPPER.put("long", Long.TYPE);
- PRIMITIVE_MAPPER.put("byte", Byte.TYPE);
- PRIMITIVE_MAPPER.put("char", Character.TYPE);
- PRIMITIVE_MAPPER.put("boolean", Boolean.TYPE);
- }
-
- /**
- * Gets special classes for the given className. Special classes are primitives and "standard" Java types (like String)
- *
- * @param className the name of the class to get
- * @return the class for the given className
- * @throws ClassNotFoundException if the class could not be found
- */
- private static Class<?> getSpecialClassForName(final String className) throws ClassNotFoundException {
- if (PRIMITIVE_MAPPER.containsKey(className))