/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: SourceTreeManager.java 468655 2006-10-28 07:12:06Z minchau $
 */
package org.apache.xpath;

import java.io.IOException;
import java.util.Vector;

import javax.xml.transform.Source;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;

import org.apache.xml.dtm.DTM;
import org.apache.xml.utils.SystemIDResolver;

import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * This class bottlenecks all management of source trees.  The methods
 * in this class should allow easy garbage collection of source
 * trees (not yet!), and should centralize parsing for those source trees.
 */
public class SourceTreeManager
{

  /** Vector of SourceTree objects that this manager manages. */
  private Vector m_sourceTree = new Vector();

  /**
   * Reset the list of SourceTree objects that this manager manages.
   *
   */
  public void reset()
  {
    m_sourceTree = new Vector();
  }

  /** The TrAX URI resolver used to obtain source trees. */
  URIResolver m_uriResolver;

  /**
   * Set an object that will be used to resolve URIs used in
   * document(), etc.
   * @param resolver An object that implements the URIResolver interface,
   * or null.
   */
  public void setURIResolver(URIResolver resolver)
  {
    m_uriResolver = resolver;
  }

  /**
   * Get the object that will be used to resolve URIs used in
   * document(), etc.
   * @return An object that implements the URIResolver interface,
   * or null.
   */
  public URIResolver getURIResolver()
  {
    return m_uriResolver;
  }

  /**
   * Given a document, find the URL associated with that document.
   * @param owner Document that was previously processed by this liaison.
   *
   * @return The base URI of the owner argument.
   */
  public String findURIFromDoc(int owner)
  {
    int n = m_sourceTree.size();

    for (int i = 0; i < n; i++)
    {
      SourceTree sTree = (SourceTree) m_sourceTree.elementAt(i);

      if (owner == sTree.m_root)
        return sTree.m_url;
    }

    return null;
  }

  /**
   * This will be called by the processor when it encounters
   * an xsl:include, xsl:import, or document() function.
   *
   * @param base The base URI that should be used.
   * @param urlString Value from an xsl:import or xsl:include's href attribute,
   * or a URI specified in the document() function.
   * 
   * @return a Source that can be used to process the resource.
   *
   * @throws IOException
   * @throws TransformerException
   */
  public Source resolveURI(
          String base, String urlString, SourceLocator locator)
            throws TransformerException, IOException
  {

    Source source = null;

    if (null != m_uriResolver)
    {
      source = m_uriResolver.resolve(urlString, base);
    }

    if (null == source)
    {
      String uri = SystemIDResolver.getAbsoluteURI(urlString, base);

      source = new StreamSource(uri);
    }

    return source;
  }

  /** JJK: Support  <?xalan:doc_cache_off?> kluge in ElemForEach.
   * TODO: This function is highly dangerous. Cache management must be improved.
   *
   * @param n The node to remove.
   */
  public void removeDocumentFromCache(int n)
  {
    if(DTM.NULL ==n)
      return;
    for(int i=m_sourceTree.size()-1;i>=0;--i)
    {
      SourceTree st=(SourceTree)m_sourceTree.elementAt(i);
      if(st!=null && st.m_root==n)
      {
	m_sourceTree.removeElementAt(i);
	return;
      }
    }
  }
  


  /**
   * Put the source tree root node in the document cache.
   * TODO: This function needs to be a LOT more sophisticated.
   *
   * @param n The node to cache.
   * @param source The Source object to cache.
   */
  public void putDocumentInCache(int n, Source source)
  {

    int cachedNode = getNode(source);

    if (DTM.NULL != cachedNode)
    {
      if (!(cachedNode == n))
        throw new RuntimeException(
          "Programmer's Error!  "
          + "putDocumentInCache found reparse of doc: "
          + source.getSystemId());
      return;
    }
    if (null != source.getSystemId())
    {
      m_sourceTree.addElement(new SourceTree(n, source.getSystemId()));
    }
  }

  /**
   * Given a Source object, find the node associated with it.
   *
   * @param source The Source object to act as the key.
   *
   * @return The node that is associated with the Source, or null if not found.
   */
  public int getNode(Source source)
  {

//    if (source instanceof DOMSource)
//      return ((DOMSource) source).getNode();

    // TODO: Not sure if the BaseID is really the same thing as the ID.
    String url = source.getSystemId();

    if (null == url)
      return DTM.NULL;

    int n = m_sourceTree.size();

    // System.out.println("getNode: "+n);
    for (int i = 0; i < n; i++)
    {
      SourceTree sTree = (SourceTree) m_sourceTree.elementAt(i);

      // System.out.println("getNode -         url: "+url);
      // System.out.println("getNode - sTree.m_url: "+sTree.m_url);
      if (url.equals(sTree.m_url))
        return sTree.m_root;
    }

    // System.out.println("getNode - returning: "+node);
    return DTM.NULL;
  }

