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

public class QDataClass implements QTargetFactory
{
    public Class wClass=null;
    public String wClassName="";
    public ArrayList values=new ArrayList();
    protected static Class constructorParamClasses[];
    protected Constructor constructor;
    public boolean isQName=false;
    public boolean isAware=false;

    public static Class aware;
    public static Class qname;

    static
    {
	try
	    {
		constructorParamClasses=new Class[1];
		constructorParamClasses[0]="".getClass();
		aware=Class.forName("com.jxml.quick.QAware");
		qname=Class.forName("com.jxml.quick.QName");
	    }
	catch (Exception e)
	    {
		throw new Error(e.toString());
	    }
    }

    public QDataClass()
    {
    }

    public QDataClass(String wClassName)
    {
	this.wClassName=wClassName;
    }

    public String toString()
    {
	return wClassName;
    }

    private synchronized void prep(QContext context)
	throws QPE
    {
	if (wClass!=null)
	    return;
	wClass=context.forName(wClassName);
	isAware=aware.isAssignableFrom(wClass);
	isQName=qname.isAssignableFrom(wClass);
	try
	    {
		constructor=wClass.getConstructor
		    (constructorParamClasses);
	    } 
	catch (NoSuchMethodException e)
	    {
		System.err.println("wClassName="+wClassName);
		context.throwPE(e);
	    }
    }

    public Object create(QContext context)
	throws QPE
    {
	return null;
    }

    public boolean isInstance(Object object,
			      QContext context)
	throws QPE
    {
	prep(context);
	return wClass.isInstance(object);
    }

    public String getName(Object object)
    {
	if (isQName)
	    return ((QName)object).getQName();
	else
	    return "";
    }

    public void validate(String text, QContext context)
	throws QPE
    {
	int s=values.size();
	if (s==0)
	    return;
	int i;
	for (i=0;i<s;++i)
	    {
		if (text.equals(values.get(i)))
		    return;
	    }
	context.throwPE("Invalid value: "+text);
    }

    public String getText(Object object, 
			  QContext context)
	throws QPE
    {
	String text=object.toString();
	validate(text,context);
	return text;
    }

    public void add(Object object, 
		    String name, 
		    String text,
		    QAccess access,
		    Object parent,
		    QTargetFactory parentFactory,
		    QContext context)
	throws QPE
    {
	prep(context);
	validate(text,context);
	try
	    {
		Object params[]=new Object[1];
		params[0]=text;
		object=constructor.newInstance(params);
	    }
	catch (InstantiationException e)
	    {
		context.throwPE(e);
	    }
	catch (IllegalAccessException e)
	    {
		context.throwPE(e);
	    }
	catch (InvocationTargetException e)
	    {
		context.throwPE(e);
	    }
	if (isQName)
	    {
		QName q=(QName)object;
		q.setQName(name);
	    }
	if (parent==null)
	    context.doc.setRoot(object);
	else
	    access.add(parent,parentFactory,object,context);
	if (isAware)
	    {
		((QAware)object).endElement(name,context);
	    }
    }

    public PropertyDescriptor[] getPropertyDescriptors(QContext context)
	throws QPE
    {
	return null;
    }

    public Field[] getFields(QContext context)
	throws QPE
    {
	return null;
    }
}
