/* SAXNullTransformerFactory.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.util;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
import java.util.Properties;

import gnu.xml.dom.Consumer;
import gnu.xml.dom.DomDocument;
import gnu.xml.pipeline.DomConsumer;
import gnu.xml.pipeline.EventFilter;

import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;

import org.xml.sax.*;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.helpers.LocatorImpl;


/**
 * Implements null transforms. XSLT stylesheets are not supported.
 * This class provides a way to translate three representations of
 * XML data (SAX event stream, DOM tree, and XML text) into each other.
 * In essence it's a thinnish wrapper around basic SAX event
 * <a href="../pipeline/package-summary.html">pipeline</a> facilities, which
 * exposes only limited functionality.  The <em>javax.xml.transform</em>
 * functionality is implemented as follows: <ul>
 *
 * <li>The {@link javax.xml.transform.sax.SAXSource SAXSource} class
 * just wraps an {@link XMLReader} and {@link InputSource}, while the
 * {@link javax.xml.transform.sax.SAXResult SAXResult} class is less
 * functional than a {@link gnu.xml.pipeline.EventConsumer EventConsumer}.
 * (Notably, it drops all but one declaration from any DTD.)</li>
 *
 * <li>The {@link javax.xml.transform.dom.DOMSource DOMSource} class
 * corresponds to special SAX parsers like {@link DomParser}, and the
 * {@link javax.xml.transform.dom.DOMResult DOMResult} class corresponds
 * to a {@link gnu.xml.pipeline.DomConsumer DomConsumer}.</li>
 *
 * <li>The {@link javax.xml.transform.stream.StreamSource StreamSource}
 * class corresponds to a SAX {@link InputSource}, and the
 * {@link javax.xml.transform.stream.StreamResult StreamResult} class
 * corresponds to a {@link gnu.xml.pipeline.TextConsumer TextConsumer}.</li>
 *
 * </ul>
 *
 * <p><em>This implementation is preliminary.</em>
 *
 * @see gnu.xml.pipeline.XsltFilter
 *
 * @author David Brownell
 */
public class SAXNullTransformerFactory extends SAXTransformerFactory
{

  private ErrorListener errListener;
  private URIResolver           uriResolver;

  /** Default constructor */
  public SAXNullTransformerFactory () { }

  //
  // only has stuff that makes sense with null transforms
  //

  /**
   * Returns true if the requested feature is supported.
   * All three kinds of input and output are accepted:
   * XML text, SAX events, and DOM nodes.
   */
  public boolean getFeature (String feature)
  {
    return SAXTransformerFactory.FEATURE.equals (feature)
      || SAXResult.FEATURE.equals (feature)
      || SAXSource.FEATURE.equals (feature)
      || DOMResult.FEATURE.equals (feature)
      || DOMSource.FEATURE.equals (feature)
      || StreamResult.FEATURE.equals (feature)
      || StreamSource.FEATURE.equals (feature)
      ;
  }

