/* TransformerImpl.java -- 
   Copyright (C) 2004,2005,2006 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.transform;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.UnknownServiceException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.xml.namespace.QName;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import gnu.xml.dom.DomDoctype;
import gnu.xml.dom.DomDocument;
import gnu.xml.dom.ls.WriterOutputStream;

/**
 * The transformation process for a given stylesheet.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class TransformerImpl
  extends Transformer
{

  final TransformerFactoryImpl factory;
  final Stylesheet stylesheet;
  URIResolver uriResolver;
  ErrorListener errorListener;
  Properties outputProperties;

  TransformerImpl(TransformerFactoryImpl factory,
                  Stylesheet stylesheet,
                  Properties outputProperties)
    throws TransformerConfigurationException
  {
    this.factory = factory;
    uriResolver = factory.userResolver;
    errorListener = factory.userListener;
    this.stylesheet = stylesheet;
    this.outputProperties = outputProperties;
    if (stylesheet != null)
      {
        // Set up parameter context for this transformer
        stylesheet.bindings.push(Bindings.PARAM);
      }
  }

  public void transform(Source xmlSource, Result outputTarget)
    throws TransformerException
  {
    // Get the source tree
    DOMSource source;
    synchronized (factory.resolver)
      {
        factory.resolver.setUserResolver(uriResolver);
        factory.resolver.setUserListener(errorListener);
        source = factory.resolver.resolveDOM(xmlSource, null, null);
      }
    Node context = source.getNode();
    Document doc = (context instanceof Document) ? (Document) context :
      context.getOwnerDocument();
    if (doc instanceof DomDocument)
      {
        // Suppress mutation events
        ((DomDocument) doc).setBuilding(true);
      }
    // Get the result tree
    Node parent = null, nextSibling = null;
    if (outputTarget instanceof DOMResult)
      {
        DOMResult dr = (DOMResult) outputTarget;
        parent = dr.getNode();
        nextSibling = dr.getNextSibling();

        Document rdoc = (parent instanceof Document) ? (Document) parent :
          parent.getOwnerDocument();
        if (rdoc instanceof DomDocument)
          {
            // Suppress mutation events and allow multiple root elements
            DomDocument drdoc = (DomDocument) rdoc;
            drdoc.setBuilding(true);
            drdoc.setCheckWellformedness(false);
          }
      }
    boolean created = false;
    // Transformation
    if (stylesheet != null)
      {
        if (parent == null)
          {
            // Create a new document to hold the result
            DomDocument resultDoc = new DomDocument();
            resultDoc.setBuilding(true);
            resultDoc.setCheckWellformedness(false);
            parent = resultDoc;
            created = true;
          }
        // Make a copy of the source node, and strip it
        context = context.cloneNode(true);
        strip(stylesheet, context);
        // XSLT transformation
        try
          {
            // Set output properties in the underlying stylesheet
            ((TransformerOutputProperties) outputProperties).apply();
            stylesheet.initTopLevelVariables(context);
            TemplateNode t = stylesheet.getTemplate(null, context, false);
            if (t != null)
              {
                stylesheet.current = context;
                t.apply(stylesheet, null, context, 1, 1, parent, nextSibling);
              }
          }
        catch (TransformerException e)
          {
            // Done transforming, reset document
            if (doc instanceof DomDocument)
              ((DomDocument) doc).setBuilding(false);
            throw e;
          }
      }
    else
      {
        // Identity transform
        Node clone = context.cloneNode(true);
        if (context.getNodeType() != Node.DOCUMENT_NODE)
          {
            Document resultDoc;
            if (parent == null)
              {
                // Create a new document to hold the result
                DomDocument rd = new DomDocument();
                rd.setBuilding(true);
                rd.setCheckWellformedness(false);
                parent = resultDoc = rd;
                created = true;
              }
            else
              {
                resultDoc = (parent instanceof Document) ?
                  (Document) parent :
                  parent.getOwnerDocument();
              }
            Document sourceDoc = context.getOwnerDocument();
            if (sourceDoc != resultDoc)
              clone = resultDoc.adoptNode(clone);
            if (nextSibling != null)
              parent.insertBefore(clone, nextSibling);
            else
              parent.appendChild(clone);
          }
        else
          {
            // Cannot append document to another tree
            parent = clone;
            created = true;
          }
      }
    String method = outputProperties.getProperty(OutputKeys.METHOD);
    int outputMethod = "html".equals(method) ? Stylesheet.OUTPUT_HTML :
      "text".equals(method) ? Stylesheet.OUTPUT_TEXT :
      Stylesheet.OUTPUT_XML;
    String encoding = outputProperties.getProperty(OutputKeys.ENCODING);
    String publicId = outputProperties.getProperty(OutputKeys.DOCTYPE_PUBLIC);
    String systemId = outputProperties.getProperty(OutputKeys.DOCTYPE_SYSTEM);
    String version = outputProperties.getProperty(OutputKeys.VERSION);
    boolean omitXmlDeclaration = 
      "yes".equals(outputProperties.getProperty(OutputKeys.OMIT_XML_DECLARATION));
    boolean standalone = 
      "yes".equals(outputProperties.getProperty(OutputKeys.STANDALONE));
    String mediaType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
    String cdataSectionElements =
      outputProperties.getProperty(OutputKeys.CDATA_SECTION_ELEMENTS);
    boolean indent =
      "yes".equals(outputProperties.getProperty(OutputKeys.INDENT));
    if (created && parent instanceof DomDocument)
      {
        // Discover document element
        DomDocument resultDoc = (DomDocument) parent;
        Node root = resultDoc.getDocumentElement();
        // Add doctype if specified
        if (publicId != null || systemId != null)
          {
            if (root != null)
              {
                // We must know the name of the root element to
                // create the document type
                DocumentType doctype = new DomDoctype(resultDoc,
                                                      root.getNodeName(),
                                                      publicId,
                                                      systemId);
                resultDoc.insertBefore(doctype, root);
              }
          }
        resultDoc.setBuilding(false);
        resultDoc.setCheckWellformedness(true);
      }
    else if (publicId != null || systemId != null)
      {
        switch (parent.getNodeType())
          {
          case Node.DOCUMENT_NODE:
          case Node.DOCUMENT_FRAGMENT_NODE:
            Document resultDoc = (parent instanceof Document) ?
              (Document) parent :
              parent.getOwnerDocument();
            DOMImplementation impl = resultDoc.getImplementation();
            Node root = resultDoc.getDocumentElement();
            if (root != null)
              {
                DocumentType doctype =
                  impl.createDocumentType(root.getNodeName(),
                                          publicId,
                                          systemId);
                resultDoc.insertBefore(doctype, root);
              }
          }
      }
    if (version != null)
      parent.setUserData("version", version, stylesheet);
    if (omitXmlDeclaration)
      parent.setUserData("omit-xml-declaration", "yes", stylesheet);
    if (standalone)
      parent.setUserData("standalone", "yes", stylesheet);
    if (mediaType != null)
      parent.setUserData("media-type", mediaType, stylesheet);
    if (cdataSectionElements != null)
      {
        List list = new LinkedList();
        StringTokenizer st = new StringTokenizer(cdataSectionElements);
        while (st.hasMoreTokens())
          {
            String name = st.nextToken();
            String localName = name;
            String uri = null;
            String prefix = null;
            int ci = name.indexOf(':');
            if (ci != -1)
              {
                // Use namespaces defined on xsl:output node to resolve
                // namespaces for QName
                prefix = name.substring(0, ci);
                localName = name.substring(ci + 1);
                uri = stylesheet.output.lookupNamespaceURI(prefix);
              }
            list.add(new QName(uri, localName, prefix));
          }
        if (!list.isEmpty())
          {
            Document resultDoc = (parent instanceof Document) ?
              (Document) parent :
              parent.getOwnerDocument();
            convertCdataSectionElements(resultDoc, parent, list);
          }
      }
    if (indent)
      {
        if (created && parent instanceof DomDocument)
          {
            DomDocument domDoc = (DomDocument) parent;
            domDoc.setBuilding(true);
            domDoc.setCheckWellformedness(false);
          }
        parent.normalize();
        if (stylesheet != null)
          strip(stylesheet, parent);
        Document resultDoc = (parent instanceof Document) ?
          (Document) parent :
          parent.getOwnerDocument();
        reindent(resultDoc, parent, 0);
        if (created && parent instanceof DomDocument)
          {
            DomDocument domDoc = (DomDocument) parent;
            domDoc.setBuilding(false);
            domDoc.setCheckWellformedness(true);
          }
      }
    // Render result to the target device
    if (outputTarget instanceof DOMResult)
      {
        if (created)
          {
            DOMResult dr = (DOMResult) outputTarget;
            dr.setNode(parent);
            dr.setNextSibling(null);
          }
      }
    else if (outputTarget instanceof StreamResult)
      {
        StreamResult sr = (StreamResult) outputTarget;
        IOException ex = null;
        try
          {
            writeStreamResult(parent, sr, outputMethod, encoding);
          }
        catch (UnsupportedEncodingException e)
          {
            try
              {
                writeStreamResult(parent, sr, outputMethod, "UTF-8");
              }
            catch (IOException e2)
              {
                ex = e2;
              }
          }
        catch (IOException e)
          {
            ex = e;
          }
        if (ex != null)
          {
            if (errorListener != null)
              errorListener.error(new TransformerException(ex));
            else
              ex.printStackTrace(System.err);
          }
      }
    else if (outputTarget instanceof SAXResult)
      {
        SAXResult sr = (SAXResult) outputTarget;
        try
          {
            ContentHandler ch = sr.getHandler();
            LexicalHandler lh = sr.getLexicalHandler();
            if (lh == null && ch instanceof LexicalHandler)
              lh = (LexicalHandler) ch;
            SAXSerializer serializer = new SAXSerializer();
            serializer.serialize(parent, ch, lh);
          }
        catch (SAXException e)
          {
            if (errorListener != null)
              errorListener.error(new TransformerException(e));
            else
              e.printStackTrace(System.err);
          }
      }
  }

  /**
   * Strip whitespace from the source tree.
   */
  static boolean strip(Stylesheet stylesheet, Node node)
    throws TransformerConfigurationException
  {
    short nt = node.getNodeType();
    if (nt == Node.ENTITY_REFERENCE_NODE)
      {
        // Replace entity reference with its content
        Node parent = node.getParentNode();
        Node nextSibling = node.getNextSibling();
        Node child = node.getFirstChild();
        while (child != null)
          {
            Node next = child.getNextSibling();
            node.removeChild(child);
            if (nextSibling != null)
              parent.insertBefore(child, nextSibling);
            else
              parent.appendChild(child);
            child = next;
          }
        return true;
      }
    if (nt == Node.TEXT_NODE || nt == Node.CDATA_SECTION_NODE)
      {
        // Denormalize text into whitespace and non-whitespace nodes
        String text = node.getNodeValue();
        String[] tokens = tokenizeWhitespace(text);
        if (tokens.length > 1)
          {
            node.setNodeValue(tokens[0]);
            Node parent = node.getParentNode();
            Node nextSibling = node.getNextSibling();
            Document doc = node.getOwnerDocument();
            for (int i = 1; i < tokens.length; i++)
              {
                Node newChild = (nt == Node.CDATA_SECTION_NODE) ?
                  doc.createCDATASection(tokens[i]) :
                  doc.createTextNode(tokens[i]);
                if (nextSibling != null)
                  parent.insertBefore(newChild, nextSibling);
                else
                  parent.appendChild(newChild);
              }
          }
        return !stylesheet.isPreserved((Text) node, true);
      }
    else
      {
        Node child = node.getFirstChild();
        while (child != null)
          {
            boolean remove = strip(stylesheet, child);
            Node next = child.getNextSibling();
            if (remove)
              node.removeChild(child);
            child = next;
          }
      }
    return false;
  }

  /**
   * Tokenize the specified text into contiguous whitespace-only and
   * non-whitespace chunks.
   */
  private static String[] tokenizeWhitespace(String text)
  {
    int len = text.length();
    int start = 0, end = len - 1;
    // Find index of text start
    for (int i = 0; i < len; i++)
      {
        char c = text.charAt(i);
        boolean whitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r');
        if (whitespace)
          start++;
        else
          break;
      }
    if (start == end) // all whitespace
      return new String[] { text };
    // Find index of text end
    for (int i = end; i > start; i--)
      {
        char c = text.charAt(i);
        boolean whitespace = (c == ' ' || c == '\n' || c == '\t' || c == '\r');
        if (whitespace)
          end--;
        else
          break;
      }
    if (start == 0 && end == len - 1) // all non-whitespace
      return new String[] { text };
    // whitespace, then text, then whitespace
    String[] ret = (start > 0 && end < len - 1) ?
      new String[3] : new String[2];
    int i = 0;
    if (start > 0)
      ret[i++] = text.substring(0, start);
    ret[i++] = text.substring(start, end + 1);
    if (end < len - 1)
      ret[i++] = text.substring(end + 1);
    return ret;
  }

  /**
   * Obtain a suitable output stream for writing the result to,
   * and use the StreamSerializer to write the result tree to the stream.
   */
  void writeStreamResult(Node node, StreamResult sr, int outputMethod,
                         String encoding)
    throws IOException
  {
    OutputStream out = null;
    boolean created = false;
    try
      {
        out = sr.getOutputStream();
        if (out == null)
          {
            Writer writer = sr.getWriter();
            if (writer != null)
              out = new WriterOutputStream(writer);
          }
        if (out == null)
          {
            String systemId = sr.getSystemId();
            try
              {
                URL url = new URL(systemId);
                URLConnection connection = url.openConnection();
                // We need to call setDoInput(false), because our
                // implementation of the file protocol allows writing
                // (unlike Sun), but it will fail with a FileNotFoundException
                // if we also open the connection for input and the output
                // file doesn't yet exist.
                connection.setDoInput(false);
                connection.setDoOutput(true);
                out = connection.getOutputStream();
              }
            catch (MalformedURLException e)
              {
                out = new FileOutputStream(systemId);
              }
            catch (UnknownServiceException e)
              {
                URL url = new URL(systemId);
                out = new FileOutputStream(url.getPath());
              }
            created = true;
          }
        out = new BufferedOutputStream(out);
        StreamSerializer serializer =
          new StreamSerializer(outputMethod, encoding, null);
        if (stylesheet != null)
          {
            Collection celem = stylesheet.outputCdataSectionElements;
            serializer.setCdataSectionElements(celem);
          }
        serializer.serialize(node, out);
        out.flush();
      }
    finally
      {
        try
          {
            if (out != null && created)
              out.close();
          }
        catch (IOException e)
          {
            if (errorListener != null)
              {
                try
                  {
                    errorListener.error(new TransformerException(e));
                  }
                catch (TransformerException e2)
                  {
                    e2.printStackTrace(System.err);
                  }
              }
            else
              e.printStackTrace(System.err);
          }
      }
  }

  void copyChildren(Document dstDoc, Node src, Node dst)
  {
    Node srcChild = src.getFirstChild();
    while (srcChild != null)
      {
        Node dstChild = dstDoc.adoptNode(srcChild);
        dst.appendChild(dstChild);
        srcChild = srcChild.getNextSibling();
      }
  }

  public void setParameter(String name, Object value)
  {
    if (stylesheet != null)
      stylesheet.bindings.set(new QName(null, name), value, Bindings.PARAM);
  }

  public Object getParameter(String name)
  {
    if (stylesheet != null)
      return stylesheet.bindings.get(new QName(null, name), null, 1, 1);
    return null;
  }

  public void clearParameters()
  {
    if (stylesheet != null)
      {
        stylesheet.bindings.pop(Bindings.PARAM);
        stylesheet.bindings.push(Bindings.PARAM);
      }
  }

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

  public URIResolver getURIResolver()
  {
    return uriResolver;
  }

  public void setOutputProperties(Properties oformat)
    throws IllegalArgumentException
  {
    if (oformat == null)
      outputProperties.clear();
    else
      outputProperties.putAll(oformat);
  }

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

  public void setOutputProperty(String name, String value)
    throws IllegalArgumentException
  {
    outputProperties.put(name, value);
  }

  public String getOutputProperty(String name)
    throws IllegalArgumentException
  {
    return outputProperties.getProperty(name);
  }

  public void setErrorListener(ErrorListener listener)
  {
    errorListener = listener;
  }

  public ErrorListener getErrorListener()
  {
    return errorListener;
  }

  static final String INDENT_WHITESPACE = "  ";

  /*
   * Apply indent formatting to the given tree.
   */
  void reindent(Document doc, Node node, int offset)
  {
    if (node.hasChildNodes())
      {
        boolean markupContent = false;
        boolean textContent = false;
        List children = new LinkedList();
        Node ctx = node.getFirstChild();
        while (ctx != null)
          {
            switch (ctx.getNodeType())
              {
              case Node.ELEMENT_NODE:
              case Node.PROCESSING_INSTRUCTION_NODE:
              case Node.DOCUMENT_TYPE_NODE:
                markupContent = true;
                break;
              case Node.TEXT_NODE:
              case Node.CDATA_SECTION_NODE:
              case Node.ENTITY_REFERENCE_NODE:
              case Node.COMMENT_NODE:
                textContent = true;
                break;
              }
            children.add(ctx);
            ctx = ctx.getNextSibling();
          }
        if (markupContent)
          {
            if (textContent)
              {
                // XXX handle mixed content differently?
              }
            int nodeType = node.getNodeType();
            if (nodeType == Node.DOCUMENT_NODE)
              {
                for (Iterator i = children.iterator(); i.hasNext(); )
                  {
                    ctx = (Node) i.next();
                    reindent(doc, ctx, offset);
                  }
              }
            else
              {
                StringBuffer buf = new StringBuffer();
                buf.append('\n');
                for (int i = 0; i < offset + 1; i++)
                  buf.append(INDENT_WHITESPACE);
                String ws = buf.toString();
                for (Iterator i = children.iterator(); i.hasNext(); )
                  {
                    ctx = (Node) i.next();
                    node.insertBefore(doc.createTextNode(ws), ctx);
                    reindent(doc, ctx, offset + 1);
                  }
                buf = new StringBuffer();
                buf.append('\n');
                for (int i = 0; i < offset; i++)
                  buf.append(INDENT_WHITESPACE);
                ws = buf.toString();
                node.appendChild(doc.createTextNode(ws));
              }
          }
      }
  }

  /**
   * Converts the text node children of any cdata-section-elements in the
   * tree to CDATA section nodes.
   */
  void convertCdataSectionElements(Document doc, Node node, List list)
  {
    if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        boolean match = false;
        for (Iterator i = list.iterator(); i.hasNext(); )
          {
            QName qname = (QName) i.next();
            if (match(qname, node))
              {
                match = true;
                break;
              }
          }
        if (match)
          {
            Node ctx = node.getFirstChild();
            while (ctx != null)
              {
                if (ctx.getNodeType() == Node.TEXT_NODE)
                  {
                    Node cdata = doc.createCDATASection(ctx.getNodeValue());
                    node.replaceChild(cdata, ctx);
                    ctx = cdata;
                  }
                ctx = ctx.getNextSibling();
              }
          }
      }
    Node ctx = node.getFirstChild();
    while (ctx != null)
      {
        if (ctx.hasChildNodes())
          convertCdataSectionElements(doc, ctx, list);
        ctx = ctx.getNextSibling();
      }
  }

  boolean match(QName qname, Node node)
  {
    String ln1 = qname.getLocalPart();
    String ln2 = node.getLocalName();
    if (ln2 == null)
      return ln1.equals(node.getNodeName());
    else
      {
        String uri1 = qname.getNamespaceURI();
        String uri2 = node.getNamespaceURI();
        return (uri1.equals(uri2) && ln1.equals(ln2));
      }
  }

}
