/* Consumer.java -- 
   Copyright (C) 2001,2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.xml.dom;

import org.w3c.dom.DocumentType;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.ext.Attributes2;

import gnu.xml.pipeline.DomConsumer;
import gnu.xml.pipeline.EventConsumer;


/**
 * Event consumer which constructs DOM documents using the implementation
 * in this package, using SAX2 events.  This packages various backdoors
 * into this DOM implementation, as needed to address DOM requirements
 * that can't be met by strictly conforming implementations of DOM.
 *
 * <p> These requirements all relate to {@link DocumentType} nodes and
 * features of that node type.  These features are normally not used,
 * because that interface only exposes a subset of the information found
 * in DTDs.  More, that subset does not include the most important typing
 * information.  For example, it excludes element content models and
 * attribute typing.  It does expose some entity management issues,
 * although entity management doesn't relate to document typing.
 *
 * <p> Note that SAX2 does not expose the literal text of the DTD's
 * internal subset, so it will not be present in DOM trees constructed
 * using this API.  (Though with a good SAX2 implementation, it could
 * be partially recreated...)
 *
 * @author David Brownell
 */
public class Consumer extends DomConsumer
{
    /**
     * Constructs an unconfigured event consumer,
     * as a terminus in a SAX event pipeline.
     */
    // used by PipelineFactory [terminus]
    public Consumer ()
    throws SAXException
    {
	super (DomDocument.class);
	setHandler (new Backdoor (this));
    }

    /**
     * Constructs an unconfigured event consumer,
     * as a stage in a SAX event pipeline.
     */
    // used by PipelineFactory [filter]
    public Consumer (EventConsumer next)
    throws SAXException
    {
	super (DomDocument.class, next);
	setHandler (new Backdoor (this));
    }

    /**
     * Implements the backdoors needed by DOM.
     * All methods in this class use implementation-specific APIs that are
     * implied by the DOM specification (needed to implement testable
     * behavior) but which are excluded from the DOM specification.
     */
    public static class Backdoor extends DomConsumer.Handler
    {
	/**
	 * Constructor.
	 * @param consumer must have been initialized to use the
	 *	{@link DomDocument} class (or a subclass) for
	 *	constructing DOM trees
	 */
	protected Backdoor (DomConsumer consumer)
	throws SAXException
	    { super (consumer); }

	// helper routine
	private DomDoctype getDoctype ()
	throws SAXException
	{
	    DomDocument		doc = (DomDocument) getDocument ();
	    DocumentType	dt = doc.getDoctype ();

	    if (dt == null)
		throw new SAXException ("doctype missing!");
	    return (DomDoctype) dt;
	}

	// SAX2 "lexical" event
	public void startDTD (String name, String publicId, String systemId)
	throws SAXException
	{
	    DomDocument		doc = (DomDocument) getDocument ();

	    super.startDTD (name, publicId, systemId);
	    // DOM L2 doctype creation model is bizarre
	    DomDoctype dt = new DomDoctype (doc, name, publicId, systemId);
	    doc.appendChild (dt);
	}

	// SAX2 "lexical" event
	public void endDTD ()
	throws SAXException
	{
	    super.endDTD ();
	    // DOM L2 has no way to make things readonly
	    getDoctype ().makeReadonly ();
	}

	// SAX1 DTD event
	public void notationDecl (
	    String name,
	    String publicId, String systemId
	) throws SAXException
	{
	    // DOM L2 can't create/save notation nodes
	    getDoctype ().declareNotation (name, publicId, systemId);
	}

	// SAX1 DTD event
	public void unparsedEntityDecl (
	    String name,
	    String publicId, String systemId,
	    String notationName
	) throws SAXException
	{
	    // DOM L2 can't create/save entity nodes
	    getDoctype ().declareEntity (name, publicId, systemId,
	    	notationName);
	}

	// SAX2 declaration event
	public void internalEntityDecl (String name, String value)
	throws SAXException
	{
	    // DOM L2 can't create/save entity nodes
	    // NOTE:  this doesn't save the value as a child of this
	    // node, though it could realistically do so.
	    getDoctype ().declareEntity (name, null, null, null);
	}

