/**
*
*/
package org.jboss.seam.solder.properties;
import static org.jboss.seam.solder.reflection.Reflections.invokeMethod;
import java.beans.Introspector;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
/**
* A bean property based on the value represented by a getter/setter method pair
*
* @author Pete Muir
* @author Shane Bryzak
*/
class MethodPropertyImpl<V> implements MethodProperty<V>
{
private final Method getterMethod;
private final String propertyName;
private final Method setterMethod;
public MethodPropertyImpl(Method method)
{
if (method.getName().startsWith("get"))
{
this.propertyName = Introspector.decapitalize(method.getName().substring(3));
}
else if (method.getName().startsWith("set"))
{
this.propertyName = Introspector.decapitalize(method.getName().substring(3));
}
else if (method.getName().startsWith("is"))
{
this.propertyName = Introspector.decapitalize(method.getName().substring(2));
}
else
{
throw new IllegalArgumentException("Invalid accessor method, must start with 'get', 'set' or 'is'. " + "Method: " + method);
}
this.getterMethod = getGetterMethod(method.getDeclaringClass(), propertyName);
this.setterMethod = getSetterMethod(method.getDeclaringClass(), propertyName);
}
public String getName()
{
return propertyName;
}
@SuppressWarnings("unchecked")
public Class<V> getJavaClass()
{
return (Class<V>) getterMethod.getReturnType();
}
public Type getBaseType()
{
return getterMethod.getGenericReturnType();
}
public Method getAnnotatedElement()
{
return getterMethod;
}
public Member getMember()
{
return getterMethod;
}
public V getValue(Object instance)
{
return getJavaClass().cast(invokeMethod(getterMethod, instance));
}
public void setValue(Object instance, V value)
{
invokeMethod(setterMethod, instance, value);
}
private static Method getSetterMethod(Class<?> clazz, String name)
{
Method[] methods = clazz.getMethods();
for (Method method : methods)
{
String methodName = method.getName();
if (methodName.startsWith("set") && method.getParameterTypes().length == 1)
{
if (Introspector.decapitalize(methodName.substring(3)).equals(name))
{
return method;
}
}
}
return null;
}
private static Method getGetterMethod(Class<?> clazz, String name)
{
for (Method method : clazz.getDeclaredMethods())
{
String methodName = method.getName();
if (method.getParameterTypes().length == 0)
{
if (methodName.startsWith("get"))
{
if (Introspector.decapitalize(methodName.substring(3)).equals(name))
{
return method;
}
}
else if (methodName.startsWith("is"))
{
if (Introspector.decapitalize(methodName.substring(2)).equals(name))
{
return method;
}
}
}
}
throw new IllegalArgumentException("no such getter method: " + clazz.getName() + '.' + name);
}
public Class<?> getDeclaringClass()
{
return getterMethod.getDeclaringClass();
}
public boolean isReadOnly()
{
return setterMethod == null;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
if (isReadOnly())
{
builder.append("read-only ").append(setterMethod.toString()).append("; ");
}
builder.append(getterMethod.toString());
return builder.toString();
}
@Override
public int hashCode()
{
int hash = 1;
hash = hash * 31 + (setterMethod == null ? 0 : setterMethod.hashCode());
hash = hash * 31 + getterMethod.hashCode();
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj instanceof MethodPropertyImpl<?>)
{
MethodPropertyImpl<?> that = (MethodPropertyImpl<?>) obj;
if (this.setterMethod == null)
{
return that.setterMethod == null && this.getterMethod.equals(that.getterMethod);
}
else
{
return this.setterMethod.equals(that.setterMethod) && this.getterMethod.equals(that.getterMethod);
}
}
else
{
return false;
}
}
}