package com.jxml.quick.model.qjml;
import com.jxml.quick.ocm.*;
import com.jxml.quick.*;
import org.xml.sax.*;
import java.util.*;
import java.io.*;

/**
 * Models an interface element in QJML.
 * An interface element has no tag attribute, since it doesn't define a particular
 * XML element. (Similarly, a Java interface can't be instantiated.)
 * Interfaces provide a means of refering to the family of beans which implement them.
 <pre>
DTD:

&lt;!ELEMENT interface (<a href="QMCoin.html#remList">rem*</a>, <a href="#extendsList">extends*</a>, <a href="#targetClass">targetClass?</a>, <a href="#propertyList">property*</a>)>

&lt;!ATTLIST interface 
&nbsp;&nbsp;&nbsp;&nbsp;<a href="QMCoin.html#label">label</a> CDATA #REQUIRED
&nbsp;&nbsp;&nbsp;&nbsp;<a href="QMCoin.html#generate">generate</a> CDATA "True"
&nbsp;&nbsp;&nbsp;&nbsp;ID id #IMPLIED
>
 </pre>
 */
public class QMInterface extends QMCoin
	implements QMElement
{
	/**
	 * A container for QMExtends objects, which model extends elements.
	 * The extends elements are optional and repeating.
	 * These extends elements name the other interface coins which this interface coin extends.
	 * (An interface element, like a Java interface class, can extend any number of
	 * other interfaces.)
	 */
	public ArrayList extendsList=new ArrayList();

	/**
	 * Models a targetClass element, which is optional.
	 * The targetClass element names the Java interface which this interface element describes.
	 */
	public QMTargetClass targetClass=null;

	/**
	 * A container for QMProperty objects, which model property elements.
	 * The property elements are optional and repeating.
	 * These property elements describe the bean property methods of the Java interface which
	 * this interface element describes.
	 */
	public ArrayList propertyList=new ArrayList();

	public Object clone()
	{
		QMInterface rv=(QMInterface)super.clone();
		rv.extendsList=clone(extendsList);
		rv.targetClass=(QMTargetClass)clone((QMCloneable)targetClass);
		rv.propertyList=clone(propertyList);
		return rv;
	}

	public void buildMaps(Map coinMap, Map contentMap)
		throws SAXException
	{
		int i;
		int s;

		if (targetClass==null)
		{
			targetClass=new QMTargetClass();
			targetClass.text="java.lang.Object";
                        generate = false;
		}

		String l=getLabel();
		if ("".equals(l))
			throw new SAXException(
				"Interface coin has no label.");
		if (coinMap.containsKey(l))
			throw new SAXException("Duplicate label: "+l);
		coinMap.put(l,this);

		s=propertyList.size();
		for (i=0;i<s;++i)
		{
			QMProperty p=(QMProperty)propertyList.get(i);
			p.abst=true;
			p.buildMaps(coinMap,contentMap,this);
		}
	}

	public QMAccess getAccessor(Map coinMap, String name)
		throws SAXException
	{
		QMAccess a=null;
		int i;
		int s=extendsList.size();
		for (i=0;(a==null && i<s);++i)
		{
			String l=((QMExtends)extendsList.get(i)).text;
			QMCoin c=(QMCoin)coinMap.get(l);
			if (c==null)
				throw new SAXException("Undefined coin: "+l);
			a=c.getAccessor(coinMap,name);
		}
		a=(QMAccess)accessors.get(name);
		return a;
	}

	public void init(Map coinMap, Map contentMap)
		throws SAXException
	{
		int i;
		int s;

		s=extendsList.size();
		for (i=0;i<s;++i)
		{
			String l=((QMExtends)extendsList.get(i)).text;
			QMCoin c=(QMCoin)coinMap.get(l);
			if (c==null)
				throw new SAXException("Undefined coin: "+l);
			c.extensions.add(this);
		}

		s=propertyList.size();
		for (i=0;i<s;++i)
		{
			QMProperty p=(QMProperty)propertyList.get(i);
			p.init(coinMap,contentMap,this,null);
		}
		if ("java.lang.Object".equals(getClassName()))
			generate=false;
	}

	public Map getAtts()
		throws SAXException
	{
		return new HashMap();
	}

	public String getClassName()
		throws SAXException
	{
		return targetClass.getClassName();
	}
}
