src/com/sun/org/apache/xpath/internal/XPathContext.java

Print this page




   5 /*
   6  * Copyright 1999-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: XPathContext.java,v 1.2.4.2 2005/09/15 01:37:55 jeffsuttor Exp $
  22  */
  23 package com.sun.org.apache.xpath.internal;
  24 
  25 import java.lang.reflect.Method;
  26 import java.util.Stack;
  27 import java.util.Vector;
  28 import java.util.HashMap;
  29 import java.util.Iterator;
  30 
  31 import javax.xml.transform.ErrorListener;
  32 import javax.xml.transform.SourceLocator;
  33 import javax.xml.transform.TransformerException;
  34 import javax.xml.transform.URIResolver;
  35 
  36 import com.sun.org.apache.xalan.internal.extensions.ExpressionContext;
  37 import com.sun.org.apache.xalan.internal.res.XSLMessages;
  38 import com.sun.org.apache.xml.internal.dtm.Axis;
  39 import com.sun.org.apache.xml.internal.dtm.DTM;
  40 import com.sun.org.apache.xml.internal.dtm.DTMFilter;
  41 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  42 import com.sun.org.apache.xml.internal.dtm.DTMManager;
  43 import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
  44 import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2RTFDTM;
  45 import com.sun.org.apache.xml.internal.utils.IntStack;
  46 import com.sun.org.apache.xml.internal.utils.NodeVector;
  47 import com.sun.org.apache.xml.internal.utils.ObjectStack;
  48 import com.sun.org.apache.xml.internal.utils.PrefixResolver;
  49 import com.sun.org.apache.xml.internal.utils.SAXSourceLocator;
  50 import com.sun.org.apache.xml.internal.utils.XMLString;
  51 import com.sun.org.apache.xpath.internal.axes.SubContextList;
  52 import com.sun.org.apache.xpath.internal.objects.XObject;
  53 import com.sun.org.apache.xpath.internal.objects.DTMXRTreeFrag;

  54 import com.sun.org.apache.xpath.internal.objects.XString;
  55 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
  56 








  57 import org.xml.sax.XMLReader;
  58 
  59 /**
  60  * Default class for the runtime execution context for XPath.
  61  *
  62  * <p>This class extends DTMManager but does not directly implement it.</p>
  63  * @xsl.usage advanced
  64  */
  65 public class XPathContext extends DTMManager // implements ExpressionContext
  66 {
  67         IntStack m_last_pushed_rtfdtm=new IntStack();
  68   /**
  69    * Stack of cached "reusable" DTMs for Result Tree Fragments.
  70    * This is a kluge to handle the problem of starting an RTF before
  71    * the old one is complete.
  72    *
  73    * %REVIEW% I'm using a Vector rather than Stack so we can reuse
  74    * the DTMs if the problem occurs multiple times. I'm not sure that's
  75    * really a net win versus discarding the DTM and starting a new one...
  76    * but the retained RTF DTM will have been tail-pruned so should be small.


 322    * @param owner Value that can be retrieved via the getOwnerObject() method.
 323    * @see #getOwnerObject
 324    */
 325   public XPathContext(Object owner)
 326   {
 327     m_owner = owner;
 328     try {
 329       m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class[] {});
 330     }
 331     catch (NoSuchMethodException nsme) {}
 332     init(true);
 333   }
 334 
 335   private void init(boolean useServicesMechanism) {
 336     m_prefixResolvers.push(null);
 337     m_currentNodes.push(DTM.NULL);
 338     m_currentExpressionNodes.push(DTM.NULL);
 339     m_saxLocations.push(null);
 340     m_useServicesMechanism = useServicesMechanism;
 341     m_dtmManager = DTMManager.newInstance(
 342                    com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory(),
 343                    m_useServicesMechanism);
 344   }
 345 
 346   /**
 347    * Reset for new run.
 348    */
 349   public void reset()
 350   {
 351     releaseDTMXRTreeFrags();
 352         // These couldn't be disposed of earlier (see comments in release()); zap them now.
 353         if(m_rtfdtm_stack!=null)
 354                  for (java.util.Enumeration e = m_rtfdtm_stack.elements() ; e.hasMoreElements() ;)
 355                         m_dtmManager.release((DTM)e.nextElement(), true);
 356 
 357     m_rtfdtm_stack=null; // drop our references too
 358     m_which_rtfdtm=-1;
 359 
 360     if(m_global_rtfdtm!=null)
 361                         m_dtmManager.release(m_global_rtfdtm,true);
 362     m_global_rtfdtm=null;
 363 
 364 
 365     m_dtmManager = DTMManager.newInstance(
 366                    com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory(),
 367                    m_useServicesMechanism);
 368 
 369     m_saxLocations.removeAllElements();
 370         m_axesIteratorStack.removeAllElements();
 371         m_contextNodeLists.removeAllElements();
 372         m_currentExpressionNodes.removeAllElements();
 373         m_currentNodes.removeAllElements();
 374         m_iteratorRoots.RemoveAllNoClear();
 375         m_predicatePos.removeAllElements();
 376         m_predicateRoots.RemoveAllNoClear();
 377         m_prefixResolvers.removeAllElements();
 378 
 379         m_prefixResolvers.push(null);
 380     m_currentNodes.push(DTM.NULL);
 381     m_currentExpressionNodes.push(DTM.NULL);
 382     m_saxLocations.push(null);
 383   }
 384 
 385   /** The current stylesheet locator. */
 386   ObjectStack m_saxLocations = new ObjectStack(RECURSIONLIMIT);
 387 


 605   {
 606     return m_primaryReader;
 607   }
 608 
 609   /**
 610    * Set primary XMLReader associated with this execution context.
 611    *
 612    * @param reader The reader of the primary source tree.
 613    */
 614   public void setPrimaryReader(XMLReader reader)
 615   {
 616     m_primaryReader = reader;
 617   }
 618 
 619   // =================================================
 620 
 621 
 622   /** Misnamed string manager for XPath messages.  */
 623   // private static XSLMessages m_XSLMessages = new XSLMessages();
 624 
 625   /**
 626    * Tell the user of an assertion error, and probably throw an
 627    * exception.
 628    *
 629    * @param b  If false, a TransformerException will be thrown.
 630    * @param msg The assertion message, which should be informative.
 631    *
 632    * @throws javax.xml.transform.TransformerException if b is false.
 633    */
 634   private void assertion(boolean b, String msg) throws javax.xml.transform.TransformerException
 635   {
 636     if (!b)
 637     {
 638       ErrorListener errorHandler = getErrorListener();
 639 
 640       if (errorHandler != null)
 641       {
 642         errorHandler.fatalError(
 643           new TransformerException(
 644             XSLMessages.createMessage(
 645               XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
 646               new Object[]{ msg }), (SAXSourceLocator)this.getSAXLocator()));
 647       }
 648     }
 649   }
 650 
 651   //==========================================================
 652   // SECTION: Execution context state tracking
 653   //==========================================================
 654 
 655   /**
 656    * The current context node list.
 657    */
 658   private Stack m_contextNodeLists = new Stack();
 659 
 660   public Stack getContextNodeListsStack() { return m_contextNodeLists; }
 661   public void setContextNodeListsStack(Stack s) { m_contextNodeLists = s; }
 662 
 663   /**
 664    * Get the current context node list.
 665    *
 666    * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
 667    * also refered to here as a <term>context node list</term>.
 668    */
 669   public final DTMIterator getContextNodeList()
 670   {
 671 
 672     if (m_contextNodeLists.size() > 0)
 673       return (DTMIterator) m_contextNodeLists.peek();
 674     else
 675       return null;
 676   }
 677 
 678   /**
 679    * Set the current context node list.
 680    *
 681    * @param nl the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
 682    * also refered to here as a <term>context node list</term>.
 683    * @xsl.usage internal
 684    */
 685   public final void pushContextNodeList(DTMIterator nl)
 686   {
 687     m_contextNodeLists.push(nl);
 688   }
 689 
 690   /**
 691    * Pop the current context node list.
 692    * @xsl.usage internal
 693    */
 694   public final void popContextNodeList()
 695   {
 696         if(m_contextNodeLists.isEmpty())
 697           System.err.println("Warning: popContextNodeList when stack is empty!");
 698         else
 699       m_contextNodeLists.pop();
 700   }
 701 
 702   /**
 703    * The ammount to use for stacks that record information during the
 704    * recursive execution.
 705    */
 706   public static final int RECURSIONLIMIT = (1024*4);
 707 
 708   /** The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
 709    *  Not to be confused with the current node list.  %REVIEW% Note that there
 710    *  are no bounds check and resize for this stack, so if it is blown, it's all
 711    *  over.  */
 712   private IntStack m_currentNodes = new IntStack(RECURSIONLIMIT);
 713 
 714 //  private NodeVector m_currentNodes = new NodeVector();
 715 
 716   public IntStack getCurrentNodeStack() {return m_currentNodes; }
 717   public void setCurrentNodeStack(IntStack nv) { m_currentNodes = nv; }
 718 
 719   /**
 720    * Get the current context node.
 721    *
 722    * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
 723    */




   5 /*
   6  * Copyright 1999-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: XPathContext.java,v 1.2.4.2 2005/09/15 01:37:55 jeffsuttor Exp $
  22  */
  23 package com.sun.org.apache.xpath.internal;
  24 











  25 import com.sun.org.apache.xalan.internal.extensions.ExpressionContext;
  26 import com.sun.org.apache.xalan.internal.res.XSLMessages;
  27 import com.sun.org.apache.xml.internal.dtm.Axis;
  28 import com.sun.org.apache.xml.internal.dtm.DTM;
  29 import com.sun.org.apache.xml.internal.dtm.DTMFilter;
  30 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  31 import com.sun.org.apache.xml.internal.dtm.DTMManager;
  32 import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
  33 import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2RTFDTM;
  34 import com.sun.org.apache.xml.internal.utils.IntStack;
  35 import com.sun.org.apache.xml.internal.utils.NodeVector;
  36 import com.sun.org.apache.xml.internal.utils.ObjectStack;
  37 import com.sun.org.apache.xml.internal.utils.PrefixResolver;

  38 import com.sun.org.apache.xml.internal.utils.XMLString;
  39 import com.sun.org.apache.xpath.internal.axes.SubContextList;

  40 import com.sun.org.apache.xpath.internal.objects.DTMXRTreeFrag;
  41 import com.sun.org.apache.xpath.internal.objects.XObject;
  42 import com.sun.org.apache.xpath.internal.objects.XString;
  43 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
  44 import java.lang.reflect.Method;
  45 import java.util.HashMap;
  46 import java.util.Iterator;
  47 import java.util.Stack;
  48 import java.util.Vector;
  49 import javax.xml.transform.ErrorListener;
  50 import javax.xml.transform.SourceLocator;
  51 import javax.xml.transform.TransformerException;
  52 import javax.xml.transform.URIResolver;
  53 import org.xml.sax.XMLReader;
  54 
  55 /**
  56  * Default class for the runtime execution context for XPath.
  57  *
  58  * <p>This class extends DTMManager but does not directly implement it.</p>
  59  * @xsl.usage advanced
  60  */
  61 public class XPathContext extends DTMManager // implements ExpressionContext
  62 {
  63         IntStack m_last_pushed_rtfdtm=new IntStack();
  64   /**
  65    * Stack of cached "reusable" DTMs for Result Tree Fragments.
  66    * This is a kluge to handle the problem of starting an RTF before
  67    * the old one is complete.
  68    *
  69    * %REVIEW% I'm using a Vector rather than Stack so we can reuse
  70    * the DTMs if the problem occurs multiple times. I'm not sure that's
  71    * really a net win versus discarding the DTM and starting a new one...
  72    * but the retained RTF DTM will have been tail-pruned so should be small.


 318    * @param owner Value that can be retrieved via the getOwnerObject() method.
 319    * @see #getOwnerObject
 320    */
 321   public XPathContext(Object owner)
 322   {
 323     m_owner = owner;
 324     try {
 325       m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class[] {});
 326     }
 327     catch (NoSuchMethodException nsme) {}
 328     init(true);
 329   }
 330 
 331   private void init(boolean useServicesMechanism) {
 332     m_prefixResolvers.push(null);
 333     m_currentNodes.push(DTM.NULL);
 334     m_currentExpressionNodes.push(DTM.NULL);
 335     m_saxLocations.push(null);
 336     m_useServicesMechanism = useServicesMechanism;
 337     m_dtmManager = DTMManager.newInstance(
 338                    com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()
 339                    );
 340   }
 341 
 342   /**
 343    * Reset for new run.
 344    */
 345   public void reset()
 346   {
 347     releaseDTMXRTreeFrags();
 348         // These couldn't be disposed of earlier (see comments in release()); zap them now.
 349         if(m_rtfdtm_stack!=null)
 350                  for (java.util.Enumeration e = m_rtfdtm_stack.elements() ; e.hasMoreElements() ;)
 351                         m_dtmManager.release((DTM)e.nextElement(), true);
 352 
 353     m_rtfdtm_stack=null; // drop our references too
 354     m_which_rtfdtm=-1;
 355 
 356     if(m_global_rtfdtm!=null)
 357                         m_dtmManager.release(m_global_rtfdtm,true);
 358     m_global_rtfdtm=null;
 359 
 360 
 361     m_dtmManager = DTMManager.newInstance(
 362                    com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()
 363                    );
 364 
 365     m_saxLocations.removeAllElements();
 366         m_axesIteratorStack.removeAllElements();
 367         m_contextNodeLists.removeAllElements();
 368         m_currentExpressionNodes.removeAllElements();
 369         m_currentNodes.removeAllElements();
 370         m_iteratorRoots.RemoveAllNoClear();
 371         m_predicatePos.removeAllElements();
 372         m_predicateRoots.RemoveAllNoClear();
 373         m_prefixResolvers.removeAllElements();
 374 
 375         m_prefixResolvers.push(null);
 376     m_currentNodes.push(DTM.NULL);
 377     m_currentExpressionNodes.push(DTM.NULL);
 378     m_saxLocations.push(null);
 379   }
 380 
 381   /** The current stylesheet locator. */
 382   ObjectStack m_saxLocations = new ObjectStack(RECURSIONLIMIT);
 383 


 601   {
 602     return m_primaryReader;
 603   }
 604 
 605   /**
 606    * Set primary XMLReader associated with this execution context.
 607    *
 608    * @param reader The reader of the primary source tree.
 609    */
 610   public void setPrimaryReader(XMLReader reader)
 611   {
 612     m_primaryReader = reader;
 613   }
 614 
 615   // =================================================
 616 
 617 
 618   /** Misnamed string manager for XPath messages.  */
 619   // private static XSLMessages m_XSLMessages = new XSLMessages();
 620 


























 621   //==========================================================
 622   // SECTION: Execution context state tracking
 623   //==========================================================
 624 
 625   /**
 626    * The current context node list.
 627    */
 628   private Stack m_contextNodeLists = new Stack();
 629 
 630   public Stack getContextNodeListsStack() { return m_contextNodeLists; }
 631   public void setContextNodeListsStack(Stack s) { m_contextNodeLists = s; }
 632 
 633   /**
 634    * Get the current context node list.
 635    *
 636    * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
 637    * also referred to here as a <term>context node list</term>.
 638    */
 639   public final DTMIterator getContextNodeList()
 640   {
 641 
 642     if (m_contextNodeLists.size() > 0)
 643       return (DTMIterator) m_contextNodeLists.peek();
 644     else
 645       return null;
 646   }
 647 
 648   /**
 649    * Set the current context node list.
 650    *
 651    * @param nl the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
 652    * also referred to here as a <term>context node list</term>.
 653    * @xsl.usage internal
 654    */
 655   public final void pushContextNodeList(DTMIterator nl)
 656   {
 657     m_contextNodeLists.push(nl);
 658   }
 659 
 660   /**
 661    * Pop the current context node list.
 662    * @xsl.usage internal
 663    */
 664   public final void popContextNodeList()
 665   {
 666         if(m_contextNodeLists.isEmpty())
 667           System.err.println("Warning: popContextNodeList when stack is empty!");
 668         else
 669       m_contextNodeLists.pop();
 670   }
 671 
 672   /**
 673    * The amount to use for stacks that record information during the
 674    * recursive execution.
 675    */
 676   public static final int RECURSIONLIMIT = (1024*4);
 677 
 678   /** The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
 679    *  Not to be confused with the current node list.  %REVIEW% Note that there
 680    *  are no bounds check and resize for this stack, so if it is blown, it's all
 681    *  over.  */
 682   private IntStack m_currentNodes = new IntStack(RECURSIONLIMIT);
 683 
 684 //  private NodeVector m_currentNodes = new NodeVector();
 685 
 686   public IntStack getCurrentNodeStack() {return m_currentNodes; }
 687   public void setCurrentNodeStack(IntStack nv) { m_currentNodes = nv; }
 688 
 689   /**
 690    * Get the current context node.
 691    *
 692    * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a>.
 693    */