FileDocCategorySizeDatePackage
BeanAdapter.javaAPI DocExample6631Mon Jul 23 13:26:44 BST 2007org.apache.struts2.views.xslt

BeanAdapter

public class BeanAdapter extends AbstractAdapterElement
This class is the most general type of adapter, utilizing reflective introspection to present a DOM view of all of the public properties of its value. For example, a property returning a JavaBean such as:
public Person getMyPerson() { ... }
...
class Person {
public String getFirstName();
public String getLastName();
}
would be rendered as: ... ...

Fields Summary
private static final Object[]
NULLPARAMS
private static Map
propertyDescriptorCache
Cache can savely be static because the cached information is the same for all instances of this class.
private Log
log
Constructors Summary
public BeanAdapter()


    //~ Constructors ///////////////////////////////////////////////////////////

      
    
public BeanAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value)

        setContext(adapterFactory, parent, propertyName, value);
    
Methods Summary
protected java.util.ListbuildChildAdapters()

        log.debug("BeanAdapter building children.  PropName = " + getPropertyName());
        List<Node> newAdapters = new ArrayList<Node>();
        Class type = getPropertyValue().getClass();
        PropertyDescriptor[] props = getPropertyDescriptors(getPropertyValue());

        if (props.length > 0) {
            for (PropertyDescriptor prop : props) {
                Method m = prop.getReadMethod();

                if (m == null) {
                    //FIXME: write only property or indexed access
                    continue;
                }
                log.debug("Bean reading property method: " + m.getName());

                String propertyName = prop.getName();
                Object propertyValue;

                /*
                    Unwrap any invocation target exceptions and log them.
                    We really need a way to control which properties are accessed.
                    Perhaps with annotations in Java5?
                */
                try {
                    propertyValue = m.invoke(getPropertyValue(), NULLPARAMS);
                } catch (Exception e) {
                    if (e instanceof InvocationTargetException)
                        e = (Exception) ((InvocationTargetException) e).getTargetException();
                    log.error(e);
                    continue;
                }

                Node childAdapter;

                if (propertyValue == null) {
                    childAdapter = getAdapterFactory().adaptNullValue(this, propertyName);
                } else {
                    childAdapter = getAdapterFactory().adaptNode(this, propertyName, propertyValue);
                }

                if (childAdapter != null)
                    newAdapters.add(childAdapter);

                if (log.isDebugEnabled()) {
                    log.debug(this + " adding adapter: " + childAdapter);
                }
            }
        } else {
            // No properties found
            log.info(
                    "Class " + type.getName() + " has no readable properties, " + " trying to adapt " + getPropertyName() + " with StringAdapter...");
        }

        return newAdapters;
    
public org.w3c.dom.NodeListgetChildNodes()

        NodeList nl = super.getChildNodes();
        // Log child nodes for debug:
        if (log.isDebugEnabled() && nl != null) {
            log.debug("BeanAdapter getChildNodes for: " + getTagName());
            log.debug(nl.toString());
        }
        return nl;
    
private synchronized java.beans.PropertyDescriptor[]getPropertyDescriptors(java.lang.Object bean)
Caching facade method to Introspector.getBeanInfo(Class, Class).getPropertyDescriptors();

        try {
            if (propertyDescriptorCache == null) {
                propertyDescriptorCache = new HashMap<Class, PropertyDescriptor[]>();
            }

            PropertyDescriptor[] props = propertyDescriptorCache.get(bean.getClass());

            if (props == null) {
                log.debug("Caching property descriptor for " + bean.getClass().getName());
                props = Introspector.getBeanInfo(bean.getClass(), Object.class).getPropertyDescriptors();
                propertyDescriptorCache.put(bean.getClass(), props);
            }

            return props;
        } catch (IntrospectionException e) {
            e.printStackTrace();
            throw new StrutsException("Error getting property descriptors for " + bean + " : " + e.getMessage());
        }
    
public java.lang.StringgetTagName()

        return getPropertyName();