/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* 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
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: XPathContext.java,v 1.2.4.2 2005/09/15 01:37:55 jeffsuttor Exp $
*/
/**
* Default class for the runtime execution context for XPath.
*
* <p>This class extends DTMManager but does not directly implement it.</p>
* @xsl.usage advanced
*/
{
/**
* Stack of cached "reusable" DTMs for Result Tree Fragments.
* This is a kluge to handle the problem of starting an RTF before
* the old one is complete.
*
* %REVIEW% I'm using a Vector rather than Stack so we can reuse
* the DTMs if the problem occurs multiple times. I'm not sure that's
* really a net win versus discarding the DTM and starting a new one...
* but the retained RTF DTM will have been tail-pruned so should be small.
*/
/** Index of currently active RTF DTM in m_rtfdtm_stack */
/**
* Most recent "reusable" DTM for Global Result Tree Fragments. No stack is
* required since we're never going to pop these.
*/
/**
* HashMap of cached the DTMXRTreeFrag objects, which are identified by DTM IDs.
* The object are just wrappers for DTMs which are used in XRTreeFrag.
*/
/**
* state of the secure processing feature.
*/
private boolean m_isSecureProcessing = false;
private boolean m_useServicesMechanism = true;
/**
* Though XPathContext context extends
* the DTMManager, it really is a proxy for this object, which
* is the real DTMManager.
*/
/**
* Return the DTMManager object. Though XPathContext context extends
* the DTMManager, it really is a proxy for the real DTMManager. If a
* caller needs to make a lot of calls to the DTMManager, it is faster
* if it gets the real one from this function.
*/
{
return m_dtmManager;
}
/**
* Set the state of the secure processing feature
*/
{
}
/**
* Return the state of the secure processing feature
*/
public boolean isSecureProcessing()
{
return m_isSecureProcessing;
}
/**
* Get an instance of a DTM, loaded with the content from the
* specified source. If the unique flag is true, a new instance will
* always be returned. Otherwise it is up to the DTMManager to return a
* new instance or an instance that it already created and may be being used
* by someone else.
* (I think more parameters will need to be added for error handling, and entity
* resolution).
*
* @param source the specification of the source object, which may be null,
* in which case it is assumed that node construction will take
* by some other means.
* @param unique true if the returned DTM must be unique, probably because it
* is going to be mutated.
* @param wsfilter Enables filtering of whitespace nodes, and may be null.
* @param incremental true if the construction should try and be incremental.
* @param doIndexing true if the caller considers it worth it to use
* indexing schemes.
*
* @return a non-null DTM reference.
*/
boolean incremental,
boolean doIndexing)
{
}
/**
* Get an instance of a DTM that "owns" a node handle.
*
* @param nodeHandle the nodeHandle.
*
* @return a non-null DTM reference.
*/
{
}
/**
* Given a W3C DOM node, try and return a DTM handle.
* Note: calling this may be non-optimal.
*
* @param node Non-null reference to a DOM node.
*
* @return a valid DTM handle.
*/
{
}
//
//
/**
* %TBD% Doc
*/
{
}
//
/**
* Creates an empty <code>DocumentFragment</code> object.
* @return A new <code>DocumentFragment handle</code>.
*/
{
return m_dtmManager.createDocumentFragment();
}
//
/**
* Release a DTM either to a lru pool, or completely remove reference.
* DTMs without system IDs are always hard deleted.
* State: experimental.
*
* @param dtm The DTM to be released.
* @param shouldHardDelete True if the DTM should be removed no matter what.
* @return true if the DTM was removed, false if it was put back in a lru pool.
*/
{
// %REVIEW% If it's a DTM which may contain multiple Result Tree
// Fragments, we can't discard it unless we know not only that it
// is empty, but that the XPathContext itself is going away. So do
// _not_ accept the request. (May want to do it as part of
// reset(), though.)
{
return false;
}
}
/**
* Create a new <code>DTMIterator</code> based on an XPath
* <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
* a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
*
* @param xpathCompiler ??? Somehow we need to pass in a subpart of the
* expression. I hate to do this with strings, since the larger expression
* has already been parsed.
*
* @param pos The position in the expression.
* @return The newly created <code>DTMIterator</code>.
*/
{
}
//
/**
* Create a new <code>DTMIterator</code> based on an XPath
* <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
* a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
*
* @param xpathString Must be a valid string expressing a
* <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
* a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
*
* @param presolver An object that can resolve prefixes to namespace URLs.
*
* @return The newly created <code>DTMIterator</code>.
*/
{
}
//
/**
* Create a new <code>DTMIterator</code> based only on a whatToShow and
* a DTMFilter. The traversal semantics are defined as the descendant
* access.
*
* @param whatToShow This flag specifies which node types may appear in
* the logical view of the tree presented by the iterator. See the
* description of <code>NodeFilter</code> for the set of possible
* <code>SHOW_</code> values.These flags can be combined using
* <code>OR</code>.
* @param filter The <code>NodeFilter</code> to be used with this
* <code>TreeWalker</code>, or <code>null</code> to indicate no filter.
* @param entityReferenceExpansion The value of this flag determines
* whether entity reference nodes are expanded.
*
* @return The newly created <code>NodeIterator</code>.
*/
{
}
/**
* Create a new <code>DTMIterator</code> that holds exactly one node.
*
* @param node The node handle that the DTMIterator will iterate to.
*
* @return The newly created <code>DTMIterator</code>.
*/
{
// DescendantIterator iter = new DescendantIterator();
return iter;
// return m_dtmManager.createDTMIterator(node);
}
/**
* Create an XPathContext instance.
*/
public XPathContext()
{
this(true);
}
}
/**
**This constructor doesn't seem to be used anywhere -- huizhe wang**
* Create an XPathContext instance.
* @param owner Value that can be retrieved via the getOwnerObject() method.
* @see #getOwnerObject
*/
{
try {
}
catch (NoSuchMethodException nsme) {}
init(true);
}
}
/**
* Reset for new run.
*/
public void reset()
{
// These couldn't be disposed of earlier (see comments in release()); zap them now.
if(m_rtfdtm_stack!=null)
m_which_rtfdtm=-1;
if(m_global_rtfdtm!=null)
}
/** The current stylesheet locator. */
/**
* Set the current locater in the stylesheet.
*
* @param location The location within the stylesheet.
*/
{
}
/**
* Set the current locater in the stylesheet.
*
* @param location The location within the stylesheet.
*/
{
}
/**
* Push a slot on the locations stack so that setSAXLocator can be
* repeatedly called.
*
*/
public void pushSAXLocatorNull()
{
}
/**
* Pop the current locater.
*/
public void popSAXLocator()
{
}
/**
* Get the current locater in the stylesheet.
*
* @return The location within the stylesheet, or null if not known.
*/
{
}
/** The owner context of this XPathContext. In the case of XSLT, this will be a
* Transformer object.
*/
/** The owner context of this XPathContext. In the case of XSLT, this will be a
* Transformer object.
*/
/**
* Get the "owner" context of this context, which should be,
* in the case of XSLT, the Transformer object. This is needed
* so that XSLT functions can get the Transformer.
* @return The owner object passed into the constructor, or null.
*/
{
return m_owner;
}
// ================ VarStack ===================
/**
* The stack of Variable stacks. A VariableStack will be
* pushed onto this stack for each template invocation.
*/
/**
* Get the variable stack, which is in charge of variables and
* parameters.
*
* @return the variable stack, which should not be null.
*/
{
return m_variableStacks;
}
/**
* Get the variable stack, which is in charge of variables and
* parameters.
*
* @param varStack non-null reference to the variable stack.
*/
{
}
// ================ SourceTreeManager ===================
/** The source tree manager, which associates Source objects to source
* tree nodes. */
/**
* Get the SourceTreeManager associated with this execution context.
*
* @return the SourceTreeManager associated with this execution context.
*/
{
return m_sourceTreeManager;
}
/**
* Set the SourceTreeManager associated with this execution context.
*
* @param mgr the SourceTreeManager to be associated with this
* execution context.
*/
{
}
// =================================================
/** The ErrorListener where errors and warnings are to be reported. */
/** A default ErrorListener in case our m_errorListener was not specified and our
* owner either does not have an ErrorListener or has a null one.
*/
/**
* Get the ErrorListener where errors and warnings are to be reported.
*
* @return A non-null ErrorListener reference.
*/
{
if (null != m_errorListener)
return m_errorListener;
try {
if (null != m_ownerGetErrorListener)
}
catch (Exception e) {}
{
if (null == m_defaultErrorListener)
}
return retval;
}
/**
* Set the ErrorListener where errors and warnings are to be reported.
*
* @param listener A non-null ErrorListener reference.
*/
{
throw new IllegalArgumentException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, null)); //"Null error handler");
}
// =================================================
/** The TrAX URI Resolver for resolving URIs from the document(...)
* function to source tree nodes. */
/**
* Get the URIResolver associated with this execution context.
*
* @return a URI resolver, which may be null.
*/
{
return m_uriResolver;
}
/**
* Set the URIResolver associated with this execution context.
*
* @param resolver the URIResolver to be associated with this
* execution context, may be null to clear an already set resolver.
*/
{
}
// =================================================
/** The reader of the primary source tree. */
/**
* Get primary XMLReader associated with this execution context.
*
* @return The reader of the primary source tree.
*/
{
return m_primaryReader;
}
/**
* Set primary XMLReader associated with this execution context.
*
* @param reader The reader of the primary source tree.
*/
{
}
// =================================================
/** Misnamed string manager for XPath messages. */
// private static XSLMessages m_XSLMessages = new XSLMessages();
/**
* Tell the user of an assertion error, and probably throw an
* exception.
*
* @param b If false, a TransformerException will be thrown.
* @param msg The assertion message, which should be informative.
*
* @throws javax.xml.transform.TransformerException if b is false.
*/
{
if (!b)
{
if (errorHandler != null)
{
new TransformerException(
}
}
}
//==========================================================
// SECTION: Execution context state tracking
//==========================================================
/**
* The current context node list.
*/
/**
* Get the current context node list.
*
* @return the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
* also refered to here as a <term>context node list</term>.
*/
{
else
return null;
}
/**
* Set the current context node list.
*
* @param nl the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
* also refered to here as a <term>context node list</term>.
* @xsl.usage internal
*/
{
}
/**
* Pop the current context node list.
* @xsl.usage internal
*/
public final void popContextNodeList()
{
if(m_contextNodeLists.isEmpty())
else
}
/**
* The ammount to use for stacks that record information during the
* recursive execution.
*/
/** The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
* Not to be confused with the current node list. %REVIEW% Note that there
* are no bounds check and resize for this stack, so if it is blown, it's all
* over. */
// private NodeVector m_currentNodes = new NodeVector();
/**
* Get the current context node.
*
* @return the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
*/
public final int getCurrentNode()
{
return m_currentNodes.peek();
}
/**
* Set the current context node and expression node.
*
* @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
* @param en the sub-expression context node.
*/
{
}
/**
* Set the current context node.
*/
public final void popCurrentNodeAndExpression()
{
}
/**
* Push the current context node, expression node, and prefix resolver.
*
* @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
* @param en the sub-expression context node.
* @param nc the namespace context (prefix resolver.
*/
{
}
/**
* Pop the current context node, expression node, and prefix resolver.
*/
public final void popExpressionState()
{
}
/**
* Set the current context node.
*
* @param n the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
*/
public final void pushCurrentNode(int n)
{
m_currentNodes.push(n);
}
/**
* Pop the current context node.
*/
public final void popCurrentNode()
{
}
/**
* Set the current predicate root.
*/
public final void pushPredicateRoot(int n)
{
m_predicateRoots.push(n);
}
/**
* Pop the current predicate root.
*/
public final void popPredicateRoot()
{
}
/**
* Get the current predicate root.
*/
public final int getPredicateRoot()
{
return m_predicateRoots.peepOrNull();
}
/**
* Set the current location path iterator root.
*/
public final void pushIteratorRoot(int n)
{
m_iteratorRoots.push(n);
}
/**
* Pop the current location path iterator root.
*/
public final void popIteratorRoot()
{
}
/**
* Get the current location path iterator root.
*/
public final int getIteratorRoot()
{
return m_iteratorRoots.peepOrNull();
}
/** A stack of the current sub-expression nodes. */
/** A stack of the current sub-expression nodes. */
/** A stack of the current sub-expression nodes. */
public final int getPredicatePos()
{
return m_predicatePos.peek();
}
public final void pushPredicatePos(int n)
{
m_predicatePos.push(n);
}
public final void popPredicatePos()
{
}
/**
* Get the current node that is the expression's context (i.e. for current() support).
*
* @return The current sub-expression node.
*/
public final int getCurrentExpressionNode()
{
return m_currentExpressionNodes.peek();
}
/**
* Set the current node that is the expression's context (i.e. for current() support).
*
* @param n The sub-expression node to be current.
*/
public final void pushCurrentExpressionNode(int n)
{
}
/**
* Pop the current node that is the expression's context
* (i.e. for current() support).
*/
public final void popCurrentExpressionNode()
{
}
= new ObjectStack(RECURSIONLIMIT);
/**
* Get the current namespace context for the xpath.
*
* @return the current prefix resolver for resolving prefixes to
* namespace URLs.
*/
{
}
/**
* Get the current namespace context for the xpath.
*
* @param pr the prefix resolver to be used for resolving prefixes to
* namespace URLs.
*/
{
}
/**
* Push a current namespace context for the xpath.
*
* @param pr the prefix resolver to be used for resolving prefixes to
* namespace URLs.
*/
{
}
/**
* Just increment the namespace contest stack, so that setNamespaceContext
* can be used on the slot.
*/
public final void pushNamespaceContextNull()
{
}
/**
* Pop the current namespace context for the xpath.
*/
public final void popNamespaceContext()
{
}
//==========================================================
// SECTION: Current TreeWalker contexts (for internal use)
//==========================================================
/**
* Stack of AxesIterators.
*/
/**
* Push a TreeWalker on the stack.
*
* @param iter A sub-context AxesWalker.
* @xsl.usage internal
*/
{
}
/**
* Pop the last pushed axes iterator.
* @xsl.usage internal
*/
public final void popSubContextList()
{
}
/**
* Get the current axes iterator, or return null if none.
*
* @return the sub-context node list.
* @xsl.usage internal
*/
{
return m_axesIteratorStack.isEmpty()
}
/**
* Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>
* as defined by the XSLT spec.
*
* @return the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>.
* @xsl.usage internal
*/
{
return m_axesIteratorStack.isEmpty()
}
//==========================================================
// SECTION: Implementation of ExpressionContext interface
//==========================================================
/**
* Get the current context node.
* @return The current context node.
*/
public final int getContextNode()
{
return this.getCurrentNode();
}
/**
* Get the current context node list.
* @return An iterator for the current context list, as
* defined in XSLT.
*/
{
try
{
return cnl.cloneWithReset();
else
return null; // for now... this might ought to be an empty iterator.
}
catch (CloneNotSupportedException cnse)
{
return null; // error reporting?
}
}
/**
* The the expression context for extensions for this context.
*
* @return An object that implements the ExpressionContext.
*/
{
return expressionContext;
}
{
/**
* Return the XPathContext associated with this XPathExpressionContext.
* Extensions should use this judiciously and only when special processing
* requirements cannot be met another way. Consider requesting an enhancement
* to the ExpressionContext interface to avoid having to call this method.
* @return the XPathContext associated with this XPathExpressionContext.
*/
{
return XPathContext.this;
}
/**
* Return the DTMManager object. Though XPathContext context extends
* the DTMManager, it really is a proxy for the real DTMManager. If a
* caller needs to make a lot of calls to the DTMManager, it is faster
* if it gets the real one from this function.
*/
{
return m_dtmManager;
}
/**
* Get the current context node.
* @return The current context node.
*/
{
int context = getCurrentNode();
}
/**
* Get the current context node list.
* @return An iterator for the current context list, as
* defined in XSLT.
*/
{
}
/**
* Get the error listener.
* @return The registered error listener.
*/
{
return XPathContext.this.getErrorListener();
}
/**
* Return the state of the services mechanism feature.
*/
public boolean useServicesMechnism() {
return m_useServicesMechanism;
}
/**
* Set the state of the services mechanism feature.
*/
}
/**
* Get the value of a node as a number.
* @param n Node to be converted to a number. May be null.
* @return value of n as a number.
*/
{
// %REVIEW% You can't get much uglier than this...
int nodeHandle = getDTMHandleFromNode(n);
}
/**
* Get the value of a node as a string.
* @param n Node to be converted to a string. May be null.
* @return value of n as a string, or an empty string if n is null.
*/
{
// %REVIEW% You can't get much uglier than this...
int nodeHandle = getDTMHandleFromNode(n);
}
/**
* Get a variable based on it's qualified name.
* @param qname The qualified name of the variable.
* @return The evaluated value of the variable.
* @throws javax.xml.transform.TransformerException
*/
{
}
}
/**
* Get a DTM to be used as a container for a global Result Tree
* Fragment. This will always be an instance of (derived from? equivalent to?)
* SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX
* output to it. It may be a single DTM containing for multiple fragments,
* if the implementation supports that.
*
* Note: The distinction between this method and getRTFDTM() is that the latter
* allocates space from the dynamic variable stack (m_rtfdtm_stack), which may
* be pruned away again as the templates which defined those variables are exited.
* Global variables may be bound late (see XUnresolvedVariable), and never want to
* be discarded, hence we need to allocate them separately and don't actually need
* a stack to track them.
*
* @return a non-null DTM reference.
*/
{
// We probably should _NOT_ be applying whitespace filtering at this stage!
//
// Some magic has been applied in DTMManagerDefault to recognize this set of options
// and generate an instance of DTM which can contain multiple documents
// (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
// I didn't want to change the manager API at this time, or expose
// too many dependencies on its internals. (Ideally, I'd like to move
// isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
// specify the subclass here.)
// If it doesn't exist, or if the one already existing is in the middle of
// being constructed, we need to obtain a new DTM to write into. I'm not sure
// the latter will ever arise, but I'd rather be just a bit paranoid..
{
}
return m_global_rtfdtm;
}
/**
* Get a DTM to be used as a container for a dynamic Result Tree
* Fragment. This will always be an instance of (derived from? equivalent to?)
* SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX
* output to it. It may be a single DTM containing for multiple fragments,
* if the implementation supports that.
*
* @return a non-null DTM reference.
*/
{
// We probably should _NOT_ be applying whitespace filtering at this stage!
//
// Some magic has been applied in DTMManagerDefault to recognize this set of options
// and generate an instance of DTM which can contain multiple documents
// (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
// I didn't want to change the manager API at this time, or expose
// too many dependencies on its internals. (Ideally, I'd like to move
// isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
// specify the subclass here.)
if(m_rtfdtm_stack==null)
{
m_rtfdtm_stack=new Vector();
}
else if(m_which_rtfdtm<0)
{
}
else
{
// It might already be under construction -- the classic example would be
// an xsl:variable which uses xsl:call-template as part of its value. To
// handle this recursion, we have to start a new RTF DTM, pushing the old
// one onto a stack so we can return to it. This is not as uncommon a case
// as we might wish, unfortunately, as some folks insist on coding XSLT
// as if it were a procedural language...
if(rtfdtm.isTreeIncomplete())
{
else
{
}
}
}
return rtfdtm;
}
/** Push the RTFDTM's context mark, to allows discarding RTFs added after this
* point. (If it doesn't exist we don't push, since we might still be able to
* get away with not creating it. That requires that excessive pops be harmless.)
* */
public void pushRTFContext()
{
if(null!=m_rtfdtm_stack)
}
/** Pop the RTFDTM's context mark. This discards any RTFs added after the last
* mark was set.
*
* If there is no RTF DTM, there's nothing to pop so this
* becomes a no-op. If pushes were issued before this was called, we count on
* the fact that popRewindMark is defined such that overpopping just resets
* to empty.
*
* Complicating factor: We need to handle the case of popping back to a previous
* RTF DTM, if one of the weird produce-an-RTF-to-build-an-RTF cases arose.
* Basically: If pop says this DTM is now empty, then return to the previous
* if one exists, in whatever state we left it in. UGLY, but hopefully the
* situation which forces us to consider this will arise exceedingly rarely.
* */
public void popRTFContext()
{
if(null==m_rtfdtm_stack)
return;
if(m_which_rtfdtm==previous)
{
{
}
}
else while(m_which_rtfdtm!=previous)
{
// Empty each DTM before popping, so it's ready for reuse
// _DON'T_ pop the previous, since it's still open (which is why we
// stacked up more of these) and did not receive a mark.
}
}
/**
* Gets DTMXRTreeFrag object if one has already been created.
* Creates new DTMXRTreeFrag object and adds to m_DTMXRTreeFrags HashMap,
* otherwise.
* @param dtmIdentity
* @return DTMXRTreeFrag
*/
if(m_DTMXRTreeFrags == null){
m_DTMXRTreeFrags = new HashMap();
}
}else{
return frag ;
}
}
/**
* Cleans DTMXRTreeFrag objects by removing references
* to DTM and XPathContext objects.
*/
private final void releaseDTMXRTreeFrags(){
if(m_DTMXRTreeFrags == null){
return;
}
}
}
}