blob: b1159747cbc460ba9c4b3d35f5ae2f5ae7a4fdd9 [file] [log] [blame]
/*
* 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.
*/
#if !defined(STYLESHEETEXECUTIONCONTEXT_HEADER_GUARD_1357924680)
#define STYLESHEETEXECUTIONCONTEXT_HEADER_GUARD_1357924680
// Base include file. Must be first.
#include <xalanc/XSLT/XSLTDefinitions.hpp>
#include <cstddef>
#include <cstdio>
#include <memory>
// Base class header file...
#include <xalanc/XPath/XPathExecutionContext.hpp>
#include <xalanc/XalanDOM/XalanDOMString.hpp>
#if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION)
#include <xalanc/PlatformSupport/XalanNumberFormat.hpp>
#endif
#include <xalanc/Include/XalanMemMgrAutoPtr.hpp>
#include <xalanc/PlatformSupport/AttributeListImpl.hpp>
#include <xalanc/PlatformSupport/FormatterListener.hpp>
#include <xalanc/PlatformSupport/XalanCollationServices.hpp>
#include <xalanc/XSLT/TopLevelArg.hpp>
namespace XALAN_CPP_NAMESPACE {
using std::FILE;
class CountersTable;
class ElemTemplate;
class ElemTemplateElement;
class ElemVariable;
class FormatterListener;
class FormatterToText;
class GenerateEvent;
class PrefixResolver;
class NodeRefListBase;
class NodeSorter;
class PrintWriter;
class XalanQName;
class SelectionEvent;
class Stylesheet;
class StylesheetRoot;
class XalanOutputStream;
class TracerEvent;
class Writer;
class XalanDocument;
class XalanDocumentFragment;
class XalanElement;
class XalanNode;
class XalanNumberFormat;
class XPath;
class XObject;
class XObjectPtr;
class XResultTreeFrag;
//
// An abstract class which provides support for executing stylesheets.
//
class XALAN_XSLT_EXPORT StylesheetExecutionContext : public XPathExecutionContext
{
public:
typedef XalanSize_t tl_size_type;
typedef FormatterListener::size_type fl_size_type;
typedef std::ostream StreamType;
explicit
StylesheetExecutionContext(
MemoryManager& theMemoryManager,
XObjectFactory* theXObjectFactory = 0);
virtual
~StylesheetExecutionContext();
// These interfaces are new...
/**
* Determine whether conflicts should be reported.
*
* @return true if conflicts should not be warned
*/
virtual bool
getQuietConflictWarnings() const = 0;
/**
* If this function returns true, only text nodes can
* be copied to the result tree.
*
* @return true or false
*/
virtual bool
getCopyTextNodesOnly() const = 0;
/**
* Set the flag that determines if only text nodes
* can be copied to the result tree.
*
* @param copyTextNodesOnly The value of the flag
*/
virtual void
pushCopyTextNodesOnly(bool copyTextNodesOnly) = 0;
/**
* Pop the last flag setting that determines if only text nodes
* can be copied to the result tree.
*/
virtual bool
popCopyTextNodesOnly() = 0;
/*
* A class to manage setting and restoring the flag
* for restricting copying only text nodes to the
* result tree
*/
class SetAndRestoreCopyTextNodesOnly
{
public:
SetAndRestoreCopyTextNodesOnly(
StylesheetExecutionContext& executionContext,
bool fValue) :
m_executionContext(executionContext)
{
executionContext.pushCopyTextNodesOnly(fValue);
}
~SetAndRestoreCopyTextNodesOnly()
{
m_executionContext.popCopyTextNodesOnly();
}
private:
// Not implemented...
SetAndRestoreCopyTextNodesOnly(const SetAndRestoreCopyTextNodesOnly&);
SetAndRestoreCopyTextNodesOnly&
operator=(const SetAndRestoreCopyTextNodesOnly&);
// Data members...
StylesheetExecutionContext& m_executionContext;
};
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/**
* Set the flag that determines if the current attribute should be executed
* @param processAttribute the value of the flag
*/
virtual void
pushProcessCurrentAttribute(bool processAttribute) = 0;
/**
* Pops the last flag setting that determines if the current attribute should be executed
*/
virtual bool
popProcessCurrentAttribute() = 0;
/**
* Set the flag that determines if an element's attributes should be skipped
*
* @param skipAttributes the value of the flag
*/
virtual void
pushSkipElementAttributes(bool skipAttributes) = 0;
/**
* Get the last flag setting that determines if an element's attributes should be skipped
* @returns the value of the flag
*/
virtual bool
getSkipElementAttributes() const = 0;
/**
* Pops the last flag setting that determines if an element's attributes should be skipped
*/
virtual bool
popSkipElementAttributes() = 0;
/**
* Set flag that determines if the if test was true
*
* @param executeIf the value of the flag
*/
virtual void
pushExecuteIf(bool executeIf) = 0;
/**
* Pop the flag that determines if the if test was true
*
* @param executeIf the value of the flag
*/
virtual bool
popExecuteIf() = 0;
#endif
/**
* Retrieve root document for stylesheet. Note that
* this does not have to be a XalanDocument -- it can
* be any node in a document.
*
* @return root document
*/
virtual XalanNode*
getRootDocument() const = 0;
/**
* Set root document for stylesheet. Note that
* this does not have to be a XalanDocument -- it can
* be any node in a document.
*
* @param theDocument root document
*/
virtual void
setRootDocument(XalanNode* theDocument) = 0;
/**
* Set root stylesheet for stylesheet.
*
* @param theStylesheet root stylesheet
*/
virtual void
setStylesheetRoot(const StylesheetRoot* theStylesheet) = 0;
/**
* Retrieve the current mode.
*
* @return QName for mode
*/
virtual const XalanQName*
getCurrentMode() const = 0;
/**
* Set the current mode.
*
* @param theMode QName for mode
*/
virtual void
pushCurrentMode(const XalanQName* theMode) = 0;
/**
* Pop the current mode
*/
virtual void
popCurrentMode() =0;
/**
* Retrieve the current template
*
* @return The current template instance or null if there is no current template
*/
virtual const ElemTemplate*
getCurrentTemplate() const = 0;
/**
* Set the current template
*
* @param theTemplate The current template instance
*/
virtual void
pushCurrentTemplate(const ElemTemplate* theTemplate) = 0;
virtual void
popCurrentTemplate() = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/*
* A class to manage pushing and popping the current
* template instance.
*/
class PushAndPopCurrentTemplate
{
public:
PushAndPopCurrentTemplate(
StylesheetExecutionContext& executionContext,
const ElemTemplate* theTemplate) :
m_executionContext(executionContext)
{
executionContext.pushCurrentTemplate(theTemplate);
}
~PushAndPopCurrentTemplate()
{
m_executionContext.popCurrentTemplate();
}
private:
// Data members...
StylesheetExecutionContext& m_executionContext;
};
#endif
/**
* See if there is an element pending.
*/
virtual bool
isElementPending() const = 0;
/**
* Replace the contents of a pending attribute.
*
* @param theName name of attribute
* @param theNewType type of attribute
* @param theNewValue new value of attribute
*/
virtual void
replacePendingAttribute(
const XalanDOMChar* theName,
const XalanDOMChar* theNewType,
const XalanDOMChar* theNewValue) = 0;
/**
* Get the current formatter listener.
*
* @return pointer to formatter listener
*/
virtual FormatterListener*
getFormatterListener() const = 0;
/**
* Set the current formatter listener.
*
* @param flistener pointer to new formatter listener
*/
virtual void
setFormatterListener(FormatterListener* flistener) = 0;
virtual void
pushOutputContext(FormatterListener* flistener = 0) = 0;
virtual void
popOutputContext() = 0;
class OutputContextPushPop
{
public:
/**
* Construct an object to push and pop the current output context.
*
* @param theExecutionContext a reference to the current execution context
* @param theNewListener the new FormatterListener to set.
*/
OutputContextPushPop(
StylesheetExecutionContext& theExecutionContext,
FormatterListener* theNewListener = 0) :
m_executionContext(theExecutionContext)
{
m_executionContext.pushOutputContext(theNewListener);
}
~OutputContextPushPop()
{
m_executionContext.popOutputContext();
}
private:
StylesheetExecutionContext& m_executionContext;
};
/**
* Add a result attribute to the list of pending attributes.
*
* @param aname name of attribute
* @param value value of attribute
*/
virtual void
addResultAttribute(
const XalanDOMString& aname,
const XalanDOMString& value) = 0;
/**
* Add a result attribute to the list of pending attributes.
*
* @param aname name of attribute
* @param value value of attribute
*/
virtual void
addResultAttribute(
const XalanDOMString& aname,
const XalanDOMChar* value) = 0;
/**
* Add namespace attributes for a node to the list of pending attributes.
*
* @param src source node
*/
virtual void
copyNamespaceAttributes(const XalanNode& src) = 0;
/**
* Retrieve the result prefix corresponding to a namespace.
*
* @param theNamespace namespace for prefix
*
* @return A pointer to a string containing the prefix, or 0 if the namespace is not mapped.
*/
virtual const XalanDOMString*
getResultPrefixForNamespace(const XalanDOMString& theNamespace) const = 0;
/**
* Retrieve the result namespace corresponding to a prefix.
*
* @param thePrefix prefix for namespace
*
* @return A pointer to a string containing the namespace, or 0 if the prefix is not mapped.
*/
virtual const XalanDOMString*
getResultNamespaceForPrefix(const XalanDOMString& thePrefix) const = 0;
/**
* 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.
*/
virtual bool
isPendingResultPrefix(const XalanDOMString& thePrefix) = 0;
/**
* Generate a random namespace prefix guaranteed to be unique.
*
* @param theValue A string for returning the new prefix
*/
virtual void
getUniqueNamespaceValue(XalanDOMString& theValue) const = 0;
/**
* Retrieve the current number of spaces to indent.
*
* @return number of spaces
*/
virtual int
getIndent() const = 0;
/**
* Set the current number of spaces to indent.
*
* @param indentAmount The number of spaces to indent. Use -1 for the default amount.
*/
virtual void
setIndent(int indentAmount) = 0;
/**
* Create and initialize an xpath and return it. This is to be used to
* create an XPath that is only used during execution.
*
* @param str string expression for XPath evaluation
* @param resolver resolver for namespace resolution
* @return pointer to resulting XPath
*/
virtual const XPath*
createMatchPattern(
const XalanDOMString& str,
const PrefixResolver& resolver) = 0;
/**
* Return the XPath created by createMatchPattern().
*
* @param xpath The XPath to return.
*/
virtual void
returnXPath(const XPath* xpath) = 0;
// A helper class to automatically return an XPath instance.
class XPathGuard
{
public:
XPathGuard(
StylesheetExecutionContext& context,
const XPath* xpath = 0) :
m_context(context),
m_xpath(xpath)
{
}
~XPathGuard()
{
if (m_xpath != 0)
{
m_context.returnXPath(m_xpath);
}
}
const XPath*
get() const
{
return m_xpath;
}
const XPath*
release()
{
const XPath* const temp = m_xpath;
m_xpath = 0;
return temp;
}
void
reset(const XPath* xpath)
{
if (m_xpath != 0)
{
m_context.returnXPath(m_xpath);
}
m_xpath = xpath;
}
private:
StylesheetExecutionContext& m_context;
const XPath* m_xpath;
};
typedef XalanVector<TopLevelArg> ParamVectorType;
/**
* Set a list of top level variables in the specified execution context
* stylesheet.
*
* @param topLevelParams list of top level parameters
*/
virtual void
pushTopLevelVariables(const ParamVectorType& topLevelParams) = 0;
/**
* Execute the supplied XPath and and create a
* variable in the current context.
*
* @param str string expression for XPath evaluation
* @param contextNode current node in the source tree
* @param resolver resolver for namespace resolution
* @return a pointer to the XObject result
*/
virtual const XObjectPtr
createVariable(
const XPath& xpath,
XalanNode* contextNode,
const PrefixResolver& resolver) = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/**
* Create an ResultTreeFragment as a variable and push it
* on to the stack with the current context.
*
* @param templateChild result tree fragment to use.
* @param sourceNode source node
* @return a pointer to the XObject result
*/
virtual const XObjectPtr
createVariable(
const ElemTemplateElement& templateChild,
XalanNode* sourceNode) = 0;
#endif
/**
* Execute an XPath using the provided expression,
* and push the result as a variable in the context of
* the supplied element.
*
* @param name name of variable
* @param element element marker for variable
* @param str string expression for XPath evaluation
* @param contextNode current node in the source tree
* @param resolver resolver for namespace resolution
* @return nothing
*/
virtual void
pushVariable(
const XalanQName& name,
const ElemTemplateElement* element,
const XalanDOMString& str,
XalanNode* contextNode,
const PrefixResolver& resolver) = 0;
/**
* Execute the supplied XPath and push the result as a
* variable in the current context.
*
* @param name name of variable
* @param element element marker for variable
* @param str string expression for XPath evaluation
* @param contextNode current node in the source tree
* @param resolver resolver for namespace resolution
* @return nothing
*/
virtual void
pushVariable(
const XalanQName& name,
const ElemTemplateElement* element,
const XPath& xpath,
XalanNode* contextNode,
const PrefixResolver& resolver) = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/**
* Create an ResultTreeFragment as a variable and push it
* on to the stack with the current context.
*
* @param name name of variable
* @param element element marker for variable
* @param templateChild result tree fragment to use.
* @param sourceNode source node
*/
virtual void
pushVariable(
const XalanQName& name,
const ElemTemplateElement* element,
const ElemTemplateElement& templateChild,
XalanNode* sourceNode) = 0;
#endif
/**
* Push a named variable onto the variables stack.
* The variable has already been evaluated.
*
* @param name name of variable
* @param val pointer to XObject value
* @param element element marker for variable
*/
virtual void
pushVariable(
const XalanQName& name,
const XObjectPtr val,
const ElemTemplateElement* element) = 0;
/**
* Push a named variable onto the processor variable stack
* The variable will be evaluated when first referenced.
*
* @param name name of variable
* @param var pointer to ElemVariable instance
* @param element element marker for variable
*/
virtual void
pushVariable(
const XalanQName& name,
const ElemVariable* var,
const ElemTemplateElement* element) = 0;
/**
* Push a context marker onto the stack to let us know when to stop
* searching for a var.
*/
virtual void
pushContextMarker() = 0;
/**
* Pop the current context from the current context stack.
*/
virtual void
popContextMarker() = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/*
* A class to manage pushing and popping an element's stack
* frame context.
*/
class PushAndPopContextMarker
{
public:
PushAndPopContextMarker(StylesheetExecutionContext& executionContext) :
m_executionContext(executionContext)
{
executionContext.pushContextMarker();
}
PushAndPopContextMarker(
StylesheetExecutionContext& executionContext,
int& currentStackFrameIndex) :
m_executionContext(executionContext)
{
currentStackFrameIndex = executionContext.getCurrentStackFrameIndex();
executionContext.pushContextMarker();
}
~PushAndPopContextMarker()
{
m_executionContext.popContextMarker();
}
StylesheetExecutionContext&
getExecutionContext() const
{
return m_executionContext;
}
private:
StylesheetExecutionContext& m_executionContext;
};
#endif
/**
* Resolve the params that were pushed by the caller.
*/
virtual void
resolveTopLevelParams() = 0;
/**
* Reset the vector of top level parameters.
*/
virtual void
clearTopLevelParams() = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
class ResolveAndClearTopLevelParams
{
public:
ResolveAndClearTopLevelParams(StylesheetExecutionContext& executionContext) :
m_executionContext(executionContext)
{
m_executionContext.resolveTopLevelParams();
}
~ResolveAndClearTopLevelParams()
{
m_executionContext.clearTopLevelParams();
}
private:
StylesheetExecutionContext& m_executionContext;
};
/**
* Given a template, search for the arguments and push them on the stack.
* Also, push default arguments on the stack.
*
* @param xslCallTemplateElement "call-template" element
*/
virtual void
pushParams(const ElemTemplateElement& xslCallTemplateElement) = 0;
#else
/**
* Initiate context to accept a new set of parameters
*/
virtual void beginParams() = 0;
/**
* Indicate parameter set is complete
*/
virtual void endParams() = 0;
/**
* Push a single paramter onto the latest initialized paramter set
* @param qName the name of the parameter
* @param theValue the value of the parameter
*/
virtual void pushParam(const XalanQName& qName,const XObjectPtr& theValue) = 0;
#endif
/**
* Given a name, return a string representing the value, but don't look in
* the global space.
*
* @param theName name of variable
* @return An XObjectPtr instance. Call XObjectPtr::null() on the instance
* to determine if the variable was found. If XObjectPtr::null()
* returns true, the variable was not found, and no other operations
* on the XObject instance are permitted.
*/
virtual const XObjectPtr
getParamVariable(const XalanQName& theName) = 0;
/**
* Push a frame marker for an element.
*
* @param elem the element
*/
virtual void
pushElementFrame(const ElemTemplateElement* elem) = 0;
/**
* Pop a frame marker for an element.
*
* @param elem the element
*/
virtual void
popElementFrame() = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/*
* A class to manage pushing and popping an element's stack
* frame context.
*/
class PushAndPopElementFrame
{
public:
PushAndPopElementFrame(
StylesheetExecutionContext& executionContext,
const ElemTemplateElement* element) :
m_executionContext(executionContext)
{
executionContext.pushElementFrame(element);
}
~PushAndPopElementFrame()
{
m_executionContext.popElementFrame();
}
private:
StylesheetExecutionContext& m_executionContext;
};
#endif
/**
* Get the top of the global stack frame.
*
* @return current value of index
*/
virtual int
getGlobalStackFrameIndex() const = 0;
/**
* Get the top of the stack frame from where a search
* for a variable or param should take place.
*
* @return current value of index
*/
virtual int
getCurrentStackFrameIndex() const = 0;
/**
* Set the top of the stack frame from where a search
* for a variable or param should take place.
*
* @param currentStackFrameIndex new value of index
*/
virtual void
pushCurrentStackFrameIndex(int currentStackFrameIndex = -1) = 0;
/**
* Pop the last stack frame index setting
*/
virtual void
popCurrentStackFrameIndex() = 0;
/*
* A class to manage the state of the variable stacks frame index.
*/
class SetAndRestoreCurrentStackFrameIndex
{
public:
SetAndRestoreCurrentStackFrameIndex(
StylesheetExecutionContext& executionContext,
int newIndex) :
m_executionContext(executionContext),
m_savedIndex(executionContext.getCurrentStackFrameIndex())
{
executionContext.pushCurrentStackFrameIndex(newIndex);
}
~SetAndRestoreCurrentStackFrameIndex()
{
m_executionContext.popCurrentStackFrameIndex();
}
private:
StylesheetExecutionContext& m_executionContext;
const int m_savedIndex;
};
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/*
* A class to manage stack state during execution.
*/
class ParamsPushPop : public PushAndPopContextMarker
{
public:
ParamsPushPop(
StylesheetExecutionContext& executionContext,
const ElemTemplateElement& xslCallTemplateElement) :
PushAndPopContextMarker(executionContext)
{
doPush(xslCallTemplateElement);
}
ParamsPushPop(
StylesheetExecutionContext& executionContext,
const ElemTemplateElement& xslCallTemplateElement,
int& savedStackFrameIndex) :
PushAndPopContextMarker(executionContext, savedStackFrameIndex)
{
doPush(
xslCallTemplateElement,
savedStackFrameIndex);
}
~ParamsPushPop()
{
}
private:
void
doPush(
const ElemTemplateElement& xslCallTemplateElement,
int stackFrameIndex);
void
doPush(const ElemTemplateElement& xslCallTemplateElement);
};
#endif
/**
* Receive notification of the beginning of a document.
*
* <p>The SAX parser will invoke this method only once, before any
* other methods in this interface or in DTDHandler (except for
* setDocumentLocator).</p>
*
* @exception SAXException
*/
virtual void
startDocument() = 0;
/**
* Receive notification of the end of a document.
*
* <p>The SAX parser will invoke this method only once, and it will
* be the last method invoked during the parse. The parser shall
* not invoke this method until it has either abandoned parsing
* (because of an unrecoverable error) or reached the end of
* input.</p>
*
* @exception SAXException
*/
virtual void
endDocument() = 0;
/**
* Receive notification of the beginning of an element.
*
* @param name element type name
*/
virtual void
startElement(const XalanDOMChar* name) = 0;
/**
* Receive notification of the end of an element.
*
* @param name element type name
*/
virtual void
endElement(const XalanDOMChar* name) = 0;
/**
* Receive notification of character data.
*
* @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
*/
virtual void
characters(
const XalanDOMChar* ch,
fl_size_type start,
fl_size_type length) = 0;
/**
* 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
*/
virtual void
charactersRaw(
const XalanDOMChar* ch,
fl_size_type start,
fl_size_type length) = 0;
/**
* Called when a Comment is to be constructed.
*
* @param data pointer to comment data
*/
virtual void
comment(const XalanDOMChar* data) = 0;
/**
* Receive notification of a processing instruction.
*
* @param target processing instruction target
* @param data processing instruction data, or null if none was supplied
*/
virtual void
processingInstruction(
const XalanDOMChar* target,
const XalanDOMChar* data) = 0;
/**
* Flush the pending element.
*/
virtual void
flushPending() = 0;
/**
* Clone a node to the result tree
*
* @param node node to clone
* @param locator The Locator, if any
*/
virtual void
cloneToResultTree(
const XalanNode& node,
const Locator* locator) = 0;
/**
* 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 locator The Locator, if any
*/
virtual void
cloneToResultTree(
const XalanNode& node,
XalanNode::NodeType nodeType,
bool overrideStrip,
bool shouldCloneAttributes,
const Locator* locator) = 0;
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/**
* Initiate creation of a result tree fragment
* @param sourceNode the source Node
*/
virtual void
beginCreateXResultTreeFrag(
XalanNode* sourceNode) = 0;
/**
* Indicate sthe completion of result tree fragment
* @return a pointer to the result tree fragment
*/
virtual const XObjectPtr
endCreateXResultTreeFrag() = 0;
/**
* Initiate to put execution result in string
*
* @param theResult the string to contain the result
*/
virtual void
beginFormatToText(
XalanDOMString& theResult) = 0;
/**
* Indicates the completion of the result string
*
*/
virtual void
endFormatToText() = 0;
#else
/**
* Create an XObject that represents a Result tree fragment.
*
* @param templateChild result tree fragment to use.
* @param sourceNode source node
* @return XObject instance
*/
virtual const XObjectPtr
createXResultTreeFrag(
const ElemTemplateElement& templateChild,
XalanNode* sourceNode) = 0;
#endif
/**
* Output an object to the result tree by doing the right conversions.
* This is public for access by extensions.
*
* @param obj the XObject to output
* @param locator The Locator, if any
*/
virtual void
outputToResultTree(
const XObject& xobj,
const Locator* locator) = 0;
/**
* Given a result tree fragment, walk the tree and
* output it to the result stream.
*
* @param theTree result tree fragment
* @param locator The Locator, if any
*/
virtual void
outputResultTreeFragment(
const XObject& theTree,
const Locator* locator) = 0;
/**
* Determine the full XSLT Namespace URI.
*
* @return Xalan namespace URI
*/
virtual const XalanDOMString&
getXSLNameSpaceURL() const = 0;
/**
* Special Xalan namespace for built-in extensions.
*
* @return Xalan namespace for extensions
*/
virtual const XalanDOMString&
getXalanXSLNameSpaceURL() const = 0;
/**
* Determine if an element is on the recursion stack.
*
* @return true if element on stack
*/
virtual bool
findOnElementRecursionStack(const ElemTemplateElement* theElement) const = 0;
/**
* Push an element onto the recursion stack.
*
* @param theElement pointer to element to push
*/
virtual void
pushOnElementRecursionStack(const ElemTemplateElement* theElement) = 0;
/**
* Pop an element off the recursion stack.
*
* @return pointer to element popped
*/
virtual const ElemTemplateElement*
popElementRecursionStack() = 0;
/**
* Class for keeping track of elements pushed on the element recursion stack
*/
class ElementRecursionStackPusher
{
public:
/**
* Construct an instance of the recursion stack pusher.
*
* @param executionContext current execution context
* @param element pointer to element to push
*/
ElementRecursionStackPusher(
StylesheetExecutionContext& executionContext,
const ElemTemplateElement* element) :
m_executionContext(executionContext)
{
m_executionContext.pushOnElementRecursionStack(element);
}
~ElementRecursionStackPusher()
{
m_executionContext.popElementRecursionStack();
}
private:
StylesheetExecutionContext& m_executionContext;
};
/**
* This is a hook that XResultTreeFrag instances (which are reference
* counted), can notify the owning StylesheetExecutionContext instance
* when they are dereferenced and can be cleaned up.
*
* @param theXResultTreeFrag The instance that is being returned.
*
* @return true if the XResultTreeFrag instance belongs to the execution context. false if not.
*/
virtual bool
returnXResultTreeFrag(XResultTreeFrag* theXResultTreeFrag) = 0;
enum eDummy
{
eDefaultXMLIndentAmount = 0,
eDefaultHTMLIndentAmount = 0
};
/**
* Enums to determine whether or not run-time escaping of URLs has been set.
*/
enum eEscapeURLs
{
eEscapeURLsDefault, // Use the value in the stylesheet
eEscapeURLsNo, // Don't escape URLs
eEscapeURLsYes // Escape URLs
};
/**
* Get the value for run-time escaping of URLs. This can
* override the property specified by the stylesheet. The
* default behavior is to honor the property in the stylesheet.
*
* @return The value of the enum
*/
virtual eEscapeURLs
getEscapeURLs() const = 0;
/**
* Set the value for run-time escaping of URLs. This can
* override the property specified by the stylesheet. The
* default behavior is to honor the property in the stylesheet.
*
* @param value The value of the enum
*/
virtual void
setEscapeURLs(eEscapeURLs value) = 0;
/**
* Enums to determine whether or not run-time omission of the META tag has been set.
*/
enum eOmitMETATag
{
eOmitMETATagDefault, // Use the value in the stylesheet
eOmitMETATagNo, // Don't omit the META tag
eOmitMETATagYes // Omit the META tag
};
/**
* Get the value for run-time omission of URLs. This can
* override the property specified by the stylesheet. The
* default behavior is to honor the property in the stylesheet.
*
* @return The value of the enum
*/
virtual eOmitMETATag
getOmitMETATag() const = 0;
/**
* Get the value for run-time omission of URLs. This can
* override the property specified by the stylesheet. The
* default behavior is to honor the property in the stylesheet.
*
* @param value The value of the enum
*/
virtual void
setOmitMETATag(eOmitMETATag value) = 0;
/**
* Create a new FormatterToXML instance. The execution context
* owns the instance and will delete it when reset.
*
* @param writer character output stream to use
* @param version version of the output method
* @param doIndent true if output is to be indented
* @param indent number of spaces to indent at each nesting level
* @param encoding character encoding for the writer
* @param mediaType media type (MIME content type) of the data
* @param doctypeSystem system identifier to be used in the document
* type declaration
* @param doctypePublic public identifier to be used in the document
* type declaration
* @param xmlDecl true if the XSLT processor should output an XML
* declaration
* @param standalone true if the XSLT processor should output a
* standalone document declaration
* @return a pointer to the new instance.
*/
virtual FormatterListener*
createFormatterToXML(
Writer& writer,
const XalanDOMString& version = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
bool doIndent = false,
int indent = eDefaultXMLIndentAmount,
const XalanDOMString& encoding = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
const XalanDOMString& mediaType = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
const XalanDOMString& doctypeSystem = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
const XalanDOMString& doctypePublic = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
bool xmlDecl = true,
const XalanDOMString& standalone = XalanDOMString(XalanMemMgrs::getDummyMemMgr())) = 0;
/**
* Create a new FormatterToHTML instance. The execution context
* owns the instance and will delete it when reset.
*
* @param writer character output stream to use
* @param encoding character encoding for the writer
* @param mediaType media type (MIME content type) of the data
* @param doctypeSystem system identifier to be used in the document
* type declaration
* @param doctypePublic public identifier to be used in the document
* type declaration
* @param doIndent true if output is to be indented
* @param indent number of spaces to indent at each nesting level
* @param escapeURLs Whether or not to escape URLs according to the recommendation. The default is true.
* @param omitMetaTag Whether or not to output a META TAG according to the recommendation. The default is false.
* @return a pointer to the new instance.
*/
virtual FormatterListener*
createFormatterToHTML(
Writer& writer,
const XalanDOMString& encoding = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
const XalanDOMString& mediaType = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
const XalanDOMString& doctypeSystem = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
const XalanDOMString& doctypePublic = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
bool doIndent = true,
int indent = eDefaultHTMLIndentAmount,
bool escapeURLs = true,
bool omitMetaTag = false) = 0;
/**
* FormatterToText instance constructor.
*
* @param writer writer for output
* @param encoding character encoding for the writer
*/
virtual FormatterListener*
createFormatterToText(
Writer& writer,
const XalanDOMString& encoding) = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
class BorrowReturnFormatterToText
{
public:
BorrowReturnFormatterToText(
StylesheetExecutionContext& executionContext,
Writer& writer,
bool normalizeLinefeed = true,
bool handleIgnorableWhitespace = true);
~BorrowReturnFormatterToText()
{
assert(m_formatter != 0);
m_executionContext.returnFormatterToText(m_formatter);
}
FormatterToText&
operator*() const
{
assert(m_formatter != 0);
return *m_formatter;
}
FormatterToText*
get() const
{
assert(m_formatter != 0);
return m_formatter;
}
FormatterToText*
operator->() const
{
return get();
}
private:
StylesheetExecutionContext& m_executionContext;
FormatterToText* m_formatter;
};
friend class BorrowReturnFormatterToText;
#endif
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/**
* Get node sorter instance
*/
virtual NodeSorter*
getNodeSorter() = 0;
#else
/**
* Borrow a cached NodeSorter instance.
*
* @return A pointer to the instance.
*/
virtual NodeSorter*
borrowNodeSorter() = 0;
/**
* Return a previously borrowed NodeSorter instance.
*
* @param theSorter A pointer the to previously borrowed instance.
* @return true if the instance was previously borrowed, false if not.
*/
virtual bool
returnNodeSorter(NodeSorter* theSorter) = 0;
class BorrowReturnNodeSorter
{
public:
BorrowReturnNodeSorter(StylesheetExecutionContext& executionContext) :
m_executionContext(executionContext),
m_sorter(executionContext.borrowNodeSorter())
{
assert(m_sorter != 0);
}
~BorrowReturnNodeSorter()
{
assert(m_sorter != 0);
m_executionContext.returnNodeSorter(m_sorter);
}
NodeSorter&
operator*() const
{
assert(m_sorter != 0);
return *m_sorter;
}
NodeSorter*
get() const
{
assert(m_sorter != 0);
return m_sorter;
}
NodeSorter*
operator->() const
{
return get();
}
private:
StylesheetExecutionContext& m_executionContext;
NodeSorter* m_sorter;
};
#endif
typedef XalanMemMgrAutoPtr<XalanNumberFormat> XalanNumberFormatAutoPtr;
/**
* Create a new XalanNumberFormat instance.
*
* @return an XalanNumberFormatAutoPtr that owns a new
* XalanNumberFormat instance.
*/
virtual XalanNumberFormatAutoPtr
createXalanNumberFormat() = 0;
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
/*
* A class to manage the attribute sets that have been executed
* by an element
*/
struct UseAttributeSetIndexes
{
UseAttributeSetIndexes() :
attributeSetNameIndex(0),
matchingAttributeSetIndex(0) {}
size_type attributeSetNameIndex;
size_type matchingAttributeSetIndex;
};
virtual void
createUseAttributeSetIndexesOnStack() = 0;
virtual UseAttributeSetIndexes&
getUseAttributeSetIndexes() = 0;
virtual void
popUseAttributeSetIndexesFromStack() = 0;
/**
* Push the element that will invoke
* non children elements (i.e templates, attribute-sets)
*
* @param invokers the element that will invoke non children elements
*/
virtual void
pushInvoker(const ElemTemplateElement * invoker) = 0;
/**
* Pop the element that invoked non children elements
*/
virtual void
popInvoker() = 0;
/**
* Get the lastest element that has invoked
* a non-child element
*/
virtual const ElemTemplateElement*
getInvoker() const = 0;
#endif
/**
* Determine the number of trace listeners.
*
* @return number of listeners
*/
virtual tl_size_type
getTraceListeners() const = 0;
/**
* Fire a generate event.
*
* @param ge generate event to fire
*/
virtual void
fireGenerateEvent(const GenerateEvent& ge) = 0;
/**
* Fire a trace event.
*
* @param te trace event to fire
*/
virtual void
fireTraceEvent(const TracerEvent& te) = 0;
/**
* Fire a selection event.
*
* @param se selection event to fire
*/
virtual void
fireSelectEvent(const SelectionEvent& se) = 0;
/**
* If this is set to true, simple traces of template calls are made.
*
* @return true if traces made
*/
virtual bool
getTraceSelects() const = 0;
/**
* Compose a diagnostic trace of the current selection
*
* @param theStylesheetElement The executing stylesheet element
* @param nl The list of selected nodes
* @param xpath A pointer to the XPath which generated the list of nodes, if any.
*/
virtual void
traceSelect(
const ElemTemplateElement& theStylesheetElement,
const NodeRefListBase& nl,
const XPath* xpath) = 0;
/**
* Compare two strings using the collation of the
* current locale.
*
* @param theLHS a string to compare
* @param theRHS a string to compare
* @param theCaseOrder the case order for the comparison
* @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
*/
virtual int
collationCompare(
const XalanDOMString& theLHS,
const XalanDOMString& theRHS,
XalanCollationServices::eCaseOrder theCaseOrder = XalanCollationServices::eDefault) = 0;
/**
* Compare two strings using the collation of the
* supplied locale.
*
* @param theLHS a string to compare
* @param theRHS a string to compare
* @param theLocal a string that specifies the locale
* @param theCaseOrder the case order for the comparison
* @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
*/
virtual int
collationCompare(
const XalanDOMString& theLHS,
const XalanDOMString& theRHS,
const XalanDOMString& theLocale,
XalanCollationServices::eCaseOrder theCaseOrder = XalanCollationServices::eDefault) = 0;
/**
* Compare two strings using the collation of the
* current locale.
*
* @param theLHS a string to compare
* @param theRHS a string to compare
* @param theCaseOrder the case order for the comparison
* @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
*/
virtual int
collationCompare(
const XalanDOMChar* theLHS,
const XalanDOMChar* theRHS,
XalanCollationServices::eCaseOrder theCaseOrder = XalanCollationServices::eDefault) = 0;
/**
* Compare two strings using the collation of the
* current locale.
*
* @param theLHS a string to compare
* @param theRHS a string to compare
* @param theLocal a string that specifies the locale
* @param theCaseOrder the case order for the comparison
* @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
*/
virtual int
collationCompare(
const XalanDOMChar* theLHS,
const XalanDOMChar* theRHS,
const XalanDOMChar* theLocale,
XalanCollationServices::eCaseOrder theCaseOrder = XalanCollationServices::eDefault) = 0;
/**
* Create a PrintWriter for the provided stream.
*
* @param theTextOutputStream The output stream for the PrintWriter.
* @return The new instance.
*/
virtual PrintWriter*
createPrintWriter(XalanOutputStream* theTextOutputStream) = 0;
/**
* Create a PrintWriter. Create an appropriate output stream
* using the provided file name and encoding.
*
* @param theFileName The file name for the output stream
* @param theEncoding The encoding for the output stream
* @return The new instance.
*/
virtual PrintWriter*
createPrintWriter(
const XalanDOMString& theFileName,
const XalanDOMString& theEncoding) = 0;
/**
* Create a PrintWriter using the provided ostream instance.
*
* @param theStream The output stream for the PrintWriter.
* @return The new instance.
*/
virtual PrintWriter*
createPrintWriter(StreamType& theStream) = 0;
/**
* Create a PrintWriter using the provided FILE instance.
*
* @param theStream The output stream for the PrintWriter.
* @return The new instance.
*/
virtual PrintWriter*
createPrintWriter(FILE* theStream) = 0;
/**
* Get the counters table, which is a table of cached
* results that is used by ElemNumber.
*
* @return A reference to the counters table.
*/
virtual CountersTable&
getCountersTable() = 0;
/**
* Send character data from a node to the result tree.
*
* @param node The node to send.
*/
virtual void
characters(const XalanNode& node) = 0;
/**
* Send character data from an XObject to the result tree.
*
* @param node The xobject to send.
*/
virtual void
characters(const XObjectPtr& xobject) = 0;
/**
* Send raw character data from a node to the result tree.
*
* @param node The node to send.
* @param length number of characters to read from the array
*/
virtual void
charactersRaw(const XalanNode& node) = 0;
/**
* Send raw character data from an XObject to the result tree.
*
* @param node The xobject to send.
*/
virtual void
charactersRaw(const XObjectPtr& xobject) = 0;
// These interfaces are inherited from XPathExecutionContext...
virtual void
reset() = 0;
virtual XalanNode*
getCurrentNode() const = 0;
virtual void
pushCurrentNode(XalanNode* theCurrentNode) = 0;
virtual void
popCurrentNode() = 0;
virtual bool
isNodeAfter(
const XalanNode& node1,
const XalanNode& node2) const = 0;
virtual void
pushContextNodeList(const NodeRefListBase& theList) = 0;
virtual void
popContextNodeList() = 0;
virtual const NodeRefListBase&
getContextNodeList() const = 0;
virtual size_type
getContextNodeListLength() const = 0;
virtual size_type
getContextNodeListPosition(const XalanNode& contextNode) const = 0;
/**
* Determine if an external element is available.
*
* @param theQName The QName of the element
*
* @return whether the given element is available or not
*/
virtual bool
elementAvailable(const XalanQName& theQName) const = 0;
/**
* Determine if an external element is available by resolving
* a string to a QName.
*
* @param theName The name of the element
* @param locator A Locator instance for error reporting
*
* @return whether the given element is available or not
*/
virtual bool
elementAvailable(
const XalanDOMString& theName,
const Locator* locator) const = 0;
/**
* Determine if a function is available.
*
* @param theQName The QName of the function
*
* @return whether the function is available or not
*/
virtual bool
functionAvailable(const XalanQName& theQName) const = 0;
/**
* Determine if a function is available.
*
* @param theName The name of the function
* @param locator A Locator instance for error reporting
*
* @return whether the function is available or not
*/
virtual bool
functionAvailable(
const XalanDOMString& theName,
const Locator* locator) const = 0;
virtual const XObjectPtr
extFunction(
const XalanDOMString& theNamespace,
const XalanDOMString& functionName,
XalanNode* context,
const XObjectArgVectorType& argVec,
const Locator* locator) = 0;
virtual XalanDocument*
parseXML(
MemoryManager& theManager,
const XalanDOMString& urlString,
const XalanDOMString& base,
ErrorHandler* theErrorHandler = 0) const = 0;
virtual MutableNodeRefList*
borrowMutableNodeRefList() = 0;
virtual bool
returnMutableNodeRefList(MutableNodeRefList* theList) = 0;
virtual MutableNodeRefList*
createMutableNodeRefList(MemoryManager& theManager) const = 0;
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
virtual MutableNodeRefList&
createAndPushMutableNodeRefList() = 0;
virtual void
releaseAndPopMutableNodeRefList() = 0;
virtual void
pushXObjectPtr(const XObjectPtr& xobjectPtr) = 0;
virtual void
popXObjectPtr() = 0;
virtual void
createAndPushNodesToTransformList(const NodeRefListBase* nodeList) = 0;
virtual XalanNode*
getNextNodeToTransform() = 0;
virtual void
popNodesToTransformList() = 0;
/**
* Get a string that is cached on a stack
* @returns a cached string
*/
virtual XalanDOMString&
getAndPushCachedString() = 0;
/**
* Gets the last string that was cached on the stack
* @returns the last string to be cached
*/
virtual XalanDOMString&
getLastCachedString() = 0;
/**
* Gets the last string to be cached on the stack and
* pops it from the stack. The reference is valid until
* the next request is made for a cached string
*
* @returns the last string to be cached
*/
virtual XalanDOMString&
getAndPopCachedString() = 0;
#endif
virtual XalanDOMString&
getCachedString() = 0;
virtual bool
releaseCachedString(XalanDOMString& theString) = 0;
virtual void
getNodeSetByKey(
XalanNode* context,
const XalanQName& qname,
const XalanDOMString& ref,
const Locator* locator,
MutableNodeRefList& nodelist) = 0;
virtual void
getNodeSetByKey(
XalanNode* context,
const XalanDOMString& name,
const XalanDOMString& ref,
const Locator* locator,
MutableNodeRefList& nodelist) = 0;
virtual const XObjectPtr
getVariable(
const XalanQName& name,
const Locator* locator = 0) = 0;
virtual const PrefixResolver*
getPrefixResolver() const = 0;
virtual void
setPrefixResolver(const PrefixResolver* thePrefixResolver) = 0;
virtual const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString& prefix) const = 0;
virtual const XalanDOMString&
findURIFromDoc(const XalanDocument* owner) const = 0;
virtual const XalanDOMString&
getUnparsedEntityURI(
const XalanDOMString& theName,
const XalanDocument& theDocument) const = 0;
virtual bool
shouldStripSourceNode(const XalanText& node) = 0;
virtual XalanDocument*
getSourceDocument(const XalanDOMString& theURI) const = 0;
virtual void
setSourceDocument(
const XalanDOMString& theURI,
XalanDocument* theDocument) = 0;
virtual void
formatNumber(
double number,
const XalanDOMString& pattern,
XalanDOMString& theResult,
const XalanNode* context = 0,
const Locator* locator = 0) = 0;
virtual void
formatNumber(
double number,
const XalanDOMString& pattern,
const XalanDOMString& dfsName,
XalanDOMString& theResult,
const XalanNode* context = 0,
const Locator* locator = 0) = 0;
// These interfaces are inherited from ExecutionContext...
virtual void
problem(
eSource source,
eClassification classification,
const XalanDOMString& msg,
const Locator* locator,
const XalanNode* sourceNode) = 0;
virtual void
problem(
eSource source,
eClassification classification,
const XalanDOMString& msg,
const XalanNode* sourceNode) = 0;
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
protected:
/**
* Borrow a cached FormatterToText instance.
*
* @return A pointer to the instance.
*/
virtual FormatterToText*
borrowFormatterToText() = 0;
/**
* Return a previously borrowed FormatterToText instance.
*
* @param theFormatter A pointer the to previously borrowed instance.
* @return true if the instance was previously borrowed, false if not.
*/
virtual bool
returnFormatterToText(FormatterToText* theFormatter) = 0;
#endif
};
}
#endif // STYLESHEETEXECUTIONCONTEXT_HEADER_GUARD_1357924680