  /**
   * Get the source tree from the a base URL and a URL string.
   *
   * @param base The base URI to use if the urlString is relative.
   * @param urlString An absolute or relative URL string.
   * @param locator The location of the caller, for diagnostic purposes.
   *
   * @return should be a non-null reference to the node identified by the 
   * base and urlString.
   *
   * @throws TransformerException If the URL can not resolve to a node.
   */
  public int getSourceTree(
          String base, String urlString, SourceLocator locator, XPathContext xctxt)
            throws TransformerException
  {

    // System.out.println("getSourceTree");
    try
    {
      Source source = this.resolveURI(base, urlString, locator);

      // System.out.println("getSourceTree - base: "+base+", urlString: "+urlString+", source: "+source.getSystemId());
      return getSourceTree(source, locator, xctxt);
    }
    catch (IOException ioe)
    {
      throw new TransformerException(ioe.getMessage(), locator, ioe);
    }

    /* catch (TransformerException te)
     {
       throw new TransformerException(te.getMessage(), locator, te);
     }*/
  }

  /**
   * Get the source tree from the input source.
   *
   * @param source The Source object that should identify the desired node.
   * @param locator The location of the caller, for diagnostic purposes.
   *
   * @return non-null reference to a node.
   *
   * @throws TransformerException if the Source argument can't be resolved to 
   *         a node.
   */
  public int getSourceTree(Source source, SourceLocator locator, XPathContext xctxt)
          throws TransformerException
  {

    int n = getNode(source);

    if (DTM.NULL != n)
      return n;

    n = parseToNode(source, locator, xctxt);

    if (DTM.NULL != n)
      putDocumentInCache(n, source);

    return n;
  }

  /**
   * Try to create a DOM source tree from the input source.
   *
   * @param source The Source object that identifies the source node.
   * @param locator The location of the caller, for diagnostic purposes.
   *
   * @return non-null reference to node identified by the source argument.
   *
   * @throws TransformerException if the source argument can not be resolved 
   *         to a source node.
   */
  public int parseToNode(Source source, SourceLocator locator, XPathContext xctxt)
          throws TransformerException
  {

    try
    {      
      Object xowner = xctxt.getOwnerObject();
      DTM dtm;
      if(null != xowner && xowner instanceof org.apache.xml.dtm.DTMWSFilter)
      {
        dtm = xctxt.getDTM(source, false, 
                          (org.apache.xml.dtm.DTMWSFilter)xowner, false, true);
      }
      else
      {
        dtm = xctxt.getDTM(source, false, null, false, true);
      }
      return dtm.getDocument();
    }
    catch (Exception e)
    {
      //e.printStackTrace();
      throw new TransformerException(e.getMessage(), locator, e);
    }

  }

  /**
   * This method returns the SAX2 parser to use with the InputSource
   * obtained from this URI.
   * It may return null if any SAX2-conformant XML parser can be used,
   * or if getInputSource() will also return null. The parser must
   * be free for use (i.e.
   * not currently in use for another parse().
   *
   * @param inputSource The value returned from the URIResolver.
   * @return a SAX2 XMLReader to use to resolve the inputSource argument.
   * @param locator The location of the original caller, for diagnostic purposes.
   *
   * @throws TransformerException if the reader can not be created.
   */
  public static XMLReader getXMLReader(Source inputSource, SourceLocator locator)
          throws TransformerException
  {

    try
    {
      XMLReader reader = (inputSource instanceof SAXSource)
                         ? ((SAXSource) inputSource).getXMLReader() : null;
                         
      if (null == reader)
      {
        try {
          javax.xml.parsers.SAXParserFactory factory=
              javax.xml.parsers.SAXParserFactory.newInstance();
          factory.setNamespaceAware( true );
          javax.xml.parsers.SAXParser jaxpParser=
              factory.newSAXParser();
          reader=jaxpParser.getXMLReader();
          
        } catch( javax.xml.parsers.ParserConfigurationException ex ) {
          throw new org.xml.sax.SAXException( ex );
        } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
            throw new org.xml.sax.SAXException( ex1.toString() );
        } catch( NoSuchMethodError ex2 ) {
        }
        catch (AbstractMethodError ame){}
        if(null == reader)
          reader = XMLReaderFactory.createXMLReader();
      }

      try
      {
        reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
                          true);
      }
      catch (org.xml.sax.SAXException se)
      {

        // What can we do?
        // TODO: User diagnostics.
      }

      return reader;
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se.getMessage(), locator, se);
    }
  }
}
