/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.aelfred2;

import java.util.Enumeration;
import java.util.Hashtable;

import org.xml.sax.Parser;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.helpers.XMLReaderAdapter;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;


/**
 * Configurable factory to create an &AElig;lfred2 JAXP parser; required
 * to bootstrap using JAXP.  You should use SAX2 directly where possible,
 * rather than through JAXP, since that gives you better control.
 * This class would normally be configured as a platform default factory.
 *
 * @author David Brownell
 */
public final class JAXPFactory
  extends SAXParserFactory
{
  
  private Hashtable flags = new Hashtable();

  /**
   * Constructs a factory which normally returns a non-validating
   * parser.
   */
  public JAXPFactory()
  {
  }

  public SAXParser newSAXParser()
    throws ParserConfigurationException, SAXException
  {
    JaxpParser jaxp = new JaxpParser();
    Enumeration e = flags.keys();
    XMLReader parser = jaxp.getXMLReader();

    parser.setFeature(SAXDriver.FEATURE + "namespaces",
                      isNamespaceAware());
    parser.setFeature(SAXDriver.FEATURE + "validation",
                      isValidating());
    // that makes SAX2 feature flags trump JAXP
    
    while (e.hasMoreElements())
      {
        String uri = (String) e.nextElement();
        Boolean value = (Boolean) flags.get(uri);
        parser.setFeature(uri, value.booleanValue());
      }

    return jaxp;
  }

  // yes, this "feature transfer" mechanism doesn't play well
  
  public void setFeature(String name, boolean value) 
    throws ParserConfigurationException, SAXNotRecognizedException,
           SAXNotSupportedException
  {
    try
      {
        // force "early" detection of errors where possible
        // (flags can't necessarily be set before parsing)
        new JaxpParser().getXMLReader().setFeature(name, value);
        
        flags.put(name, new Boolean(value));
      }
    catch (SAXNotRecognizedException e)
      {
        throw new SAXNotRecognizedException(name);
      }
    catch (SAXNotSupportedException e)
      {
        throw new SAXNotSupportedException(name);
      }
    catch (Exception e)
      {
        throw new ParserConfigurationException(e.getClass().getName()
                                               + ": "
                                               + e.getMessage());
      }
  }

  public boolean getFeature(String name) 
    throws ParserConfigurationException, SAXNotRecognizedException,
           SAXNotSupportedException
  {
    Boolean value = (Boolean) flags.get(name);
    
    if (value != null)
      {
        return value.booleanValue();
      }
    else
      {
        try
          {
            return new JaxpParser().getXMLReader().getFeature(name);
          }
        catch (SAXNotRecognizedException e)
          {
            throw new SAXNotRecognizedException(name);
          }
        catch (SAXNotSupportedException e)
          {
            throw new SAXNotSupportedException(name);
          }
        catch (SAXException e)
          {
            throw new ParserConfigurationException(e.getClass().getName()
                                                   + ": "
                                                   + e.getMessage());
          }
      }
  }
           
  private static class JaxpParser
    extends SAXParser
  {
    
    private XmlReader ae2 = new XmlReader();
    private XMLReaderAdapter parser = null;
    
    JaxpParser()
    {
    }

    public void setProperty(String id, Object value) 
      throws SAXNotRecognizedException, SAXNotSupportedException
    {
      ae2.setProperty(id, value);
    }

    public Object getProperty(String id) 
      throws SAXNotRecognizedException, SAXNotSupportedException
    {
      return ae2.getProperty(id);
    }

    public Parser getParser()
      throws SAXException
    {
      if (parser == null)
        {
          parser = new XMLReaderAdapter(ae2);
        }
      return parser;
    }

    public XMLReader getXMLReader ()
      throws SAXException
    {
      return ae2;
    }

    public boolean isNamespaceAware()
    {
      try
        {
          return ae2.getFeature(SAXDriver.FEATURE + "namespaces");
        }
      catch (Exception e)
        {
          throw new Error();
        }
    }
    
    public boolean isValidating()
    {
      try
        {
          return ae2.getFeature(SAXDriver.FEATURE + "validation");
        }
      catch (Exception e)
        {
          throw new Error();
        }
    }
    
    // TODO isXIncludeAware()
    
  }
  
}

