Logo Search packages:      
Sourcecode: xalan version File versions  Download package

XSLTEngineImpl.hpp

/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed 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.
 */
#if !defined(XALAN_XSLTENGINEIMPL_HEADER_GUARD)
#define XALAN_XSLTENGINEIMPL_HEADER_GUARD



// Base include file.  Must be first.
#include "XSLTDefinitions.hpp"



// Base class
#include "XSLTProcessor.hpp"




// Standard library headers
#include <cassert>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



#if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION)
#include <xalanc/XPath/XPathProcessor.hpp>
#endif



#include <xalanc/Include/XalanMemMgrAutoPtr.hpp>
#include <xalanc/Include/XalanMap.hpp>



#include <xalanc/PlatformSupport/AttributeListImpl.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/PlatformSupport/PrefixResolver.hpp>



#include <xalanc/DOMSupport/XalanNamespacesStack.hpp>



#include <xalanc/XPath/Function.hpp>



#include <xalanc/XPath/XPathConstructionContextDefault.hpp>



#include "OutputContextStack.hpp"
#include "ProblemListenerDefault.hpp"
#include "ResultNamespacesStack.hpp"
#include "StylesheetExecutionContext.hpp"
#include "XSLTProcessorException.hpp"



XALAN_DECLARE_XERCES_CLASS(InputSource)
XALAN_DECLARE_XERCES_CLASS(DocumentHandler)



XALAN_CPP_NAMESPACE_BEGIN



typedef XERCES_CPP_NAMESPACE_QUALIFIER InputSource          InputSourceType;
typedef XERCES_CPP_NAMESPACE_QUALIFIER DocumentHandler      DocumentHandlerType;



// Forward declarations...
class DOMSupport;
class GenerateEvent;
class PrintWriter;
class StylesheetConstructionContext;
class StylesheetRoot;
class XalanAttr;
class XalanSourceTreeDocument;
class XalanText;
class XMLParserLiaison;
class XObject;
class XPathEnvSupport;
class XPathFactory;
class XPathProcessor;
class XSLTResultTarget;



/**
 * It's the responsibility of the XSLTEngineImpl class, collaborating with the
 * XML parser liaison, the DOM, and the XPath engine, to transform a source
 * tree of nodes into a result tree according to instructions and templates
 * specified by a stylesheet tree.  The process method is the primary
 * public entry points.
 * 
 * 
 * If you reuse the processor instance, you should call reset() between calls.
 *
 */

