package com.jxml.quick.access;
import com.jxml.quick.*;
import com.jxml.quick.tf.*;
import java.lang.reflect.*;

public class QFieldAccess extends QAccess
{
    public String field;
    protected Field pd=null;

    protected void setPD(QTargetFactory tf, QContext context)
	throws QPE
    {
	if (pd!=null)
	    return;
	Field[] pds=tf.getFields(context);
	if (pds==null)
	    context.throwPE(field+": No Fields Available: "+tf.getClass().getName());
	int s=pds.length;
	int i;
	for (i=0;i<s;++i)
	    {
		if (field.equals(pds[i].getName()))
		    {
			pd=pds[i];
			validateField(pd,context);
			return;
		    }
	    }
	context.throwPE("Invalid field: "+field);
    }

    protected void validateField(Field pd, QContext context)
	throws QPE
    {
    }

    public boolean readable(QTargetFactory parentFactory, QContext context)
	throws QPE
    {
	return true;
    }

    public QIterator createIterator()
    {
	return new QSimpleIterator();
    }

    protected Object get(QTargetFactory parentFactory, Object parent, QContext context)
	throws QPE
    {
	try
	{
		return pd.get(parent);
	}
	catch (Exception e)
	{
		try
	        {
			pd=null;
			setPD(parentFactory,context);
			return pd.get(parent);
	        }
		catch (IllegalAccessException ex)
	    	{
			System.err.println("parent="+parent.getClass());
			System.err.println("pd="+pd);
			context.throwPE(ex);
	    	}
	}
	return null;
    }

    public void setIteratorParent(QIterator it, 
				  Object parent, 
				  QTargetFactory parentFactory,
				  QContext context)
	throws QPE
    {
	setPD(parentFactory,context);
	((QSimpleIterator)it).setCurrent(get(parentFactory,parent,context));
    }

    public boolean writeable(QTargetFactory parentFactory, QContext context)
	throws QPE
    {
	return true;
    }

    public void add(Object parent, 
		    QTargetFactory parentFactory,
		    Object child, 
		    QContext context)
	throws QPE
    {
	setPD(parentFactory,context);
	try
	{
		pd.set(parent,child);
	}
	catch (Exception e)
	{
		try
	    	{
			pd=null;
			setPD(parentFactory,context);
			pd.set(parent,child);
	    	}
		catch (IllegalAccessException ex)
		{
			System.err.println("field="+field);
			context.throwPE(ex);
	    	}
	}
    }
}
