/* JAXPFactory.java -- 
   Copyright (C) 2001 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 java.io.IOException;

import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;

import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;


/**
 * DOM bootstrapping API, for use with JAXP.
 *
 * @see Consumer
 *
 * @author David Brownell
 */
public final class JAXPFactory
  extends DocumentBuilderFactory
{
  
  private static final String	PROPERTY = "http://xml.org/sax/properties/";
  private static final String	FEATURE = "http://xml.org/sax/features/";
  
  private SAXParserFactory	pf;
  private boolean secureProcessing;
  
  /**
   * Default constructor.
   */
  public JAXPFactory()
  {
  }
  
  /**
   * Constructs a JAXP document builder which uses the default
   * JAXP SAX2 parser and the DOM implementation in this package.
   */
  public DocumentBuilder newDocumentBuilder()
    throws ParserConfigurationException
  {
    if (pf == null)
      {
        // Force use of AElfred2 since not all JAXP parsers
        // conform very well to the SAX2 API spec ...
        pf = new gnu.xml.aelfred2.JAXPFactory();
        // pf = SAXParserFactory.newInstance ();
      }
    
    // JAXP default: false
    pf.setValidating(isValidating());

    // FIXME:  this namespace setup may cause errors in some
    // conformant SAX2 parsers, which we CAN patch up by
    // splicing a "NSFilter" stage up front ...
    
    // JAXP default: false
    pf.setNamespaceAware(isNamespaceAware());

    try
      {
        // undo rude "namespace-prefixes=false" default
        pf.setFeature(FEATURE + "namespace-prefixes", true);

        return new JAXPBuilder(pf.newSAXParser().getXMLReader(), this);
      }
    catch (SAXException e)
      {
        String msg = "can't create JAXP DocumentBuilder: " + e.getMessage();
        throw new ParserConfigurationException(msg);
      }
  }
  
  /** There seems to be no useful specification for attribute names */
  public void setAttribute(String name, Object value)
    throws IllegalArgumentException
  {
    if ("http://java.sun.com/xml/jaxp/properties/schemaLanguage".equals(name))
      {
        // TODO
      }
    else
      {
        throw new IllegalArgumentException(name);
      }
  }

  /** There seems to be no useful specification for attribute names */
  public Object getAttribute(String name)
    throws IllegalArgumentException
  {
    throw new IllegalArgumentException(name);
  }

  public void setFeature(String name, boolean value)
    throws ParserConfigurationException
  {
    if (name == null)
      throw new NullPointerException();
    if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name))
      {
        secureProcessing = true;
        return;
      }
    throw new ParserConfigurationException(name);
  }

  public boolean getFeature(String name)
    throws ParserConfigurationException
  {
    if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(name))
      return secureProcessing;
    throw new ParserConfigurationException(name);
  }
  
  static final class JAXPBuilder
    extends DocumentBuilder
    implements ErrorHandler
  {

    private Consumer	consumer;
    private XMLReader	producer;
    private DomImpl		impl;
    
    JAXPBuilder(XMLReader parser, JAXPFactory factory)
      throws ParserConfigurationException
    {
      impl = new DomImpl();
      
      // set up consumer side
      try
        {
          consumer = new Consumer();
        }
      catch (SAXException e)
        {
          throw new ParserConfigurationException(e.getMessage());
        }

      // JAXP defaults: true, noise nodes are good (bleech)
      consumer.setHidingReferences(factory.isExpandEntityReferences());
      consumer.setHidingComments(factory.isIgnoringComments());
      consumer.setHidingWhitespace(factory.isIgnoringElementContentWhitespace());
      consumer.setHidingCDATA(factory.isCoalescing());

      // set up producer side
      producer = parser;
      producer.setContentHandler(consumer.getContentHandler());
      producer.setDTDHandler(consumer.getDTDHandler());

      try
        {
          String	id;
          
          // if validating, report validity errors, and default
          // to treating them as fatal
          if (factory.isValidating ())
            {
              producer.setFeature(FEATURE + "validation", true);
              producer.setErrorHandler(this);
            }
          
          // always save prefix info, maybe do namespace processing
          producer.setFeature(FEATURE + "namespace-prefixes", true);
          producer.setFeature(FEATURE + "namespaces",
                              factory.isNamespaceAware());

          // set important handlers
          id = PROPERTY + "lexical-handler";
          producer.setProperty(id, consumer.getProperty(id));

          id = PROPERTY + "declaration-handler";
          producer.setProperty(id, consumer.getProperty(id));
          
        }
      catch (SAXException e)
        {
          throw new ParserConfigurationException(e.getMessage());
        }
    }
    
    public Document parse(InputSource source) 
      throws SAXException, IOException
    {
      producer.parse(source);
      Document doc = consumer.getDocument();
      // TODO inputEncoding
      doc.setDocumentURI(source.getSystemId());
      return doc;
    }

    public boolean isNamespaceAware()
    {
      try
        {
          return producer.getFeature(FEATURE + "namespaces");
        }
      catch (SAXException e)
        {
          // "can't happen"
          throw new RuntimeException(e.getMessage());
        }
    }

    public boolean isValidating()
    {
      try
        {
          return producer.getFeature(FEATURE + "validation");
        }
      catch (SAXException e)
        {
          // "can't happen"
          throw new RuntimeException(e.getMessage());
        }
    }

    public void setEntityResolver(EntityResolver resolver)
    {
      producer.setEntityResolver(resolver);
    }

    public void setErrorHandler(ErrorHandler handler)
    {
      producer.setErrorHandler(handler);
      consumer.setErrorHandler(handler);
    }

    public DOMImplementation getDOMImplementation()
    {
      return impl;
    }

    public Document newDocument()
    {
      return new DomDocument();
    }
	
    // implementation of error handler that's used when validating
    public void fatalError(SAXParseException e)
      throws SAXException
    {
      throw e;
    }
    
    public void error(SAXParseException e)
      throws SAXException
    {
      throw e;
    }
    
    public void warning(SAXParseException e)
      throws SAXException
    {
      /* ignore */
    }
 
  }

}