	// SAX2 declaration event
	public void externalEntityDecl (
	    String name,
	    String publicId,
	    String systemId
	) throws SAXException
	{
	    // DOM L2 can't create/save entity nodes
	    // NOTE:  DOM allows for these to have children, if
	    // they don't have unbound namespace references.
	    getDoctype ().declareEntity (name, publicId, systemId, null);
	}

	// SAX2 element
	public void startElement (
	    String uri,
	    String localName,
	    String qName,
	    Attributes atts
	) throws SAXException
	{
	    Node		top;

	    super.startElement (uri, localName, qName, atts);

	    // might there be more work?
	    top = getTop ();
	    if (!top.hasAttributes () || !(atts instanceof Attributes2))
		return;

	    // remember any attributes that got defaulted
	    DomNamedNodeMap	map = (DomNamedNodeMap) top.getAttributes ();
	    Attributes2		attrs = (Attributes2) atts;
	    int			length = atts.getLength ();

	    //map.compact ();
	    for (int i = 0; i < length; i++) {
		if (attrs.isSpecified (i))
		    continue;

		// value was defaulted.
		String		temp = attrs.getQName (i);
		DomAttr		attr;

		if ("".equals (temp))
		    attr = (DomAttr) map.getNamedItemNS (attrs.getURI (i),
			    atts.getLocalName (i));
		else
		    attr = (DomAttr) map.getNamedItem (temp);

		// DOM L2 can't write this flag, only read it
		attr.setSpecified (false);
	    }
	}

	public void endElement (
	    String uri,
	    String localName,
	    String qName
	) throws SAXException
	{
	    DomNode	top = (DomNode) getTop ();
	    top.compact ();
	    super.endElement (uri, localName, qName);
	}

	protected Text createText (
	    boolean	isCDATA,
	    char	buf [],
	    int		off,
	    int		len
	) {
	    DomDocument	doc = (DomDocument) getDocument ();

	    if (isCDATA)
		return doc.createCDATASection (buf, off, len);
	    else
		return doc.createTextNode (buf, off, len);
	}

        public void elementDecl(String name, String model)
          throws SAXException
        {
          getDoctype().elementDecl(name, model);
        }

	public void attributeDecl (
	    String	ename,
	    String	aname,
	    String	type,
	    String	mode,
	    String	value
	) throws SAXException
	{
          getDoctype().attributeDecl(ename, aname, type, mode, value);
            /*
	    if (value == null && !"ID".equals (type))
		return;
	    
	    DomDoctype.ElementInfo	info;

	    info = getDoctype ().getElementInfo (ename);
	    if (value != null)
		info.setAttrDefault (aname, value);
	    if ("ID".equals (type))
		info.setIdAttr (aname);
                */
            
	}

	// force duplicate name checking off while we're
	// using parser output (don't duplicate the work)
	public void startDocument () throws SAXException
	{
	    super.startDocument ();
	    
            DomDocument doc = (DomDocument) getDocument ();
            doc.setStrictErrorChecking(false);
            doc.setBuilding(true);
	}

	public void endDocument ()
	throws SAXException
	{
	    DomDocument doc = (DomDocument) getDocument ();
	    doc.setStrictErrorChecking(true);
            doc.setBuilding(false);
	    doc.compact ();
            DomDoctype doctype = (DomDoctype) doc.getDoctype();
            if (doctype != null)
              {
                doctype.makeReadonly();
              }
	    super.endDocument ();
	}

	// these three methods collaborate to populate entity
	// refs, marking contents readonly on end-of-entity

	public boolean canPopulateEntityRefs ()
	    { return true; }

	public void startEntity (String name)
	throws SAXException
	{
	    if (name.charAt (0) == '%' || "[dtd]".equals (name))
		return;
	    super.startEntity (name);

	    DomNode	top = (DomNode) getTop ();

	    if (top.getNodeType () == Node.ENTITY_REFERENCE_NODE)
		top.readonly = false;
	}

	public void endEntity (String name)
	throws SAXException
	{
	    if (name.charAt (0) == '%' || "[dtd]".equals (name))
		return;
	    DomNode	top = (DomNode) getTop ();

	    if (top.getNodeType () == Node.ENTITY_REFERENCE_NODE) {
		top.compact ();
		top.makeReadonly ();
	    }
	    super.endEntity (name);
	}
    }
}
