
/*
 * JRiReportXMLDataSource.java
 *
 * Created on 22 giugno 2004, 14.55
 */

package it.businesslogic.ireport.connection;


import java.util.*;


/**
 * The XML datasource define a row as a path.
 * A path can be truncated.
 * @author  Administrator
 */
public class JRExtendedBeanDataSource implements net.sf.jasperreports.engine.JRDataSource {

    private Object[] beans = null;
    private int index = -1;
    
    public JRExtendedBeanDataSource(Vector beans)
    {
        this.beans = beans.toArray();
    } 
    
    public JRExtendedBeanDataSource(Object[] beans)
    {
        this.beans = beans;
    } 
    
    public Object getFieldValue(net.sf.jasperreports.engine.JRField jRField) throws net.sf.jasperreports.engine.JRException {
        
        String path = jRField.getDescription();
        
        Object val = getPathValue(beans[index], path);
        
        if (val == null) return null;
        if (val.getClass().isAssignableFrom( jRField.getValueClass() )) return val;
        return null;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                
    }
    
     public boolean next() throws net.sf.jasperreports.engine.JRException {       

        index++;
        if (index >= beans.length) return false;
        return true;
    }
    
   
    private Object getPathValue(Object bean, String path)
    {
        if (path == null || bean == null || path.trim().length() == 0)
        {
            return bean;
        }
	if (path.startsWith(".")) path = path.substring(1);
        if (path.trim().length() == 0) return bean;
        
        path = path.trim();
        String attr_name = getNextNodeName(path );   
        
        
        /*
        java.lang.reflect.Method m = null;
        try {
            m = bean.getClass().getMethod("get" + attr_name,  new Class[]{});
        } catch (Exception ex){ return null; }
        
        if (m.getReturnType().isArray())
        {
            if (path.equals(attr_name))
            {
                try {
                     return new JRExtendedBeanDataSource( (Object[])m.invoke(bean, new Object[]{}) ); 
                } catch (Exception ex){ return null; }
            }
            else return null;
        }
        else
        {
            if (path.equals(attr_name))
            {
                try {
                    return m.invoke(bean, new Object[]{});
                } catch (Exception ex){ return null; }
            }
            else
            {
                Object child_bean  = null;
                try {
                    child_bean = m.invoke(bean, new Object[]{});
                } catch (Exception ex){ return null; }
                path = path.substring(attr_name.length());
                return getPathValue(child_bean, path );
            }           
        } 
         */
        Class clazz  = null;
        try {
            org.apache.commons.beanutils.PropertyUtils.getPropertyType(bean,attr_name);
        } catch (Exception ex){ return null; }
    
        if (clazz == null) // Attribute not found!!!!
        {
            return null;
        }
        else if ( clazz.isArray() )
        {
            try {
                     return new JRExtendedBeanDataSource( (Object[])org.apache.commons.beanutils.PropertyUtils.getProperty(bean, attr_name) ); 
                } catch (Exception ex){ return null; }
        }
        else
        {
            if (path.equals(attr_name))
            {
                try {
                    return org.apache.commons.beanutils.PropertyUtils.getProperty(bean, attr_name);
                } catch (Exception ex){ return null; }
            }
            else
            {
                Object child_bean  = null;
                try {
                    child_bean = org.apache.commons.beanutils.PropertyUtils.getProperty(bean, attr_name);
                } catch (Exception ex){ return null; }
                path = path.substring(attr_name.length());
                return getPathValue(child_bean, path );
            }      
        }   
    }
        
    private static String getNextNodeName( String path)
    {
        
        if (path == null || path.length() ==0) return "";
        if (path.startsWith(".")) path = path.substring(1);
        
        String childToTake = path;
        if (path.indexOf(".") >= 0)
        {
                childToTake = path.substring(0,path.indexOf("."));
        }
               
        return childToTake;
    }
}
