001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: TransformSnapshotImpl.java 468645 2006-10-28 06:57:24Z minchau $
020     */
021    package org.apache.xalan.transformer;
022    
023    import java.util.Enumeration;
024    import java.util.Stack;
025    
026    import org.apache.xml.dtm.DTMIterator;
027    import org.apache.xml.utils.BoolStack;
028    import org.apache.xml.utils.IntStack;
029    import org.apache.xml.utils.NamespaceSupport2;
030    import org.apache.xml.utils.NodeVector;
031    import org.apache.xml.utils.ObjectStack;
032    import org.apache.xpath.VariableStack;
033    import org.apache.xpath.XPathContext;
034    
035    import org.xml.sax.helpers.NamespaceSupport;
036    
037    import org.apache.xml.serializer.NamespaceMappings;
038    import org.apache.xml.serializer.SerializationHandler;
039    /**
040     * This class holds a "snapshot" of it's current transformer state,
041     * which can later be restored.
042     *
043     * This only saves state which can change over the course of the side-effect-free
044     * (i.e. no extensions that call setURIResolver, etc.).
045     * 
046     * @deprecated  It doesn't look like this code, which is for tooling, has
047     * functioned propery for a while, so it doesn't look like it is being used.
048     */
049    class TransformSnapshotImpl implements TransformSnapshot
050    {
051    
052      /**
053       * The stack of Variable stack frames.
054       */
055      private VariableStack m_variableStacks;
056    
057      /**
058       * The stack of <a href="http://www.w3.org/TR/xslt#dt-current-node">current node</a> objects.
059       *  Not to be confused with the current node list.  
060       */
061      private IntStack m_currentNodes;
062    
063      /** A stack of the current sub-expression nodes. */
064      private IntStack m_currentExpressionNodes;
065    
066      /**
067       * The current context node lists stack.
068       */
069      private Stack m_contextNodeLists;
070    
071      /**
072       * The current context node list.
073       */
074      private DTMIterator m_contextNodeList;
075    
076      /**
077       * Stack of AxesIterators.
078       */
079      private Stack m_axesIteratorStack;
080    
081      /**
082       * Is > 0 when we're processing a for-each.
083       */
084      private BoolStack m_currentTemplateRuleIsNull;
085    
086      /**
087       * A node vector used as a stack to track the current
088       * ElemTemplateElement.  Needed for the
089       * org.apache.xalan.transformer.TransformState interface,
090       * so a tool can discover the calling template. 
091       */
092      private ObjectStack m_currentTemplateElements;
093    
094      /**
095       * A node vector used as a stack to track the current
096       * ElemTemplate that was matched, as well as the node that
097       * was matched.  Needed for the
098       * org.apache.xalan.transformer.TransformState interface,
099       * so a tool can discover the matched template, and matched
100       * node. 
101       */
102      private Stack m_currentMatchTemplates;
103    
104      /**
105       * A node vector used as a stack to track the current
106       * ElemTemplate that was matched, as well as the node that
107       * was matched.  Needed for the
108       * org.apache.xalan.transformer.TransformState interface,
109       * so a tool can discover the matched template, and matched
110       * node. 
111       */
112      private NodeVector m_currentMatchNodes;
113    
114      /**
115       * The table of counters for xsl:number support.
116       * @see ElemNumber
117       */
118      private CountersTable m_countersTable;
119    
120      /**
121       * Stack for the purposes of flagging infinite recursion with
122       * attribute sets.
123       */
124      private Stack m_attrSetStack;
125    
126      /** Indicate whether a namespace context was pushed */
127      boolean m_nsContextPushed;
128    
129      /**
130       * Use the SAX2 helper class to track result namespaces.
131       */
132      private NamespaceMappings m_nsSupport;
133    
134      /** The number of events queued */
135    //  int m_eventCount;
136    
137      /**
138       * Constructor TransformSnapshotImpl
139       * Take a snapshot of the currently executing context.
140       *
141       * @param transformer Non null transformer instance
142       * @deprecated  It doesn't look like this code, which is for tooling, has
143       * functioned propery for a while, so it doesn't look like it is being used.
144       */
145      TransformSnapshotImpl(TransformerImpl transformer)
146      {
147    
148        try
149        {
150    
151          // Are all these clones deep enough?
152          SerializationHandler rtf = transformer.getResultTreeHandler();
153    
154          {
155            // save serializer fields
156            m_nsSupport = (NamespaceMappings)rtf.getNamespaceMappings().clone();
157            
158            // Do other fields need to be saved/restored?
159          }
160     
161          XPathContext xpc = transformer.getXPathContext();
162    
163          m_variableStacks = (VariableStack) xpc.getVarStack().clone();
164          m_currentNodes = (IntStack) xpc.getCurrentNodeStack().clone();
165          m_currentExpressionNodes =
166            (IntStack) xpc.getCurrentExpressionNodeStack().clone();
167          m_contextNodeLists = (Stack) xpc.getContextNodeListsStack().clone();
168    
169          if (!m_contextNodeLists.empty())
170            m_contextNodeList =
171              (DTMIterator) xpc.getContextNodeList().clone();
172    
173          m_axesIteratorStack = (Stack) xpc.getAxesIteratorStackStacks().clone();
174          m_currentTemplateRuleIsNull =
175            (BoolStack) transformer.m_currentTemplateRuleIsNull.clone();
176          m_currentTemplateElements =
177            (ObjectStack) transformer.m_currentTemplateElements.clone();
178          m_currentMatchTemplates =
179            (Stack) transformer.m_currentMatchTemplates.clone();
180          m_currentMatchNodes =
181            (NodeVector) transformer.m_currentMatchedNodes.clone();
182          m_countersTable =
183            (CountersTable) transformer.getCountersTable().clone();
184    
185          if (transformer.m_attrSetStack != null)
186            m_attrSetStack = (Stack) transformer.m_attrSetStack.clone();
187        }
188        catch (CloneNotSupportedException cnse)
189        {
190          throw new org.apache.xml.utils.WrappedRuntimeException(cnse);
191        }
192      }
193    
194      /**
195       * This will reset the stylesheet to a given execution context
196       * based on some previously taken snapshot where we can then start execution 
197       *
198       * @param transformer Non null transformer instance
199       * 
200       * @deprecated  It doesn't look like this code, which is for tooling, has
201       * functioned propery for a while, so it doesn't look like it is being used.
202       */
203      void apply(TransformerImpl transformer)
204      {
205    
206        try
207        {
208    
209          // Are all these clones deep enough?
210          SerializationHandler rtf = transformer.getResultTreeHandler();
211    
212          if (rtf != null)
213          {
214            // restore serializer fields
215             rtf.setNamespaceMappings((NamespaceMappings)m_nsSupport.clone());
216          }
217    
218          XPathContext xpc = transformer.getXPathContext();
219    
220          xpc.setVarStack((VariableStack) m_variableStacks.clone());
221          xpc.setCurrentNodeStack((IntStack) m_currentNodes.clone());
222          xpc.setCurrentExpressionNodeStack(
223            (IntStack) m_currentExpressionNodes.clone());
224          xpc.setContextNodeListsStack((Stack) m_contextNodeLists.clone());
225    
226          if (m_contextNodeList != null)
227            xpc.pushContextNodeList((DTMIterator) m_contextNodeList.clone());
228    
229          xpc.setAxesIteratorStackStacks((Stack) m_axesIteratorStack.clone());
230    
231          transformer.m_currentTemplateRuleIsNull =
232            (BoolStack) m_currentTemplateRuleIsNull.clone();
233          transformer.m_currentTemplateElements =
234            (ObjectStack) m_currentTemplateElements.clone();
235          transformer.m_currentMatchTemplates =
236            (Stack) m_currentMatchTemplates.clone();
237          transformer.m_currentMatchedNodes =
238            (NodeVector) m_currentMatchNodes.clone();
239          transformer.m_countersTable = (CountersTable) m_countersTable.clone();
240    
241          if (m_attrSetStack != null)
242            transformer.m_attrSetStack = (Stack) m_attrSetStack.clone();
243        }
244        catch (CloneNotSupportedException cnse)
245        {
246          throw new org.apache.xml.utils.WrappedRuntimeException(cnse);
247        }
248      }
249    }