00122 class XALAN_XSLT_EXPORT XSLTEngineImpl : public XSLTProcessor, public PrefixResolver
{
public:

      struct LessXalanDOMStringPointers
      {
            bool
            operator()(
                        const XalanDOMString*   theLHS,
                        const XalanDOMString*   theRHS) const
            {
                  if (theLHS == 0 && theRHS != 0)
                  {
                        return true;
                  }
                  else if (theRHS == 0)
                  {
                        return false;
                  }
                  else
                  {
                        return theLHS->compare(*theRHS) < 0 ? true : false;
                  }
            }
      };

      typedef XalanVector<const LocatorType*>         LocatorStack;
      typedef XalanVector<TraceListener*>             TraceListenerVectorType;
      typedef XalanVector<const XalanDOMString*>      XalanDOMStringPointerVectorType;

      typedef XalanVector<bool>                                         BoolVectorType;

      struct FindStringPointerFunctor
      {
            FindStringPointerFunctor(const XalanDOMString&  theString) :
                  m_string(theString)
            {
            }

            bool
            operator()(const XalanDOMString*    theString) const
            {
                  assert(theString != 0);

                  return *theString == m_string;
            }

      private:

            const XalanDOMString&   m_string;
      };

      typedef XalanMemMgrAutoPtr<XPathProcessor, true>                        XPathProcessorPtrType;
      typedef Function::XObjectArgVectorType                      XObjectArgVectorType;
      typedef StylesheetExecutionContext::ParamVectorType   ParamVectorType;
    typedef XPathConstructionContext::GetAndReleaseCachedString     CCGetAndReleaseCachedString;
    typedef XPathExecutionContext::GetAndReleaseCachedString        ECGetAndReleaseCachedString;

      // Public members
      //---------------------------------------------------------------------

      /**
       * Construct an XSL processor that can call back to a XML processor, so it
       * can handle included files, and the like. You must create a new instance
       * of the XSLTEngineImpl class each time you run a transformation.
       *
       * @param XMLParserLiaison liaison to an object that can help with a
       *                                     specific parser implementation
       * @param xpathEnvSupport  An XPathEnvSupport instance
       * @param domSupport       A DOMSupport instance for the DOM being used
       * @param xobjectFactory   object responsible for XObject objects
       * @param xpathFactory     object responsible for XPath objects
       */
      XSLTEngineImpl(
            MemoryManagerType&  theManager,
                  XMLParserLiaison& parserLiaison,
                  XPathEnvSupport&  xpathEnvSupport,
                  DOMSupport&             domSupport,
                  XObjectFactory&   xobjectFactory,
                  XPathFactory&           xpathFactory);

      virtual
      ~XSLTEngineImpl();

    MemoryManagerType&
    getMemoryManager()
    {
        return m_xpathConstructionContext.getMemoryManager();
    }

      /**
       * Perform initialization of statics -- must be called before any
       * processing occurs.  See class XSLTInit.
       */
      static void
      initialize(MemoryManagerType&      theManager);

      /**
       * Perform termination of statics.  See class XSLTInit.
       */
      static void
      terminate();

      // These methods are inherited from XSLTProcessor ...
      
      virtual void
      process(
                  const XSLTInputSource&              inputSource, 
                  const XSLTInputSource&              stylesheetSource,
                  XSLTResultTarget&                   outputTarget,
                  StylesheetConstructionContext&      constructionContext,
                  StylesheetExecutionContext&   executionContext);

      virtual void
      process(
                  const XSLTInputSource&              inputSource,
                  XSLTResultTarget&                   outputTarget,
                  StylesheetExecutionContext&   executionContext);

      virtual StylesheetRoot*
      processStylesheet(
                  const XSLTInputSource&              stylesheetSource,
                  StylesheetConstructionContext&      constructionContext);

      virtual StylesheetRoot*
      processStylesheet(
                  const XalanDOMString&               xsldocURLString,
                  StylesheetConstructionContext&      constructionContext);

      virtual XalanNode*
      getSourceTreeFromInput(const XSLTInputSource&   inputSource);

      virtual void
      resolveTopLevelParams(StylesheetExecutionContext&     executionContext);

      virtual XMLParserLiaison&
      getXMLParserLiaison() const;

      virtual void
      getUniqueNamespaceValue(XalanDOMString&         theValue);

      virtual void
      setStylesheetParam(     
                              const XalanDOMString&   key,
                              const XalanDOMString&   expression);

      virtual void
      setStylesheetParam(
                  const XalanDOMString&   key,
                  XObjectPtr                    value);

      virtual FormatterListener*
      getFormatterListener() const;

      virtual void
      setFormatterListener(FormatterListener* flistener);

      // Trace-related functions...

      virtual size_type
      getTraceListeners() const;

      virtual void
      addTraceListener(TraceListener*     tl);

      virtual void
      removeTraceListener(TraceListener*  tl);

      virtual void
      fireGenerateEvent(const GenerateEvent&    ge);
        
      virtual void
      fireTraceEvent(const TracerEvent&   te);

      virtual void
      fireSelectEvent(const SelectionEvent&     se);

      virtual bool
      getTraceSelects() const;

      virtual void
      setTraceSelects(bool    b);

      void
      traceSelect(
                  StylesheetExecutionContext&   executionContext,
                  const ElemTemplateElement&          theTemplate,
                  const NodeRefListBase&              nl,
                  const XPath*                              xpath) const;

      virtual void
      setQuietConflictWarnings(bool b);

      virtual void
      setDiagnosticsOutput(PrintWriter*   pw);


      // Inherited from PrefixResolver...

      /**
       * Retrieve a namespace corresponding to a prefix.  This assumes that 
       * the PrevixResolver hold's its own namespace context, or is a namespace
       * context itself.
       *
       * @param prefix Prefix to resolve
       * @return namespace that prefix resolves to, or null if prefix is not found
       */
      virtual const XalanDOMString*
      getNamespaceForPrefix(const XalanDOMString&           prefix) const;

      /**
       * Retrieve the base URI for the resolver.
       * 
       * @return URI string
       */
      virtual const XalanDOMString&
      getURI() const;

      /**
       * Read in the XML file, either producing a Document or calling SAX events,
       * and register the document in a table.  If the document has already been
       * read in, it will not be reparsed.
       *
       * @param urlString location of the XML
       * @param docHandler pointer to SAX event handler
       * @param docToRegister if using a SAX event handler, the object to register in the source docs table. 
       * @return document object, which represents the parsed XML
       * @exception SAXException
       */
      XalanDocument*
      parseXML(
                  const XalanDOMString&   urlString,
                  DocumentHandlerType*    docHandler,
                  XalanDocument*                docToRegister);

      /**
       * Read in the XML file, either producing a Document or calling SAX events,
       * and register the document in a table.  If the document has already been
       * read in, it will not be reparsed.
       *
       * @param inputSource location of the XML
       * @param docHandler pointer to SAX event handler
       * @param docToRegister if using a SAX event handler, the object to register in the source docs table. 
       * @return document object, which represents the parsed XML
       * @exception SAXException
       */
      XalanDocument*
      parseXML(
                  const InputSourceType&  inputSource,
                  DocumentHandlerType*    docHandler,
                  XalanDocument*                docToRegister);

      /**
       * Reset the state of the XSL processor by reading in a new XSL stylesheet
       * from a processing instruction.
       *
       * @param xslURLString          valid URI to an XSL stylesheet
       * @param fragBase                    base of tree if URI represents document
       *                                          fragment
       * @param xmlBaseIdent          base identifier for stylesheet URI
       * @param isRoot                true if stylesheet is root of tree
       * @param constructionContext context for construction of object
       * @return pointer to stylesheet
       */
      Stylesheet*
      getStylesheetFromPIURL(
                  const XalanDOMString&               xslURLString,
                  XalanNode&                                fragBase,
                  const XalanDOMString&               xmlBaseIdent,
                  bool                                      isRoot,
                  StylesheetConstructionContext&      constructionContext);

      /**
       * Flush the pending element.
       */
      void
      flushPending();

      /**
       * Add a namespace declaration to the namespace stack
       *
       * @param prefix     namespace prefix
       * @param namespaceVal value of namespace
       */
      void
00407       addResultNamespaceDecl(
                  const XalanDOMString&   prefix, 
                  const XalanDOMString&   namespaceVal)
      {
            addResultNamespaceDecl(
                  prefix,
                  namespaceVal.c_str(),
                  namespaceVal.length());
      }

      /**
       * Add a namespace declaration to the namespace stack
       *
       * @param prefix namespace prefix
       * @param namespaceVal value of namespace
       * @param len length of namespace
       */
      void
00425       addResultNamespaceDecl(
                  const XalanDOMString&         prefix, 
                  const XalanDOMChar*                 namespaceVal,
                  XalanDOMString::size_type     len)
      {
            m_resultNamespacesStack.addDeclaration(
                  prefix,
                  namespaceVal,
                  len);
      }

      /**
       * Add attribute to attribute list, and if it is a namespace, add it to the
       * namespaces stack.
       *
       * @param attList attribute list added to
       * @param aname   name of attribute
       * @param value   value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
       */
      void
00447       addResultAttribute(
                  AttributeListImpl&            attList,
                  const XalanDOMString&   aname,
                  const XalanDOMString&   value,
            bool                    fromCopy = false,
                  const LocatorType*          locator = 0)
      {
            addResultAttribute(
                  attList,
                  aname,
                  value.c_str(),
            fromCopy,
            locator);
      }

      /**
       * Add attribute to attribute list, and if it is a namespace, add it to the
       * namespaces stack.
       *
       * @param attList attribute list added to
       * @param aname name of attribute
       * @param value value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
       */
      void
00473       addResultAttribute(
                  AttributeListImpl&            attList,
                  const XalanDOMString&   aname,
                  const XalanDOMChar*         value,
            bool                    fromCopy = false,
                  const LocatorType*          locator = 0)
    {
          addResultAttribute(
                  attList,
                  aname,
            value,
            length(value),
            fromCopy,
            locator);
    }

      /**
       * Add attribute to attribute list, and if it is a namespace, add it to the
       * namespaces stack.
       *
       * @param attList attribute list added to
       * @param aname name of attribute
       * @param value value of attribute
     * @param theLength The length of the value
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
       */
      void
      addResultAttribute(
                  AttributeListImpl&                  attList,
                  const XalanDOMString&         aname,
                  const XalanDOMChar*                 value,
            XalanDOMString::size_type   theLength,
            bool                        fromCopy = false,
                  const LocatorType*              locator = 0);

      /**
       * Add attribute to pending attributes list, and if it is a namespace, add
       * it to the namespaces stack.
       *
       * @param aname name of attribute
       * @param value value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
       */
      void
00519       addResultAttribute(
                  const XalanDOMString&         aname,
                  const XalanDOMChar*                 value,
            bool                        fromCopy = false,
                  const LocatorType*              locator = 0)
      {
            assert(m_outputContextStack.empty() == false);

            addResultAttribute(
                        getPendingAttributesImpl(),
                        aname,
                        value,
                fromCopy,
                locator);
      }

      /**
       * Add attribute to pending attributes list, and if it is a namespace, add
       * it to the namespaces stack.
       *
       * @param aname   name of attribute
       * @param value   value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
       */
      void
00545       addResultAttribute(
                  const XalanDOMString&   aname,
                  const XalanDOMString&   value,
            bool                    fromCopy = false,
                  const LocatorType*          locator = 0)
      {
            assert(m_outputContextStack.empty() == false);

            addResultAttribute(
                        getPendingAttributesImpl(),
                        aname,
                        value,
                fromCopy,
                locator);
      }

      /**
       * Report an error copying a duplicate namespace node.
       *
       * @param theName The name of the node.
       */
    void
    reportDuplicateNamespaceNodeError(
            const XalanDOMString&   theName,
                  const LocatorType*          locator);

      void
      setDocumentLocator(const LocatorType*     locator);

      void
      startDocument();

      void
      endDocument();
      
      void
      startElement(
                  const XalanDOMChar*           name,
                  AttributeListType&            atts);

      void
      endElement(const XalanDOMChar*      name);

      void
      characters (
                  const XalanDOMChar*                 ch,
                  XalanDOMString::size_type     length);

      void
      ignorableWhitespace(
                  const XalanDOMChar*                 ch,
                  XalanDOMString::size_type     length);

      void
      processingInstruction(
                  const XalanDOMChar*           target,
                  const XalanDOMChar*           data);

      void
      resetDocument();

      /**
       * Receive notification of character data.
       *
       * @param ch       pointer to characters from the XML document
       * @param start  startng offset in 'ch' array
       * @param length number of characters to read from the array 
       */
      void
      characters(
                  const XalanDOMChar*                 ch,
                  XalanDOMString::size_type     start,
                  XalanDOMString::size_type     length);

      /**
       * Send character data from the node to the result tree.
       *
       * @param node The node to send.
       */
      void
      characters(const XalanNode&         node);

      /**
       * Send character data from an XObject to the result tree.
       *
       * @param node The xobject to send.
       */
      void
      characters(const XObjectPtr&  xobject);

      /**
       * Receive notification of the beginning of an element with an empty
       * attribute list
       *
       * @param name element type name
       */
      void
      startElement(const XalanDOMChar*    name);

      /**
       * Receive notification of character data. If available, when the
       * disable-output-escaping attribute is used, output raw text without
       * escaping.
       *
       * @param ch pointer to characters from the XML document
       * @param start start position in the array
       * @param length number of characters to read from the array
       */
      void
      charactersRaw(
                  const XalanDOMChar*                 ch,
                  XalanDOMString::size_type     start,
                  XalanDOMString::size_type     length);

      /**
       * Send raw character data from the node to the result tree.
       *
       * @param node The node to send.
       */
      void
      charactersRaw(const XalanNode&      node);

      /**
       * Send raw character data from an XObject to the result tree.
       *
       * @param node The xobject to send.
       */
      void
      charactersRaw(const XObjectPtr&           xobject);

      /**
       * Called when a Comment is to be constructed.
       *
       * @param   data  pointer to comment data
       */
      void
      comment(const XalanDOMChar*         data);

      /**
       * Receive notification of a entityReference.
       *
       * @param data pointer to characters from the XML document
       * @exception SAXException
       */
      void
      entityReference(const XalanDOMChar*       data);

      /**
       * Receive notification of cdata.
       *
       * @param ch       pointer to characters from the XML document
       * @param start  start position in the array
       * @param length number of characters to read from the array
       */
      void
      cdata(
                  const XalanDOMChar*                 ch,
                  XalanDOMString::size_type     start,
                  XalanDOMString::size_type     length);

      /**
       * Clone a node to the result tree
       *
       * @param node      node to clone
       * @param cloneTextNodesOnly    if true, only text nodes will be cloned
       * @param locator the Locator for the event, if any.
       */
      void
      cloneToResultTree(
                  const XalanNode&  node,
                  bool                    cloneTextNodesOnly,
                  const LocatorType*      locator);

      /**
       * Clone a node to the result tree
       *
       * @param node                            node to clone
       * @param nodeType                        the type of the node
       * @param overrideStrip             false if white space stripping should be done
       * @param shouldCloneAttributes true if attributes should be cloned
       * @param cloneTextNodesOnly    if true, only text nodes will be cloned
       * @param locator                   the Locator for the event, if any.
       */
      void
      cloneToResultTree(
                  const XalanNode&        node,
                  XalanNode::NodeType           nodeType,
                  bool                          overrideStrip,
                  bool                          shouldCloneAttributes,
                  bool                          cloneTextNodesOnly,
                  const LocatorType*            locator);

   /**
      * Output an object to the result tree by doing the right conversions.
      *
      * @param value the XObject to output
      * @param outputTextNodesOnly if true, only text nodes will be copied
      * @param locator                    the Locator for the event, if any.
      */
      void
      outputToResultTree(
                  const XObject&          value,
                  bool                    outputTextNodesOnly,
                  const LocatorType*      locator);

      /**
       * Given a result tree fragment, walk the tree and output it to the result
       * stream.
       *
       * @param theTree result tree fragment
       * @param outputTextNodesOnly if true, only text nodes will be copied
       * @param locator the Locator for the event, if any.
       */
      void
00759       outputResultTreeFragment(
                  const XObject&          theTree,
                  bool                    outputTextNodesOnly,
                  const LocatorType*      locator)
      {
            outputResultTreeFragment(theTree.rtree(), outputTextNodesOnly, locator);
      }

      /**
       * Given a result tree fragment, walk the tree and output it to the result
       * stream.
       *
       * @param theTree result tree fragment
       * @param outputTextNodesOnly if true, only text nodes will be copied
       * @param locator the Locator for the event, if any.
       */
      void
      outputResultTreeFragment(
                  const XalanDocumentFragment&  theTree,
                  bool                                      outputTextNodesOnly,
                  const LocatorType*                        locator);

      /**
       * Retrieve the root stylesheet.
       * 
       * @return pointer to root stylesheet
       */
      virtual const StylesheetRoot*
      getStylesheetRoot() const;

      /**
       * Set the root stylesheet.
       * 
       * @param theStylesheet pointer to new root stylesheet
       */
      virtual void
      setStylesheetRoot(const StylesheetRoot*         theStylesheet);

      /**
       * Set the execution context.
       * 
       * @param theExecutionContext pointer to new execution context.
       */
      virtual void
      setExecutionContext(StylesheetExecutionContext*       theExecutionContext);

      /**
       * Retrieve the URI for the current XSL namespace, for example,
       * "http://www.w3.org/1999/XSL/Transform"
       * 
       * @return URI string
       */
      static const XalanDOMString&
00812       getXSLNameSpaceURL()
      {
            return s_XSLNameSpaceURL;
      }

      /**
       * Special Xalan namespace for built-in extensions.
       *
       * @return Xalan namespace for extensions
       */
      static const XalanDOMString&
00823       getXalanXSLNameSpaceURL()
      {
            return s_XalanNamespaceURL;
      }

      /**
       * Whether to warn about pattern match conflicts.
       *
       * @return true to not warn about pattern match conflicts
       */
      bool
00834       getQuietConflictWarnings() const
      {
            return m_quietConflictWarnings;
      }

      virtual void
      message(
                  const XalanDOMString&         msg,
                  const XalanNode*              sourceNode = 0,
                  const ElemTemplateElement*    styleNode = 0) const;

      virtual void
      message(
                  const XalanDOMString&   msg,
                  const LocatorType&            locator,
                  const XalanNode*        sourceNode = 0) const;

      virtual void
      warn(
                  const XalanDOMString&         msg,
                  const XalanNode*              sourceNode = 0,
                  const ElemTemplateElement*    styleNode = 0) const;


      virtual void
      warn(
                  const XalanDOMString&   msg,
                  const LocatorType&            locator,
                  const XalanNode*        sourceNode = 0) const;

      virtual void
      error(
                  const XalanDOMString&         msg,
                  const XalanNode*              sourceNode = 0,
                  const ElemTemplateElement*    styleNode = 0) const;

      virtual void
      error(
                  const XalanDOMString&   msg,
                  const LocatorType&            locator,
                  const XalanNode*        sourceNode = 0) const;

public:

      /**
       * Retrieve the result namespace corresponding to a prefix.
       * 
       * @param prefix prefix for namespace
       * @return string for namespace URI
       */
      const XalanDOMString*
      getResultNamespaceForPrefix(const XalanDOMString&     prefix) const;

      /**
       * Retrieve the result prefix corresponding to a namespace.
       * 
       * @param theNamespace namespace for prefix
       * @return string for namespace prefix
       */
      const XalanDOMString*
      getResultPrefixForNamespace(const XalanDOMString&     theNamespace) const;

      /**
       * Determine whether or not a prefix is in use on the pending element or
       * the pending attributes.
       * 
       * @param thePrefix prefix for namespace
       *
       * @return true if the prefix is in use, false if not.
       */
      bool
      isPendingResultPrefix(const XalanDOMString&           thePrefix) const;

      /**
       * Evaluate an xpath string and return the result as a numberic score.
       *
       * @param str                    string to evaluate
       * @param context          context node
       * @param executionContext current execution context
       * @return score number, higher representing better match
       */
      double
      evalMatchPatternStr(
                  const XalanDOMString&   str,
                  XalanNode*                    context,
                  XPathExecutionContext&  executionContext);

      /**
       * Create and initialize an xpath and return it.
       *
       * @param str        string for XPath
       * @param resolver resolver for namespace resolution
       * @return pointer to XPath created
       */
      const XPath*
      createMatchPattern(
                  const XalanDOMString&   str,
                  const PrefixResolver&   resolver);

      /**
       * Return the xpath created by createXPath() or
       * createMatchPattern().
       *
       * @param xpath      The XPath to return.
       */
      void
      returnXPath(const XPath*      xpath);

      /**
       * Copy XMLNS: attributes in if not already in scope.
       *
       * @param src                         source node
       */
      void
      copyNamespaceAttributes(const XalanNode&  src);

      /**
       * Evaluate an xpath string and return the result.
       *
       * @param str                    string to evaluate
       * @param executionContext current execution context
       * @return pointer to XObject result
       */
      const XObjectPtr
      evalXPathStr(
                  const XalanDOMString&   str,
                  XPathExecutionContext&  executionContext);

      /**
       * Evaluate an xpath string and return the result.
       * 
       * @param str                    string to evaluate
       * @param contextNode      context node
       * @param prefixResolver prefix resolver to use
       * @param executionContext current execution context
       * @return pointer to XObject result
       */
      const XObjectPtr
      evalXPathStr(
                  const XalanDOMString&   str,
                  XalanNode*                    contextNode,
                  const PrefixResolver&   prefixResolver,
                  XPathExecutionContext&  executionContext);

      /**
       * Evaluate an xpath string and return the result.
       * 
       * @param str                    string to evaluate
       * @param contextNode      context node
       * @param prefixResolver prefix resolver to use
       * @param executionContext current execution context
       * @return pointer to XObject result
       */
      const XObjectPtr
      evalXPathStr(
                  const XalanDOMString&   str,
                  XalanNode*                    contextNode,
                  const XalanElement&           prefixResolver,
                  XPathExecutionContext&  executionContext);

      /**
       * Copy an attribute to an AttributeListImpl.
       *
       * @param attrName The name of the attribute
       * @param attrValue The value of the attribute
       * @param attrList The attribute list added to
       */
      void
      copyAttributeToTarget(
                  const XalanDOMString&   attrName,
                  const XalanDOMString&   attrValue,
                  AttributeListImpl&            attrList);

      /**
       * Get the factory for making xpaths.
       *
       * @return XPath factory object
       */
      XPathFactory&
01013       getXPathFactory()
      {
            return m_xpathFactory;
      }

      /**
       * Get the XPath processor object.
       *
       * @return XPathProcessor interface being used
       */
      XPathProcessor&
01024       getXPathProcessor()
      {
            return *m_xpathProcessor.get();
      }

      /**
       * Reset the state.  This needs to be called after a process() call 
       * is invoked, if the processor is to be used again.
       */
      virtual void
      reset();

      /**
       * Retrieve the XPath environment support object
       *
       * @return XPath environment support object
       */
      XPathEnvSupport&
01042       getXPathEnvSupport()
      {
            return m_xpathEnvSupport;
      }

      /**
       * Set the problem listener property. The XSL class can have a single
       * listener that can be informed of errors and warnings, and can normally
       * control if an exception is thrown or not (or the problem listeners can
       * throw their own RuntimeExceptions).
       *
       * @param l pointer to ProblemListener interface
       */
      void
01056       setProblemListener(ProblemListener*       l)
      {
            m_problemListener = l;
      }

      /**
       * Get the problem listener property. The XSL class can have a single
       * listener that can be informed of errors and warnings, and can normally
       * control if an exception is thrown or not (or the problem listeners can
       * throw their own RuntimeExceptions).
       *
       * @return pointer to ProblemListener interface
       */
      ProblemListener*
01070       getProblemListener() const
      {
            return m_problemListener;
      }

      /*
       * Push a new output context using the provided FormatterListener.
       *
       * @param A pointer to the FormatterListener instance for the new context.
       */
      void
      pushOutputContext(FormatterListener*      theListener)
      {
            m_outputContextStack.pushContext(theListener);
      }

      /*
       * Pop the current output context.
       */
      void
      popOutputContext()
      {
            m_outputContextStack.popContext();
      }

      /*
       * See if there is a pending start document event waiting.
       * @return true if there is a start document event waiting.
       */
      bool
      getHasPendingStartDocument() const
      {
            return getHasPendingStartDocumentImpl();
      }

      /*
       * Set the pending start document event state.
       * @param the new value
       */
      void
      setHasPendingStartDocument(bool     b)
      {
            setHasPendingStartDocumentImpl(b);
      }

      /*
       * See if a pending start document event must be flushed.
       * @return true if the event must be flushed.
       */
      bool
      getMustFlushPendingStartDocument() const
      {
            return getMustFlushPendingStartDocumentImpl();
      }

      /*
       * Set the pending start document event flush state.
       * @param the new value
       */
      void
      setMustFlushPendingStartDocument(bool     b)
      {
            setMustFlushPendingStartDocumentImpl(b);
      }

      /**
       * Get the list of attributes yet to be processed
       * 
       * @return attribute list
       */
      const AttributeListType&
01141       getPendingAttributes() const
      {
            return getPendingAttributesImpl();
      }

      /**
       * Set the list of attributes yet to be processed
       * 
       * @param pendingAttributes The attribute list
       */
      void
01152       setPendingAttributes(const AttributeListType&   pendingAttributes)
      {
            getPendingAttributesImpl() = pendingAttributes;
      }

      /**
       * Replace the contents of a pending attribute.
       * 
       * @param theName           name of attribute
       * @param theNewType        type of attribute
       * @param theNewValue       new value of attribute
       */
      void
01165       replacePendingAttribute(
                  const XalanDOMChar*           theName,
                  const XalanDOMChar*           theNewType,
                  const XalanDOMChar*           theNewValue)
      {
            // Remove the old attribute, then add the new one.  AttributeListImpl::addAttribute()
            // does this for us.
            getPendingAttributesImpl().addAttribute(theName, theNewType, theNewValue);
      }

      bool
      isElementPending() const
      {
            return length(getPendingElementNameImpl()) != 0 ? true : false;
      }

      /**
       * Retrieve name of the pending element currently being processed.
       * 
       * @return element name
       */
      const XalanDOMString&
01187       getPendingElementName() const
      {
            return getPendingElementNameImpl();
      }

      /**
       * Changes the currently pending element name.
       * 
       * @param elementName new name of element
       */
      void
01198       setPendingElementName(const XalanDOMString&           elementName)
      {
            setPendingElementNameImpl(elementName);
      }

      void
      setPendingElementName(const XalanDOMChar* elementName)
      {
            setPendingElementNameImpl(elementName);
      }

      /**
       * Get the locator from the top of the locator stack.
       *
       * @return A pointer to the Locator, or 0 if there is nothing on the stack.
       */
      const LocatorType*
01215       getLocatorFromStack() const
      {
            return m_stylesheetLocatorStack.empty() == true ? 0 : m_stylesheetLocatorStack.back();
      }

      /**
       * Push a locator on to the locator stack.
       *
       * @param A pointer to the Locator to push.
       */
      void
01226       pushLocatorOnStack(const LocatorType*     locator)
      {
            m_stylesheetLocatorStack.push_back(locator);
      }

      /**
       * Pop the locator from the top of the locator stack.
       */
      void
01235       popLocatorStack()
      {
            if (m_stylesheetLocatorStack.empty() == false)
            {
                  m_stylesheetLocatorStack.pop_back();
            }
      }

protected:

      /**
       * Get the list of attributes yet to be processed
       * 
       * @return attribute list
       */
      const AttributeListImpl&
01251       getPendingAttributesImpl() const
      {
            return m_outputContextStack.getPendingAttributes();
      }

      /**
       * Get the list of attributes yet to be processed
       * 
       * @return attribute list
       */
      AttributeListImpl&
01262       getPendingAttributesImpl()
      {
            return m_outputContextStack.getPendingAttributes();
      }

      /**
       * Set the list of attributes yet to be processed
       * 
       * @param pendingAttributes The attribute list
       */
      void
01273       setPendingAttributesImpl(const AttributeListType&     pendingAttributes)
      {
            getPendingAttributesImpl() = pendingAttributes;
      }

      /**
       * Retrieve name of the pending element currently being processed.
       * 
       * @return element name
       */
      const XalanDOMString&
01284       getPendingElementNameImpl() const
      {
            return m_outputContextStack.getPendingElementName();
      }

      /**
       * Retrieve name of the pending element currently being processed.
       * 
       * @return element name
       */
      XalanDOMString&
01295       getPendingElementNameImpl()
      {
            return m_outputContextStack.getPendingElementName();
      }

      /**
       * Changes the currently pending element name.
       * 
       * @param elementName new name of element
       */
      void
01306       setPendingElementNameImpl(const XalanDOMString&       elementName)
      {
            m_outputContextStack.getPendingElementName() = elementName;
      }

      /**
       * Changes the currently pending element name.
       * 
       * @param elementName new name of element
       */
      void
01317       setPendingElementNameImpl(const XalanDOMChar*   elementName)
      {
            assert(elementName != 0);

            m_outputContextStack.getPendingElementName() = elementName;
      }

      /*
       * See if there is a pending start document event waiting.
       * @return true if there is a start document event waiting.
       */
      bool
      getHasPendingStartDocumentImpl() const
      {
            return m_outputContextStack.getHasPendingStartDocument();
      }

      /*
       * Set the pending start document event state.
       * @param the new value
       */
      void
      setHasPendingStartDocumentImpl(bool       b)
      {
            m_outputContextStack.getHasPendingStartDocument() = b;
      }

      /*
       * See if a pending start document event must be flushed.
       * @return true if the event must be flushed.
       */
      bool
      getMustFlushPendingStartDocumentImpl() const
      {
            return m_outputContextStack.getMustFlushPendingStartDocument();
      }

      /*
       * Set the pending start document event flush state.
       * @param the new value
       */
      void
      setMustFlushPendingStartDocumentImpl(bool b)
      {
            m_outputContextStack.getMustFlushPendingStartDocument() = b;
      }

      FormatterListener*
      getFormatterListenerImpl() const
      {
            return m_outputContextStack.getFormatterListener();
      }

      void
      setFormatterListenerImpl(FormatterListener*           flistener)
      {
            m_outputContextStack.getFormatterListener() = flistener;
      }

      /**
       * The namespace that the result tree conforms to.  A null value 
       * indicates that result-ns is not used and there is no checking. 
       * A empty string indicates that the result tree conforms to the 
       * default namespace.
       */
01382       XalanDOMString    m_resultNameSpacePrefix;

      /**
       * The URL that belongs to the result namespace.
       */
01387       XalanDOMString    m_resultNameSpaceURL;


      /**
       * Copy the attributes from the XSL element to the created 
       * output element.
       */
      void
      copyAttributesToAttList(
                  const XalanNode&  node,
                  AttributeListImpl&      attList);

      // Factory for creating xpaths.
      XPathFactory&                 m_xpathFactory;

      // Factory for creating xobjects
      XObjectFactory&         m_xobjectFactory;

      // The query/pattern-matcher object.
      const XPathProcessorPtrType         m_xpathProcessor;

      /**
       * Stack of Booleans to keep track of if we should be outputting 
       * cdata instead of escaped text.
       */
01412       BoolVectorType    m_cdataStack;

private:

      /**
       * Issue a warning that only text nodes can be copied.
       *
       * @param sourceNode node in source where error occurred
       * @param locator The Locator to use, if any.
       */
      void
      warnCopyTextNodesOnly(
                  const XalanNode*  sourceNode,
                  const LocatorType*      locator);

      /**
       * Clone a text node to the result tree
       *
       * @param node                            node to clone
       * @param overrideStrip             false if white space stripping should be done
       */
      void
      cloneToResultTree(
                  const XalanText&  node,
                  bool                    overrideStrip);

      /**
       * Determine if any pending attributes is a default
       * namespace.
       */
      bool
      pendingAttributesHasDefaultNS() const; 

      void
      addResultNamespace(
                  const XalanDOMString&   thePrefix,
                  const XalanDOMString&   theName,
                  const XalanNode&        theNode,
                  AttributeListImpl&            thePendingAttributes,
                  bool                          fOnlyIfPrefixNotPresent);

      void
      addResultNamespace(
                  const XalanNode&  theNode,
                  AttributeListImpl&      thePendingAttributes,
                  bool                    fOnlyIfPrefixNotPresent = false);

  /**
   * The top of this stack should contain the currently processed
   * stylesheet SAX locator object.
   */
01463       LocatorStack  m_stylesheetLocatorStack;

      /**
       * The XSL class can have a single listener that can be informed 
       * of errors and warnings, and can normally control if an exception
       * is thrown or not (or the problem listeners can throw their 
       * own RuntimeExceptions).
       */
01471       ProblemListenerDefault  m_defaultProblemListener;

      ProblemListener*  m_problemListener;

      /**
       * The root of a linked set of stylesheets.
       */
01478       const StylesheetRoot*                     m_stylesheetRoot;

      /**
       * The namespace that we must match as a minimum for XSLT.
       */
01483       static const XalanDOMString&        s_XSLNameSpaceURL;      //"http://www.w3.org/1999/XSL/Transform"

      /**
       * Special Xalan namespace for built-in extensions.
       */
01488       static const XalanDOMString&        s_XalanNamespaceURL; // "http://xml.apache.org/xalan"

      /**
       * Prefix to use when generating unique namespaces.
       */
01493       static const XalanDOMString&        s_uniqueNamespacePrefix;

      /**
       * If this is set to true, selects will be traced
       */
01498       bool  m_traceSelects;

      /**
       * If this is set to true, do not warn about pattern 
       * match conflicts.
       */
01504       bool  m_quietConflictWarnings;

      /*
       * A stream to print diagnostics to.
       */
      PrintWriter*      m_diagnosticsPrintWriter;

      /**
       * List of listeners who are interested in tracing what's 
       * being generated.
       */
01515       TraceListenerVectorType       m_traceListeners;
      
      void
      problem(
                  const XalanDOMString&                     msg, 
                  ProblemListener::eClassification    classification,
                  const XalanNode*                          sourceNode,
                  const ElemTemplateElement*                styleNode) const;

      void
      problem(
                  const XalanDOMString&                     msg, 
                  ProblemListener::eClassification    classification,
                  const LocatorType&                              locator,
                  const XalanNode*                          sourceNode) const;

  //==========================================================
  // SECTION: Function to do with attribute handling
  //==========================================================

      /**
       * This is used whenever a unique namespace is needed.
       */
01538       unsigned long           m_uniqueNSValue;

      ParamVectorType   m_topLevelParams;

public:

      /**
       * Reset the vector of top level parameters
       */
      void
01548       clearTopLevelParams()
      {
            m_topLevelParams.clear();
      }

private:

      bool
      generateCDATASection() const
      {
            if (m_hasCDATASectionElements == false)
            {
                  return false;
            }
            else
            {
                  assert(m_cdataStack.empty() == false);

                  return m_cdataStack.back();
            }
      }

      void
      doFlushPending()
      {
            setMustFlushPendingStartDocument(true);

            flushPending();
      }

      /**
       * Tell if a given element name should output its text 
       * as cdata.
       *
       * @param elementName name of element
       * @return true if it should output as cdata
       */
      bool
      isCDataResultElem(const XalanDOMString&         elementName) const;

      void
      fireCharacterGenerateEvent(
                  const XalanNode&  theNode,
                  bool                    isCDATA);

      void
      fireCharacterGenerateEvent(
                  const XObjectPtr& theXObject,
                  bool                    isCDATA);

      void
      fireCharacterGenerateEvent(
                  const XalanDOMString&   theString,
                  bool                          isCDATA);

      void
      fireCharacterGenerateEvent(
                  const XalanDOMChar*                 ch,
                  XalanDOMString::size_type     start,
                  XalanDOMString::size_type     length,
                  bool                                isCDATA);

      void
      checkDefaultNamespace(
                  const XalanDOMString&   theElementName,
                  const XalanDOMString&   theElementNamespaceURI);



      // Data members...
      XMLParserLiaison& m_parserLiaison;

      XPathEnvSupport&  m_xpathEnvSupport;

      DOMSupport&             m_domSupport;

      /**
       * Current execution context...
       */
01627       StylesheetExecutionContext*         m_executionContext;

      /*
       * Stack of current output contexts...
       */
      OutputContextStack                        m_outputContextStack;

      /*
       * Stack of current result namespaces...
       */
      XalanNamespacesStack                m_resultNamespacesStack;

      /*
       * Dummy AttributeListImpl
       */
      AttributeListImpl                         m_dummyAttributesList;

      XalanDOMString                                  m_scratchString;

      XalanDOMStringPointerVectorType           m_attributeNamesVisited;

      bool                                            m_hasCDATASectionElements;

      XPathConstructionContextDefault           m_xpathConstructionContext;

      static void
      installFunctions(MemoryManagerType& theManager);

      static void
      uninstallFunctions();


      static const XalanDOMString         s_emptyString;

      static const XalanDOMString&  s_stylesheetNodeName;
      static const XalanDOMString&  s_typeString;
      static const XalanDOMString&  s_hrefString;
      static const XalanDOMString&  s_piTokenizerString;
      static const XalanDOMString&  s_typeValueString1;
      static const XalanDOMString&  s_typeValueString2;
      static const XalanDOMString&  s_typeValueString3;
      static const XalanDOMString&  s_typeValueString4;

      // Not implemented...
    XSLTEngineImpl(const XSLTEngineImpl&);

    XSLTEngineImpl&
    operator=(const XSLTEngineImpl&);

    bool
    operator==(const XSLTEngineImpl&) const;
};



XALAN_CPP_NAMESPACE_END



#endif      // XALAN_XSLTENGINEIMPL_HEADER_GUARD

Generated by  Doxygen 1.6.0   Back to index