src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPathContext.java
changeset 47359 e1a6c0168741
parent 47216 71c04702a3d5
child 48409 5ab69533994b
equal deleted inserted replaced
47358:d07d5f7cab35 47359:e1a6c0168741
     1 /*
     1 /*
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * @LastModified: Oct 2017
     3  */
     4  */
     4 /*
     5 /*
     5  * Licensed to the Apache Software Foundation (ASF) under one or more
     6  * Licensed to the Apache Software Foundation (ASF) under one or more
     6  * contributor license agreements.  See the NOTICE file distributed with
     7  * contributor license agreements.  See the NOTICE file distributed with
     7  * this work for additional information regarding copyright ownership.
     8  * this work for additional information regarding copyright ownership.
    38 import com.sun.org.apache.xpath.internal.objects.DTMXRTreeFrag;
    39 import com.sun.org.apache.xpath.internal.objects.DTMXRTreeFrag;
    39 import com.sun.org.apache.xpath.internal.objects.XObject;
    40 import com.sun.org.apache.xpath.internal.objects.XObject;
    40 import com.sun.org.apache.xpath.internal.objects.XString;
    41 import com.sun.org.apache.xpath.internal.objects.XString;
    41 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
    42 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
    42 import java.lang.reflect.Method;
    43 import java.lang.reflect.Method;
       
    44 import java.util.ArrayList;
    43 import java.util.HashMap;
    45 import java.util.HashMap;
    44 import java.util.Iterator;
    46 import java.util.Iterator;
       
    47 import java.util.List;
       
    48 import java.util.Map;
    45 import java.util.Stack;
    49 import java.util.Stack;
    46 import java.util.Vector;
       
    47 import javax.xml.transform.ErrorListener;
    50 import javax.xml.transform.ErrorListener;
    48 import javax.xml.transform.SourceLocator;
    51 import javax.xml.transform.SourceLocator;
    49 import javax.xml.transform.TransformerException;
       
    50 import javax.xml.transform.URIResolver;
    52 import javax.xml.transform.URIResolver;
    51 import org.xml.sax.XMLReader;
    53 import org.xml.sax.XMLReader;
    52 
    54 
    53 /**
    55 /**
    54  * Default class for the runtime execution context for XPath.
    56  * Default class for the runtime execution context for XPath.
    67    * %REVIEW% I'm using a Vector rather than Stack so we can reuse
    69    * %REVIEW% I'm using a Vector rather than Stack so we can reuse
    68    * the DTMs if the problem occurs multiple times. I'm not sure that's
    70    * the DTMs if the problem occurs multiple times. I'm not sure that's
    69    * really a net win versus discarding the DTM and starting a new one...
    71    * really a net win versus discarding the DTM and starting a new one...
    70    * but the retained RTF DTM will have been tail-pruned so should be small.
    72    * but the retained RTF DTM will have been tail-pruned so should be small.
    71    */
    73    */
    72   private Vector m_rtfdtm_stack=null;
    74   private List<DTM> m_rtfdtm_stack=null;
    73   /** Index of currently active RTF DTM in m_rtfdtm_stack */
    75   /** Index of currently active RTF DTM in m_rtfdtm_stack */
    74   private int m_which_rtfdtm=-1;
    76   private int m_which_rtfdtm=-1;
    75 
    77 
    76  /**
    78  /**
    77    * Most recent "reusable" DTM for Global Result Tree Fragments. No stack is
    79    * Most recent "reusable" DTM for Global Result Tree Fragments. No stack is
    81 
    83 
    82   /**
    84   /**
    83    * HashMap of cached the DTMXRTreeFrag objects, which are identified by DTM IDs.
    85    * HashMap of cached the DTMXRTreeFrag objects, which are identified by DTM IDs.
    84    * The object are just wrappers for DTMs which are used in  XRTreeFrag.
    86    * The object are just wrappers for DTMs which are used in  XRTreeFrag.
    85    */
    87    */
    86   private HashMap m_DTMXRTreeFrags = null;
    88   private Map<Integer, DTMXRTreeFrag> m_DTMXRTreeFrags = null;
    87 
    89 
    88   /**
    90   /**
    89    * state of the secure processing feature.
    91    * state of the secure processing feature.
    90    */
    92    */
    91   private boolean m_isSecureProcessing = false;
    93   private boolean m_isSecureProcessing = false;
   317    */
   319    */
   318   public XPathContext(Object owner)
   320   public XPathContext(Object owner)
   319   {
   321   {
   320     m_owner = owner;
   322     m_owner = owner;
   321     try {
   323     try {
   322       m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class[] {});
   324       m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class<?>[] {});
   323     }
   325     }
   324     catch (NoSuchMethodException nsme) {}
   326     catch (NoSuchMethodException nsme) {}
   325     init(true);
   327     init(true);
   326   }
   328   }
   327 
   329 
   340    * Reset for new run.
   342    * Reset for new run.
   341    */
   343    */
   342   public void reset()
   344   public void reset()
   343   {
   345   {
   344     releaseDTMXRTreeFrags();
   346     releaseDTMXRTreeFrags();
   345         // These couldn't be disposed of earlier (see comments in release()); zap them now.
   347     // These couldn't be disposed of earlier (see comments in release()); zap them now.
   346         if(m_rtfdtm_stack!=null)
   348     if(m_rtfdtm_stack!=null) {
   347                  for (java.util.Enumeration e = m_rtfdtm_stack.elements() ; e.hasMoreElements() ;)
   349         for (DTM dtm : m_rtfdtm_stack) {
   348                         m_dtmManager.release((DTM)e.nextElement(), true);
   350             m_dtmManager.release(dtm, true);
       
   351         }
       
   352     }
   349 
   353 
   350     m_rtfdtm_stack=null; // drop our references too
   354     m_rtfdtm_stack=null; // drop our references too
   351     m_which_rtfdtm=-1;
   355     m_which_rtfdtm=-1;
   352 
   356 
   353     if(m_global_rtfdtm!=null)
   357     if(m_global_rtfdtm!=null)
   358     m_dtmManager = DTMManager.newInstance(
   362     m_dtmManager = DTMManager.newInstance(
   359                    com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()
   363                    com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()
   360                    );
   364                    );
   361 
   365 
   362     m_saxLocations.removeAllElements();
   366     m_saxLocations.removeAllElements();
   363         m_axesIteratorStack.removeAllElements();
   367     m_axesIteratorStack.removeAllElements();
   364         m_contextNodeLists.removeAllElements();
   368     m_contextNodeLists.removeAllElements();
   365         m_currentExpressionNodes.removeAllElements();
   369     m_currentExpressionNodes.removeAllElements();
   366         m_currentNodes.removeAllElements();
   370     m_currentNodes.removeAllElements();
   367         m_iteratorRoots.RemoveAllNoClear();
   371     m_iteratorRoots.RemoveAllNoClear();
   368         m_predicatePos.removeAllElements();
   372     m_predicatePos.removeAllElements();
   369         m_predicateRoots.RemoveAllNoClear();
   373     m_predicateRoots.RemoveAllNoClear();
   370         m_prefixResolvers.removeAllElements();
   374     m_prefixResolvers.removeAllElements();
   371 
   375 
   372         m_prefixResolvers.push(null);
   376     m_prefixResolvers.push(null);
   373     m_currentNodes.push(DTM.NULL);
   377     m_currentNodes.push(DTM.NULL);
   374     m_currentExpressionNodes.push(DTM.NULL);
   378     m_currentExpressionNodes.push(DTM.NULL);
   375     m_saxLocations.push(null);
   379     m_saxLocations.push(null);
   376   }
   380   }
   377 
   381 
   620   //==========================================================
   624   //==========================================================
   621 
   625 
   622   /**
   626   /**
   623    * The current context node list.
   627    * The current context node list.
   624    */
   628    */
   625   private Stack m_contextNodeLists = new Stack();
   629   private Stack<DTMIterator> m_contextNodeLists = new Stack<>();
   626 
   630 
   627   public Stack getContextNodeListsStack() { return m_contextNodeLists; }
   631   public Stack<DTMIterator> getContextNodeListsStack() { return m_contextNodeLists; }
   628   public void setContextNodeListsStack(Stack s) { m_contextNodeLists = s; }
   632   public void setContextNodeListsStack(Stack<DTMIterator> s) { m_contextNodeLists = s; }
   629 
   633 
   630   /**
   634   /**
   631    * Get the current context node list.
   635    * Get the current context node list.
   632    *
   636    *
   633    * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
   637    * @return  the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>,
   635    */
   639    */
   636   public final DTMIterator getContextNodeList()
   640   public final DTMIterator getContextNodeList()
   637   {
   641   {
   638 
   642 
   639     if (m_contextNodeLists.size() > 0)
   643     if (m_contextNodeLists.size() > 0)
   640       return (DTMIterator) m_contextNodeLists.peek();
   644       return m_contextNodeLists.peek();
   641     else
   645     else
   642       return null;
   646       return null;
   643   }
   647   }
   644 
   648 
   645   /**
   649   /**
   923   //==========================================================
   927   //==========================================================
   924 
   928 
   925   /**
   929   /**
   926    * Stack of AxesIterators.
   930    * Stack of AxesIterators.
   927    */
   931    */
   928   private Stack m_axesIteratorStack = new Stack();
   932   private Stack<SubContextList> m_axesIteratorStack = new Stack<>();
   929 
   933 
   930   public Stack getAxesIteratorStackStacks() { return m_axesIteratorStack; }
   934   public Stack<SubContextList> getAxesIteratorStackStacks() { return m_axesIteratorStack; }
   931   public void setAxesIteratorStackStacks(Stack s) { m_axesIteratorStack = s; }
   935   public void setAxesIteratorStackStacks(Stack<SubContextList> s) { m_axesIteratorStack = s; }
   932 
   936 
   933   /**
   937   /**
   934    * Push a TreeWalker on the stack.
   938    * Push a TreeWalker on the stack.
   935    *
   939    *
   936    * @param iter A sub-context AxesWalker.
   940    * @param iter A sub-context AxesWalker.
   956    * @return the sub-context node list.
   960    * @return the sub-context node list.
   957    * @xsl.usage internal
   961    * @xsl.usage internal
   958    */
   962    */
   959   public SubContextList getSubContextList()
   963   public SubContextList getSubContextList()
   960   {
   964   {
   961     return m_axesIteratorStack.isEmpty()
   965     return m_axesIteratorStack.isEmpty() ? null : m_axesIteratorStack.peek();
   962            ? null : (SubContextList) m_axesIteratorStack.peek();
       
   963   }
   966   }
   964 
   967 
   965   /**
   968   /**
   966    * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>
   969    * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>
   967    * as defined by the XSLT spec.
   970    * as defined by the XSLT spec.
   970    * @xsl.usage internal
   973    * @xsl.usage internal
   971    */
   974    */
   972 
   975 
   973   public com.sun.org.apache.xpath.internal.axes.SubContextList getCurrentNodeList()
   976   public com.sun.org.apache.xpath.internal.axes.SubContextList getCurrentNodeList()
   974   {
   977   {
   975     return m_axesIteratorStack.isEmpty()
   978     return m_axesIteratorStack.isEmpty() ? null : m_axesIteratorStack.get(0);
   976            ? null : (SubContextList) m_axesIteratorStack.elementAt(0);
       
   977   }
   979   }
   978   //==========================================================
   980   //==========================================================
   979   // SECTION: Implementation of ExpressionContext interface
   981   // SECTION: Implementation of ExpressionContext interface
   980   //==========================================================
   982   //==========================================================
   981 
   983 
  1198         // isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
  1200         // isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly
  1199         // specify the subclass here.)
  1201         // specify the subclass here.)
  1200 
  1202 
  1201         if(m_rtfdtm_stack==null)
  1203         if(m_rtfdtm_stack==null)
  1202         {
  1204         {
  1203                 m_rtfdtm_stack=new Vector();
  1205             m_rtfdtm_stack=new ArrayList<>();
  1204                 rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
  1206             rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
  1205     m_rtfdtm_stack.addElement(rtfdtm);
  1207             m_rtfdtm_stack.add(rtfdtm);
  1206                 ++m_which_rtfdtm;
  1208             ++m_which_rtfdtm;
  1207         }
  1209         }
  1208         else if(m_which_rtfdtm<0)
  1210         else if(m_which_rtfdtm<0)
  1209         {
  1211         {
  1210                 rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(++m_which_rtfdtm);
  1212             rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.get(++m_which_rtfdtm);
  1211         }
  1213         }
  1212         else
  1214         else
  1213         {
  1215         {
  1214                 rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
  1216             rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.get(m_which_rtfdtm);
  1215 
  1217 
  1216                 // It might already be under construction -- the classic example would be
  1218             // It might already be under construction -- the classic example would be
  1217                 // an xsl:variable which uses xsl:call-template as part of its value. To
  1219             // an xsl:variable which uses xsl:call-template as part of its value. To
  1218                 // handle this recursion, we have to start a new RTF DTM, pushing the old
  1220             // handle this recursion, we have to start a new RTF DTM, pushing the old
  1219                 // one onto a stack so we can return to it. This is not as uncommon a case
  1221             // one onto a stack so we can return to it. This is not as uncommon a case
  1220                 // as we might wish, unfortunately, as some folks insist on coding XSLT
  1222             // as we might wish, unfortunately, as some folks insist on coding XSLT
  1221                 // as if it were a procedural language...
  1223             // as if it were a procedural language...
  1222                 if(rtfdtm.isTreeIncomplete())
  1224             if(rtfdtm.isTreeIncomplete())
       
  1225             {
       
  1226                 if(++m_which_rtfdtm < m_rtfdtm_stack.size())
       
  1227                     rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.get(m_which_rtfdtm);
       
  1228                 else
  1223                 {
  1229                 {
  1224                         if(++m_which_rtfdtm < m_rtfdtm_stack.size())
  1230                     rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
  1225                                 rtfdtm=(SAX2RTFDTM)m_rtfdtm_stack.elementAt(m_which_rtfdtm);
  1231                     m_rtfdtm_stack.add(rtfdtm);
  1226                         else
       
  1227                         {
       
  1228                                 rtfdtm=(SAX2RTFDTM)m_dtmManager.getDTM(null,true,null,false,false);
       
  1229           m_rtfdtm_stack.addElement(rtfdtm);
       
  1230                         }
       
  1231                 }
  1232                 }
       
  1233             }
  1232         }
  1234         }
  1233 
  1235 
  1234     return rtfdtm;
  1236     return rtfdtm;
  1235   }
  1237   }
  1236 
  1238 
  1267 
  1269 
  1268         if(m_which_rtfdtm==previous)
  1270         if(m_which_rtfdtm==previous)
  1269         {
  1271         {
  1270                 if(previous>=0) // guard against none-active
  1272                 if(previous>=0) // guard against none-active
  1271                 {
  1273                 {
  1272                         boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(previous))).popRewindMark();
  1274                         boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.get(previous))).popRewindMark();
  1273                 }
  1275                 }
  1274         }
  1276         }
  1275         else while(m_which_rtfdtm!=previous)
  1277         else while(m_which_rtfdtm!=previous)
  1276         {
  1278         {
  1277                 // Empty each DTM before popping, so it's ready for reuse
  1279                 // Empty each DTM before popping, so it's ready for reuse
  1278                 // _DON'T_ pop the previous, since it's still open (which is why we
  1280                 // _DON'T_ pop the previous, since it's still open (which is why we
  1279                 // stacked up more of these) and did not receive a mark.
  1281                 // stacked up more of these) and did not receive a mark.
  1280                 boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(m_which_rtfdtm))).popRewindMark();
  1282                 boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.get(m_which_rtfdtm))).popRewindMark();
  1281                 --m_which_rtfdtm;
  1283                 --m_which_rtfdtm;
  1282         }
  1284         }
  1283   }
  1285   }
  1284 
  1286 
  1285   /**
  1287   /**
  1289    * @param dtmIdentity
  1291    * @param dtmIdentity
  1290    * @return DTMXRTreeFrag
  1292    * @return DTMXRTreeFrag
  1291    */
  1293    */
  1292   public DTMXRTreeFrag getDTMXRTreeFrag(int dtmIdentity){
  1294   public DTMXRTreeFrag getDTMXRTreeFrag(int dtmIdentity){
  1293     if(m_DTMXRTreeFrags == null){
  1295     if(m_DTMXRTreeFrags == null){
  1294       m_DTMXRTreeFrags = new HashMap();
  1296       m_DTMXRTreeFrags = new HashMap<>();
  1295     }
  1297     }
  1296 
  1298 
  1297     if(m_DTMXRTreeFrags.containsKey(dtmIdentity)){
  1299     if(m_DTMXRTreeFrags.containsKey(dtmIdentity)){
  1298        return (DTMXRTreeFrag)m_DTMXRTreeFrags.get(dtmIdentity);
  1300        return m_DTMXRTreeFrags.get(dtmIdentity);
  1299     }else{
  1301     }else{
  1300       final DTMXRTreeFrag frag = new DTMXRTreeFrag(dtmIdentity,this);
  1302       final DTMXRTreeFrag frag = new DTMXRTreeFrag(dtmIdentity,this);
  1301       m_DTMXRTreeFrags.put(dtmIdentity,frag);
  1303       m_DTMXRTreeFrags.put(dtmIdentity,frag);
  1302       return frag ;
  1304       return frag ;
  1303     }
  1305     }
  1309    */
  1311    */
  1310   private final void releaseDTMXRTreeFrags(){
  1312   private final void releaseDTMXRTreeFrags(){
  1311     if(m_DTMXRTreeFrags == null){
  1313     if(m_DTMXRTreeFrags == null){
  1312       return;
  1314       return;
  1313     }
  1315     }
  1314     final Iterator iter = (m_DTMXRTreeFrags.values()).iterator();
  1316     final Iterator<DTMXRTreeFrag> iter = (m_DTMXRTreeFrags.values()).iterator();
  1315     while(iter.hasNext()){
  1317     while(iter.hasNext()){
  1316       DTMXRTreeFrag frag = (DTMXRTreeFrag)iter.next();
  1318       DTMXRTreeFrag frag = iter.next();
  1317       frag.destruct();
  1319       frag.destruct();
  1318       iter.remove();
  1320       iter.remove();
  1319     }
  1321     }
  1320     m_DTMXRTreeFrags = null;
  1322     m_DTMXRTreeFrags = null;
  1321  }
  1323  }