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 #include "ElemChoose.hpp"
19 
20 
21 
22 #include <xercesc/sax/AttributeList.hpp>
23 
24 
25 
26 #include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
27 
28 
29 
30 #include <xalanc/XPath/XObjectFactory.hpp>
31 #include <xalanc/XPath/XPath.hpp>
32 
33 
34 
35 #include "Constants.hpp"
36 #include "ElemWhen.hpp"
37 #include "SelectionEvent.hpp"
38 #include "Stylesheet.hpp"
39 #include "StylesheetConstructionContext.hpp"
40 #include "StylesheetExecutionContext.hpp"
41 #include "StylesheetRoot.hpp"
42 
43 
44 
45 namespace XALAN_CPP_NAMESPACE {
46 
47 
48 
ElemChoose(StylesheetConstructionContext & constructionContext,Stylesheet & stylesheetTree,const AttributeListType & atts,XalanFileLoc lineNumber,XalanFileLoc columnNumber)49 ElemChoose::ElemChoose(
50             StylesheetConstructionContext&  constructionContext,
51             Stylesheet&                     stylesheetTree,
52             const AttributeListType&        atts,
53             XalanFileLoc                    lineNumber,
54             XalanFileLoc                    columnNumber) :
55     ElemTemplateElement(constructionContext,
56                         stylesheetTree,
57                         lineNumber,
58                         columnNumber,
59                         StylesheetConstructionContext::ELEMNAME_CHOOSE)
60 {
61     const XalanSize_t   nAttrs = atts.getLength();
62 
63     for (XalanSize_t i = 0; i < nAttrs; i++)
64     {
65         const XalanDOMChar* const   aname = atts.getName(i);
66 
67         if (isAttrOK(
68                 aname,
69                 atts,
70                 i,
71                 constructionContext) == false &&
72             processSpaceAttr(
73                 Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING.c_str(),
74                 aname,
75                 atts,
76                 i,
77                 constructionContext) == false)
78         {
79             error(
80                 constructionContext,
81                 XalanMessages::ElementHasIllegalAttribute_2Param,
82                 Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING.c_str(),
83                 aname);
84         }
85     }
86 }
87 
88 
89 
90 const XalanDOMString&
getElementName() const91 ElemChoose::getElementName() const
92 {
93     return Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING;
94 }
95 
96 
97 
98 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
99 const ElemTemplateElement*
startElement(StylesheetExecutionContext & executionContext) const100 ElemChoose::startElement(StylesheetExecutionContext&        executionContext) const
101 {
102     ElemTemplateElement::startElement(executionContext);
103 
104     XalanNode* sourceNode = executionContext.getCurrentNode();
105 
106     for (const ElemTemplateElement* node = getFirstChildElem();
107             node != 0;
108                 node = node->getNextSiblingElem())
109     {
110         const int   type = node->getXSLToken();
111 
112         if (StylesheetConstructionContext::ELEMNAME_WHEN == type)
113         {
114 
115             const XPath* const      theXPath = node->getXPath(0);
116             assert(theXPath != 0);
117 
118             bool    test;
119 
120             theXPath->execute(*this, executionContext, test);
121 
122             if (0 != executionContext.getTraceListeners())
123             {
124                 executionContext.fireSelectEvent(
125                     SelectionEvent(executionContext,
126                     sourceNode,
127                     *node,
128                     Constants::ATTRNAME_TEST,
129                     *theXPath,
130                     test));
131             }
132 
133             if(test == true)
134             {
135                 return node;
136             }
137         }
138         else
139         {
140             // xsl:otherwise
141             return node;
142         }
143     }
144     return 0;
145 }
146 
147 
148 
149 const ElemTemplateElement*
getNextChildElemToExecute(StylesheetExecutionContext &,const ElemTemplateElement *) const150 ElemChoose::getNextChildElemToExecute(
151             StylesheetExecutionContext& /*executionContext*/,
152             const ElemTemplateElement*  /*currentElem*/) const
153 {
154     return 0;
155 }
156 #endif
157 
158 
159 
160 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
161 void
execute(StylesheetExecutionContext & executionContext) const162 ElemChoose::execute(StylesheetExecutionContext&     executionContext) const
163 {
164     ElemTemplateElement::execute(executionContext);
165 
166     XalanNode* sourceNode = executionContext.getCurrentNode();
167 
168     for (const ElemTemplateElement* node = getFirstChildElem();
169             node != 0;
170                 node = node->getNextSiblingElem())
171     {
172         const int   type = node->getXSLToken();
173 
174         if(StylesheetConstructionContext::ELEMNAME_WHEN == type)
175         {
176 
177             const XPath* const      theXPath = node->getXPath(0);
178             assert(theXPath != 0);
179 
180             bool    test;
181 
182             theXPath->execute(*this, executionContext, test);
183 
184             if(0 != executionContext.getTraceListeners())
185             {
186                 executionContext.fireSelectEvent(
187                     SelectionEvent(executionContext,
188                     sourceNode,
189                     *node,
190                     Constants::ATTRNAME_TEST,
191                     *theXPath,
192                     test));
193             }
194 
195             if(test == true)
196             {
197                 node->execute(executionContext);
198 
199                 break;
200             }
201         }
202         else
203         {
204             // xsl:otherwise
205             node->execute(executionContext);
206         }
207     }
208 }
209 #endif
210 
211 
212 
213 bool
childTypeAllowed(int xslToken) const214 ElemChoose::childTypeAllowed(int    xslToken) const
215 {
216     bool    fResult = false;
217 
218     switch(xslToken)
219     {
220     // char-instructions
221     case StylesheetConstructionContext::ELEMNAME_WHEN:
222     case StylesheetConstructionContext::ELEMNAME_OTHERWISE:
223         fResult = true;
224         break;
225 
226     default:
227         break;
228     }
229 
230     return fResult;
231 }
232 
233 
234 
235 }
236