/* XIncludeFilter.java -- 
   Copyright (C) 2005  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.stream;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.ReaderDelegate;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.TypeInfo;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.TreeWalker;
import org.w3c.dom.xpath.XPathEvaluator;
import org.w3c.dom.xpath.XPathNSResolver;
import org.w3c.dom.xpath.XPathResult;
import org.xml.sax.SAXException;

/**
 * StAX filter for performing XInclude processing.
 *
 * @see http://www.w3.org/TR/xinclude/
 * @see http://www.w3.org/TR/xptr-framework/
 * @see http://www.w3.org/TR/xptr-element/
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class XIncludeFilter
  extends ReaderDelegate
{

  static final String XINCLUDE_NS_URI = "http://www.w3.org/2001/XInclude";
  static final int SHOW_FLAGS =
    NodeFilter.SHOW_CDATA_SECTION |
    NodeFilter.SHOW_COMMENT |
    NodeFilter.SHOW_ELEMENT |
    NodeFilter.SHOW_ENTITY_REFERENCE |
    NodeFilter.SHOW_PROCESSING_INSTRUCTION |
    NodeFilter.SHOW_TEXT;

  final String systemId;
  final boolean namespaceAware;
  final boolean validating;
  final boolean expandERefs;
  String href;
  int event;
  boolean included;
  XPathResult result;
  int snapshotIndex;
  Node current;
  TreeWalker walker;
  HashSet seen = new HashSet();
  boolean backtracking;
  boolean lookahead;
  
  Reader includedText;
  char[] buf;
  int len = -1;
  boolean inInclude, inFallback, seenFallback;

  DocumentBuilder builder;

  XIncludeFilter(XMLStreamReader reader, String systemId,
                 boolean namespaceAware, boolean validating,
                 boolean expandERefs)
  {
    super(reader);
    try
      {
        this.systemId = XMLParser.absolutize(null, systemId);
      }
    catch (MalformedURLException e)
      {
        RuntimeException e2 = new RuntimeException("unsupported URL: " +
                                                   systemId);
        e2.initCause(e);
        throw e2;
      }
    this.namespaceAware = namespaceAware;
    this.validating = validating;
    this.expandERefs = expandERefs;
  }

  public int getAttributeCount()
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        return (attrs == null) ? 0 : attrs.getLength();
      }
    return super.getAttributeCount();
  }

  public String getAttributeLocalName(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Node attr = attrs.item(index);
        return attr.getLocalName();
      }
    return super.getAttributeLocalName(index);
  }

  public String getAttributeNamespace(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Node attr = attrs.item(index);
        return attr.getNamespaceURI();
      }
    return super.getAttributeNamespace(index);
  }

  public String getAttributePrefix(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Node attr = attrs.item(index);
        return attr.getPrefix();
      }
    return super.getAttributePrefix(index);
  }

  public QName getAttributeName(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Node attr = attrs.item(index);
        String localName = attr.getLocalName();
        String uri = attr.getNamespaceURI();
        String prefix = attr.getPrefix();
        return new QName(uri, localName, prefix);
      }
    return super.getAttributeName(index);
  }

  public String getAttributeType(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Attr attr = (Attr) attrs.item(index);
        TypeInfo ti = attr.getSchemaTypeInfo();
        return (ti == null) ? "CDATA" : ti.getTypeName();
      }
    return super.getAttributeType(index);
  }

  public boolean isAttributeSpecified(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
          return false;
        Attr attr = (Attr) attrs.item(index);
        return attr.getSpecified();
      }
    return super.isAttributeSpecified(index);
  }

  public String getAttributeValue(int index)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Node attr = attrs.item(index);
        return attr.getNodeValue();
      }
    return super.getAttributeValue(index);
  }

  public String getAttributeValue(String uri, String localName)
  {
    if (current != null)
      {
        NamedNodeMap attrs = current.getAttributes();
        if (attrs == null)
         return null;
        Node attr = attrs.getNamedItemNS(uri, localName);
        return (attr == null) ? null : attr.getNodeValue();
      }
    return super.getAttributeValue(uri, localName);
  }

  public String getElementText()
    throws XMLStreamException
  {
    if (current != null)
      return current.getTextContent();
    return super.getElementText();
  }

  public int getEventType()
  {
    return event;
  }

  public String getLocalName()
  {
    if (current != null)
      return current.getLocalName();
    return super.getLocalName();
  }

  public QName getName()
  {
    if (current != null)
      {
        String localName = current.getLocalName();
        String uri = current.getNamespaceURI();
        String prefix = current.getPrefix();
        return new QName(uri, localName, prefix);
      }
    return super.getName();
  }

  public String getNamespaceURI()
  {
    if (current != null)
      return current.getNamespaceURI();
    return super.getNamespaceURI();
  }

  // TODO namespaces

  public String getPIData()
  {
    if (current != null)
      return ((ProcessingInstruction) current).getData();
    return super.getPIData();
  }

  public String getPITarget()
  {
    if (current != null)
      return ((ProcessingInstruction) current).getTarget();
    return super.getPITarget();
  }

  public String getPrefix()
  {
    if (current != null)
      return current.getPrefix();
    return super.getPrefix();
  }

  public String getText()
  {
    if (current != null)
      return current.getNodeValue();
    if (walker != null)
      {
        Node n = walker.getCurrentNode();
        if (n != null)
          return n.getTextContent();
      }
    if (buf != null)
      return new String(buf, 0, len);
    return super.getText();
  }

  public char[] getTextCharacters()
  {
    if (current != null)
      {
        buf = current.getNodeValue().toCharArray();
        len = buf.length;
      }
    if (buf != null)
      return buf;
    return super.getTextCharacters();
  }

  public int getTextCharacters(int sourceStart, char[] target,
                               int targetStart, int length)
    throws XMLStreamException
  {
    if (current != null)
      {
        buf = current.getNodeValue().toCharArray();
        len = buf.length;
      }
    if (buf != null)
      {
        int max = Math.min(len - sourceStart, length);
        if (max > 0)
          System.arraycopy(buf, sourceStart, target, targetStart, max);
        return max;
      }
    return super.getTextCharacters(sourceStart, target, targetStart, length);
  }

  public int getTextLength()
  {
    if (current != null)
      {
        buf = current.getNodeValue().toCharArray();
        len = buf.length;
      }
    if (buf != null)
      return len;
    return super.getTextLength();
  }

  public int getTextStart()
  {
    if (current != null)
      {
        buf = current.getNodeValue().toCharArray();
        len = buf.length;
      }
    if (buf != null)
      return 0;
    return super.getTextStart();
  }

  public boolean hasNext()
    throws XMLStreamException
  {
    if (!lookahead)
      {
        try
          {
            next();
          }
        catch (NoSuchElementException e)
          {
            event = -1;
          }
        lookahead = true;
      }
    return (event != -1);
  }

  public int next()
    throws XMLStreamException
  {
    if (lookahead)
      {
        lookahead = false;
        return event;
      }
    buf = null;
    len = 0;
    if (walker != null)
      {
        Node c = walker.getCurrentNode();
        Node n = null;
        if (c.getNodeType() == Node.ELEMENT_NODE)
          {
            boolean isStartElement = !seen.contains(c);
            if (isStartElement)
              {
                seen.add(c);
                current = c;
                event = XMLStreamConstants.START_ELEMENT;
                return event;
              }
            else if (backtracking)
              {
                n = walker.nextSibling();
                if (n != null)
                  backtracking = false;
              }
            else
              {
                n = walker.firstChild();
                if (n == null)
                  n = walker.nextSibling();
              }
          }
        else
          {
            n = walker.firstChild();
            if (n == null)
              n = walker.nextSibling();
          }
        if (n == null)
          {
            current = walker.parentNode();
            if (current != null && current.getNodeType() == Node.ELEMENT_NODE)
              {
                // end-element
                backtracking = true;
                event = XMLStreamConstants.END_ELEMENT;
                return event;
              }
            else
              {
                walker = null;
                current = null;
              }
          }
        else
          {
            current = n;
            switch (n.getNodeType())
              {
              case Node.ELEMENT_NODE:
                return next();
              case Node.TEXT_NODE:
                String text = n.getNodeValue();
                buf = text.toCharArray();
                len = buf.length;
                event = isSpace(buf, len) ?
                  XMLStreamConstants.SPACE :
                  XMLStreamConstants.CHARACTERS;
                return event;
              case Node.CDATA_SECTION_NODE:
                event = XMLStreamConstants.CDATA;
                return event;
              case Node.COMMENT_NODE:
                event = XMLStreamConstants.COMMENT;
                return event;
              case Node.PROCESSING_INSTRUCTION_NODE:
                event = XMLStreamConstants.PROCESSING_INSTRUCTION;
                return event;
              case Node.ENTITY_REFERENCE_NODE:
                event = XMLStreamConstants.ENTITY_REFERENCE;
                return event;
              default:
                throw new IllegalStateException();
              }
          }
      }
    if (result != null)
      {
        switch (result.getResultType())
          {
          case XPathResult.BOOLEAN_TYPE:
            boolean bval = result.getBooleanValue();
            String btext = bval ? "true" : "false";
            buf = btext.toCharArray();
            len = buf.length;
            result = null;
            event = XMLStreamConstants.CHARACTERS;
            return event;
          case XPathResult.NUMBER_TYPE:
            double nval = result.getNumberValue();
            String ntext = new Double(nval).toString();
            buf = ntext.toCharArray();
            len = buf.length;
            result = null;
            event = XMLStreamConstants.CHARACTERS;
            return event;
          case XPathResult.STRING_TYPE:
            String stext = result.getStringValue();
            buf = stext.toCharArray();
            len = buf.length;
            result = null;
            event = isSpace(buf, len) ?
              XMLStreamConstants.SPACE :
              XMLStreamConstants.CHARACTERS;
            return event;
          case XPathResult.ANY_UNORDERED_NODE_TYPE:
          case XPathResult.FIRST_ORDERED_NODE_TYPE:
            Node n1 = result.getSingleNodeValue();
            Document d1 = getDocument(n1);
            walker = getDocumentTraversal(d1)
              .createTreeWalker(n1, SHOW_FLAGS, null, expandERefs);
            result = null;
            return next();
          case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
          case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
            Node n2 = result.iterateNext();
            if (n2 == null)
              {
                result = null;
                return next();
              }
            Document d2 = getDocument(n2);
            walker = getDocumentTraversal(d2)
              .createTreeWalker(n2, SHOW_FLAGS, null, expandERefs);
            return next();
          case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
          case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
            Node n3 = result.snapshotItem(snapshotIndex++);
            if (n3 == null)
              {
                result = null;
                return next();
              }
            Document d3 = getDocument(n3);
            walker = getDocumentTraversal(d3)
              .createTreeWalker(n3, SHOW_FLAGS, null, expandERefs);
            return next();
          default:
            throw new IllegalStateException();
          }
      }
    if (includedText != null)
      {
        // fill buffer
        if (buf == null)
          buf = new char[2048];
        try
          {
            len = includedText.read(buf, 0, buf.length);
            if (len == -1)
              {
                includedText = null;
                buf = null;
                return next();
              }
            // chars or space?
            return (event = isSpace(buf, len) ?
                    XMLStreamConstants.SPACE :
                    XMLStreamConstants.CHARACTERS);
          }
        catch (IOException e)
          {
            XMLStreamException e2 = new XMLStreamException(e.getMessage());
            e2.initCause(e);
            throw e2;
          }
      }
    event = super.next();
    switch (event)
      {
      case XMLStreamConstants.START_ELEMENT:
        String uri = getNamespaceURI();
        if (XINCLUDE_NS_URI.equals(uri))
          {
            String localName = getLocalName();
            if ("include".equals(localName))
              {
                href = getAttributeValue(null, "href");
                String parse = getAttributeValue(null, "parse");
                String xpointer = getAttributeValue(null, "xpointer");
                String encoding = getAttributeValue(null, "encoding");
                String accept = getAttributeValue(null, "accept");
                String acceptLanguage = getAttributeValue(null,
                                                          "accept-language");
                if (includeResource(href, parse, xpointer, encoding,
                                    accept, acceptLanguage))
                  {
                    // Skip to xi:include end-element event
                    int depth = 0;
                    while (depth >= 0)
                      {
                        event = super.next();
                        switch (event)
                          {
                          case XMLStreamConstants.START_ELEMENT:
                            depth++;
                            break;
                          case XMLStreamConstants.END_ELEMENT:
                            depth--;
                          }
                      }
                  }
                else
                  inInclude = true;
              }
            else if (inInclude && "fallback".equals(localName))
              {
                if (!seenFallback)
                  inFallback = seenFallback = true;
                else
                  throw new XMLStreamException("duplicate xi:fallback element");
              }
            else if (inInclude)
              {
                throw new XMLStreamException("illegal xi element '" +
                                             localName + "'");
              }
            return next();
          }
        break;
      case XMLStreamConstants.END_ELEMENT:
        String uri2 = getNamespaceURI();
        if (XINCLUDE_NS_URI.equals(uri2))
          {
            String localName = getLocalName();
            if ("include".equals(localName))
              {
                if (!seenFallback && included)
                  {
                    String msg = "Unable to read " + href +
                      " and no xi:fallback element present";
                    throw new XMLStreamException(msg);
                  }
                included = false;
                href = null;
                inInclude = inFallback = seenFallback = false;
              }
            else if ("fallback".equals(localName))
              inFallback = false;
            return next();
          }
        break;
      }
    if (inInclude && !inFallback)
      return next();
    return event;
  }

  boolean isSpace(char[] text, int len)
  {
    boolean space = true;
    for (int i = 0; i < len; i++)
      {
        char c = text[i];
        if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
          {
            space = false;
            break;
          }
      }
    return space;
  }

  String getBaseURI()
  {
    String base = (String) getParent().getProperty("gnu.xml.stream.baseURI");
    return (base == null) ? systemId : base;
  }
  
  boolean includeResource(String href, String parse, String xpointer,
                          String encoding, String accept,
                          String acceptLanguage)
  {
    included = false;
    try
      {
        if (xpointer != null)
          throw new XMLStreamException("xpointer attribute not yet supported");
        String base = getBaseURI();
        if (href == null || "".equals(href))
          href = base;
        else
          href = XMLParser.absolutize(base, href);
        if (parse == null || "xml".equals(parse))
          {
            seen.clear();
            result = null;
            snapshotIndex = 0;
            walker = null;
            current = null;
            backtracking = false;
            
            URLConnection connection = getURLConnection(href, accept,
                                                        acceptLanguage);
            InputStream in = connection.getInputStream();
            Document doc = getDocumentBuilder().parse(in, href);
            DocumentTraversal dt = getDocumentTraversal(doc);
            if (xpointer == null)
              {
                result = null;
                Node item = doc.getDocumentElement();
                walker = dt.createTreeWalker(item, SHOW_FLAGS, null,
                                             expandERefs);
              }
            else
              {
                result = null;
                snapshotIndex = 0;
                walker = null;
                // shorthand or scheme-based?
                int lpi = xpointer.indexOf('(');
                int rpi = xpointer.indexOf(')', lpi);
                if (lpi != -1 && rpi != -1)
                  {
                    String scheme = xpointer.substring(0, lpi);
                    if ("element".equals(scheme))
                      {
                        // element() scheme
                        String elementSchemeData =
                          xpointer.substring(lpi + 1, rpi);
                        Node item = doc;
                        int si = elementSchemeData.indexOf('/');
                        if (si == -1)
                          {
                            if (elementSchemeData.length() > 0)
                              item = doc.getElementById(elementSchemeData);
                          }
                        else
                          {
                            if (si > 0)
                              {
                                String context =
                                  elementSchemeData.substring(0, si);
                                item = doc.getElementById(context);
                                elementSchemeData =
                                  elementSchemeData.substring(si + 1);
                              }
                            StringTokenizer st =
                              new StringTokenizer(elementSchemeData, "/");
                            while (st.hasMoreTokens() && item != null)
                              {
                                int n = Integer.parseInt(st.nextToken());
                                Node ctx = item.getFirstChild();
                                int count = 1;
                                while (ctx != null && count++ < n)
                                  ctx = ctx.getNextSibling();
                                item = ctx;
                              }
                          }
                        walker = dt.createTreeWalker(item, SHOW_FLAGS, null,
                                                     expandERefs);
                        included = true;
                      }
                    else if ("xpointer".equals(scheme))
                      {
                        xpointer = xpointer.substring(lpi + 1, rpi);
                        XPathEvaluator eval = getXPathEvaluator(doc);
                        XPathNSResolver resolver = eval.createNSResolver(doc);
                        result =
                          (XPathResult) eval.evaluate(xpointer, doc,
                                                      resolver,
                                                      XPathResult.ANY_TYPE,
                                                      null);
                        // TODO xpointer() scheme functions
                        included = true;
                      }
                    else
                      {
                        String msg = "Unknown XPointer scheme: " + scheme;
                        throw new XMLStreamException(msg);
                      }
                  }
                else
                  {
                    Node item = doc.getElementById(xpointer);
                    walker = dt.createTreeWalker(item, SHOW_FLAGS, null,
                                                 expandERefs);
                    included = true;
                  }
              }
          }
        else if ("text".equals(parse))
          {
            URLConnection connection = getURLConnection(href, accept,
                                                        acceptLanguage);
            InputStream in = connection.getInputStream();
            if (encoding == null)
              {
                encoding = connection.getContentEncoding();
                if (encoding == null)
                  {
                    String contentType = connection.getContentType();
                    if (contentType != null)
                      encoding = getParameter(contentType, "charset");
                  }
              }
            if (encoding == null)
              includedText = new InputStreamReader(in, "UTF-8");
            else
              includedText = new InputStreamReader(in, encoding);
            included = true;
          }
        else
          throw new XMLStreamException("value of 'parse' attribute must be "+
                                       "'xml' or 'text'");
        return true;
      }
    catch (IOException e)
      {
        return false;
      }
    catch (XMLStreamException e)
      {
        return false;
      }
    catch (SAXException e)
      {
        return false;
      }
  }

  URLConnection getURLConnection(String href, String accept,
                                 String acceptLanguage)
    throws IOException
  {
    URL url = new URL(href);
    URLConnection connection = url.openConnection();
    if (connection instanceof HttpURLConnection)
      {
        HttpURLConnection http = (HttpURLConnection) connection;
        http.setInstanceFollowRedirects(true);
        if (accept != null)
          http.setRequestProperty("Accept", accept);
        if (acceptLanguage != null)
          http.setRequestProperty("Accept-Language", acceptLanguage);
      }
    return connection;
  }

  Document getDocument(Node node)
  {
    if (node.getNodeType() == Node.DOCUMENT_NODE)
      return (Document) node;
    return node.getOwnerDocument();
  }

  DocumentBuilder getDocumentBuilder()
    throws XMLStreamException
  {
    if (builder == null)
      {
        try
          {
            DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
            f.setXIncludeAware(true);
            f.setNamespaceAware(namespaceAware);
            f.setValidating(validating);
            builder = f.newDocumentBuilder();
          }
        catch (ParserConfigurationException e)
          {
            XMLStreamException e2 = new XMLStreamException(e.getMessage());
            e2.initCause(e);
            throw e2;
          }
      }
    builder.reset();
    return builder;
  }

  DocumentTraversal getDocumentTraversal(Document doc)
    throws XMLStreamException
  {
    DOMImplementation dom = doc.getImplementation();
    if (!dom.hasFeature("Traversal", "2.0"))
      throw new XMLStreamException("Traversal not supported");
    return (DocumentTraversal) doc;
  }

  XPathEvaluator getXPathEvaluator(Document doc)
    throws XMLStreamException
  {
    DOMImplementation dom = doc.getImplementation();
    if (!dom.hasFeature("XPath", "3.0"))
      throw new XMLStreamException("XPath not supported");
    return (XPathEvaluator) doc;
  }

  static String getParameter(String contentType, String name)
  {
    StringTokenizer st = new StringTokenizer(contentType, " ;");
    if (st.hasMoreTokens())
      st.nextToken();
    while (st.hasMoreTokens())
      {
        String token = st.nextToken();
        int ei = token.indexOf('=');
        if (ei != -1)
          {
            String key = token.substring(0, ei);
            if (key.equals(name))
              {
                String value = token.substring(ei + 1);
                int len = value.length();
                if (len > 1 &&
                    value.charAt(0) == '"' &&
                    value.charAt(len - 1) == '"')
                  value = value.substring(1, len - 1);
                else if (len > 1 &&
                         value.charAt(0) == '\'' &&
                         value.charAt(len - 1) == '\'')
                  value = value.substring(1, len - 1);
                return value;
              }
          }
      }
    return null;
  }
  
}
