/* XSLURIResolver.java -- 
   Copyright (C) 2004 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.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import gnu.xml.dom.DomDocument;
import gnu.xml.dom.ls.SAXEventSink;
import gnu.xml.dom.ls.ReaderInputStream;

/**
 * URI resolver for XSLT.
 * This resolver parses external entities into DOMSources. It
 * maintains a cache of URIs to DOMSources to avoid expensive re-parsing.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class XSLURIResolver
  implements URIResolver
{

  final Map<String,Long> lastModifiedCache = new HashMap<String,Long>();
  final Map<String,Node> nodeCache = new HashMap<String,Node>();
  DocumentBuilder builder;
  URIResolver userResolver;
  ErrorListener userListener;

  void setUserResolver(URIResolver userResolver)
  {
    this.userResolver = userResolver;
  }

  void setUserListener(ErrorListener userListener)
  {
    this.userListener = userListener;
  }

  /**
   * Clear the cache.
   */
  void flush()
  {
    lastModifiedCache.clear();
    nodeCache.clear();
  }

  public Source resolve(String href, String base)
    throws TransformerException
  {
    Source source = null;
    if (userResolver != null)
      {
        source = userResolver.resolve(base, href);
      }
    return resolveDOM(source, href, base);
  }

  DOMSource resolveDOM(Source source, String base, String href)
    throws TransformerException
  {
    if (source != null && source instanceof DOMSource)
      {
        return (DOMSource) source;
      }
    String systemId = (source == null) ? null : source.getSystemId();
    long lastModified = 0L, lastLastModified = 0L;

    try
      {
        Node node = null;
        InputStream in = null;
        if (source != null && source instanceof StreamSource)
          {
            StreamSource ss = (StreamSource) source;
            in = ss.getInputStream();
            if (in == null)
              {
                Reader reader = ss.getReader();
                if (reader != null)
                  {
                    in = new ReaderInputStream(reader);
                  }
              }
          }
        else if (source != null && source instanceof SAXSource)
          {
            SAXSource ss = (SAXSource) source;
            InputSource input = ss.getInputSource();
            if (input != null)
              {
                if (systemId == null)
                  systemId = input.getSystemId();
                XMLReader reader = ss.getXMLReader();
                if (reader != null)
                  return parse(input, reader);
              }
          }
        if (in == null)
          {
            URL url = resolveURL(systemId, base, href);
            if (url != null)
              {
                systemId = url.toString();
                node = nodeCache.get(systemId);
                // Is the resource up to date?
                URLConnection conn = url.openConnection();
                Long llm = lastModifiedCache.get(systemId);
                if (llm != null)
                  {
                    lastLastModified = llm.longValue();
                    conn.setIfModifiedSince(lastLastModified);
                  }
                conn.connect();
                lastModified = conn.getLastModified();
                if (node != null && 
                    lastModified > 0L &&
                    lastModified <= lastLastModified)
                  {
                    // Resource unchanged
                    return new DOMSource(node, systemId);
                  }
                else
                  {
                    // Resource new or modified
                    in = conn.getInputStream();
                    nodeCache.put(systemId, node);
                    lastModifiedCache.put(systemId, new Long(lastModified));
                  }
              }
            else
              {
                throw new TransformerException("can't resolve URL: " +
                                               systemId);
              }
          }
        InputSource input = new InputSource(in);
        input.setSystemId(systemId);
        DocumentBuilder builder = getDocumentBuilder();
        node = builder.parse(input);
        return new DOMSource(node, systemId);
      }
    catch (IOException e)
      {
        throw new TransformerException(e);
      }
    catch (SAXException e)
      {
        throw new TransformerException(e);
      }
  }

  URL resolveURL(String systemId, String base, String href)
    throws IOException
  {
    URL url = null;
    try
      {
        if (systemId != null)
          {
            try
              {
                url = new URL(systemId);
              }
            catch (MalformedURLException e)
              {
                // Try building from base + href
              }
          }
        if (url == null)
          {
            if (base != null)
              {
                URL baseURL = new URL(base);
                url = new URL(baseURL, href);
              }
            else if (href != null)
              {
                url = new URL(href);
              }
            else
              {
                // See below
                throw new MalformedURLException(systemId);
              }
          }
        return url;
      }
    catch (MalformedURLException e)
      {
        // Fall back to local filesystem
        File file = null;
        if (href == null)
          {
            href = systemId;
          }
        if (base != null)
          {
            int lsi = base.lastIndexOf(File.separatorChar);
            if (lsi != -1 && lsi < base.length() - 1)
              {
                base = base.substring(0, lsi);
              }
            File baseFile = new File(base);
            file = new File(baseFile, href);
          }
        else if (href != null)
          {
            file = new File(href);
          }
        return (file == null) ? null : file.toURL();
      }
  }
  
  DocumentBuilder getDocumentBuilder()
    throws TransformerException
  {
    try
      {
        if (builder == null)
          {
            DocumentBuilderFactory factory =
              DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            factory.setExpandEntityReferences(true);
            builder = factory.newDocumentBuilder();
          }
        if (userResolver != null)
          {
            builder.setEntityResolver(new URIResolverEntityResolver(userResolver));
          }
        if (userListener != null)
          {
            builder.setErrorHandler(new ErrorListenerErrorHandler(userListener));
          }
        return builder;
      }
    catch (Exception e)
      {
        throw new TransformerException(e);
      }
  }

  DOMSource parse(InputSource source, XMLReader reader)
    throws SAXException, IOException
  {
    SAXEventSink eventSink = new SAXEventSink();
    eventSink.setReader(reader);
    eventSink.setNamespaceAware(true);
    reader.setContentHandler(eventSink);
    reader.setDTDHandler(eventSink);
    reader.setProperty("http://xml.org/sax/properties/lexical-handler",
            eventSink);
    reader.setProperty("http://xml.org/sax/properties/declaration-handler",
            eventSink);
    // XXX entityResolver
    // XXX errorHandler
    reader.parse(source);
    Document doc = eventSink.getDocument();
    String systemId = source.getSystemId();
    if (systemId != null && doc instanceof DomDocument)
      ((DomDocument) doc).setDocumentURI(systemId);
    return new DOMSource(doc, systemId);
  }
  
}

