1 /*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "stdafx.h"
17
18 #include "system/globalenv.h"
19
20 #include "context/static_context.h"
21
22 #include "types/typemanager.h"
23 #include "types/casting.h"
24
25 #include "compiler/api/compilercb.h"
26
27 #include "runtime/qnames/qnames.h"
28 #include "runtime/visitors/planiter_visitor.h"
29
30 #include "store/api/store.h"
31 #include "store/api/item_factory.h"
32 #include "store/api/item.h"
33
34
35 namespace zorba {
36 #define GENV_GCAST (*GenericCast::instance ())
37
38 //11.1.1 fn:resolve-QName
39 bool
nextImpl(store::Item_t & result,PlanState & planState) const40 ResolveQNameIterator::nextImpl(store::Item_t& result, PlanState& planState) const
41 {
42 store::Item_t itemQName;
43 store::Item_t itemElem;
44 zstring qname;
45 zstring resNs;
46 zstring resPre;
47 zstring resLocal;
48 zstring::size_type index;
49 store::NsBindings NamespaceBindings;
50 store::NsBindings::const_iterator iter;
51
52 PlanIteratorState* state;
53 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
54
55 if (consumeNext(itemQName, theChild0.getp(), planState ))
56 {
57 itemQName->getStringValue2(qname);
58
59 ascii::trim_whitespace(qname);
60
61 index = qname.find(":", 0, 1);
62
63 if (index != zstring::npos)
64 {
65 resPre = qname.substr(0, index);
66 resLocal = qname.substr(index+1, qname.size() - index);
67
68 // must check for FOCA0002 first
69 if (!GENV_GCAST.castableToNCName(resPre) || ! GENV_GCAST.castableToNCName(resLocal))
70 throw XQUERY_EXCEPTION(
71 err::FOCA0002, ERROR_PARAMS( qname ), ERROR_LOC(loc)
72 );
73 }
74 else
75 {
76 resLocal = qname;
77
78 if (! GENV_GCAST.castableToNCName(resLocal))
79 throw XQUERY_EXCEPTION(
80 err::FOCA0002, ERROR_PARAMS( qname ), ERROR_LOC(loc)
81 );
82 }
83
84 if (consumeNext(itemElem, theChild1, planState ))
85 {
86 itemElem->getNamespaceBindings(NamespaceBindings);
87
88 bool found = false;
89
90 for (iter = NamespaceBindings.begin();
91 iter != NamespaceBindings.end();
92 ++iter)
93 {
94 if ((*iter).first == resPre)
95 {
96 resNs = (*iter).second;
97 found = true;
98 break;
99 }
100 }
101
102 if (!found && !resPre.empty())
103 throw XQUERY_EXCEPTION(
104 err::FONS0004, ERROR_PARAMS( resPre ), ERROR_LOC( loc )
105 );
106 }
107
108 GENV_ITEMFACTORY->createQName(result, resNs, resPre, resLocal);
109
110 STACK_PUSH(true, state);
111 }
112
113 STACK_END(state);
114 }
115
116
117 //11.1.2 fn:QName
nextImpl(store::Item_t & result,PlanState & planState) const118 bool QNameIterator::nextImpl(store::Item_t& result, PlanState& planState) const
119 {
120 store::Item_t itemURI;
121 store::Item_t itemQName;
122 zstring qname;
123 zstring resNs;
124 zstring resPre;
125 zstring resLocal;
126 zstring::size_type index;
127
128 PlanIteratorState* state;
129 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
130
131 if (consumeNext(itemURI, theChild0.getp(), planState ))
132 {
133 itemURI->getStringValue2(resNs);
134
135 ascii::trim_whitespace(resNs);
136 }
137
138 consumeNext(itemQName, theChild1.getp(), planState );
139
140 itemQName->getStringValue2(qname);
141
142 ascii::trim_whitespace(qname);
143
144 index = qname.find(":", 0, 1);
145
146 if (index != zstring::npos)
147 {
148 if (resNs.empty())
149 throw XQUERY_EXCEPTION(
150 err::FOCA0002, ERROR_PARAMS( resNs ), ERROR_LOC(loc)
151 );
152
153 resPre = qname.substr(0, index);
154 resLocal = qname.substr(index+1, qname.size() - index);
155 }
156 else
157 {
158 resLocal = qname;
159 }
160
161 if ((index != zstring::npos && ! GENV_GCAST.castableToNCName(resPre)) ||
162 ! GENV_GCAST.castableToNCName(resLocal))
163 {
164 throw XQUERY_EXCEPTION(
165 err::FOCA0002, ERROR_PARAMS( qname ), ERROR_LOC(loc)
166 );
167 }
168
169 GENV_ITEMFACTORY->createQName(result, resNs, resPre, resLocal);
170
171 STACK_PUSH(true, state);
172 STACK_END(state);
173 }
174
175
176 //11.2.1 op:QName-equal
nextImpl(store::Item_t & result,PlanState & planState) const177 bool QNameEqualIterator::nextImpl(
178 store::Item_t& result,
179 PlanState& planState) const
180 {
181 store::Item_t arg1;
182 store::Item_t arg2;
183
184 PlanIteratorState* state;
185 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
186
187 if (consumeNext(arg1, theChild0.getp(), planState ))
188 {
189 if (consumeNext(arg2, theChild1.getp(), planState ))
190 {
191 if(arg1->getLocalName() == arg2->getLocalName())
192 {
193 if (arg1->getNamespace() == arg2->getNamespace())
194 GENV_ITEMFACTORY->createBoolean(result, true);
195 else
196 GENV_ITEMFACTORY->createBoolean(result, false);
197 }
198 else
199 {
200 GENV_ITEMFACTORY->createBoolean(result, false);
201 }
202
203 STACK_PUSH(true, state );
204 }
205 }
206 STACK_END (state);
207 }
208
209
210 //11.2.2 fn:prefix-from-QName
nextImpl(store::Item_t & result,PlanState & planState) const211 bool PrefixFromQNameIterator::nextImpl(
212 store::Item_t& result,
213 PlanState& planState) const
214 {
215 store::Item_t item;
216 zstring tmp;
217
218 PlanIteratorState* state;
219 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
220
221 if (consumeNext(item, theChild.getp(), planState))
222 {
223 if(!item->getPrefix().empty())
224 {
225 tmp = item->getPrefix();
226 STACK_PUSH( GENV_ITEMFACTORY->createNCName(result, tmp), state );
227 }
228 }
229 STACK_END (state);
230 }
231
232
233 //11.2.3 fn:local-name-from-QName
nextImpl(store::Item_t & result,PlanState & planState) const234 bool LocalNameFromQNameIterator::nextImpl(
235 store::Item_t& result,
236 PlanState& planState) const
237 {
238 store::Item_t item;
239 zstring localName;
240
241 PlanIteratorState* state;
242 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
243
244 if (consumeNext(item, theChild.getp(), planState))
245 {
246 localName = item->getLocalName();
247 STACK_PUSH(GENV_ITEMFACTORY->createNCName(result, localName), state);
248 }
249 STACK_END (state);
250 }
251
252
253 //11.2.4 fn:namespace-uri-from-QName
nextImpl(store::Item_t & result,PlanState & planState) const254 bool NamespaceUriFromQNameIterator::nextImpl(
255 store::Item_t& result,
256 PlanState& planState) const
257 {
258 store::Item_t item;
259 zstring ns;
260
261 PlanIteratorState* state;
262 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
263
264 if (consumeNext(item, theChild.getp(), planState))
265 {
266 ns = item->getNamespace();
267 STACK_PUSH( GENV_ITEMFACTORY->createAnyURI(result, ns), state );
268 }
269 STACK_END (state);
270 }
271
272
273 //11.2.5 fn:namespace-uri-for-prefix
nextImpl(store::Item_t & result,PlanState & planState) const274 bool NamespaceUriForPrefixIterator::nextImpl(
275 store::Item_t& result,
276 PlanState& planState) const
277 {
278 store::Item_t itemPrefix, itemElem;
279 zstring resNs;
280 zstring prefix;
281 bool found = false;
282 store::NsBindings NamespaceBindings;
283 store::NsBindings::const_iterator iter;
284
285 PlanIteratorState* state;
286 DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
287
288 if (!consumeNext(itemPrefix, theChildren[0].getp(), planState ))
289 {
290 prefix = "";
291 }
292 else
293 {
294 itemPrefix->getStringValue2(prefix);
295 ascii::trim_whitespace(prefix);
296 }
297
298 if (!consumeNext(itemElem, theChildren[1].getp(), planState ))
299 {
300 ZORBA_ASSERT(false);
301 }
302 else
303 {
304 itemElem->getNamespaceBindings(NamespaceBindings);
305
306 for (iter = NamespaceBindings.begin();
307 iter != NamespaceBindings.end();
308 ++iter)
309 {
310 if (((*iter).first == prefix) &&
311 !(*iter).second.empty())
312 {
313 resNs = (*iter).second;
314 found = true;
315 break;
316 }
317 }
318 }
319
320 if (found)
321 {
322 STACK_PUSH( GENV_ITEMFACTORY->createString(result, resNs), state );
323 }
324
325 STACK_END (state);
326 }
327
328 //11.2.6 fn:in-scope-prefixes
init(PlanState & planState)329 void InScopePrefixesIteratorState::init(PlanState& planState)
330 {
331 PlanIteratorState::init(planState);
332 theBindings.clear();
333 theCurrentPos = 0;
334 }
335
reset(PlanState & planState)336 void InScopePrefixesIteratorState::reset(PlanState& planState)
337 {
338 PlanIteratorState::reset(planState);
339 theBindings.clear();
340 theCurrentPos = 0;
341 }
342
343 bool
nextImpl(store::Item_t & result,PlanState & planState) const344 InScopePrefixesIterator::nextImpl(store::Item_t& result, PlanState& planState) const
345 {
346 store::Item_t itemElem;
347 zstring ncname("xml");
348
349 InScopePrefixesIteratorState* state;
350 DEFAULT_STACK_INIT(InScopePrefixesIteratorState, state, planState);
351
352 STACK_PUSH(GENV_ITEMFACTORY->createNCName(result, ncname), state);
353
354 if (consumeNext(itemElem, theChild.getp(), planState ))
355 {
356 itemElem->getNamespaceBindings(state->theBindings);
357 while (state->theCurrentPos < state->theBindings.size())
358 {
359 if (!state->theBindings[state->theCurrentPos].second.empty())
360 {
361 ncname = state->theBindings[state->theCurrentPos].first;
362 STACK_PUSH(GENV_ITEMFACTORY->createNCName(result, ncname), state);
363 }
364 state->theCurrentPos++;
365 }
366 }
367
368 STACK_END (state);
369 }
370
371 } // namespace zorba
372 /* vim:set et sw=2 ts=2: */
373