package org.jboss.seam.util;
import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TypedBeanProperty
{
private Field propertyField;
private Method propertyGetter;
private Method propertySetter;
private String name;
private boolean isFieldProperty;
private boolean set = false;
public TypedBeanProperty(Class<?> cls, Class type)
{
// First check declared fields
for (Field f : cls.getDeclaredFields())
{
if (f.getGenericType().equals(type))
{
setupFieldProperty(f);
set = true;
return;
}
}
// Then check public fields, in case it's inherited
for (Field f : cls.getFields())
{
if (f.getGenericType().equals(type))
{
setupFieldProperty(f);
set = true;
return;
}
}
// Then check public methods (we ignore private methods)
for (Method m : cls.getMethods())
{
if (m.getGenericReturnType().equals(type))
{
String methodName = m.getName();
if ( m.getName().startsWith("get") )
{
this.name = Introspector.decapitalize( m.getName().substring(3) );
}
else if ( methodName.startsWith("is") )
{
this.name = Introspector.decapitalize( m.getName().substring(2) );
}
if (this.name != null)
{
this.propertyGetter = Reflections.getGetterMethod(cls, this.name);
this.propertySetter = Reflections.getSetterMethod(cls, this.name);
isFieldProperty = false;
set = true;
}
else
{
throw new IllegalStateException("Invalid accessor method, must start with 'get' or 'is'. " +
"Method: " + m + " in class: " + cls);
}
}
}
}
private void setupFieldProperty(Field propertyField)
{
this.propertyField = propertyField;
isFieldProperty = true;
this.name = propertyField.getName();
}
public void setValue(Object bean, Object value)
{
if (isFieldProperty)
{
Reflections.setAndWrap(propertyField, bean, value);
}
else
{
Reflections.invokeAndWrap(propertySetter, bean, value);
}
}
public Object getValue(Object bean)
{
if (isFieldProperty)
{
return Reflections.getAndWrap(propertyField, bean);
}
else
{
return Reflections.invokeAndWrap(propertyGetter, bean);
}
}
public String getName()
{
return name;
}
public boolean isSet()
{
return set;
}
}