blob: 41e86478d039df812ac3cd4d88507353fbbb2795 [file] [log] [blame]
package org.eclipse.text.tests;
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.eclipse.core.runtime.Assert;
/**
* Helper class for accessing classes and members which cannot
* be accessed using standard Java access control like private
* or package visible elements.
*
* @since 3.1
*/
public class Accessor {
/** The class to access. */
private Class fClass;
/** The instance to access. */
private Object fInstance;
/**
* Creates an accessor for the given <code>instance</code> and
* <code>class</code>. Only non-inherited members that particular
* <code>class</code> can be accessed.
*
* @param instance the instance
* @param clazz the class
*/
public Accessor(Object instance, Class clazz) {
org.eclipse.core.runtime.Assert.isNotNull(instance);
Assert.isNotNull(clazz);
fInstance= instance;
fClass= clazz;
}
/**
* Creates an accessor for the given <code>instance</code> and
* <code>class</code>. Only non-inherited members that particular
* <code>class</code> can be accessed.
*
* @param instance the instance
* @param className the name of the class
* @param classLoader the class loader to use i.e. <code>getClass().getClassLoader()</code>
*/
public Accessor(Object instance, String className, ClassLoader classLoader) {
Assert.isNotNull(instance);
Assert.isNotNull(className);
Assert.isNotNull(classLoader);
fInstance= instance;
try {
fClass= Class.forName(className, true, classLoader);
} catch (ClassNotFoundException e) {
fail();
} catch (ExceptionInInitializerError e) {
fail();
}
}
/**
* Creates an accessor for the given class.
* <p>
* In order to get the type information from the given
* arguments they must all be instanceof Object. Use
* {@link #Accessor(String, ClassLoader, Class[], Object[])} if this
* is not the case.</p>
*
* @param className the name of the class
* @param classLoader the class loader to use i.e. <code>getClass().getClassLoader()</code>
* @param constructorArgs the constructor arguments which must all be instance of Object
*/
public Accessor(String className, ClassLoader classLoader, Object[] constructorArgs) {
this(className, classLoader, getTypes(constructorArgs), constructorArgs);
}
/**
* Creates an accessor for the given class.
*
* @param className the name of the class
* @param classLoader the class loader to use i.e. <code>getClass().getClassLoader()</code>
* @param constructorTypes the types of the constructor arguments
* @param constructorArgs the constructor arguments
*/
public Accessor(String className, ClassLoader classLoader, Class[] constructorTypes, Object[] constructorArgs) {
try {
fClass= Class.forName(className, true, classLoader);
} catch (ClassNotFoundException e) {
fail();
} catch (ExceptionInInitializerError e) {
fail();
}
Constructor constructor= null;
try {
constructor= fClass.getDeclaredConstructor(constructorTypes);
} catch (SecurityException e2) {
fail();
} catch (NoSuchMethodException e2) {
fail();
}
Assert.isNotNull(constructor);
constructor.setAccessible(true);
try {
fInstance= constructor.newInstance(constructorArgs);
} catch (IllegalArgumentException e) {
fail();
} catch (InvocationTargetException e) {
fail();
} catch (InstantiationException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
}
/**
* Creates an accessor for the given class.
* <p>
* This constructor is used to access static stuff.
* </p>
*
* @param className the name of the class
* @param classLoader the class loader to use i.e. <code>getClass().getClassLoader()</code>
*/
public Accessor(String className, ClassLoader classLoader) {
try {
fClass= Class.forName(className, true, classLoader);
} catch (ClassNotFoundException e) {
fail();
} catch (ExceptionInInitializerError e) {
fail();
}
}
/**
* Invokes the method with the given method name and arguments.
* <p>
* In order to get the type information from the given
* arguments all those arguments must be instance of Object. Use
* {@link #invoke(String, Class[], Object[])} if this
* is not the case.</p>
*
* @param methodName the method name
* @param arguments the method arguments which must all be instance of Object
* @return the method return value
*/
public Object invoke(String methodName, Object[] arguments) {
return invoke(methodName, getTypes(arguments), arguments);
}
/**
* Invokes the method with the given method name and arguments.
*
* @param methodName the method name
* @param types the argument types
* @param arguments the method arguments
* @return the method return value
*/
public Object invoke(String methodName, Class[] types, Object[] arguments) {
Method method= null;
try {
method= fClass.getDeclaredMethod(methodName, types);
} catch (SecurityException e) {
fail();
} catch (NoSuchMethodException ex) {
fail();
}
Assert.isNotNull(method);
method.setAccessible(true);
try {
return method.invoke(fInstance, arguments);
} catch (IllegalArgumentException e) {
fail();
} catch (InvocationTargetException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
return null;
}
/**
* Assigns the given value to the field with the given name.
*
* @param fieldName the field name
* @param value the value to assign to the field
*/
public void set(String fieldName, Object value) {
Field field= getField(fieldName);
try {
field.set(fInstance, value);
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
}
/**
* Assigns the given value to the field with the given name.
*
* @param fieldName the field name
* @param value the value to assign to the field
*/
public void set(String fieldName, boolean value) {
Field field= getField(fieldName);
try {
field.setBoolean(fInstance, value);
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
}
/**
* Assigns the given value to the field with the given name.
*
* @param fieldName the field name
* @param value the value to assign to the field
*/
public void set(String fieldName, int value) {
Field field= getField(fieldName);
try {
field.setInt(fInstance, value);
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
}
/**
* Returns the value of the field with the given name.
*
* @param fieldName the field name
* @return the value of the field
*/
public Object get(String fieldName) {
Field field= getField(fieldName);
try {
return field.get(fInstance);
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
// Unreachable code
return null;
}
/**
* Returns the value of the field with the given name.
*
* @param fieldName the field name
* @return the value of the field
*/
public boolean getBoolean(String fieldName) {
Field field= getField(fieldName);
try {
return field.getBoolean(fInstance);
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
// Unreachable code
return false;
}
/**
* Returns the value of the field with the given name.
*
* @param fieldName the field name
* @return the value of the field
*/
public int getInt(String fieldName) {
Field field= getField(fieldName);
try {
return field.getInt(fInstance);
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
}
// Unreachable code
return 0;
}
private Field getField(String fieldName) {
Field field= null;
try {
field= fClass.getDeclaredField(fieldName);
} catch (SecurityException e) {
fail();
} catch (NoSuchFieldException e) {
fail();
}
field.setAccessible(true);
return field;
}
private static Class[] getTypes(Object[] objects) {
if (objects == null)
return null;
int length= objects.length;
Class[] classes= new Class[length];
for (int i= 0; i < length; i++) {
Assert.isNotNull(objects[i]);
classes[i]= objects[i].getClass();
}
return classes;
}
private void fail() {
Assert.isTrue(false);
}
}