19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: XPathContext.java 524809 2007-04-02 15:51:51Z zongaro $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.lang.reflect.Method;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Stack;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Vector;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.HashMap;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Iterator;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.ErrorListener;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.SourceLocator;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.URIResolver;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.extensions.ExpressionContext;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.Axis;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM;
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMFilter;
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMIterator;
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMManager;
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMWSFilter;
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.ref.sax2dtm.SAX2RTFDTM;
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.IntStack;
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.NodeVector;
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.ObjectStack;
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.PrefixResolver;
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.SAXSourceLocator;
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.XMLString;
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.axes.SubContextList;
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject;
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.DTMXRTreeFrag;
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XString;
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.res.XPATHErrorResources;
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.XMLReader;
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Default class for the runtime execution context for XPath.
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>This class extends DTMManager but does not directly implement it.</p>
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage advanced
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class XPathContext extends DTMManager // implements ExpressionContext
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	IntStack m_last_pushed_rtfdtm=new IntStack();
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Stack of cached "reusable" DTMs for Result Tree Fragments.
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This is a kluge to handle the problem of starting an RTF before
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the old one is complete.
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %REVIEW% I'm using a Vector rather than Stack so we can reuse
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the DTMs if the problem occurs multiple times. I'm not sure that's
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * really a net win versus discarding the DTM and starting a new one...
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * but the retained RTF DTM will have been tail-pruned so should be small.
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Vector m_rtfdtm_stack=null;
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Index of currently active RTF DTM in m_rtfdtm_stack */
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int m_which_rtfdtm=-1;
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /**
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Most recent "reusable" DTM for Global Result Tree Fragments. No stack is
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * required since we're never going to pop these.
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private SAX2RTFDTM m_global_rtfdtm=null;
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * HashMap of cached the DTMXRTreeFrag objects, which are identified by DTM IDs.
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The object are just wrappers for DTMs which are used in  XRTreeFrag.
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private HashMap m_DTMXRTreeFrags = null;
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * state of the secure processing feature.
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private boolean m_isSecureProcessing = false;
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Though XPathContext context extends
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the DTMManager, it really is a proxy for this object, which
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is the real DTMManager.
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected DTMManager m_dtmManager = DTMManager.newInstance(
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                   org.apache.xpath.objects.XMLStringFactoryImpl.getFactory());
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the DTMManager object.  Though XPathContext context extends
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the DTMManager, it really is a proxy for the real DTMManager.  If a
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * caller needs to make a lot of calls to the DTMManager, it is faster
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if it gets the real one from this function.
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   public DTMManager getDTMManager()
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   {
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     return m_dtmManager;
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   }
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the state of the secure processing feature
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setSecureProcessing(boolean flag)
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_isSecureProcessing = flag;
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the state of the secure processing feature
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean isSecureProcessing()
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_isSecureProcessing;
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get an instance of a DTM, loaded with the content from the
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specified source.  If the unique flag is true, a new instance will
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * always be returned.  Otherwise it is up to the DTMManager to return a
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * new instance or an instance that it already created and may be being used
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * by someone else.
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * (I think more parameters will need to be added for error handling, and entity
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * resolution).
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param source the specification of the source object, which may be null,
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               in which case it is assumed that node construction will take
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *               by some other means.
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param unique true if the returned DTM must be unique, probably because it
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is going to be mutated.
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param wsfilter Enables filtering of whitespace nodes, and may be null.
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param incremental true if the construction should try and be incremental.
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param doIndexing true if the caller considers it worth it to use
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                   indexing schemes.
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return a non-null DTM reference.
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTM getDTM(javax.xml.transform.Source source, boolean unique,
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    DTMWSFilter wsfilter,
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    boolean incremental,
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    boolean doIndexing)
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.getDTM(source, unique, wsfilter,
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               incremental, doIndexing);
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get an instance of a DTM that "owns" a node handle.
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nodeHandle the nodeHandle.
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return a non-null DTM reference.
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTM getDTM(int nodeHandle)
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.getDTM(nodeHandle);
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a W3C DOM node, try and return a DTM handle.
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note: calling this may be non-optimal.
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node Non-null reference to a DOM node.
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return a valid DTM handle.
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getDTMHandleFromNode(org.w3c.dom.Node node)
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.getDTMHandleFromNode(node);
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %TBD% Doc
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getDTMIdentity(DTM dtm)
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.getDTMIdentity(dtm);
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Creates an empty <code>DocumentFragment</code> object.
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A new <code>DocumentFragment handle</code>.
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTM createDocumentFragment()
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.createDocumentFragment();
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Release a DTM either to a lru pool, or completely remove reference.
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * DTMs without system IDs are always hard deleted.
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * State: experimental.
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param dtm The DTM to be released.
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param shouldHardDelete True if the DTM should be removed no matter what.
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the DTM was removed, false if it was put back in a lru pool.
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public boolean release(DTM dtm, boolean shouldHardDelete)
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // %REVIEW% If it's a DTM which may contain multiple Result Tree
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Fragments, we can't discard it unless we know not only that it
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // is empty, but that the XPathContext itself is going away. So do
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // _not_ accept the request. (May want to do it as part of
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // reset(), though.)
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_rtfdtm_stack!=null && m_rtfdtm_stack.contains(dtm))
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.release(dtm, shouldHardDelete);
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new <code>DTMIterator</code> based on an XPath
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xpathCompiler ??? Somehow we need to pass in a subpart of the
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * expression.  I hate to do this with strings, since the larger expression
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * has already been parsed.
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pos The position in the expression.
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The newly created <code>DTMIterator</code>.
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMIterator createDTMIterator(Object xpathCompiler, int pos)
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.createDTMIterator(xpathCompiler, pos);
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new <code>DTMIterator</code> based on an XPath
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xpathString Must be a valid string expressing a
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <a href="http://www.w3.org/TR/xpath#NT-LocationPath>LocationPath</a> or
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a <a href="http://www.w3.org/TR/xpath#NT-UnionExpr">UnionExpr</a>.
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param presolver An object that can resolve prefixes to namespace URLs.
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The newly created <code>DTMIterator</code>.
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMIterator createDTMIterator(String xpathString,
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          PrefixResolver presolver)
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.createDTMIterator(xpathString, presolver);
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new <code>DTMIterator</code> based only on a whatToShow and
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a DTMFilter.  The traversal semantics are defined as the descendant
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * access.
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param whatToShow This flag specifies which node types may appear in
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   the logical view of the tree presented by the iterator. See the
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   description of <code>NodeFilter</code> for the set of possible
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   <code>SHOW_</code> values.These flags can be combined using
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   <code>OR</code>.
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param filter The <code>NodeFilter</code> to be used with this
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   <code>TreeWalker</code>, or <code>null</code> to indicate no filter.
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param entityReferenceExpansion The value of this flag determines
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *   whether entity reference nodes are expanded.
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The newly created <code>NodeIterator</code>.
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMIterator createDTMIterator(int whatToShow,
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          DTMFilter filter, boolean entityReferenceExpansion)
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_dtmManager.createDTMIterator(whatToShow, filter, entityReferenceExpansion);
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new <code>DTMIterator</code> that holds exactly one node.
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node The node handle that the DTMIterator will iterate to.
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The newly created <code>DTMIterator</code>.
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMIterator createDTMIterator(int node)
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // DescendantIterator iter = new DescendantIterator();
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTMIterator iter = new org.apache.xpath.axes.OneStepIteratorForward(Axis.SELF);
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    iter.setRoot(node, this);
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return iter;
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // return m_dtmManager.createDTMIterator(node);
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create an XPathContext instance.  This is equivalent to calling
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the {@link #XPathContext(boolean)} constructor with the value
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <code>true</code>.
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPathContext() {
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this(true);
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create an XPathContext instance.
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param recursiveVarContext A <code>boolean</code> value indicating whether
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             the XPath context needs to support pushing of scopes for
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             variable resolution
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPathContext(boolean recursiveVarContext) {
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.push(null);
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.push(DTM.NULL);
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.push(DTM.NULL);
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.push(null);
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_variableStacks = recursiveVarContext ? new VariableStack()
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                           : new VariableStack(1);
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create an XPathContext instance.  This is equivalent to calling the
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * constructor {@link #XPathContext(java.lang.Object,boolean)} with the
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * value of the second parameter set to <code>true</code>.
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param owner Value that can be retrieved via the getOwnerObject() method.
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see #getOwnerObject
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPathContext(Object owner)
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this(owner, true);
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create an XPathContext instance.
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param owner Value that can be retrieved via the getOwnerObject() method.
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see #getOwnerObject
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param recursiveVarContext A <code>boolean</code> value indicating whether
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             the XPath context needs to support pushing of scopes for
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *             variable resolution
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPathContext(Object owner, boolean recursiveVarContext) {
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    this(recursiveVarContext);
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_owner = owner;
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try {
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class[] {});
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (NoSuchMethodException nsme) {}
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Reset for new run.
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void reset()
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    releaseDTMXRTreeFrags();
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// These couldn't be disposed of earlier (see comments in release()); zap them now.
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(m_rtfdtm_stack!=null)
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		 for (java.util.Enumeration e = m_rtfdtm_stack.elements() ; e.hasMoreElements() ;)
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		 	m_dtmManager.release((DTM)e.nextElement(), true);
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_rtfdtm_stack=null; // drop our references too
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_which_rtfdtm=-1;
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_global_rtfdtm!=null)
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		 	m_dtmManager.release(m_global_rtfdtm,true);
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_global_rtfdtm=null;
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_dtmManager = DTMManager.newInstance(
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                   org.apache.xpath.objects.XMLStringFactoryImpl.getFactory());
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.removeAllElements();
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_axesIteratorStack.removeAllElements();
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_contextNodeLists.removeAllElements();
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_currentExpressionNodes.removeAllElements();
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_currentNodes.removeAllElements();
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_iteratorRoots.RemoveAllNoClear();
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_predicatePos.removeAllElements();
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_predicateRoots.RemoveAllNoClear();
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_prefixResolvers.removeAllElements();
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	m_prefixResolvers.push(null);
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.push(DTM.NULL);
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.push(DTM.NULL);
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.push(null);
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The current stylesheet locator. */
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  ObjectStack m_saxLocations = new ObjectStack(RECURSIONLIMIT);
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current locater in the stylesheet.
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param location The location within the stylesheet.
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setSAXLocator(SourceLocator location)
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.setTop(location);
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current locater in the stylesheet.
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param location The location within the stylesheet.
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void pushSAXLocator(SourceLocator location)
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.push(location);
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Push a slot on the locations stack so that setSAXLocator can be
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * repeatedly called.
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void pushSAXLocatorNull()
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.push(null);
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current locater.
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void popSAXLocator()
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_saxLocations.pop();
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current locater in the stylesheet.
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The location within the stylesheet, or null if not known.
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public SourceLocator getSAXLocator()
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (SourceLocator) m_saxLocations.peek();
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The owner context of this XPathContext.  In the case of XSLT, this will be a
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  Transformer object.
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Object m_owner;
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The owner context of this XPathContext.  In the case of XSLT, this will be a
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  Transformer object.
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Method m_ownerGetErrorListener;
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "owner" context of this context, which should be,
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in the case of XSLT, the Transformer object.  This is needed
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * so that XSLT functions can get the Transformer.
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The owner object passed into the constructor, or null.
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Object getOwnerObject()
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_owner;
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // ================ VarStack ===================
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The stack of Variable stacks.  A VariableStack will be
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * pushed onto this stack for each template invocation.
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private VariableStack m_variableStacks;
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the variable stack, which is in charge of variables and
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * parameters.
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the variable stack, which should not be null.
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final VariableStack getVarStack()
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_variableStacks;
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the variable stack, which is in charge of variables and
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * parameters.
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param varStack non-null reference to the variable stack.
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void setVarStack(VariableStack varStack)
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_variableStacks = varStack;
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // ================ SourceTreeManager ===================
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The source tree manager, which associates Source objects to source
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  tree nodes. */
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private SourceTreeManager m_sourceTreeManager = new SourceTreeManager();
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the SourceTreeManager associated with this execution context.
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the SourceTreeManager associated with this execution context.
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final SourceTreeManager getSourceTreeManager()
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_sourceTreeManager;
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the SourceTreeManager associated with this execution context.
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mgr the SourceTreeManager to be associated with this
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        execution context.
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setSourceTreeManager(SourceTreeManager mgr)
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_sourceTreeManager = mgr;
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // =================================================
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The ErrorListener where errors and warnings are to be reported.   */
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private ErrorListener m_errorListener;
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** A default ErrorListener in case our m_errorListener was not specified and our
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  owner either does not have an ErrorListener or has a null one.
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private ErrorListener m_defaultErrorListener;
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the ErrorListener where errors and warnings are to be reported.
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A non-null ErrorListener reference.
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final ErrorListener getErrorListener()
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_errorListener)
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return m_errorListener;
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    ErrorListener retval = null;
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try {
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != m_ownerGetErrorListener)
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        retval = (ErrorListener) m_ownerGetErrorListener.invoke(m_owner, new Object[] {});
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (Exception e) {}
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null == retval)
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == m_defaultErrorListener)
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        m_defaultErrorListener = new org.apache.xml.utils.DefaultErrorHandler();
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      retval = m_defaultErrorListener;
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return retval;
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the ErrorListener where errors and warnings are to be reported.
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param listener A non-null ErrorListener reference.
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setErrorListener(ErrorListener listener) throws IllegalArgumentException
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (listener == null)
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new IllegalArgumentException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, null)); //"Null error handler");
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_errorListener = listener;
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // =================================================
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The TrAX URI Resolver for resolving URIs from the document(...)
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  function to source tree nodes.  */
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private URIResolver m_uriResolver;
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the URIResolver associated with this execution context.
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return a URI resolver, which may be null.
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final URIResolver getURIResolver()
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_uriResolver;
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the URIResolver associated with this execution context.
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param resolver the URIResolver to be associated with this
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *        execution context, may be null to clear an already set resolver.
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setURIResolver(URIResolver resolver)
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_uriResolver = resolver;
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // =================================================
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The reader of the primary source tree.    */
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XMLReader m_primaryReader;
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get primary XMLReader associated with this execution context.
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The reader of the primary source tree.
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final XMLReader getPrimaryReader()
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_primaryReader;
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set primary XMLReader associated with this execution context.
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param reader The reader of the primary source tree.
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setPrimaryReader(XMLReader reader)
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_primaryReader = reader;
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // =================================================
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Misnamed string manager for XPath messages.  */
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // private static XSLMessages m_XSLMessages = new XSLMessages();
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Tell the user of an assertion error, and probably throw an
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * exception.
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param b  If false, a TransformerException will be thrown.
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param msg The assertion message, which should be informative.
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException if b is false.
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void assertion(boolean b, String msg) throws javax.xml.transform.TransformerException
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (!b)
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ErrorListener errorHandler = getErrorListener();
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (errorHandler != null)
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        errorHandler.fatalError(
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          new TransformerException(
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            XSLMessages.createMessage(
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              new Object[]{ msg }), (SAXSourceLocator)this.getSAXLocator()));
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //==========================================================
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // SECTION: Execution context state tracking
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //==========================================================
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The current context node list.
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Stack m_contextNodeLists = new Stack();
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Stack getContextNodeListsStack() { return m_contextNodeLists; }
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setContextNodeListsStack(Stack s) { m_contextNodeLists = s; }
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current context node list.
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * also refered to here as a <term>context node list</term>.
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final DTMIterator getContextNodeList()
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_contextNodeLists.size() > 0)
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (DTMIterator) m_contextNodeLists.peek();
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return null;
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current context node list.
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nl the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * also refered to here as a <term>context node list</term>.
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushContextNodeList(DTMIterator nl)
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_contextNodeLists.push(nl);
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current context node list.
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popContextNodeList()
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(m_contextNodeLists.isEmpty())
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	  System.err.println("Warning: popContextNodeList when stack is empty!");
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_contextNodeLists.pop();
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The ammount to use for stacks that record information during the
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * recursive execution.
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int RECURSIONLIMIT = (1024*4);
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  Not to be confused with the current node list.  %REVIEW% Note that there
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  are no bounds check and resize for this stack, so if it is blown, it's all
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  over.  */
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private IntStack m_currentNodes = new IntStack(RECURSIONLIMIT);
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//  private NodeVector m_currentNodes = new NodeVector();
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public IntStack getCurrentNodeStack() {return m_currentNodes; }
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setCurrentNodeStack(IntStack nv) { m_currentNodes = nv; }
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current context node.
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getCurrentNode()
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_currentNodes.peek();
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current context node and expression node.
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param en the sub-expression context node.
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushCurrentNodeAndExpression(int cn, int en)
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.push(cn);
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.push(cn);
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current context node.
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popCurrentNodeAndExpression()
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.quickPop(1);
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.quickPop(1);
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Push the current context node, expression node, and prefix resolver.
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param cn the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param en the sub-expression context node.
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param nc the namespace context (prefix resolver.
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushExpressionState(int cn, int en, PrefixResolver nc)
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.push(cn);
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.push(cn);
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.push(nc);
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current context node, expression node, and prefix resolver.
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popExpressionState()
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.quickPop(1);
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.quickPop(1);
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.pop();
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current context node.
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param n the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushCurrentNode(int n)
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.push(n);
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current context node.
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popCurrentNode()
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentNodes.quickPop(1);
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current predicate root.
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushPredicateRoot(int n)
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_predicateRoots.push(n);
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current predicate root.
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popPredicateRoot()
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_predicateRoots.popQuick();
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current predicate root.
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getPredicateRoot()
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_predicateRoots.peepOrNull();
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current location path iterator root.
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushIteratorRoot(int n)
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_iteratorRoots.push(n);
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current location path iterator root.
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popIteratorRoot()
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_iteratorRoots.popQuick();
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current location path iterator root.
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getIteratorRoot()
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_iteratorRoots.peepOrNull();
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** A stack of the current sub-expression nodes.  */
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private NodeVector m_iteratorRoots = new NodeVector();
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** A stack of the current sub-expression nodes.  */
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private NodeVector m_predicateRoots = new NodeVector();
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** A stack of the current sub-expression nodes.  */
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private IntStack m_currentExpressionNodes = new IntStack(RECURSIONLIMIT);
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public IntStack getCurrentExpressionNodeStack() { return m_currentExpressionNodes; }
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setCurrentExpressionNodeStack(IntStack nv) { m_currentExpressionNodes = nv; }
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private IntStack m_predicatePos = new IntStack();
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getPredicatePos()
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_predicatePos.peek();
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushPredicatePos(int n)
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_predicatePos.push(n);
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popPredicatePos()
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_predicatePos.pop();
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current node that is the expression's context (i.e. for current() support).
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The current sub-expression node.
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getCurrentExpressionNode()
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_currentExpressionNodes.peek();
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the current node that is the expression's context (i.e. for current() support).
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param n The sub-expression node to be current.
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushCurrentExpressionNode(int n)
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.push(n);
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current node that is the expression's context
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * (i.e. for current() support).
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popCurrentExpressionNode()
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_currentExpressionNodes.quickPop(1);
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private ObjectStack m_prefixResolvers
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                   = new ObjectStack(RECURSIONLIMIT);
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current namespace context for the xpath.
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the current prefix resolver for resolving prefixes to
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         namespace URLs.
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final PrefixResolver getNamespaceContext()
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (PrefixResolver) m_prefixResolvers.peek();
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current namespace context for the xpath.
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pr the prefix resolver to be used for resolving prefixes to
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         namespace URLs.
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void setNamespaceContext(PrefixResolver pr)
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.setTop(pr);
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Push a current namespace context for the xpath.
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pr the prefix resolver to be used for resolving prefixes to
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *         namespace URLs.
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushNamespaceContext(PrefixResolver pr)
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.push(pr);
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Just increment the namespace contest stack, so that setNamespaceContext
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * can be used on the slot.
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushNamespaceContextNull()
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.push(null);
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the current namespace context for the xpath.
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popNamespaceContext()
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_prefixResolvers.pop();
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //==========================================================
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // SECTION: Current TreeWalker contexts (for internal use)
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //==========================================================
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Stack of AxesIterators.
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private Stack m_axesIteratorStack = new Stack();
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Stack getAxesIteratorStackStacks() { return m_axesIteratorStack; }
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setAxesIteratorStackStacks(Stack s) { m_axesIteratorStack = s; }
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Push a TreeWalker on the stack.
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param iter A sub-context AxesWalker.
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void pushSubContextList(SubContextList iter)
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_axesIteratorStack.push(iter);
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Pop the last pushed axes iterator.
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final void popSubContextList()
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_axesIteratorStack.pop();
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current axes iterator, or return null if none.
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the sub-context node list.
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public SubContextList getSubContextList()
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_axesIteratorStack.isEmpty()
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ? null : (SubContextList) m_axesIteratorStack.peek();
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as defined by the XSLT spec.
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>.
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage internal
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public org.apache.xpath.axes.SubContextList getCurrentNodeList()
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_axesIteratorStack.isEmpty()
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ? null : (SubContextList) m_axesIteratorStack.elementAt(0);
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //==========================================================
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // SECTION: Implementation of ExpressionContext interface
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //==========================================================
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current context node.
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The current context node.
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final int getContextNode()
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return this.getCurrentNode();
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the current context node list.
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return An iterator for the current context list, as
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * defined in XSLT.
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public final DTMIterator getContextNodes()
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DTMIterator cnl = getContextNodeList();
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != cnl)
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return cnl.cloneWithReset();
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return null;  // for now... this might ought to be an empty iterator.
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch (CloneNotSupportedException cnse)
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return null;  // error reporting?
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  XPathExpressionContext expressionContext = new XPathExpressionContext();
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The the expression context for extensions for this context.
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return An object that implements the ExpressionContext.
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ExpressionContext getExpressionContext()
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return expressionContext;
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public class XPathExpressionContext implements ExpressionContext
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the XPathContext associated with this XPathExpressionContext.
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Extensions should use this judiciously and only when special processing
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * requirements cannot be met another way.  Consider requesting an enhancement
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * to the ExpressionContext interface to avoid having to call this method.
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return the XPathContext associated with this XPathExpressionContext.
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     public XPathContext getXPathContext()
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     {
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       return XPathContext.this;
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     }
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Return the DTMManager object.  Though XPathContext context extends
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * the DTMManager, it really is a proxy for the real DTMManager.  If a
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * caller needs to make a lot of calls to the DTMManager, it is faster
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * if it gets the real one from this function.
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     public DTMManager getDTMManager()
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     {
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       return m_dtmManager;
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     }
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the current context node.
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The current context node.
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public org.w3c.dom.Node getContextNode()
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int context = getCurrentNode();
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getDTM(context).getNode(context);
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the current context node list.
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return An iterator for the current context list, as
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * defined in XSLT.
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public org.w3c.dom.traversal.NodeIterator getContextNodes()
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return new org.apache.xml.dtm.ref.DTMNodeIterator(getContextNodeList());
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the error listener.
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The registered error listener.
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public ErrorListener getErrorListener()
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return XPathContext.this.getErrorListener();
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the value of a node as a number.
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param n Node to be converted to a number.  May be null.
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return value of n as a number.
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public double toNumber(org.w3c.dom.Node n)
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %REVIEW% You can't get much uglier than this...
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nodeHandle = getDTMHandleFromNode(n);
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DTM dtm = getDTM(nodeHandle);
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XString xobj = (XString)dtm.getStringValue(nodeHandle);
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return xobj.num();
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get the value of a node as a string.
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param n Node to be converted to a string.  May be null.
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return value of n as a string, or an empty string if n is null.
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public String toString(org.w3c.dom.Node n)
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // %REVIEW% You can't get much uglier than this...
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nodeHandle = getDTMHandleFromNode(n);
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DTM dtm = getDTM(nodeHandle);
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XMLString strVal = dtm.getStringValue(nodeHandle);
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return strVal.toString();
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get a variable based on it's qualified name.
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param qname The qualified name of the variable.
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return The evaluated value of the variable.
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws javax.xml.transform.TransformerException
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public final XObject getVariableOrParam(org.apache.xml.utils.QName qname)
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              throws javax.xml.transform.TransformerException
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_variableStacks.getVariableOrParam(XPathContext.this, qname);
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /**
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a DTM to be used as a container for a global Result Tree
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Fragment. This will always be an instance of (derived from? equivalent to?)
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * output to it. It may be a single DTM containing for multiple fragments,
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if the implementation supports that.
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note: The distinction between this method and getRTFDTM() is that the latter
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * allocates space from the dynamic variable stack (m_rtfdtm_stack), which may
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be pruned away again as the templates which defined those variables are exited.
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Global variables may be bound late (see XUnresolvedVariable), and never want to
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be discarded, hence we need to allocate them separately and don't actually need
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a stack to track them.
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return a non-null DTM reference.
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTM getGlobalRTFDTM()
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// We probably should _NOT_ be applying whitespace filtering at this stage!
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	//
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// Some magic has been applied in DTMManagerDefault to recognize this set of options
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// and generate an instance of DTM which can contain multiple documents
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// I didn't want to change the manager API at this time, or expose
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// too many dependencies on its internals. (Ideally, I'd like to move
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// specify the subclass here.)
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	// If it doesn't exist, or if the one already existing is in the middle of
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	// being constructed, we need to obtain a new DTM to write into. I'm not sure
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	// the latter will ever arise, but I'd rather be just a bit paranoid..
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if( m_global_rtfdtm==null || m_global_rtfdtm.isTreeIncomplete() )
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_global_rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_global_rtfdtm;
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a DTM to be used as a container for a dynamic Result Tree
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Fragment. This will always be an instance of (derived from? equivalent to?)
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * SAX2DTM, since each RTF is constructed by temporarily redirecting our SAX
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * output to it. It may be a single DTM containing for multiple fragments,
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if the implementation supports that.
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return a non-null DTM reference.
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTM getRTFDTM()
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	SAX2RTFDTM rtfdtm;
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// We probably should _NOT_ be applying whitespace filtering at this stage!
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	//
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// Some magic has been applied in DTMManagerDefault to recognize this set of options
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// and generate an instance of DTM which can contain multiple documents
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// I didn't want to change the manager API at this time, or expose
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// too many dependencies on its internals. (Ideally, I'd like to move
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	// specify the subclass here.)
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	if(m_rtfdtm_stack==null)
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		m_rtfdtm_stack=new Vector();
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_rtfdtm_stack.addElement(rtfdtm);
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		++m_which_rtfdtm;
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else if(m_which_rtfdtm<0)
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(++m_which_rtfdtm);
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	else
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	{
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	// It might already be under construction -- the classic example would be
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 	 	// an xsl:variable which uses xsl:call-template as part of its value. To
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// handle this recursion, we have to start a new RTF DTM, pushing the old
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// one onto a stack so we can return to it. This is not as uncommon a case
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// as we might wish, unfortunately, as some folks insist on coding XSLT
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// as if it were a procedural language...
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		if(rtfdtm.isTreeIncomplete())
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	{
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		if(++m_which_rtfdtm < m_rtfdtm_stack.size())
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson				rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		else
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		{
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		  		rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          m_rtfdtm_stack.addElement(rtfdtm);
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		}
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 	 	}
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	}
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return rtfdtm;
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Push the RTFDTM's context mark, to allows discarding RTFs added after this
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * point. (If it doesn't exist we don't push, since we might still be able to
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * get away with not creating it. That requires that excessive pops be harmless.)
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * */
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void pushRTFContext()
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	m_last_pushed_rtfdtm.push(m_which_rtfdtm);
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null!=m_rtfdtm_stack)
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	((SAX2RTFDTM)(getRTFDTM())).pushRewindMark();
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Pop the RTFDTM's context mark. This discards any RTFs added after the last
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * mark was set.
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If there is no RTF DTM, there's nothing to pop so this
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * becomes a no-op. If pushes were issued before this was called, we count on
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the fact that popRewindMark is defined such that overpopping just resets
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to empty.
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Complicating factor: We need to handle the case of popping back to a previous
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * RTF DTM, if one of the weird produce-an-RTF-to-build-an-RTF cases arose.
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Basically: If pop says this DTM is now empty, then return to the previous
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * if one exists, in whatever state we left it in. UGLY, but hopefully the
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * situation which forces us to consider this will arise exceedingly rarely.
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * */
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void popRTFContext()
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	int previous=m_last_pushed_rtfdtm.pop();
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(null==m_rtfdtm_stack)
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		return;
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(m_which_rtfdtm==previous)
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		if(previous>=0) // guard against none-active
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		{
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(previous))).popRewindMark();
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		}
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	else while(m_which_rtfdtm!=previous)
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// Empty each DTM before popping, so it's ready for reuse
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// _DON'T_ pop the previous, since it's still open (which is why we
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		// stacked up more of these) and did not receive a mark.
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(m_which_rtfdtm))).popRewindMark();
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		--m_which_rtfdtm;
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Gets DTMXRTreeFrag object if one has already been created.
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Creates new DTMXRTreeFrag object and adds to m_DTMXRTreeFrags  HashMap,
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * otherwise.
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param dtmIdentity
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return DTMXRTreeFrag
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public DTMXRTreeFrag getDTMXRTreeFrag(int dtmIdentity){
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_DTMXRTreeFrags == null){
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_DTMXRTreeFrags = new HashMap();
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_DTMXRTreeFrags.containsKey(new Integer(dtmIdentity))){
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       return (DTMXRTreeFrag)m_DTMXRTreeFrags.get(new Integer(dtmIdentity));
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }else{
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      final DTMXRTreeFrag frag = new DTMXRTreeFrag(dtmIdentity,this);
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_DTMXRTreeFrags.put(new Integer(dtmIdentity),frag);
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return frag ;
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Cleans DTMXRTreeFrag objects by removing references
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to DTM and XPathContext objects.
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private final void releaseDTMXRTreeFrags(){
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(m_DTMXRTreeFrags == null){
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return;
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    final Iterator iter = (m_DTMXRTreeFrags.values()).iterator();
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while(iter.hasNext()){
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DTMXRTreeFrag frag = (DTMXRTreeFrag)iter.next();
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      frag.destruct();
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      iter.remove();
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_DTMXRTreeFrags = null;
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson }
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1353