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 */ |