/* TransformerFactoryImpl.java -- 
   Copyright (C) 2004,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.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.XMLFilter;
import gnu.xml.dom.DomDocument;

/**
 * GNU transformer factory implementation.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
public class TransformerFactoryImpl
  extends SAXTransformerFactory
{

  final XPathFactory xpathFactory;
  final XSLURIResolver resolver;
  ErrorListener userListener;
  URIResolver userResolver;

  public TransformerFactoryImpl()
  {
    xpathFactory = new gnu.xml.xpath.XPathFactoryImpl();
    resolver = new XSLURIResolver();
  }

  public Transformer newTransformer(Source source)
    throws TransformerConfigurationException
  {
    Stylesheet stylesheet = newStylesheet(source, 0, null);
    Properties outputProperties =
      new TransformerOutputProperties(stylesheet);
    TransformerImpl transformer =
      new TransformerImpl(this, stylesheet, outputProperties);
    stylesheet.transformer = transformer;
    return transformer;
  }

  public Transformer newTransformer()
    throws TransformerConfigurationException
  {
    return new TransformerImpl(this, null, new Properties());
  }

  public Templates newTemplates(Source source)
    throws TransformerConfigurationException
  {
    Stylesheet stylesheet = newStylesheet(source, 0, null);
    return new TemplatesImpl(this, stylesheet);
  }

  Stylesheet newStylesheet(Source source, int precedence, Stylesheet parent)
    throws TransformerConfigurationException
  {
    Document doc = null;
    String systemId = null;
    if (source != null)
      {
        try
          {
            DOMSource ds;
            synchronized (resolver)
              {
                resolver.setUserResolver(userResolver);
                resolver.setUserListener(userListener);
                ds = resolver.resolveDOM(source, null, null);
              }
            Node node = ds.getNode();
            if (node == null)
              {
                throw new TransformerConfigurationException("no source document");
              }
            doc = (node instanceof Document) ? (Document) node :
              node.getOwnerDocument();
            systemId = ds.getSystemId();
          }
        catch (TransformerException e)
          {
            throw new TransformerConfigurationException(e);
          }
      }
    return new Stylesheet(this, parent, doc, systemId, precedence);
  }
  
  public Source getAssociatedStylesheet(Source source,
                                        String media,
                                        String title,
                                        String charset)
    throws TransformerConfigurationException
  {
    try
      {
        DOMSource ds;
        synchronized (resolver)
          {
            resolver.setUserResolver(userResolver);
            resolver.setUserListener(userListener);
            ds = resolver.resolveDOM(source, null, null);
          }
        Node node = ds.getNode();
        if (node == null)
          {
            throw new TransformerConfigurationException("no source document");
          }
        Document doc = (node instanceof Document) ? (Document) node :
          node.getOwnerDocument();
        LinkedList matches = new LinkedList();
        for (node = doc.getFirstChild();
             node != null;
             node = node.getNextSibling())
          {
            if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
                "xml-stylesheet".equals(node.getNodeName()))
              {
                Map params = parseParameters(node.getNodeValue());
                if (media != null && !media.equals(params.get("media")))
                  {
                    continue;
                  }
                if (title != null && !title.equals(params.get("title")))
                  {
                    continue;
                  }
                if (charset != null && !charset.equals(params.get("charset")))
                  {
                    continue;
                  }
                String href = (String) params.get("href");
                URL url = resolver.resolveURL(null, node.getBaseURI(), href);
                matches.add(url);
              }
          }
        switch (matches.size())
          {
          case 0:
            return null;
          case 1:
            return new StreamSource(((URL) matches.getFirst()).toString());
          default:
            // Create a source representing a stylesheet with a list of
            // imports
            DomDocument ssDoc = new DomDocument();
            ssDoc.setBuilding(true);
            // Create document element
            Node root =
              ssDoc.createElementNS(Stylesheet.XSL_NS, "stylesheet");
            Node version =
              ssDoc.createAttributeNS(null, "version");
            version.setNodeValue("1.0");
            root.getAttributes().setNamedItemNS(version);
            ssDoc.appendChild(root);
            // Create xsl:import for each URL
            for (Iterator i = matches.iterator(); i.hasNext(); )
              {
                URL url = (URL) i.next();
                Node imp =
                  ssDoc.createElementNS(Stylesheet.XSL_NS, "import");
                Node href =
                  ssDoc.createAttributeNS(null, "href");
                href.setNodeValue(url.toString());
                imp.getAttributes().setNamedItemNS(href);
                root.appendChild(imp);
              }
            ssDoc.setBuilding(false);
            return new DOMSource(ssDoc);
          }
      }
    catch (IOException e)
      {
        throw new TransformerConfigurationException(e);
      }
    catch (TransformerException e)
      {
        throw new TransformerConfigurationException(e);
      }
  }

  Map parseParameters(String data)
  {
    Map ret = new LinkedHashMap();
    int len = data.length();
    String key = null;
    int start = 0;
    char quoteChar = '\u0000';
    for (int i = 0; i < len; i++)
      {
        char c = data.charAt(i);
        if (quoteChar == '\u0000' && c == ' ')
          {
            if (key == null && start < i)
              {
                key = data.substring(start, i);
              }
            else
              {
                String val = unquote(data.substring(start, i).trim());
                ret.put(key, val);
                key = null;
              }
            start = i + 1;
          }
        else if (c == '"')
          {
            quoteChar = (quoteChar == c) ? '\u0000' : c;
          }
        else if (c == '\'')
          {
            quoteChar = (quoteChar == c) ? '\u0000' : c;
          }
      }
    if (start < len && key != null)
      {
        String val = unquote(data.substring(start, len).trim());
        ret.put(key, val);
      }
    return ret;
  }

  String unquote(String text)
  {
    int end = text.length() - 1;
    if (text.charAt(0) == '\'' && text.charAt(end) == '\'')
      {
        return text.substring(1, end);
      }
    if (text.charAt(0) == '"' && text.charAt(end) == '"')
      {
        return text.substring(1, end);
      }
    return text;
  }

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

  public URIResolver getURIResolver()
  {
    return userResolver;
  }

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

  public boolean getFeature(String name)
  {
    if (SAXSource.FEATURE.equals(name) ||
        SAXResult.FEATURE.equals(name) ||
        StreamSource.FEATURE.equals(name) ||
        StreamResult.FEATURE.equals(name) ||
        DOMSource.FEATURE.equals(name) ||
        DOMResult.FEATURE.equals(name) ||
        SAXTransformerFactory.FEATURE.equals(name))
      {
        return true;
      }
    return false;
  }

  public void setAttribute(String name, Object value)
    throws IllegalArgumentException
  {
    throw new IllegalArgumentException("not supported");
  }

  public Object getAttribute(String name)
    throws IllegalArgumentException
  {
    throw new IllegalArgumentException("not supported");
  }

  public void setErrorListener(ErrorListener listener)
    throws IllegalArgumentException
  {
    userListener = listener;
  }

  public ErrorListener getErrorListener()
  {
    return userListener;
  }

  // -- SAXTransformerFactory --

  public TemplatesHandler newTemplatesHandler()
    throws TransformerConfigurationException
  {
    return new SAXTemplatesHandler(this);
  }

  public TransformerHandler newTransformerHandler()
    throws TransformerConfigurationException
  {
    Transformer transformer = newTransformer();
    return new SAXTransformerHandler(this, transformer);
  }
  
  public TransformerHandler newTransformerHandler(Source source)
    throws TransformerConfigurationException
  {
    Transformer transformer = newTransformer(source);
    return new SAXTransformerHandler(this, transformer);
  }
  
  public TransformerHandler newTransformerHandler(Templates templates)
    throws TransformerConfigurationException
  {
    Transformer transformer = templates.newTransformer();
    return new SAXTransformerHandler(this, transformer);
  }

  public XMLFilter newXMLFilter(Source source)
    throws TransformerConfigurationException
  {
    throw new UnsupportedOperationException();
  }

  public XMLFilter newXMLFilter(Templates templates)
    throws TransformerConfigurationException
  {
    throw new UnsupportedOperationException();
  }
  
  // -- SAXTransformerFactory end --

  /**
   * Syntax: TransformerFactoryImpl [<stylesheet> [<input> [<output>]]]
   */
  public static void main(String[] args)
    throws Exception
  {
    InputStream stylesheet = null, in = null;
    OutputStream out = null;
    try
      {
        if (args.length > 0)
          {
            stylesheet = new FileInputStream(args[0]);
            if (args.length > 1)
              {
                in = new FileInputStream(args[1]);
                if (args.length > 2)
                  out = new FileOutputStream(args[2]);
              }
          }
        if (in == null)
          in = System.in;
        if (out == null)
          out = System.out;
        TransformerFactory f = new TransformerFactoryImpl();
        Transformer t = (stylesheet != null) ?
          f.newTransformer(new StreamSource(stylesheet)) :
          f.newTransformer();
        t.transform(new StreamSource(in), new StreamResult(out));
      }
    finally
      {
        if (stylesheet != null)
          stylesheet.close();
        if (in != null && in instanceof FileInputStream)
          in.close();
        if (out != null && out instanceof FileOutputStream)
          out.close();
      }
  }
  
}
