package org.jboss.seam.debug;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.contexts.Contexts;
@Name("org.jboss.seam.debug.introspector")
@Install(debug=true, precedence=BUILT_IN)
public class Introspector {
@RequestParameter
private String name;
public Attribute[] getAttributes() throws Exception
{
if (name==null) return null;
Object component = Contexts.lookupInStatefulContexts(name);
if (component==null)
{
return null;
}
else if (component instanceof Map)
{
return getMapAttributes( (Map) component );
}
else if (component instanceof List)
{
return getListAttributes( (List) component );
}
else
{
return getComponentAttributes(component);
}
}
public Attribute[] getMapAttributes(Map<Object, Object> map)
{
Attribute[] attributes = new Attribute[map.size()];
int i=0;
for( Map.Entry me: map.entrySet() )
{
attributes[i++] = new Attribute( me.getKey().toString(), me.getValue() );
}
return attributes;
}
public Attribute[] getListAttributes(List list)
{
Attribute[] attributes = new Attribute[list.size()];
for(int i=0; i<list.size(); i++ )
{
attributes[i] = new Attribute( Integer.toString(i), list.get(i) );
}
return attributes;
}
private Attribute[] getComponentAttributes(Object component) throws IntrospectionException, IllegalAccessException {
BeanInfo bi = java.beans.Introspector.getBeanInfo( component.getClass() );
//MethodDescriptor[] methods = bi.getMethodDescriptors();
PropertyDescriptor[] properties = bi.getPropertyDescriptors();
Attribute[] attributes = new Attribute[properties.length+1];
for (int i=0; i<properties.length; i++)
{
Object value;
try
{
Method readMethod = properties[i].getReadMethod();
if (readMethod==null) continue;
value = readMethod.invoke(component);
}
catch (InvocationTargetException ite)
{
Throwable e = ite.getCause();
value = toString(e);
}
boolean convertArrayToList = value!=null &&
value.getClass().isArray() &&
!value.getClass().getComponentType().isPrimitive();
if ( convertArrayToList )
{
value = Arrays.asList( (Object[]) value );
}
attributes[i] = new Attribute( properties[i].getDisplayName(), value );
}
String toString;
try
{
toString = component.toString();
}
catch (Exception e)
{
toString = e.getClass().getName() + '[' + e.getMessage() + ']';
}
attributes[properties.length] = new Attribute("toString()", toString);
return attributes;
}
private static String toString(Throwable e)
{
return e.getClass().getName() + '[' + e.getMessage() + ']';
}
public static class Attribute
{
private String name;
private Object value;
public Attribute(String name, Object value)
{
this.name = name;
this.value = value;
}
public String getName()
{
return name;
}
public Object getValue()
{
return value;
}
public String getStringValue()
{
try
{
return value==null ? null : value.toString();
}
catch (Throwable e)
{
return Introspector.toString(e);
}
}
}
}