1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #if !defined(XALAN_ELEMFOREACH_HEADER_GUARD)
19 #define XALAN_ELEMFOREACH_HEADER_GUARD
20 
21 
22 
23 // Base include file.  Must be first.
24 #include "XSLTDefinitions.hpp"
25 
26 
27 
28 #include <xalanc/Include/XalanVector.hpp>
29 
30 
31 
32 // Base class header file.
33 #include "ElemTemplateElement.hpp"
34 
35 
36 
37 #include <xalanc/XPath/NodeRefListBase.hpp>
38 #include <xalanc/XPath/MutableNodeRefList.hpp>
39 #include <xalanc/XPath/XObject.hpp>
40 
41 
42 
43 #include "Constants.hpp"
44 
45 
46 
47 namespace XALAN_CPP_NAMESPACE {
48 
49 
50 
51 class ElemSort;
52 class ElemTemplate;
53 class NodeSorter;
54 class XPath;
55 
56 
57 
58 class ElemForEach: public ElemTemplateElement
59 {
60 public:
61 
62     /**
63      * Construct an object corresponding to an "xsl:for-each" element
64      *
65      * @param constructionContext context for construction of object
66      * @param stylesheetTree      stylesheet containing element
67      * @param atts                list of attributes for element
68      * @param lineNumber            line number in document
69      * @param columnNumber          column number in document
70      */
71     ElemForEach(
72             StylesheetConstructionContext&  constructionContext,
73             Stylesheet&                     stylesheetTree,
74             const AttributeListType&        atts,
75             XalanFileLoc                    lineNumber,
76             XalanFileLoc                    columnNumber);
77 
78     virtual
79     ~ElemForEach();
80 
81     typedef XalanVector<ElemSort*>      SortElemsVectorType;
82 
83     // These methods are inherited from ElemTemplateElement ...
84 
85     virtual const XalanDOMString&
86     getElementName() const;
87 
88     virtual void
89     processSortElement(
90             StylesheetConstructionContext&  constructionContext,
91             Stylesheet&                     theStylesheet,
92             const AttributeListType&        atts,
93             const Locator*                  locator = 0);
94 
95     virtual void
96     postConstruction(
97             StylesheetConstructionContext&  constructionContext,
98             const NamespacesHandler&        theParentHandler);
99 
100 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
101     virtual const ElemTemplateElement*
102     startElement(StylesheetExecutionContext&    executionContext) const;
103 
104     virtual void
105     endElement(StylesheetExecutionContext&      executionContext) const;
106 
107     virtual const ElemTemplateElement*
108     getNextChildElemToExecute(
109                StylesheetExecutionContext&  executionContext,
110                const ElemTemplateElement*   currentElem) const;
111 #else
112     virtual void
113     execute(StylesheetExecutionContext&     executionContext) const;
114 #endif
115 
116     virtual const XPath*
117     getXPath(XalanSize_t    index) const;
118 
119 protected:
120 
121     /**
122      * Construct an object derived from ElemForEach
123      *
124      * @param constructionContext context for construction of object
125      * @param stylesheetTree      stylesheet containing element
126      * @param lineNumber            line number in document
127      * @param columnNumber          column number in document
128      * @param xslToken             an integer representing the type of instance.
129      */
130     ElemForEach(
131             StylesheetConstructionContext&  constructionContext,
132             Stylesheet&                     stylesheetTree,
133             XalanFileLoc                    lineNumber,
134             XalanFileLoc                    columnNumber,
135             int                             xslToken);
136 
137 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
138 
139     /*
140      * Returns a pointer to a list of the selected nodes.  The
141      * nodes are sorted if required.
142      *
143      * @param executionContext  context for executing this element
144      * @return pointer to the list of selected (and sorted) nodes
145      */
146     virtual const NodeRefListBase*
147     createSelectedAndSortedNodeList(
148             StylesheetExecutionContext&     executionContext) const;
149 
150     /*
151      * Release any objects used to maintain the last selected
152      * (and sorted) node list to be created
153      *
154      * @param executionContext  context for executing this element
155      */
156     virtual void
157     releaseSelectedAndSortedNodeList(
158             StylesheetExecutionContext&     executionContext) const;
159 
160     /*
161      * Sorts a list of nodes
162      *
163      * @param executionContext  context for executing this element
164      * @param selectedNodeList  list of nodes to be sorted
165      * @param sortedNodeList    list for sorted nodes
166      *
167      * @returns pointer to list of sorted nodes
168      */
169     virtual const NodeRefListBase*
170     sortChildren(
171             StylesheetExecutionContext&     executionContext,
172             const NodeRefListBase&          selectedNodeList,
173             MutableNodeRefList&             sortedNodeList) const;
174 
175 #else
176     /**
177      * Perform a query if needed, and call transformChild for each child.
178      *
179      * @param executionContext  The current execution context
180      * @param template The owning template context.
181      * @param sourceNodeContext The current source node context.
182      */
183     void
184     transformSelectedChildren(
185             StylesheetExecutionContext&     executionContext,
186             const ElemTemplateElement*      theTemplate) const;
187 
188     /**
189      * Perform a query if needed, and call transformChild for each child.
190      *
191      * @param executionContext The current execution context
192      * @param theTemplate The owning template context.
193      * @param sourceNodes The source nodes to transform.
194      * @param sourceNodesCount The count of source nodes to transform.
195      */
196     void
197     transformSelectedChildren(
198             StylesheetExecutionContext&     executionContext,
199             const ElemTemplateElement*      theTemplate,
200             const NodeRefListBase&          sourceNodes,
201             NodeRefListBase::size_type      sourceNodesCount) const;
202 
203     /**
204      * Perform a query if needed, and call transformChild for each child.
205      *
206      * @param executionContext  The current execution context
207      * @param template The owning template context.
208      * @param sorter The NodeSorter instance, if any.
209      * @param selectStackFrameIndex stack frame context for executing the
210      *                              select statement
211      */
212     virtual void
213     selectAndSortChildren(
214             StylesheetExecutionContext&     executionContext,
215             const ElemTemplateElement*      theTemplate,
216             NodeSorter*                     sorter,
217             int                             selectStackFrameIndex) const;
218 #endif
219 
220     const XPath*            m_selectPattern;
221 
222 private:
223 
224     SortElemsVectorType             m_sortElems;
225 
226     SortElemsVectorType::size_type  m_sortElemsCount;
227 
228 };
229 
230 
231 
232 }
233 
234 
235 
236 #endif  // XALAN_ELEMFOREACH_HEADER_GUARD
237