  public void setFeature(String name, boolean value)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException(name);
  }


  /** Throws an exception (no implementation attributes are supported) */
  public void setAttribute (String key, Object value)
  {
    throw new IllegalArgumentException ();
  }

  /** Throws an exception (no implementation attributes are supported) */
  public Object getAttribute (String key)
  {
    throw new IllegalArgumentException ();
  }

  /** (not yet implemented) */
  public Source getAssociatedStylesheet (Source source,
                                         String media,
                                         String title,
                                         String charset)
    throws TransformerConfigurationException
  {
    // parse, and find the appropriate xsl-stylesheet PI contents
    throw new IllegalArgumentException ();
  }

  public Transformer newTransformer ()
    throws TransformerConfigurationException
  {
    return new NullTransformer ();
  }

  /**
   * Returns a TransformerHandler that knows how to generate output
   * in all three standard formats.  Output text is generated using
   * {@link XMLWriter}, and the GNU implementation of
   * {@link DomDocument DOM} is used.
   *
   * @see SAXResult
   * @see StreamResult
   * @see DOMResult
   */
  public TransformerHandler newTransformerHandler ()
    throws TransformerConfigurationException
  {
    NullTransformer     transformer = new NullTransformer ();
    return transformer.handler;
  }

  //
  // Stuff that depends on XSLT support, which we don't provide
  //
  private static final String           noXSLT = "No XSLT support";

  /** Throws an exception (XSLT is not supported). */
  public Transformer newTransformer (Source stylesheet)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Throws an exception (XSLT is not supported). */
  public Templates newTemplates (Source stylesheet)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Throws an exception (XSLT is not supported). */
  public TemplatesHandler newTemplatesHandler ()
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Throws an exception (XSLT is not supported). */
  public TransformerHandler newTransformerHandler (Source stylesheet)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Throws an exception (XSLT is not supported). */
  public TransformerHandler newTransformerHandler (Templates stylesheet)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Throws an exception (XSLT is not supported). */
  public XMLFilter newXMLFilter (Source stylesheet)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Throws an exception (XSLT is not supported). */
  public XMLFilter newXMLFilter (Templates stylesheet)
    throws TransformerConfigurationException
  {
    throw new TransformerConfigurationException (noXSLT);
  }

  /** Returns the value assigned by {@link #setErrorListener}.  */
  public ErrorListener getErrorListener ()
  {
    return errListener;
  }

  /** Assigns a value that would be used when parsing stylesheets */
  public void setErrorListener (ErrorListener e)
  {
    errListener = e;
  }

  /** Returns the value assigned by {@link #setURIResolver}.  */
  public URIResolver getURIResolver ()
  {
    return uriResolver;
  }

  /** Assigns a value that would be used when parsing stylesheets */
  public void setURIResolver (URIResolver u)
  {
    uriResolver = u;
  }


  //
  // Helper classes.  These might in theory be subclassed
  // by an XSLT implementation, if they were exported.
  //

  static class DomTerminus
    extends DomConsumer
  {

    DomTerminus (DOMResult result)
      throws SAXException
    {
      // won't really throw SAXException
      super (DomDocument.class);
      setHandler (new DomHandler (this, result));
    }

  }

  static class DomHandler
    extends Consumer.Backdoor
  {

    private DOMResult   result;

    DomHandler (DomConsumer c, DOMResult r)
      throws SAXException
    {
      // won't really throw SAXException
      super (c);
      result = r;
    }

    public void endDocument ()
      throws SAXException
    {
      super.endDocument ();
      result.setNode (getDocument ());
    }

  }

  private static OutputStream getOutputStream (String uri)
    throws IOException
  {
    // JDK stupidity:  file "protocol does not support output" ...
    if (uri.startsWith ("file:"))
      return new FileOutputStream (uri.substring (5));

    // Otherwise ...
    URL         url = new URL (uri);
    URLConnection       conn = url.openConnection ();

    conn.setDoOutput (true);
    return conn.getOutputStream ();
  }


  static class NullHandler
    extends EventFilter
    implements TransformerHandler
  {

    private String              systemId;
    private Transformer transformer;

    NullHandler (Transformer t)
    {
      transformer = t;
    }

    public Transformer getTransformer ()
    {
      return transformer;
    }

    public String getSystemId ()
    {
      return systemId;
    }

    public void setSystemId (String id)
    {
      systemId = id;
    }

    public void setResult (Result result)
    {
      if (result.getSystemId () != null)
        systemId = result.getSystemId ();

      try
        {

          // output to partial SAX event stream?
          if (result instanceof SAXResult)
            {
              SAXResult         r = (SAXResult) result;

              setContentHandler (r.getHandler ());
              setProperty (LEXICAL_HANDLER, r.getLexicalHandler ());
              // DTD info is filtered out by javax.transform

              // output to DOM tree?
            }
          else if (result instanceof DOMResult)
            {
              DomTerminus       out = new DomTerminus ((DOMResult) result);

              setContentHandler (out.getContentHandler ());
              setProperty (LEXICAL_HANDLER,
                           out.getProperty (LEXICAL_HANDLER));
              // save DTD-derived info, if any.
              setDTDHandler (out.getDTDHandler ());
              setProperty (DECL_HANDLER,
                           out.getProperty (DECL_HANDLER));

              // node is saved into result on endDocument()

              // output to (XML) text?
            }
          else if (result instanceof StreamResult)
            {
              StreamResult      r = (StreamResult) result;
              XMLWriter         out;

              // FIXME:  when do output properties take effect?
              // encoding, standalone decl, xml/xhtml/... ...

              // FIXME:  maybe put nsfix filter up front

              try
                {
                  if (r.getWriter () != null)
                    out = new XMLWriter (r.getWriter ());
                  else if (r.getOutputStream () != null)
                    out = new XMLWriter (r.getOutputStream ());
                  else if (r.getSystemId () != null)
                    out = new XMLWriter (
                                         getOutputStream (r.getSystemId ()));
                  else
                    throw new IllegalArgumentException (
                                                        "bad StreamResult");
                }
              catch (IOException e)
                {
                  e.printStackTrace ();
                  // on jdk 1.4, pass the root cause ...
                  throw new IllegalArgumentException (e.getMessage ());
                }

              // out.setExpandingEntities (true);
              // out.setPrettyPrinting (true);
              // out.setXhtml (true);

              setContentHandler (out);
              setProperty (LEXICAL_HANDLER, out);
              // save DTD info, if any; why not?
              setDTDHandler (out);
              setProperty (DECL_HANDLER, out);
            }

        }
      catch (SAXException e)
        {
          // SAXNotSupportedException or SAXNotRecognizedException:
          // "can't happen" ... but SAXException for DOM build probs
          // could happen, so ...
          // on jdk 1.4, pass the root cause ...
          throw new IllegalArgumentException (e.getMessage ());
        }
    }
  }

  // an interface that adds no value
  static class LocatorAdapter
    extends LocatorImpl
    implements SourceLocator
  {

    LocatorAdapter (SAXParseException e)
    {
      setSystemId (e.getSystemId ());
      setPublicId (e.getPublicId ());
      setLineNumber (e.getLineNumber ());
      setColumnNumber (e.getColumnNumber ());
    }

  }

  // another interface that adds no value
  static class ListenerAdapter
    implements ErrorHandler
  {

    NullTransformer     transformer;

    ListenerAdapter (NullTransformer t)
    {
      transformer = t;
    }

    private TransformerException map (SAXParseException e)
    {
      return new TransformerException (
                                       e.getMessage (),
                                       new LocatorAdapter (e),
                                       e);
    }

    public void error (SAXParseException e)
      throws SAXParseException
    {
      try
        {
          if (transformer.errListener != null)
            transformer.errListener.error (map (e));
        }
      catch (TransformerException ex)
        {
          transformer.ex = ex;
          throw e;
        }
    }

    public void fatalError (SAXParseException e)
      throws SAXParseException
    {
      try
        {
          if (transformer.errListener != null)
            transformer.errListener.fatalError (map (e));
          else
            throw map (e);
        } catch (TransformerException ex) {
          transformer.ex = ex;
          throw e;
        }
    }

    public void warning (SAXParseException e)
      throws SAXParseException
    {
      try
        {
          if (transformer.errListener != null)
            transformer.errListener.warning (map (e));
        }
      catch (TransformerException ex)
        {
          transformer.ex = ex;
          throw e;
        }
    }
  }

  static class NullTransformer
    extends Transformer
  {

    private URIResolver         uriResolver;
    private Properties          props = new Properties ();
    private Hashtable           params = new Hashtable (7);

    ErrorListener                       errListener = null;
    TransformerException                ex = null;
    NullHandler                 handler;

    NullTransformer ()
    {
      super ();
      handler = new NullHandler (this);
    }

    public ErrorListener getErrorListener ()
    {
      return errListener;
    }

    public void setErrorListener (ErrorListener e)
    {
      errListener = e;
    }

    public URIResolver getURIResolver ()
    {
      return uriResolver;
    }

    public void setURIResolver (URIResolver u)
    {
      uriResolver = u;
    }

    public void setOutputProperties (Properties p)
    {
      props = (Properties) p.clone ();
    }

    public Properties getOutputProperties ()
    {
      return (Properties) props.clone ();
    }

    public void setOutputProperty (String name, String value)
    {
      props.setProperty (name, value);
    }

    public String getOutputProperty (String name)
    {
      return props.getProperty (name);
    }

    public void clearParameters ()
    {
      params.clear ();
    }

    public void setParameter (String name, Object value)
    {
      props.put (name, value);
    }

    public Object getParameter (String name)
    {
      return props.get (name);
    }

    public void transform (Source in, Result out)
      throws TransformerException
    {
      try
        {
          XMLReader             producer;
          InputSource           input;

          // Input from DOM?
          if (in instanceof DOMSource)
            {
              DOMSource source = (DOMSource) in;

              if (source.getNode () == null)
                throw new IllegalArgumentException ("no DOM node");
              producer = new DomParser (source.getNode ());
              input = null;

              // Input from SAX?
            }
          else if (in instanceof SAXSource)
            {
              SAXSource source = (SAXSource) in;

              producer = source.getXMLReader ();
              if (producer == null)
                producer = XMLReaderFactory.createXMLReader ();

              input = source.getInputSource ();
              if (input == null)
                {
                  if (source.getSystemId () != null)
                    input = new InputSource (source.getSystemId ());
                  else
                    throw new IllegalArgumentException (
                                                        "missing SAX input");
                }

              // Input from a stream or something?
            }
          else
            {
              producer = XMLReaderFactory.createXMLReader ();
              input = SAXSource.sourceToInputSource (in);
              if (input == null)
                throw new IllegalArgumentException ("missing input");
            }

          // preserve original namespace prefixes
          try
            {
              producer.setFeature(EventFilter.FEATURE_URI +
                                  "namespace-prefixes",
                                  true);
            }
          catch (Exception e)
            {
              /* ignore */
              // FIXME if we couldn't, "NsFix" stage before the output ..
            }

          // arrange the output
          handler.setResult (out);
          EventFilter.bind (producer, handler);

          // then parse ... single element pipeline
          producer.parse (input);

        }
      catch (IOException e)
        {
          throw new TransformerException ("transform failed", e);

        }
      catch (SAXException e)
        {
          if (ex == null && ex.getCause () == e)
            throw ex;
          else
            throw new TransformerException ("transform failed", e);

        }
      finally
        {
          ex = null;
        }
    }
  }

}
