All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.amygdalum.xrayinterface.FieldSetter Maven / Gradle / Ivy

Go to download

An application to get controlled access to private fields and methods of Java classes

There is a newer version: 0.3.5
Show newest version
package net.amygdalum.xrayinterface;

import static net.amygdalum.xrayinterface.Converter.convertArgument;

import java.lang.invoke.MethodHandle;
import java.lang.reflect.InvocationTargetException;

/**
 * Wraps a field with modification (setter) access.
 */
public class FieldSetter implements MethodInvocationHandler {

	private String fieldName;
	private MethodHandle setter;
	private Class target;

	/**
	 * Sets a value on the given field.
	 * 
	 * @param fieldName the name of the field to set
	 * @param setter the setter method handle for the field to access
	 */
	public FieldSetter(String fieldName, MethodHandle setter) {
		this.fieldName = fieldName;
		this.setter = setter;
	}
	
	/**
	 * Sets a value on the given field. Beyond {@link #FieldSetter(String,MethodHandle)} this constructor also converts the argument
	 * 
	 * @param fieldName the name of the field to set
	 * @param setter the setter method handle for the field to access
	 * @param target the target signature (source arguments)
	 * @see Convert 
	 */
	public FieldSetter(String fieldName, MethodHandle setter, Class target) {
		this(fieldName, setter);
		this.target = target;
	}
	
	public String getFieldName() {
		return fieldName;
	}

	public Class getType() {
		return setter.type().parameterType(1);
	}

	public Class getTarget() {
		return target;
	}
	
	@Override
	public Object invoke(Object object, Object... args) throws Throwable {
		if (args == null || args.length != 1) {
			throw new IllegalArgumentException("setters can only be invoked with exactly one argument, was " + (args == null ? "null" : String.valueOf(args.length)) + " arguments");
		}
		Object arg = a(args[0]);
		if (arg != null && !BoxingUtil.getBoxed(setter.type().parameterType(1)).isInstance(arg)) {
			throw new ClassCastException("defined type of field is " + arg.getClass().getSimpleName() + ", but assigned type was " + setter.type().parameterType(1).getSimpleName());
		}
		setter.invoke(object, arg);
		return null;
	}

	private Object a(Object arg) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
		if (target == null) {
			return arg;
		}
		return convertArgument(target, setter.type().parameterType(1), arg);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy