package eu.stratosphere.util.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
public class DynamicMethod<ReturnType> extends DynamicInvokable<Method, Object, ReturnType> {
private Class<?> returnType;
public DynamicMethod(final String name) {
super(name);
}
/**
* Initializes DynamicMethod.
*/
DynamicMethod() {
}
@Override
public void addSignature(final Method member) {
super.addSignature(member);
if (this.returnType == null)
this.returnType = member.getReturnType();
else if (member.getReturnType() != this.returnType)
this.returnType = member.getReturnType().isAssignableFrom(this.returnType) ? this.returnType
: member.getReturnType();
}
/*
* (non-Javadoc)
* @see eu.stratosphere.util.reflect.DynamicInvokable#copy(com.esotericsoftware.kryo.Kryo)
*/
@Override
public DynamicMethod<ReturnType> copy(final Kryo kryo) {
final DynamicMethod<ReturnType> copy = (DynamicMethod<ReturnType>) super.copy(kryo);
copy.returnType = this.returnType;
return copy;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (this.getClass() != obj.getClass())
return false;
final DynamicMethod<?> other = (DynamicMethod<?>) obj;
return this.returnType.equals(other.returnType);
}
public Method getMethod(final Signature signature) {
return super.getMember(signature);
}
@SuppressWarnings("unchecked")
@Override
public Class<ReturnType> getReturnType() {
return (Class<ReturnType>) this.returnType;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.returnType.hashCode();
return result;
}
/*
* (non-Javadoc)
* @see eu.stratosphere.util.reflect.DynamicInvokable#read(com.esotericsoftware.kryo.Kryo,
* com.esotericsoftware.kryo.io.Input)
*/
@Override
public void read(final Kryo kryo, final Input input) {
super.read(kryo, input);
this.returnType = kryo.readObject(input, Class.class);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getName();
}
/*
* (non-Javadoc)
* @see eu.stratosphere.util.reflect.DynamicInvokable#write(com.esotericsoftware.kryo.Kryo,
* com.esotericsoftware.kryo.io.Output)
*/
@Override
public void write(final Kryo kryo, final Output output) {
super.write(kryo, output);
kryo.writeObject(output, this.returnType);
}
@Override
protected Method findMember(final String name, final java.lang.Class<Object> clazz,
final java.lang.Class<?>[] parameterTypes)
throws NoSuchMethodException {
return clazz.getDeclaredMethod(name, parameterTypes);
}
@Override
protected Class<?>[] getParameterTypes(final Method method) {
return method.getParameterTypes();
}
@SuppressWarnings("unchecked")
@Override
protected ReturnType invokeDirectly(final Method method, final Object context, final Object[] params)
throws IllegalAccessException,
InvocationTargetException {
return (ReturnType) method.invoke(context, params);
}
@Override
protected boolean isVarargs(final Method method) {
return method.isVarArgs();
}
/*
* (non-Javadoc)
* @see eu.stratosphere.util.reflect.DynamicInvokable#needsInstance(java.lang.reflect.Member)
*/
@Override
protected boolean needsInstance(final Method member) {
return (member.getModifiers() & Modifier.STATIC) == 0;
}
public static DynamicMethod<?> valueOf(final Class<?> clazz, final String name) {
final DynamicMethod<?> method = new DynamicMethod<Object>(name);
for (final Method m : clazz.getDeclaredMethods())
if (m.getName().equals(name))
method.addSignature(m);
return method;
}
}