Package org.apache.xpath

Source Code of org.apache.xpath.SourceTreeManager

/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
*    nor may "Apache" appear in their name, without prior written
*    permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xpath;

import java.net.MalformedURLException;

import java.io.File;
import java.io.IOException;

import java.util.StringTokenizer;
import java.util.Vector;

import org.w3c.dom.Node;
import org.w3c.dom.Document;

import javax.xml.transform.URIResolver;
import javax.xml.transform.TransformerException;

import org.xml.sax.InputSource;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.XMLReader;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;

// import org.xml.sax.Locator;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.stree.SourceTreeHandler;
import org.apache.xml.utils.SystemIDResolver;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xpath.res.XPATHErrorResources;

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

/**
* 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(Document owner)
  {

    Node root = owner.getOwnerDocument();

    if (null == root)
      root = owner;

    String url = null;
    int n = m_sourceTree.size();

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

      if (root == sTree.m_root)
      {
        url = sTree.m_url;

        break;
      }
    }

    return url;
  }

  /**
   * 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;
  }

  /**
   * 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(Node n, Source source)
  {

    Node cachedNode = getNode(source);

    if (null != cachedNode)
    {
      if (!cachedNode.equals(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 Node 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 null;

    Node node = 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))
      {
        node = sTree.m_root;

        break;
      }
    }

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

  /**
   * 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 Node getSourceTree(
          String base, String urlString, SourceLocator locator)
            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);
    }
    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 Node getSourceTree(Source source, SourceLocator locator)
          throws TransformerException
  {

    Node n = getNode(source);

    if (null != n)
      return n;

    n = getDOMNode(source, locator);

    if (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 Node getDOMNode(Source source, SourceLocator locator)
          throws TransformerException
  {

    if (source instanceof DOMSource)
    {
      return ((DOMSource) source).getNode();
    }

    Node doc = null;

    try
    {

      // System.out.println("reading: "+source.getSystemId());
      XMLReader reader = getXMLReader(source, locator);

      // TODO: Need to use factory of some kind to create the ContentHandler
      // (Also, try using JAXP if need be...)
      ContentHandler handler = new SourceTreeHandler();

      if (handler instanceof org.apache.xalan.stree.SourceTreeHandler)
      {

        // temp hack
        ((org.apache.xalan.stree.SourceTreeHandler) handler).setUseMultiThreading(
          false);
      }

      reader.setContentHandler(handler);

      if (handler instanceof org.xml.sax.DTDHandler)
        reader.setDTDHandler((org.xml.sax.DTDHandler) handler);

      try
      {
        if (handler instanceof org.xml.sax.ext.LexicalHandler)
          reader.setProperty("http://xml.org/sax/properties/lexical-handler",
                             handler);

        if (handler instanceof org.xml.sax.ext.DeclHandler)
          reader.setProperty(
            "http://xml.org/sax/properties/declaration-handler", handler);
      }
      catch (org.xml.sax.SAXException se){}

      try
      {
        if (handler instanceof org.xml.sax.ext.LexicalHandler)
          reader.setProperty("http://xml.org/sax/handlers/LexicalHandler",
                             handler);

        if (handler instanceof org.xml.sax.ext.DeclHandler)
          reader.setProperty("http://xml.org/sax/handlers/DeclHandler",
                             handler);
      }
      catch (org.xml.sax.SAXNotRecognizedException snre){}

      InputSource isource = SAXSource.sourceToInputSource(source);

      reader.parse(isource);

      if (handler instanceof org.apache.xalan.stree.SourceTreeHandler)
      {
        doc = ((org.apache.xalan.stree.SourceTreeHandler) handler).getRoot();
      }
    }
    catch (IOException ioe)
    {
      throw new TransformerException(ioe.getMessage(), locator, ioe);
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se.getMessage(), locator, se);
    }

    return doc;
  }

  /**
   * 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.
   * @returns a SAX2 XMLReader to use to resolve the inputSource argument.
   * @param locator The location of the original caller, for diagnostic purposes.
   *
   * @return non-null XMLReader reference ready to parse.
   *
   * @throws TransformerException if the reader can not be created.
   */
  public 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);
        reader.setFeature("http://apache.org/xml/features/validation/dynamic",
                          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);
    }
  }
}
TOP

Related Classes of org.apache.xpath.SourceTreeManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.