1 /*
2 * Copyright 2006-2012 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 <assert.h>
19 #include <algorithm>
20 #include <memory>
21
22 #include <zorba/external_module.h>
23 #include <zorba/serialization_callback.h>
24
25 #include "functions/udf.h"
26
27 #include "zorbamisc/ns_consts.h"
28 #include "util/string_util.h"
29
30 #define ZORBA_UTILS_HASHMAP_WITH_SERIALIZATION
31 #include "zorbautils/hashmap_itemp.h"
32 #undef ZORBA_UTILS_HASHMAP_WITH_SERIALIZATION
33
34 #include "context/static_context_consts.h"
35 #include "context/static_context.h"
36 #include "context/root_static_context.h"
37 #include "context/dynamic_loader.h"
38 #include "context/decimal_format.h"
39 #include "context/sctx_map_iterator.h"
40
41 #include "compiler/expression/expr_base.h"
42 #include "compiler/expression/var_expr.h"
43 #ifndef ZORBA_NO_FULL_TEXT
44 #include "compiler/expression/ftnode.h"
45 #endif /* ZORBA_NO_FULL_TEXT */
46 #include "compiler/xqddf/collection_decl.h"
47 #include "compiler/xqddf/value_index.h"
48 #include "compiler/xqddf/value_ic.h"
49
50 #include "zorbatypes/collation_manager.h"
51 #include "zorbatypes/URI.h"
52
53 #include "api/unmarshaller.h"
54 #include "api/auditimpl.h"
55
56 #include "api/uri_resolver_wrappers.h"
57
58 #include "diagnostics/xquery_diagnostics.h"
59 #include "diagnostics/util_macros.h"
60
61 #include "system/globalenv.h"
62
63 #include "types/typemanager.h"
64 #include "types/casting.h"
65 #include "types/typeops.h"
66 #include "types/schema/validate.h"
67
68 #include "functions/function.h"
69 #include "functions/library.h"
70 #include "functions/signature.h"
71
72 #include "compiler/translator/module_version.h"
73
74 #include "zorbaserialization/serialize_zorba_types.h"
75 #include "zorbaserialization/serialize_template_types.h"
76
77 #include "store/api/store.h"
78 #include "store/api/item_factory.h"
79 #include "store/api/iterator.h"
80
81
82 using namespace std;
83 #ifndef ZORBA_NO_FULL_TEXT
84 using namespace zorba::locale;
85 #endif /* ZORBA_NO_FULL_TEXT */
86
87 namespace zorba
88 {
89
90 #define ITEM_FACTORY (GENV.getStore().getItemFactory())
91
92
93 SERIALIZABLE_CLASS_VERSIONS(BaseUriInfo)
94
SERIALIZABLE_CLASS_VERSIONS(FunctionInfo)95 SERIALIZABLE_CLASS_VERSIONS(FunctionInfo)
96
97 SERIALIZABLE_CLASS_VERSIONS(VarInfo)
98
99 SERIALIZABLE_CLASS_VERSIONS(PrologOption)
100
101 SERIALIZABLE_CLASS_VERSIONS_2(static_context::ctx_module_t, TYPE_sctx_module)
102
103 SERIALIZABLE_CLASS_VERSIONS(static_context)
104
105
106 /**************************************************************************//**
107
108 *******************************************************************************/
109 void BaseUriInfo::serialize(::zorba::serialization::Archiver& ar)
110 {
111 ar & thePrologBaseUri;
112 ar & theApplicationBaseUri;
113 ar & theEntityRetrievalUri;
114 ar & theEncapsulatingEntityUri;
115
116 ar & theBaseUri;
117
118 ar & theHavePrologBaseUri;
119 ar & theHaveApplicationBaseUri;
120 ar & theHaveEntityRetrievalUri;
121 ar & theHaveEncapsulatingEntityUri;
122
123 ar & theHaveBaseUri;
124 }
125
126
127 /**************************************************************************//**
128
129 *******************************************************************************/
FunctionInfo()130 FunctionInfo::FunctionInfo()
131 :
132 theIsDisabled(false)
133 {
134 }
135
136
FunctionInfo(const function_t & f,bool disabled)137 FunctionInfo::FunctionInfo(const function_t& f, bool disabled)
138 :
139 theFunction(f),
140 theIsDisabled(disabled)
141 {
142 }
143
144
FunctionInfo(::zorba::serialization::Archiver & ar)145 FunctionInfo::FunctionInfo(::zorba::serialization::Archiver& ar)
146 :
147 ::zorba::serialization::SerializeBaseClass()
148 {
149 }
150
151
152 /**************************************************************************//**
153
154 *******************************************************************************/
~FunctionInfo()155 FunctionInfo::~FunctionInfo()
156 {
157 }
158
159
160 /**************************************************************************//**
161
162 *******************************************************************************/
serialize(::zorba::serialization::Archiver & ar)163 void FunctionInfo::serialize(::zorba::serialization::Archiver& ar)
164 {
165 ar & theFunction;
166 ar & theIsDisabled;
167 }
168
169
170 /**************************************************************************//**
171
172 *******************************************************************************/
VarInfo()173 VarInfo::VarInfo()
174 :
175 theId(0),
176 theKind(var_expr::unknown_var),
177 theVarExpr(NULL)
178 {
179 }
180
181
182 /**************************************************************************//**
183
184 *******************************************************************************/
VarInfo(::zorba::serialization::Archiver & ar)185 VarInfo::VarInfo(::zorba::serialization::Archiver& ar)
186 :
187 SimpleRCObject(ar)
188 {
189 }
190
191
192 /**************************************************************************//**
193
194 *******************************************************************************/
~VarInfo()195 VarInfo::~VarInfo()
196 {
197 }
198
199
200 /**************************************************************************//**
201
202 *******************************************************************************/
VarInfo(var_expr * v)203 VarInfo::VarInfo(var_expr* v)
204 :
205 theName(v->get_name()),
206 theId(v->get_unique_id()),
207 theKind(v->get_kind()),
208 theType(v->get_type()),
209 theIsExternal(v->is_external()),
210 theHasInitializer(v->has_initializer()),
211 theVarExpr(v)
212 {
213 }
214
215
216 /**************************************************************************//**
217
218 *******************************************************************************/
serialize(::zorba::serialization::Archiver & ar)219 void VarInfo::serialize(::zorba::serialization::Archiver& ar)
220 {
221 ar & theName;
222 ar & theId;
223 ar & theKind;
224 ar & theType;
225 ar & theIsExternal;
226 ar & theHasInitializer;
227 }
228
229
230 /**************************************************************************//**
231
232 *******************************************************************************/
setType(const xqtref_t & t)233 void VarInfo::setType(const xqtref_t& t)
234 {
235 theType = t;
236 }
237
238
239 /**************************************************************************//**
240
241 *******************************************************************************/
serialize(::zorba::serialization::Archiver & ar)242 void PrologOption::serialize(::zorba::serialization::Archiver& ar)
243 {
244 ar & theName;
245 ar & theValue;
246 }
247
248
249 /**************************************************************************//**
250
251 *******************************************************************************/
serialize(serialization::Archiver & ar)252 void static_context::ctx_module_t::serialize(serialization::Archiver& ar)
253 {
254 if (ar.is_serializing_out())
255 {
256 // serialize out: the uri of the module that is used in this plan
257
258 zstring lURI = Unmarshaller::getInternalString(module->getURI());
259 ar.set_is_temp_field(true);
260 ar.dont_allow_delay();
261 ar & lURI;
262 ar.set_is_temp_field(false);
263 ar & dyn_loaded_module;
264 ar & sctx;
265 }
266 else
267 {
268 // serialize in: load the serialized uri of the module and
269 // get the externalmodule from the user's
270 // registered serialization callback
271 zstring lURI;
272 ar.set_is_temp_field(true);
273 ar & lURI;
274 ar.set_is_temp_field(false);
275 ar & dyn_loaded_module;
276 ar & sctx;
277
278 if (dyn_loaded_module)
279 {
280 ZORBA_ASSERT(sctx);
281 module = GENV_DYNAMIC_LOADER->getExternalModule(lURI, *sctx);
282
283 // no way to get the module
284 if (!module)
285 {
286 throw ZORBA_EXCEPTION(zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
287 ERROR_PARAMS(ZED(NoExternalModuleFromDLL), lURI));
288 }
289 }
290 else
291 {
292 // class registered by the user
293 SerializationCallback* lCallback = ar.getUserCallback();
294 if (!lCallback)
295 {
296 throw ZORBA_EXCEPTION(zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
297 ERROR_PARAMS(ZED(NoSerializationCallbackForModule), lURI));
298 }
299
300 // the life-cycle of the module is managed by the user
301 module = lCallback->getExternalModule(lURI.str());
302 if (!module)
303 {
304 throw ZORBA_EXCEPTION(zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
305 ERROR_PARAMS(ZED(NoRegisteredSerializationCallback_2), lURI));
306 }
307 }
308 }
309 }
310
311
312 /***************************************************************************//**
313 Target namespaces of zorba builtin modules
314 ********************************************************************************/
315
316 const zstring
317 static_context::DOT_VAR_NAME = "$$context-item";
318
319 const zstring
320 static_context::DOT_POS_VAR_NAME = "$$context-position";
321
322 const zstring
323 static_context::DOT_SIZE_VAR_NAME = "$$context-size";
324
325 const char*
326 static_context::W3C_NS_PREFIX = "http://www.w3.org/";
327
328 const char*
329 static_context::ZORBA_NS_PREFIX = "http://www.zorba-xquery.com/";
330
331 const char*
332 static_context::W3C_FN_NS = "http://www.w3.org/2005/xpath-functions";
333
334 const char*
335 static_context::W3C_XML_NS = "http://www.w3.org/XML/1998/namespace";
336
337 const char*
338 static_context::ZORBA_MATH_FN_NS =
339 "http://www.zorba-xquery.com/modules/math";
340
341 const char*
342 static_context::ZORBA_BASE64_FN_NS =
343 "http://www.zorba-xquery.com/modules/converters/base64";
344
345 const char*
346 static_context::ZORBA_JSON_FN_NS =
347 "http://www.zorba-xquery.com/modules/converters/json";
348
349 const char*
350 static_context::ZORBA_NODEREF_FN_NS =
351 "http://www.zorba-xquery.com/modules/node-reference";
352
353 const char*
354 static_context::ZORBA_NODEPOS_FN_NS =
355 "http://www.zorba-xquery.com/modules/node-position";
356
357 const char*
358 static_context::ZORBA_STORE_DYNAMIC_COLLECTIONS_DDL_FN_NS =
359 "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl";
360
361 const char*
362 static_context::ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_FN_NS =
363 "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml";
364
365 const char*
366 static_context::ZORBA_STORE_STATIC_COLLECTIONS_DDL_FN_NS =
367 "http://www.zorba-xquery.com/modules/store/static/collections/ddl";
368
369 const char*
370 static_context::ZORBA_STORE_STATIC_COLLECTIONS_DML_FN_NS =
371 "http://www.zorba-xquery.com/modules/store/static/collections/dml";
372
373 const char*
374 static_context::ZORBA_STORE_STATIC_INDEXES_DDL_FN_NS =
375 "http://www.zorba-xquery.com/modules/store/static/indexes/ddl";
376
377 const char*
378 static_context::ZORBA_STORE_STATIC_INDEXES_DML_FN_NS =
379 "http://www.zorba-xquery.com/modules/store/static/indexes/dml";
380
381 const char*
382 static_context::ZORBA_STORE_STATIC_INTEGRITY_CONSTRAINTS_DDL_FN_NS =
383 "http://www.zorba-xquery.com/modules/store/static/integrity_constraints/ddl";
384
385 const char*
386 static_context::ZORBA_STORE_STATIC_INTEGRITY_CONSTRAINTS_DML_FN_NS =
387 "http://www.zorba-xquery.com/modules/store/static/integrity_constraints/dml";
388
389 const char*
390 static_context::ZORBA_STORE_DYNAMIC_DOCUMENTS_FN_NS =
391 "http://www.zorba-xquery.com/modules/store/dynamic/documents";
392
393 const char*
394 static_context::ZORBA_STORE_DYNAMIC_UNORDERED_MAP_FN_NS =
395 "http://www.zorba-xquery.com/modules/store/data-structures/unordered-map";
396
397 #ifdef ZORBA_WITH_JSON
398
399 const char*
400 static_context::JSONIQ_DM_NS =
401 "http://jsoniq.org/types";
402
403 const char*
404 static_context::JSONIQ_FN_NS =
405 "http://jsoniq.org/functions";
406
407 #endif
408
409 const char*
410 static_context::ZORBA_SCHEMA_FN_NS =
411 "http://www.zorba-xquery.com/modules/schema";
412
413 const char*
414 static_context::ZORBA_XQDOC_FN_NS =
415 "http://www.zorba-xquery.com/modules/xqdoc";
416
417 const char*
418 static_context::ZORBA_RANDOM_FN_NS =
419 "http://www.zorba-xquery.com/modules/random";
420
421 const char*
422 static_context::ZORBA_INTROSP_SCTX_FN_NS =
423 "http://www.zorba-xquery.com/modules/introspection/sctx";
424
425 const char*
426 static_context::ZORBA_REFLECTION_FN_NS =
427 "http://www.zorba-xquery.com/modules/reflection";
428
429 const char*
430 static_context::ZORBA_UTIL_FN_NS =
431 "http://www.zorba-xquery.com/zorba/util-functions";
432
433 const char*
434 static_context::ZORBA_SCRIPTING_FN_NS =
435 "http://www.zorba-xquery.com/zorba/scripting";
436
437 const char*
438 static_context::ZORBA_STRING_FN_NS =
439 "http://www.zorba-xquery.com/modules/string";
440
441 const char*
442 static_context::ZORBA_URI_FN_NS =
443 "http://www.zorba-xquery.com/modules/uri";
444
445 const char*
446 static_context::ZORBA_FETCH_FN_NS =
447 "http://www.zorba-xquery.com/modules/fetch";
448
449 const char*
450 static_context::ZORBA_NODE_FN_NS =
451 "http://www.zorba-xquery.com/modules/node";
452
453 const char*
454 static_context::ZORBA_XML_FN_NS =
455 "http://www.zorba-xquery.com/modules/xml";
456
457 #ifndef ZORBA_NO_FULL_TEXT
458 const char*
459 static_context::ZORBA_FULL_TEXT_FN_NS =
460 "http://www.zorba-xquery.com/modules/full-text";
461 #endif /* ZORBA_NO_FULL_TEXT */
462
463 const char*
464 static_context::ZORBA_XML_FN_OPTIONS_NS =
465 "http://www.zorba-xquery.com/modules/xml-options";
466
467 /***************************************************************************//**
468 Target namespaces of zorba reserved modules
469 ********************************************************************************/
470 const char*
471 static_context::XQUERY_OP_NS =
472 "http://www.zorba-xquery.com/internal/xquery-ops";
473
474 const char*
475 static_context::ZORBA_OP_NS =
476 "http://www.zorba-xquery.com/internal/zorba-ops";
477
478 /***************************************************************************//**
479 Options-related namespaces
480 ********************************************************************************/
481 const char*
482 static_context::ZORBA_OPTIONS_NS =
483 "http://www.zorba-xquery.com/options";
484
485 const char*
486 static_context::ZORBA_OPTION_WARN_NS =
487 "http://www.zorba-xquery.com/options/warnings";
488
489 const char*
490 static_context::ZORBA_OPTION_FEATURE_NS =
491 "http://www.zorba-xquery.com/options/features";
492
493 const char*
494 static_context::ZORBA_OPTION_OPTIM_NS =
495 "http://www.zorba-xquery.com/options/optimizer";
496
497 const char*
498 static_context::ZORBA_VERSIONING_NS =
499 "http://www.zorba-xquery.com/options/versioning";
500
501
502 /***************************************************************************//**
503 Static method to check if a given target namespace identifies a zorba
504 builtin module.
505 ********************************************************************************/
is_builtin_module(const zstring & ns)506 bool static_context::is_builtin_module(const zstring& ns)
507 {
508 if (ns.compare(0, strlen(ZORBA_NS_PREFIX), ZORBA_NS_PREFIX) == 0)
509 {
510 return (ns == ZORBA_MATH_FN_NS ||
511 ns == ZORBA_BASE64_FN_NS ||
512 ns == ZORBA_NODEREF_FN_NS ||
513 ns == ZORBA_NODEPOS_FN_NS ||
514
515 ns == ZORBA_STORE_DYNAMIC_DOCUMENTS_FN_NS ||
516 ns == ZORBA_STORE_DYNAMIC_UNORDERED_MAP_FN_NS ||
517 ns == ZORBA_STORE_DYNAMIC_COLLECTIONS_DDL_FN_NS ||
518 ns == ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_FN_NS ||
519 ns == ZORBA_STORE_STATIC_COLLECTIONS_DDL_FN_NS ||
520 ns == ZORBA_STORE_STATIC_COLLECTIONS_DML_FN_NS ||
521 ns == ZORBA_STORE_STATIC_INDEXES_DDL_FN_NS ||
522 ns == ZORBA_STORE_STATIC_INDEXES_DML_FN_NS ||
523 ns == ZORBA_STORE_STATIC_INTEGRITY_CONSTRAINTS_DDL_FN_NS ||
524 ns == ZORBA_STORE_STATIC_INTEGRITY_CONSTRAINTS_DML_FN_NS ||
525 ns == ZORBA_SCHEMA_FN_NS ||
526 ns == ZORBA_XQDOC_FN_NS ||
527 ns == ZORBA_RANDOM_FN_NS ||
528 ns == ZORBA_INTROSP_SCTX_FN_NS ||
529 ns == ZORBA_REFLECTION_FN_NS ||
530 ns == ZORBA_SCRIPTING_FN_NS ||
531 ns == ZORBA_STRING_FN_NS ||
532
533 ns == ZORBA_URI_FN_NS ||
534
535 ns == ZORBA_JSON_FN_NS ||
536 ns == ZORBA_FETCH_FN_NS ||
537 ns == ZORBA_NODE_FN_NS ||
538 #ifndef ZORBA_NO_FULL_TEXT
539 ns == ZORBA_FULL_TEXT_FN_NS ||
540 #endif /* ZORBA_NO_FULL_TEXT */
541 #ifdef ZORBA_WITH_JSON
542 ns == JSONIQ_FN_NS ||
543 #endif /* ZORBA_WITH_JSON */
544 ns == ZORBA_XML_FN_NS);
545 }
546 else if (ns == W3C_FN_NS || ns == XQUERY_MATH_FN_NS)
547 {
548 return true;
549 }
550
551 return false;
552 }
553
554
555 /***************************************************************************//**
556 Static method to check if a given target namespace identifies a zorba
557 builtin virtual module. Virtual builtin modules do not actually exist (that's
558 why they are called virtual), but they still have to be imported in order
559 to make the functions in them visible to the importing module.
560 ********************************************************************************/
is_builtin_virtual_module(const zstring & ns)561 bool static_context::is_builtin_virtual_module(const zstring& ns)
562 {
563 if (ns.compare(0, strlen(ZORBA_NS_PREFIX), ZORBA_NS_PREFIX) == 0)
564 {
565 return (ns == ZORBA_SCRIPTING_FN_NS ||
566 ns == ZORBA_UTIL_FN_NS);
567 }
568 else if (ns == W3C_FN_NS || ns == XQUERY_MATH_FN_NS)
569 {
570 return true;
571 }
572
573 return false;
574 }
575
576
577 /***************************************************************************//**
578 Static method to check if a given target namespace identifies a zorba non
579 pure builtin module, i.e. a builtin module that, in addition to builtin
580 external functions, contains variable declarations and/or udfs.
581
582 Note: The fuul-text module must be included here because it MUST be processed
583 when imported, even in RELEASE mode. The reason is that the
584 current-compare-options(), tokenize(), and tokenizer-properties() functions
585 must be registered in the module's sctx (in addition to the root sctx).
586 ********************************************************************************/
is_non_pure_builtin_module(const zstring & ns)587 bool static_context::is_non_pure_builtin_module(const zstring& ns)
588 {
589 if (ns.compare(0, strlen(ZORBA_NS_PREFIX), ZORBA_NS_PREFIX) == 0)
590 {
591 return (ns == ZORBA_MATH_FN_NS ||
592 ns == ZORBA_INTROSP_SCTX_FN_NS ||
593 ns == ZORBA_STRING_FN_NS ||
594 ns == ZORBA_JSON_FN_NS ||
595 ns == ZORBA_XQDOC_FN_NS ||
596 #ifdef ZORBA_WITH_JSON
597 ns == JSONIQ_FN_NS ||
598 #endif
599 ns == ZORBA_URI_FN_NS ||
600 ns == ZORBA_RANDOM_FN_NS ||
601 ns == ZORBA_FETCH_FN_NS ||
602 #ifndef ZORBA_NO_FULL_TEXT
603 ns == ZORBA_FULL_TEXT_FN_NS ||
604 #endif /* ZORBA_NO_FULL_TEXT */
605 ns == ZORBA_XML_FN_NS);
606 }
607
608 return false;
609 }
610
611
612 /***************************************************************************//**
613 Static method to check if a given target namespace identifies a zorba
614 reserved module.
615 ********************************************************************************/
is_reserved_module(const zstring & ns)616 bool static_context::is_reserved_module(const zstring& ns)
617 {
618 if (ns.compare(0, strlen(ZORBA_NS_PREFIX), ZORBA_NS_PREFIX) == 0)
619 {
620 return (ns == ZORBA_OP_NS || ns == XQUERY_OP_NS);
621 }
622
623 return false;
624 }
625
626
627 /***************************************************************************//**
628 Static method
629 ********************************************************************************/
var_name(const store::Item * aVarName)630 zstring static_context::var_name(const store::Item* aVarName)
631 {
632 zstring lVarName = aVarName->getStringValue();
633 if (lVarName == static_context::DOT_POS_VAR_NAME)
634 {
635 lVarName = "context position";
636 }
637 else if (lVarName == static_context::DOT_SIZE_VAR_NAME)
638 {
639 lVarName = "context size";
640 }
641 else if (lVarName == static_context::DOT_VAR_NAME)
642 {
643 lVarName = "context item";
644 }
645 return lVarName;
646 }
647
648
649 /***************************************************************************//**
650 Default Constructor.
651 ********************************************************************************/
static_context()652 static_context::static_context()
653 :
654 theParent(NULL),
655 theTraceStream(NULL),
656 theQueryExpr(NULL),
657 theBaseUriInfo(NULL),
658 theExternalModulesMap(NULL),
659 theNamespaceBindings(NULL),
660 theHaveDefaultElementNamespace(false),
661 theHaveDefaultFunctionNamespace(false),
662 theContextItemType(NULL),
663 theVariablesMap(NULL),
664 theImportedPrivateVariablesMap(NULL),
665 theFunctionMap(NULL),
666 theFunctionArityMap(NULL),
667 theCollectionMap(NULL),
668 theW3CCollectionMap(NULL),
669 theIndexMap(NULL),
670 theICMap(NULL),
671 theDocumentMap(NULL),
672 theCollationMap(NULL),
673 theDefaultCollation(NULL),
674 theCachedDefaultCollator(NULL),
675 theOptionMap(NULL),
676 theAuditEvent(&zorba::audit::NOP_EVENT_IMPL),
677 #ifndef ZORBA_NO_FULL_TEXT
678 theFTMatchOptions(NULL),
679 #endif /* ZORBA_NO_FULL_TEXT */
680 theXQueryVersion(StaticContextConsts::xquery_version_unknown),
681 theXPathCompatibility(StaticContextConsts::xpath_unknown),
682 theConstructionMode(StaticContextConsts::cons_unknown),
683 theInheritNamespaces(true),
684 thePreserveNamespaces(true),
685 theOrderingMode(StaticContextConsts::ordering_unknown),
686 theEmptyOrderMode(StaticContextConsts::empty_order_unknown),
687 theBoundarySpaceMode(StaticContextConsts::boundary_space_unknown),
688 theValidationMode(StaticContextConsts::validation_unknown),
689 theAllWarningsDisabled(false),
690 theAllWarningsErrors(false),
691 theFeatures(0)
692 {
693 }
694
695
696 /*******************************************************************************
697
698 ********************************************************************************/
static_context(static_context * parent)699 static_context::static_context(static_context* parent)
700 :
701 theParent(parent),
702 theTraceStream(NULL),
703 theQueryExpr(NULL),
704 theBaseUriInfo(NULL),
705 theExternalModulesMap(NULL),
706 theNamespaceBindings(NULL),
707 theHaveDefaultElementNamespace(false),
708 theHaveDefaultFunctionNamespace(false),
709 theContextItemType(NULL),
710 theVariablesMap(NULL),
711 theImportedPrivateVariablesMap(NULL),
712 theFunctionMap(NULL),
713 theFunctionArityMap(NULL),
714 theCollectionMap(0),
715 theW3CCollectionMap(NULL),
716 theIndexMap(NULL),
717 theICMap(NULL),
718 theDocumentMap(NULL),
719 theCollationMap(NULL),
720 theDefaultCollation(NULL),
721 theCachedDefaultCollator(NULL),
722 theOptionMap(NULL),
723 theAuditEvent(&zorba::audit::NOP_EVENT_IMPL),
724 #ifndef ZORBA_NO_FULL_TEXT
725 theFTMatchOptions(NULL),
726 #endif /* ZORBA_NO_FULL_TEXT */
727 theXQueryVersion(StaticContextConsts::xquery_version_unknown),
728 theXPathCompatibility(StaticContextConsts::xpath_unknown),
729 theConstructionMode(StaticContextConsts::cons_unknown),
730 theInheritNamespaces(parent->theInheritNamespaces),
731 thePreserveNamespaces(parent->thePreserveNamespaces),
732 theOrderingMode(StaticContextConsts::ordering_unknown),
733 theEmptyOrderMode(StaticContextConsts::empty_order_unknown),
734 theBoundarySpaceMode(StaticContextConsts::boundary_space_unknown),
735 theValidationMode(StaticContextConsts::validation_unknown),
736 theAllWarningsDisabled(false),
737 theAllWarningsErrors(false),
738 // we copy features from the parent such that it's
739 // easy to set and unset them
740 theFeatures(parent->theFeatures)
741 {
742 if (theParent != NULL)
743 RCHelper::addReference(theParent);
744 }
745
746
747 /*******************************************************************************
748
749 ********************************************************************************/
static_context(::zorba::serialization::Archiver & ar)750 static_context::static_context(::zorba::serialization::Archiver& ar)
751 :
752 SimpleRCObject(ar),
753 theParent(NULL),
754 theTraceStream(NULL),
755 theQueryExpr(NULL),
756 theBaseUriInfo(NULL),
757 theExternalModulesMap(NULL),
758 theNamespaceBindings(NULL),
759 theHaveDefaultElementNamespace(false),
760 theHaveDefaultFunctionNamespace(false),
761 theContextItemType(NULL),
762 theVariablesMap(NULL),
763 theImportedPrivateVariablesMap(NULL),
764 theFunctionMap(NULL),
765 theFunctionArityMap(NULL),
766 theCollectionMap(0),
767 theW3CCollectionMap(NULL),
768 theIndexMap(0),
769 theICMap(0),
770 theDocumentMap(NULL),
771 theCollationMap(NULL),
772 theDefaultCollation(NULL),
773 theCachedDefaultCollator(NULL),
774 theOptionMap(NULL),
775 theAuditEvent(&zorba::audit::NOP_EVENT_IMPL),
776 #ifndef ZORBA_NO_FULL_TEXT
777 theFTMatchOptions(NULL),
778 #endif /* ZORBA_NO_FULL_TEXT */
779 theXQueryVersion(StaticContextConsts::xquery_version_unknown),
780 theXPathCompatibility(StaticContextConsts::xpath_unknown),
781 theConstructionMode(StaticContextConsts::cons_unknown),
782 theInheritNamespaces(true),
783 thePreserveNamespaces(true),
784 theOrderingMode(StaticContextConsts::ordering_unknown),
785 theEmptyOrderMode(StaticContextConsts::empty_order_unknown),
786 theBoundarySpaceMode(StaticContextConsts::boundary_space_unknown),
787 theValidationMode(StaticContextConsts::validation_unknown),
788 theAllWarningsDisabled(false),
789 theAllWarningsErrors(false),
790 theFeatures(0)
791 {
792 }
793
794
795 /***************************************************************************//**
796 Destructor.
797 ********************************************************************************/
~static_context()798 static_context::~static_context()
799 {
800 if (theExternalModulesMap)
801 {
802 ExternalModuleMap::iterator ite = theExternalModulesMap->begin();
803 ExternalModuleMap::iterator end = theExternalModulesMap->end();
804 for(; ite != end; ++ite)
805 {
806 const ctx_module_t& val = ite.getValue();
807 if (val.dyn_loaded_module)
808 {
809 val.module->destroy();
810 }
811 }
812
813 delete theExternalModulesMap;
814 }
815
816 if (theW3CCollectionMap)
817 delete theW3CCollectionMap;
818
819 if (theCollectionMap)
820 delete theCollectionMap;
821
822 if (theIndexMap)
823 delete theIndexMap;
824
825 if (theICMap)
826 delete theICMap;
827
828 if (theFunctionMap)
829 delete theFunctionMap;
830
831 if (theFunctionArityMap)
832 {
833 FunctionArityMap::iterator ite = theFunctionArityMap->begin();
834 FunctionArityMap::iterator end = theFunctionArityMap->end();
835 for (; ite != end; ++ite)
836 {
837 delete (*ite).second;
838 }
839
840 delete theFunctionArityMap;
841 }
842
843 if (theVariablesMap)
844 {
845 delete theVariablesMap;
846 theVariablesMap = NULL;
847 }
848
849 if (theImportedPrivateVariablesMap)
850 {
851 delete theImportedPrivateVariablesMap;
852 theImportedPrivateVariablesMap = NULL;
853 }
854
855 if (theNamespaceBindings)
856 delete theNamespaceBindings;
857
858 if (theDefaultCollation)
859 delete theDefaultCollation;
860
861 if (theCollationMap)
862 {
863 CollationMap::iterator ite = theCollationMap->begin();
864 CollationMap::iterator end = theCollationMap->end();
865 for ( ; ite != end ; ++ite)
866 {
867 delete ite->second;
868 }
869
870 delete theCollationMap;
871 theCollationMap = 0;
872 }
873
874 if (theOptionMap)
875 delete theOptionMap;
876
877 #ifndef ZORBA_NO_FULL_TEXT
878 delete theFTMatchOptions;
879 #endif /* ZORBA_NO_FULL_TEXT */
880
881 if (theBaseUriInfo)
882 delete theBaseUriInfo;
883
884 if (theParent)
885 RCHelper::removeReference(theParent);
886 }
887
888
889 /*******************************************************************************
890
891 ********************************************************************************/
serialize_resolvers(serialization::Archiver & ar)892 void static_context::serialize_resolvers(serialization::Archiver& ar)
893 {
894 csize lNumURIMappers;
895 csize lNumURLResolvers;
896
897 if (ar.is_serializing_out())
898 {
899 lNumURIMappers = theURIMappers.size();
900 lNumURLResolvers = theURLResolvers.size();
901
902 ar.set_is_temp_field(true);
903 ar & lNumURIMappers;
904 ar & lNumURLResolvers;
905 ar.set_is_temp_field(false);
906 }
907 else
908 {
909 // serialize in: set the document and collection resolvers
910 // use one by the user or use the default
911 // if null is returned
912 SerializationCallback* lCallback = ar.getUserCallback();
913
914 ar.set_is_temp_field(true);
915 // number of URIMappers passed by the user
916 ar & lNumURIMappers;
917 // number of URLResolvers passed by the user
918 ar & lNumURLResolvers;
919 ar.set_is_temp_field(false);
920
921 // callback required but not available
922 if ((lNumURIMappers || lNumURLResolvers) && !lCallback)
923 {
924 throw ZORBA_EXCEPTION(zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
925 ERROR_PARAMS(ZED(NoSerializationCallbackForDocColMod)));
926 }
927
928 if (lNumURIMappers)
929 {
930 for (size_t i = 0; i < lNumURIMappers; ++i)
931 {
932 zorba::URIMapper* lURIMapper = lCallback->getURIMapper(i);
933 if (!lURIMapper)
934 {
935 throw ZORBA_EXCEPTION(zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
936 ERROR_PARAMS(ZED(NoModuleURIResolver)));
937 }
938
939 add_uri_mapper(new URIMapperWrapper(*lURIMapper));
940 }
941 }
942
943 if (lNumURLResolvers)
944 {
945 for (size_t i = 0; i < lNumURLResolvers; ++i)
946 {
947 zorba::URLResolver* lURLResolver = lCallback->getURLResolver(i);
948 if (!lURLResolver)
949 {
950 throw ZORBA_EXCEPTION(zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
951 ERROR_PARAMS(ZED(NoModuleURIResolver)));
952 }
953
954 add_url_resolver(new URLResolverWrapper(*lURLResolver));
955 }
956 }
957 }
958 }
959
960
961 /*******************************************************************************
962
963 ********************************************************************************/
serialize_tracestream(serialization::Archiver & ar)964 void static_context::serialize_tracestream(serialization::Archiver& ar)
965 {
966 bool lUserTraceStream;
967 if (ar.is_serializing_out())
968 {
969 // serialize out: remember whether the user registered a trace stream
970 lUserTraceStream = (theTraceStream != 0);
971
972 ar.set_is_temp_field(true);
973 ar & lUserTraceStream;
974 ar.set_is_temp_field(false);
975 }
976 else
977 {
978 // serialize in: set the trace stream from the user
979 // std::cerr is used if non was registered
980 SerializationCallback* lCallback = ar.getUserCallback();
981
982 ar.set_is_temp_field(true);
983 ar & lUserTraceStream; // trace stream passed by the user
984 ar.set_is_temp_field(false);
985
986 // callback required but not available
987 if (lUserTraceStream && !lCallback)
988 {
989 throw ZORBA_EXCEPTION(
990 zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
991 ERROR_PARAMS( ZED( NoSerializationCallbackForTraceStream ) )
992 );
993 }
994
995 if (lUserTraceStream) {
996 bool lTraceStream = lCallback->getTraceStream(theTraceStream);
997 if (!lTraceStream) {
998 throw ZORBA_EXCEPTION(
999 zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY,
1000 ERROR_PARAMS( ZED( BadTraceStream ) )
1001 );
1002 }
1003 }
1004 }
1005 }
1006
1007
1008 /*******************************************************************************
1009
1010 ********************************************************************************/
serialize(::zorba::serialization::Archiver & ar)1011 void static_context::serialize(::zorba::serialization::Archiver& ar)
1012 {
1013 if (ar.is_serializing_out())
1014 {
1015 ar.set_is_temp_field(true);
1016 bool parent_is_root = check_parent_is_root();
1017 ar & parent_is_root;
1018 ar.set_is_temp_field(false);
1019
1020 if(!parent_is_root)
1021 {
1022 ar.dont_allow_delay();
1023 ar & theParent;
1024 }
1025 else
1026 {
1027 // context *fooctx = NULL;
1028 // ar & fooctx;
1029 }
1030 }
1031 else
1032 {
1033 //in serialization
1034 ar.set_is_temp_field(true);
1035 bool parent_is_root;
1036 ar & parent_is_root;
1037 ar.set_is_temp_field(false);
1038
1039 if(parent_is_root)
1040 {
1041 set_parent_as_root();
1042 }
1043 else
1044 ar & theParent;
1045
1046 if (theParent)
1047 theParent->addReference(SYNC_CODE(theParent->getRCLock()));
1048 }
1049
1050 ar & theModuleNamespace;
1051 ar & theImportedBuiltinModules;
1052
1053 ar & theBaseUriInfo;
1054
1055 serialize_resolvers(ar);
1056 serialize_tracestream(ar);
1057
1058 ar & theURIPath;
1059 ar & theLibPath;
1060
1061 // Options must be serialized BEFORE external modules
1062 ar & theOptionMap;
1063 ar & theExternalModulesMap;
1064
1065 SERIALIZE_TYPEMANAGER_RCHANDLE(TypeManager, theTypeManager);
1066
1067 ar & theNamespaceBindings;
1068 ar & theDefaultElementNamespace;
1069 ar & theHaveDefaultElementNamespace;
1070 ar & theDefaultFunctionNamespace;
1071 ar & theHaveDefaultFunctionNamespace;
1072
1073 ar & theContextItemType;
1074
1075 ar & theVariablesMap;
1076 ar & theImportedPrivateVariablesMap;
1077
1078 ar.set_serialize_only_for_eval(true);
1079 ar & theFunctionMap;
1080 ar & theFunctionArityMap;
1081 ar.set_serialize_only_for_eval(false);
1082
1083 ar & theCollectionMap;
1084
1085 ar & theW3CCollectionMap;
1086 ar & theDefaultW3CCollectionType;
1087
1088 ar & theIndexMap;
1089
1090 ar & theICMap;
1091
1092 ar & theDocumentMap;
1093
1094 ar & theCollationMap;
1095 ar & theDefaultCollation;
1096
1097 #ifndef ZORBA_NO_FULL_TEXT
1098 ar & theFTMatchOptions;
1099 #endif /* ZORBA_NO_FULL_TEXT */
1100
1101 SERIALIZE_ENUM(StaticContextConsts::xquery_version_t, theXQueryVersion);
1102 SERIALIZE_ENUM(StaticContextConsts::xpath_compatibility_t, theXPathCompatibility);
1103 SERIALIZE_ENUM(StaticContextConsts::construction_mode_t, theConstructionMode);
1104 ar & theInheritNamespaces;
1105 ar & thePreserveNamespaces;
1106 SERIALIZE_ENUM(StaticContextConsts::ordering_mode_t, theOrderingMode);
1107 SERIALIZE_ENUM(StaticContextConsts::empty_order_mode_t, theEmptyOrderMode);
1108 SERIALIZE_ENUM(StaticContextConsts::boundary_space_mode_t, theBoundarySpaceMode);
1109 SERIALIZE_ENUM(StaticContextConsts::validation_mode_t, theValidationMode);
1110
1111 ar & theDecimalFormats;
1112
1113 ar & theDisabledWarnings;
1114
1115 ar & theAllWarningsDisabled;
1116
1117 ar & theWarningsAreErrors;
1118
1119 ar & theAllWarningsErrors;
1120
1121 ar & theFeatures;
1122 }
1123
1124
1125 /***************************************************************************//**
1126 Create a new static_context obj and make a child of "this" static_context obj.
1127 ********************************************************************************/
create_child_context()1128 static_context* static_context::create_child_context()
1129 {
1130 return new static_context(this);
1131 }
1132
1133
1134 /***************************************************************************//**
1135
1136 ********************************************************************************/
is_global_root_sctx() const1137 bool static_context::is_global_root_sctx() const
1138 {
1139 return (this == &GENV_ROOT_STATIC_CONTEXT);
1140 }
1141
1142
1143 /***************************************************************************//**
1144
1145 ********************************************************************************/
check_parent_is_root()1146 bool static_context::check_parent_is_root()
1147 {
1148 return theParent == &GENV_ROOT_STATIC_CONTEXT;
1149 }
1150
1151
1152 /***************************************************************************//**
1153
1154 ********************************************************************************/
set_parent_as_root()1155 void static_context::set_parent_as_root()
1156 {
1157 theParent = &GENV_ROOT_STATIC_CONTEXT;
1158 }
1159
1160
1161 /***************************************************************************//**
1162
1163 ********************************************************************************/
get_query_expr() const1164 expr* static_context::get_query_expr() const
1165 {
1166 return theQueryExpr;
1167 }
1168
1169
1170 /***************************************************************************//**
1171
1172 ********************************************************************************/
set_query_expr(expr * expr)1173 void static_context::set_query_expr(expr* expr)
1174 {
1175 theQueryExpr = expr;
1176 }
1177
1178
1179 /***************************************************************************//**
1180
1181 ********************************************************************************/
set_trace_stream(std::ostream & os)1182 void static_context::set_trace_stream(std::ostream& os)
1183 {
1184 theTraceStream = &os;
1185 }
1186
1187
1188 /***************************************************************************//**
1189
1190 ********************************************************************************/
get_trace_stream() const1191 std::ostream* static_context::get_trace_stream() const
1192 {
1193 if (theTraceStream)
1194 return theTraceStream;
1195
1196 return (theParent == NULL ?
1197 &std::cerr :
1198 dynamic_cast<static_context*>(theParent)->get_trace_stream());
1199 }
1200
1201
1202 /***************************************************************************//**
1203
1204 ********************************************************************************/
add_imported_builtin_module(const zstring & ns)1205 void static_context::add_imported_builtin_module(const zstring& ns)
1206 {
1207 theImportedBuiltinModules.push_back(ns);
1208 }
1209
1210
1211 /***************************************************************************//**
1212
1213 ********************************************************************************/
is_imported_builtin_module(const zstring & ns)1214 bool static_context::is_imported_builtin_module(const zstring& ns)
1215 {
1216 static_context* sctx = this;
1217
1218 while (sctx != NULL)
1219 {
1220 if (!sctx->theImportedBuiltinModules.empty())
1221 {
1222 std::vector<zstring>::const_iterator ite = sctx->theImportedBuiltinModules.begin();
1223 std::vector<zstring>::const_iterator end = sctx->theImportedBuiltinModules.end();
1224 for (; ite != end; ++ite)
1225 {
1226 if (*ite == ns)
1227 return true;
1228 }
1229 }
1230
1231 sctx = sctx->theParent;
1232 }
1233
1234 return false;
1235 }
1236
1237
1238 /////////////////////////////////////////////////////////////////////////////////
1239 // //
1240 // Base URI //
1241 // //
1242 /////////////////////////////////////////////////////////////////////////////////
1243
1244
1245 /***************************************************************************//**
1246
1247 ********************************************************************************/
get_implementation_baseuri() const1248 zstring static_context::get_implementation_baseuri() const
1249 {
1250 return reinterpret_cast<root_static_context*>(&GENV_ROOT_STATIC_CONTEXT)->
1251 theImplementationBaseUri;
1252 }
1253
1254
1255 /***************************************************************************//**
1256
1257 ********************************************************************************/
get_encapsulating_entity_uri(zstring & res) const1258 bool static_context::get_encapsulating_entity_uri(zstring& res) const
1259 {
1260 const static_context* sctx = this;
1261 while (sctx != NULL)
1262 {
1263 if (sctx->theBaseUriInfo != NULL &&
1264 sctx->theBaseUriInfo->theHaveEncapsulatingEntityUri)
1265 {
1266 res = sctx->theBaseUriInfo->theEncapsulatingEntityUri;
1267 return true;
1268 }
1269
1270 sctx = sctx->theParent;
1271 }
1272
1273 return false;
1274 }
1275
1276
1277 /***************************************************************************//**
1278
1279 ********************************************************************************/
set_encapsulating_entity_uri(const zstring & uri)1280 void static_context::set_encapsulating_entity_uri(const zstring& uri)
1281 {
1282 if (theBaseUriInfo == NULL)
1283 {
1284 theBaseUriInfo = new BaseUriInfo;
1285 }
1286
1287 theBaseUriInfo->theEncapsulatingEntityUri = uri;
1288 theBaseUriInfo->theHaveEncapsulatingEntityUri = true;
1289
1290 compute_base_uri();
1291 }
1292
1293
1294 /***************************************************************************//**
1295
1296 ********************************************************************************/
get_entity_retrieval_uri(zstring & res) const1297 bool static_context::get_entity_retrieval_uri(zstring& res) const
1298 {
1299 const static_context* sctx = this;
1300 while (sctx != NULL)
1301 {
1302 if (sctx->theBaseUriInfo != NULL &&
1303 sctx->theBaseUriInfo->theHaveEntityRetrievalUri)
1304 {
1305 res = sctx->theBaseUriInfo->theEntityRetrievalUri;
1306 return true;
1307 }
1308
1309 sctx = sctx->theParent;
1310 }
1311
1312 return false;
1313 }
1314
1315
1316 /***************************************************************************//**
1317
1318 ********************************************************************************/
set_entity_retrieval_uri(const zstring & uri)1319 void static_context::set_entity_retrieval_uri(const zstring& uri)
1320 {
1321 if (theBaseUriInfo == NULL)
1322 {
1323 theBaseUriInfo = new BaseUriInfo;
1324 }
1325
1326 theBaseUriInfo->theEntityRetrievalUri = uri;
1327 theBaseUriInfo->theHaveEntityRetrievalUri = true;
1328
1329 compute_base_uri();
1330 }
1331
1332
1333 /***************************************************************************//**
1334
1335 ********************************************************************************/
get_base_uri() const1336 zstring static_context::get_base_uri() const
1337 {
1338 const static_context* sctx = this;
1339 while (sctx != NULL)
1340 {
1341 if (sctx->theBaseUriInfo != NULL &&
1342 sctx->theBaseUriInfo->theHaveBaseUri)
1343 {
1344 return sctx->theBaseUriInfo->theBaseUri;
1345 }
1346
1347 sctx = sctx->theParent;
1348 }
1349 return ""; //undefined
1350 }
1351
1352
1353 /***************************************************************************//**
1354
1355 ********************************************************************************/
set_base_uri(const zstring & uri,bool from_prolog)1356 void static_context::set_base_uri(const zstring& uri, bool from_prolog)
1357 {
1358 if (theBaseUriInfo == NULL)
1359 {
1360 theBaseUriInfo = new BaseUriInfo;
1361 }
1362
1363 if (from_prolog)
1364 {
1365 if (theBaseUriInfo->theHavePrologBaseUri)
1366 throw XQUERY_EXCEPTION(err::XQST0032);
1367
1368 theBaseUriInfo->thePrologBaseUri = uri;
1369 theBaseUriInfo->theHavePrologBaseUri = true;
1370 }
1371 else
1372 {
1373 // overwite existing value of application baseuri, if any
1374 theBaseUriInfo->theApplicationBaseUri = uri;
1375 theBaseUriInfo->theHaveApplicationBaseUri = true;
1376 }
1377
1378 compute_base_uri();
1379 }
1380
1381 /***************************************************************************//**
1382 Base Uri Computation
1383
1384 The from_prolog_baseuri is the one declared in the prolog. The baseuri is set
1385 explicitly from the C++/C api. If both the from_prolog_baseuri and the baseuri
1386 are set, the from_prolog_baseuri hides the baseuri.
1387
1388 For the main module, the entity_retrieval_url is set by default to the name
1389 of file containing the query we are running. For library modules, it is set
1390 to the location uri of each module component. It may also be set explicitly
1391 from the C++/C api.
1392 ********************************************************************************/
compute_base_uri()1393 void static_context::compute_base_uri()
1394 {
1395 if (theBaseUriInfo == NULL)
1396 {
1397 theBaseUriInfo = new BaseUriInfo;
1398 }
1399
1400 bool found;
1401
1402 bool foundUserBaseUri = false;
1403 zstring userBaseUri;
1404 zstring encapsulatingUri;
1405 zstring entityUri;
1406
1407 const static_context* sctx = this;
1408
1409 while (sctx != NULL)
1410 {
1411 if (sctx->theBaseUriInfo != NULL &&
1412 sctx->theBaseUriInfo->theHavePrologBaseUri)
1413 {
1414 userBaseUri = sctx->theBaseUriInfo->thePrologBaseUri;
1415 foundUserBaseUri = true;
1416 break;
1417 }
1418
1419 sctx = sctx->theParent;
1420 }
1421
1422 if (!foundUserBaseUri)
1423 {
1424 sctx = this;
1425
1426 while (sctx != NULL)
1427 {
1428 if (sctx->theBaseUriInfo != NULL &&
1429 sctx->theBaseUriInfo->theHaveApplicationBaseUri)
1430 {
1431 userBaseUri = sctx->theBaseUriInfo->theApplicationBaseUri;
1432 foundUserBaseUri = true;
1433 break;
1434 }
1435
1436 sctx = sctx->theParent;
1437 }
1438 }
1439
1440 if (foundUserBaseUri)
1441 {
1442 try
1443 {
1444 URI lCheckValid(userBaseUri);
1445 if (lCheckValid.is_absolute())
1446 {
1447 theBaseUriInfo->theBaseUri = lCheckValid.toString();
1448 theBaseUriInfo->theHaveBaseUri = true;
1449 return; // valid (absolute) uri
1450 }
1451 }
1452 catch (ZorbaException const&)
1453 {
1454 // assume it's relative and go on
1455 }
1456
1457 /// is relative, needs to be resolved
1458 found = get_encapsulating_entity_uri(encapsulatingUri);
1459 if (found)
1460 {
1461 URI base(encapsulatingUri);
1462 URI resolvedURI(base, userBaseUri);
1463 theBaseUriInfo->theBaseUri = resolvedURI.toString();
1464 theBaseUriInfo->theHaveBaseUri = true;
1465 return;
1466 }
1467
1468 found = get_entity_retrieval_uri(entityUri);
1469 if (found)
1470 {
1471 URI base(entityUri);
1472 URI resolvedURI(base, userBaseUri);
1473 theBaseUriInfo->theBaseUri = resolvedURI.toString();
1474 theBaseUriInfo->theHaveBaseUri = true;
1475 return;
1476 }
1477
1478 URI base(get_implementation_baseuri());
1479 URI resolvedURI(base, userBaseUri);
1480 theBaseUriInfo->theBaseUri = resolvedURI.toString();
1481 theBaseUriInfo->theHaveBaseUri = true;
1482 return;
1483 }
1484
1485 found = get_encapsulating_entity_uri(encapsulatingUri);
1486 if (found)
1487 {
1488 theBaseUriInfo->theBaseUri = encapsulatingUri;
1489 theBaseUriInfo->theHaveBaseUri = true;
1490 return;
1491 }
1492
1493 found = get_entity_retrieval_uri(entityUri);
1494 if (found)
1495 {
1496 theBaseUriInfo->theBaseUri = entityUri;
1497 theBaseUriInfo->theHaveBaseUri = true;
1498 return;
1499 }
1500
1501 theBaseUriInfo->theBaseUri = "";
1502 theBaseUriInfo->theHaveBaseUri = false;
1503 return;
1504 }
1505
1506
1507 ////////////////////////////////////////////////////////////////////////////////
1508 // //
1509 // URI Absolutization //
1510 // //
1511 ////////////////////////////////////////////////////////////////////////////////
1512
1513
1514 /***************************************************************************//**
1515
1516 ********************************************************************************/
resolve_relative_uri(const zstring & aUri,bool aValidate) const1517 zstring static_context::resolve_relative_uri(
1518 const zstring& aUri,
1519 bool aValidate) const
1520 {
1521 URI lBaseUri(get_base_uri());
1522 URI lResolvedUri(lBaseUri, aUri, aValidate);
1523 return lResolvedUri.toString();
1524 }
1525
1526
1527 /***************************************************************************//**
1528
1529 ********************************************************************************/
resolve_relative_uri(const zstring & aRelativeUri,const zstring & aBaseUri,bool aValidate) const1530 zstring static_context::resolve_relative_uri(
1531 const zstring& aRelativeUri,
1532 const zstring& aBaseUri,
1533 bool aValidate) const
1534 {
1535 URI lBaseUri(aBaseUri);
1536 URI lResolvedUri(lBaseUri, aRelativeUri, aValidate);
1537 return lResolvedUri.toString();
1538 }
1539
1540
1541 ////////////////////////////////////////////////////////////////////////////////
1542 // //
1543 // URI Resolution //
1544 // //
1545 ////////////////////////////////////////////////////////////////////////////////
1546
1547
1548 /***************************************************************************//**
1549
1550 ********************************************************************************/
add_uri_mapper(internal::URIMapper * aMapper)1551 void static_context::add_uri_mapper(internal::URIMapper* aMapper)
1552 {
1553 theURIMappers.push_back(std::auto_ptr<internal::URIMapper>(aMapper));
1554 }
1555
1556
1557 /***************************************************************************//**
1558
1559 ********************************************************************************/
add_url_resolver(internal::URLResolver * aResolver)1560 void static_context::add_url_resolver(internal::URLResolver* aResolver)
1561 {
1562 theURLResolvers.push_back(std::auto_ptr<internal::URLResolver>(aResolver));
1563 }
1564
1565
1566 /***************************************************************************//**
1567
1568 ********************************************************************************/
resolve_uri(zstring const & aUri,internal::EntityData::Kind aEntityKind,zstring & oErrorMessage) const1569 std::auto_ptr<internal::Resource> static_context::resolve_uri(
1570 zstring const& aUri,
1571 internal::EntityData::Kind aEntityKind,
1572 zstring& oErrorMessage) const
1573 {
1574 // Create a simple EntityData that just reports the specified Kind
1575 internal::EntityData const lData(aEntityKind);
1576 return this->resolve_uri(aUri, lData, oErrorMessage);
1577 }
1578
resolve_uri(zstring const & aUri,internal::EntityData const & aEntityData,zstring & oErrorMessage) const1579 std::auto_ptr<internal::Resource> static_context::resolve_uri(
1580 zstring const& aUri,
1581 internal::EntityData const& aEntityData,
1582 zstring& oErrorMessage) const
1583 {
1584 std::vector<zstring> lUris;
1585 apply_uri_mappers(aUri, &aEntityData, internal::URIMapper::CANDIDATE, lUris);
1586
1587 std::auto_ptr<internal::Resource> lRetval;
1588 apply_url_resolvers(lUris, &aEntityData, lRetval, oErrorMessage);
1589
1590 return lRetval;
1591 }
1592
get_component_uris(zstring const & aUri,internal::EntityData::Kind aEntityKind,std::vector<zstring> & oComponents) const1593 void static_context::get_component_uris(
1594 zstring const& aUri,
1595 internal::EntityData::Kind aEntityKind,
1596 std::vector<zstring>& oComponents) const
1597 {
1598 // Create a simple EntityData that just reports the specified Kind
1599 internal::EntityData const lData(aEntityKind);
1600
1601 apply_uri_mappers(aUri, &lData, internal::URIMapper::COMPONENT, oComponents);
1602 if (oComponents.size() == 0)
1603 {
1604 oComponents.push_back(aUri);
1605 }
1606 }
1607
get_candidate_uris(zstring const & aUri,internal::EntityData::Kind aEntityKind,std::vector<zstring> & oComponents) const1608 void static_context::get_candidate_uris(
1609 zstring const& aUri,
1610 internal::EntityData::Kind aEntityKind,
1611 std::vector<zstring>& oComponents) const
1612 {
1613 // Create a simple EntityData that just reports the specified Kind
1614 internal::EntityData const lData(aEntityKind);
1615
1616 apply_uri_mappers(aUri, &lData, internal::URIMapper::CANDIDATE, oComponents);
1617 if (oComponents.size() == 0)
1618 {
1619 oComponents.push_back(aUri);
1620 }
1621 }
1622
1623
1624 /***************************************************************************//**
1625
1626 ********************************************************************************/
apply_uri_mappers(zstring const & aUri,internal::EntityData const * aEntityData,internal::URIMapper::Kind aMapperKind,std::vector<zstring> & oUris) const1627 void static_context::apply_uri_mappers(
1628 zstring const& aUri,
1629 internal::EntityData const* aEntityData,
1630 internal::URIMapper::Kind aMapperKind,
1631 std::vector<zstring>& oUris) const
1632 {
1633 // Initialize list with the one input URI.
1634 oUris.push_back(aUri);
1635
1636 // Iterate upwards through the static_context tree...
1637 for (static_context const* sctx = this;
1638 sctx != NULL; sctx = sctx->theParent)
1639 {
1640 // Iterate through all available mappers on this static_context...
1641 for (ztd::auto_vector<internal::URIMapper>::const_iterator mapper =
1642 sctx->theURIMappers.begin();
1643 mapper != sctx->theURIMappers.end(); mapper++)
1644 {
1645 // Only call mappers of the appropriate kind
1646 if ((*mapper)->mapperKind() != aMapperKind)
1647 {
1648 continue;
1649 }
1650
1651 // Create new list (currently empty) for this mapper
1652 std::vector<zstring> lResultUris;
1653
1654 // Iterate through all URIs on the current list...
1655 for (std::vector<zstring>::iterator uri = oUris.begin();
1656 uri != oUris.end(); uri++)
1657 {
1658 // And call the current mapper with the current URI.
1659 size_t const lPreNumResultUris = lResultUris.size();
1660 (*mapper)->mapURI(*uri, aEntityData, *this, lResultUris);
1661 size_t const lPostNumResultUris = lResultUris.size();
1662 if (lPreNumResultUris == lPostNumResultUris)
1663 {
1664 // Mapper didn't map this URI to anything new, therefore add
1665 // the original URI to the result list
1666 lResultUris.push_back(*uri);
1667 }
1668 else
1669 {
1670 // Check the new entries for DENY_ACCESS.
1671 for (size_t i = lPreNumResultUris; i < lPostNumResultUris; i++)
1672 {
1673 if (lResultUris.at(i) == internal::URIMapper::DENY_ACCESS) {
1674 throw XQUERY_EXCEPTION(zerr::ZXQP0029_URI_ACCESS_DENIED,
1675 ERROR_PARAMS(aUri));
1676 }
1677 }
1678 }
1679 }
1680
1681 // Now repeat process with the next mapper using the new list of
1682 // URIs.
1683 oUris = lResultUris;
1684 }
1685 }
1686 }
1687
1688
1689 /***************************************************************************//**
1690
1691 ********************************************************************************/
apply_url_resolvers(std::vector<zstring> & aUrls,internal::EntityData const * aEntityData,std::auto_ptr<internal::Resource> & oResource,zstring & oErrorMessage) const1692 void static_context::apply_url_resolvers(
1693 std::vector<zstring>& aUrls,
1694 internal::EntityData const* aEntityData,
1695 std::auto_ptr<internal::Resource>& oResource,
1696 zstring& oErrorMessage) const
1697 {
1698 oErrorMessage.clear();
1699
1700 // Iterate through all candidate URLs...
1701 for (std::vector<zstring>::iterator url = aUrls.begin();
1702 url != aUrls.end(); url++)
1703 {
1704 // We should never try to load the http-client module using its original URI,
1705 // because that URI starts with http:, so we'll try to load the http-client
1706 // module, leading to a stack overflow.
1707 if (ascii::begins_with(*url, "http://www.zorba-xquery.com/modules/http-client"))
1708 {
1709 continue;
1710 }
1711
1712 // Iterate upwards through the static_context tree...
1713 for (static_context const* sctx = this;
1714 sctx != NULL; sctx = sctx->theParent)
1715 {
1716 // Iterate through all available resolvers on this static_context...
1717 for (ztd::auto_vector<internal::URLResolver>::const_iterator resolver =
1718 sctx->theURLResolvers.begin();
1719 resolver != sctx->theURLResolvers.end(); resolver++)
1720 {
1721 try
1722 {
1723 // Take ownership of returned Resource (if any)
1724 oResource.reset((*resolver)->resolveURL(*url, aEntityData));
1725 if (oResource.get() != NULL)
1726 {
1727 // Populate the URL used to load this Resource
1728 oResource->setUrl(*url);
1729 return;
1730 }
1731 }
1732 catch (const std::exception& e)
1733 {
1734 if (oErrorMessage.empty())
1735 {
1736 // Really no point in saving anything more than the first message
1737 oErrorMessage = e.what();
1738 }
1739 }
1740 catch (...)
1741 {
1742 // Not much we can do here except try the rest of the
1743 // candidate URIs
1744 }
1745 }
1746 }
1747 }
1748 }
1749
1750
1751 /*******************************************************************************
1752
1753 ********************************************************************************/
set_uri_path(const std::vector<zstring> & path)1754 void static_context::set_uri_path(const std::vector<zstring>& path)
1755 {
1756 theURIPath = path;
1757 }
1758
1759
1760 /*******************************************************************************
1761
1762 ********************************************************************************/
get_uri_path(std::vector<zstring> & path) const1763 void static_context::get_uri_path(std::vector<zstring>& path) const
1764 {
1765 path.insert(path.end(), theURIPath.begin(), theURIPath.end());
1766 }
1767
1768
1769 /*******************************************************************************
1770
1771 ********************************************************************************/
get_full_uri_path(std::vector<zstring> & path) const1772 void static_context::get_full_uri_path(std::vector<zstring>& path) const
1773 {
1774 if (theParent != NULL)
1775 {
1776 theParent->get_full_uri_path(path);
1777 }
1778
1779 get_uri_path(path);
1780 }
1781
1782 /*******************************************************************************
1783
1784 ********************************************************************************/
set_lib_path(const std::vector<zstring> & path)1785 void static_context::set_lib_path(const std::vector<zstring>& path)
1786 {
1787 theLibPath = path;
1788 }
1789
1790
1791 /*******************************************************************************
1792
1793 ********************************************************************************/
get_lib_path(std::vector<zstring> & path) const1794 void static_context::get_lib_path(std::vector<zstring>& path) const
1795 {
1796 path.insert(path.end(), theLibPath.begin(), theLibPath.end());
1797 }
1798
1799
1800 /*******************************************************************************
1801
1802 ********************************************************************************/
get_full_lib_path(std::vector<zstring> & path) const1803 void static_context::get_full_lib_path(std::vector<zstring>& path) const
1804 {
1805 if (theParent != NULL)
1806 {
1807 theParent->get_full_lib_path(path);
1808 }
1809
1810 get_lib_path(path);
1811 }
1812
1813
1814 /////////////////////////////////////////////////////////////////////////////////
1815 // //
1816 // Validating Items //
1817 // //
1818 /////////////////////////////////////////////////////////////////////////////////
1819
1820
1821 /***************************************************************************//**
1822
1823 ********************************************************************************/
validate(store::Item * rootElement,store::Item_t & validatedResult,StaticContextConsts::validation_mode_t validationMode) const1824 bool static_context::validate(
1825 store::Item* rootElement,
1826 store::Item_t& validatedResult,
1827 StaticContextConsts::validation_mode_t validationMode) const
1828 {
1829 zstring xsTns(XML_SCHEMA_NS);
1830 return validate(rootElement, validatedResult, xsTns, validationMode);
1831 }
1832
1833
1834 /***************************************************************************//**
1835
1836 ********************************************************************************/
validate(store::Item * rootElement,store::Item_t & validatedResult,const zstring & targetNamespace,StaticContextConsts::validation_mode_t validationMode) const1837 bool static_context::validate(
1838 store::Item* rootElement,
1839 store::Item_t& validatedResult,
1840 const zstring& targetNamespace,
1841 StaticContextConsts::validation_mode_t validationMode) const
1842 {
1843 if ( !rootElement->isNode() ||
1844 (rootElement->getNodeKind() != store::StoreConsts::documentNode &&
1845 rootElement->getNodeKind() != store::StoreConsts::elementNode))
1846 return false;
1847
1848 if ( rootElement->isValidated() )
1849 return true;
1850
1851 #ifndef ZORBA_NO_XMLSCHEMA
1852
1853 TypeManager* tm = this->get_typemanager();
1854 zstring docUri;
1855 rootElement->getDocumentURI(docUri);
1856
1857 if (validationMode != StaticContextConsts::skip_validation)
1858 {
1859 store::Item_t validatedNode;
1860 store::Item_t typeName;
1861 QueryLoc loc;
1862
1863 ParseConstants::validation_mode_t mode;
1864 switch( validationMode )
1865 {
1866 case StaticContextConsts::strict_validation:
1867 mode = ParseConstants::val_strict;
1868 break;
1869 case StaticContextConsts::lax_dtd_validation:
1870 mode = ParseConstants::val_dtd_lax;
1871 break;
1872 case StaticContextConsts::lax_validation:
1873 default:
1874 mode = ParseConstants::val_lax;
1875 }
1876
1877 return Validator::effectiveValidationValue(validatedResult,
1878 rootElement,
1879 typeName,
1880 tm,
1881 mode,
1882 this,
1883 loc);
1884
1885 }
1886 #endif //ZORBA_NO_XMLSCHEMA
1887
1888 return false;
1889 }
1890
1891
1892 /***************************************************************************//**
1893
1894 ********************************************************************************/
validateSimpleContent(zstring & stringValue,store::Item * typeQName,std::vector<store::Item_t> & resultList) const1895 bool static_context::validateSimpleContent(
1896 zstring& stringValue,
1897 store::Item* typeQName,
1898 std::vector<store::Item_t>& resultList) const
1899 {
1900 store::NsBindings bindings;
1901 this->get_namespace_bindings(bindings);
1902 store::Item_t lTypeQName(typeQName);
1903
1904 #ifndef ZORBA_NO_XMLSCHEMA
1905 Validator::processTextValue(
1906 this,
1907 this->get_typemanager(),
1908 bindings,
1909 lTypeQName,
1910 stringValue,
1911 resultList,
1912 QueryLoc::null);
1913
1914 return true;
1915 #else
1916 throw ZORBA_EXCEPTION(err::XQST0009);
1917 return false;
1918 #endif
1919 }
1920
1921 /////////////////////////////////////////////////////////////////////////////////
1922 // //
1923 // Type Manager //
1924 // //
1925 /////////////////////////////////////////////////////////////////////////////////
1926
1927
1928 /*******************************************************************************
1929
1930 ********************************************************************************/
set_typemanager(rchandle<TypeManager> typemgr)1931 void static_context::set_typemanager(rchandle<TypeManager> typemgr)
1932 {
1933 theTypeManager = typemgr;
1934 }
1935
1936
get_typemanager() const1937 TypeManager* static_context::get_typemanager() const
1938 {
1939 TypeManager* tm = theTypeManager.getp();
1940 if (tm != NULL)
1941 {
1942 return tm;
1943 }
1944 return static_cast<static_context *>(theParent)->get_typemanager();
1945 }
1946
1947
get_local_typemanager() const1948 TypeManager* static_context::get_local_typemanager() const
1949 {
1950 return theTypeManager.getp();
1951 }
1952
1953
1954 /////////////////////////////////////////////////////////////////////////////////
1955 // //
1956 // Namespace Bindings //
1957 // //
1958 /////////////////////////////////////////////////////////////////////////////////
1959
1960
1961 /***************************************************************************//**
1962 Get the default namespace for element and type qnames.
1963 ********************************************************************************/
default_elem_type_ns() const1964 const zstring& static_context::default_elem_type_ns() const
1965 {
1966 if (theHaveDefaultElementNamespace || theParent == NULL)
1967 {
1968 return theDefaultElementNamespace;
1969 }
1970 else
1971 {
1972 return theParent->default_elem_type_ns();
1973 }
1974 }
1975
1976
1977 /***************************************************************************//**
1978 Set the default namespace for element and type qnames to the given namespace.
1979 ********************************************************************************/
set_default_elem_type_ns(const zstring & ns,bool raiseError,const QueryLoc & loc)1980 void static_context::set_default_elem_type_ns(
1981 const zstring& ns,
1982 bool raiseError,
1983 const QueryLoc& loc)
1984 {
1985 if (!theHaveDefaultElementNamespace)
1986 {
1987 theDefaultElementNamespace = ns;
1988 theHaveDefaultElementNamespace = true;
1989 }
1990 else if (raiseError)
1991 {
1992 throw XQUERY_EXCEPTION(err::XQST0066, ERROR_LOC(loc));
1993 }
1994 else
1995 {
1996 theDefaultElementNamespace = ns;
1997 }
1998 }
1999
2000
2001 /***************************************************************************//**
2002 Get the default namespace for function qnames.
2003 ********************************************************************************/
default_function_ns() const2004 const zstring& static_context::default_function_ns() const
2005 {
2006 if (theHaveDefaultFunctionNamespace || theParent == NULL)
2007 {
2008 return theDefaultFunctionNamespace;
2009 }
2010 else
2011 {
2012 return theParent->default_function_ns();
2013 }
2014 }
2015
2016
2017 /***************************************************************************//**
2018 Set the default namespace for function qnames to the given namespace.
2019 ********************************************************************************/
set_default_function_ns(const zstring & ns,bool raiseError,const QueryLoc & loc)2020 void static_context::set_default_function_ns(
2021 const zstring& ns,
2022 bool raiseError,
2023 const QueryLoc& loc)
2024 {
2025 if (!theHaveDefaultFunctionNamespace)
2026 {
2027 theDefaultFunctionNamespace = ns;
2028 theHaveDefaultFunctionNamespace = true;
2029 }
2030 else if (raiseError)
2031 {
2032 throw XQUERY_EXCEPTION(err::XQST0066, ERROR_LOC(loc));
2033 }
2034 else
2035 {
2036 theDefaultFunctionNamespace = ns;
2037 }
2038 }
2039
2040
2041 /***************************************************************************//**
2042 Bind the given prefix to the given namaspace uri. The binding is stored in
2043 "this". If there is already in "this" a binding for the prefix, raise error.
2044 ********************************************************************************/
bind_ns(const zstring & prefix,const zstring & ns,const QueryLoc & loc,const Error & err)2045 void static_context::bind_ns(
2046 const zstring& prefix,
2047 const zstring& ns,
2048 const QueryLoc& loc,
2049 const Error& err)
2050 {
2051 if (theNamespaceBindings == NULL)
2052 {
2053 theNamespaceBindings = new NamespaceBindings(16, false);
2054 }
2055
2056 zstring temp(ns);
2057
2058 if (!theNamespaceBindings->insert(prefix, temp))
2059 {
2060 throw XQUERY_EXCEPTION_VAR(err,
2061 ERROR_PARAMS(prefix, temp),
2062 ERROR_LOC(loc));
2063 }
2064 }
2065
2066
2067 /***************************************************************************//**
2068 Search the static-context tree, starting from "this" and moving upwards,
2069 looking for the 1st namespace binding for the given prefix. If no such
2070 binding is found, either raise an error (if the given error code is not
2071 ZXQP0000_NO_ERROR) or return false. Otherwise, return true and the
2072 associated namespace uri.
2073 ********************************************************************************/
lookup_ns(zstring & ns,const zstring & prefix,const QueryLoc & loc,const Error & err) const2074 bool static_context::lookup_ns(
2075 zstring& ns,
2076 const zstring& prefix,
2077 const QueryLoc& loc,
2078 const Error& err) const
2079 {
2080 if (theNamespaceBindings == NULL || !theNamespaceBindings->get(prefix, ns))
2081 {
2082 if (theParent != NULL)
2083 {
2084 return theParent->lookup_ns(ns, prefix, loc, err);
2085 }
2086 else if (err != zerr::ZXQP0000_NO_ERROR)
2087 {
2088 throw XQUERY_EXCEPTION_VAR(
2089 err, ERROR_PARAMS( prefix ), ERROR_LOC( loc )
2090 );
2091 }
2092 else
2093 {
2094 return false;
2095 }
2096 }
2097 else if (!prefix.empty() && ns.empty())
2098 {
2099 if (err != zerr::ZXQP0000_NO_ERROR)
2100 {
2101 throw XQUERY_EXCEPTION_VAR(
2102 err, ERROR_PARAMS( prefix ), ERROR_LOC( loc )
2103 );
2104 }
2105 else
2106 {
2107 return false;
2108 }
2109 }
2110
2111 return true;
2112 }
2113
2114
2115 /***************************************************************************//**
2116 Convert a [prefix, localName] pair to an expanded QName item, using the given
2117 default namespace if the prefix is empty. Raise error if the prefix is non-
2118 empty and there is no associated namespace uri.
2119 ********************************************************************************/
expand_qname(store::Item_t & qname,const zstring & default_ns,const zstring & prefix,const zstring & local,const QueryLoc & loc) const2120 void static_context::expand_qname(
2121 store::Item_t& qname,
2122 const zstring& default_ns,
2123 const zstring& prefix,
2124 const zstring& local,
2125 const QueryLoc& loc) const
2126 {
2127 if (prefix.empty())
2128 {
2129 ITEM_FACTORY->createQName(qname, default_ns, prefix, local);
2130 }
2131 else
2132 {
2133 zstring ns;
2134 lookup_ns(ns, prefix, loc);
2135 ITEM_FACTORY->createQName(qname, ns, prefix, local);
2136 }
2137 }
2138
2139
2140 /***************************************************************************//**
2141
2142 ********************************************************************************/
get_namespace_bindings(store::NsBindings & bindings) const2143 void static_context::get_namespace_bindings(store::NsBindings& bindings) const
2144 {
2145 const static_context* sctx = this;
2146
2147 while (sctx != NULL)
2148 {
2149 if (sctx->theNamespaceBindings != NULL)
2150 {
2151 NamespaceBindings::iterator ite = sctx->theNamespaceBindings->begin();
2152 NamespaceBindings::iterator end = sctx->theNamespaceBindings->end();
2153
2154 for (; ite != end; ++ite)
2155 {
2156 std::pair<zstring, zstring> binding = (*ite);
2157
2158 // Ignore duplicates
2159 const zstring& prefix = binding.first;
2160 ulong numBindings = (ulong)bindings.size();
2161 bool found = 0;
2162 for (unsigned int i = 0; i < numBindings; ++i)
2163 {
2164 if (bindings[i].first == prefix)
2165 {
2166 found = 1;
2167 break;
2168 }
2169 }
2170
2171 if (!found)
2172 bindings.push_back(binding);
2173 }
2174 }
2175
2176 sctx = sctx->theParent;
2177 }
2178 }
2179
2180
2181 /////////////////////////////////////////////////////////////////////////////////
2182 // //
2183 // Variables //
2184 // //
2185 /////////////////////////////////////////////////////////////////////////////////
2186
2187
2188 /***************************************************************************//**
2189
2190 ********************************************************************************/
bind_var(var_expr * varExpr,const QueryLoc & loc,const Error & err)2191 void static_context::bind_var(
2192 var_expr* varExpr,
2193 const QueryLoc& loc,
2194 const Error& err)
2195 {
2196 if (theVariablesMap == NULL)
2197 {
2198 theVariablesMap = new VariableMap(HashMapItemPointerCmp(0, NULL), 16, false);
2199 }
2200
2201 store::Item* qname = varExpr->get_name();
2202
2203 VarInfo_t vi = varExpr->get_var_info();
2204
2205 if (vi == NULL)
2206 {
2207 vi = new VarInfo(varExpr);
2208
2209 if (!theVariablesMap->insert(qname, vi))
2210 {
2211 throw XQUERY_EXCEPTION_VAR(err,
2212 ERROR_PARAMS(qname->getStringValue()), ERROR_LOC(loc));
2213 }
2214
2215 if (varExpr->get_kind() == var_expr::prolog_var)
2216 varExpr->set_var_info(vi);
2217 }
2218 else
2219 {
2220 if (!theVariablesMap->insert(qname, vi))
2221 {
2222 throw XQUERY_EXCEPTION_VAR(err,
2223 ERROR_PARAMS(qname->getStringValue()), ERROR_LOC(loc));
2224 }
2225 }
2226 }
2227
2228
2229 /***************************************************************************//**
2230 Lookup variable by expanded qname. Search starts from the "current" sctx and
2231 moves upwards the ancestor path until the first instance (if any) of the var
2232 is found.
2233
2234 If var is not found, the method raises the given error, unless the given error
2235 is ZXQP0000_NO_ERROR, in which case it returns NULL.
2236 ********************************************************************************/
lookup_var(const store::Item * qname) const2237 VarInfo* static_context::lookup_var(const store::Item* qname) const
2238 {
2239 store::Item* qname2 = const_cast<store::Item*>(qname);
2240
2241 VarInfo_t var;
2242
2243 const static_context* sctx = this;
2244
2245 while (sctx != NULL)
2246 {
2247 if (sctx->theVariablesMap != NULL &&
2248 sctx->theVariablesMap->get(qname2, var))
2249 {
2250 return var.getp();
2251 }
2252
2253 sctx = sctx->theParent;
2254 }
2255
2256 return NULL;
2257 }
2258
2259
2260 /***************************************************************************//**
2261 This method is used by introspection and debugger
2262 ********************************************************************************/
getVariables(std::vector<VarInfo * > & vars,bool localsOnly,bool returnPrivateVars,bool externalVarsOnly) const2263 void static_context::getVariables(
2264 std::vector<VarInfo*>& vars,
2265 bool localsOnly,
2266 bool returnPrivateVars,
2267 bool externalVarsOnly) const
2268 {
2269 const static_context* sctx = this;
2270
2271 while (sctx != NULL)
2272 {
2273 if (sctx->theVariablesMap != NULL)
2274 {
2275 VariableMap::iterator ite = sctx->theVariablesMap->begin();
2276 VariableMap::iterator end = sctx->theVariablesMap->end();
2277
2278 for (; ite != end; ++ite)
2279 {
2280 csize numVars = vars.size();
2281 csize i = 0;
2282 for (; i < numVars; ++i)
2283 {
2284 if (vars[i]->getName()->equals((*ite).first))
2285 break;
2286 }
2287
2288 if (i == numVars)
2289 {
2290 if (externalVarsOnly)
2291 {
2292 if ((*ite).second->isExternal())
2293 vars.push_back((*ite).second.getp());
2294 }
2295 else
2296 {
2297 vars.push_back((*ite).second.getp());
2298 }
2299 }
2300 }
2301 }
2302
2303 if (returnPrivateVars && sctx->theImportedPrivateVariablesMap != NULL)
2304 {
2305 VariableMap::iterator ite = sctx->theImportedPrivateVariablesMap->begin();
2306 VariableMap::iterator end = sctx->theImportedPrivateVariablesMap->end();
2307
2308 for (; ite != end; ++ite)
2309 {
2310 csize numVars = vars.size();
2311 csize i = 0;
2312 for (; i < numVars; ++i)
2313 {
2314 if (vars[i]->getName()->equals((*ite).first))
2315 break;
2316 }
2317
2318 if (i == numVars)
2319 {
2320 if (externalVarsOnly)
2321 {
2322 if((*ite).second->isExternal())
2323 vars.push_back((*ite).second.getp());
2324 }
2325 else
2326 vars.push_back((*ite).second.getp());
2327 }
2328 }
2329 }
2330
2331 if (localsOnly)
2332 {
2333 break;
2334 }
2335
2336 sctx = sctx->theParent;
2337 }
2338 }
2339
2340
2341 /***************************************************************************//**
2342
2343 ********************************************************************************/
set_context_item_type(const xqtref_t & t,const QueryLoc & loc)2344 void static_context::set_context_item_type(const xqtref_t& t, const QueryLoc& loc)
2345 {
2346 if (theContextItemType != NULL)
2347 {
2348 RAISE_ERROR_NO_PARAMS(err::XQST0099, loc);
2349 }
2350
2351 theContextItemType = t;
2352 }
2353
2354
2355 /***************************************************************************//**
2356
2357 ********************************************************************************/
get_context_item_type() const2358 const XQType* static_context::get_context_item_type() const
2359 {
2360 const static_context* sctx = this;
2361 while (sctx != NULL)
2362 {
2363 if (sctx->theContextItemType != NULL)
2364 return sctx->theContextItemType.getp();
2365
2366 sctx = sctx->theParent;
2367 }
2368
2369 return NULL;
2370 }
2371
2372
2373 /////////////////////////////////////////////////////////////////////////////////
2374 // //
2375 // Functions //
2376 // //
2377 /////////////////////////////////////////////////////////////////////////////////
2378
2379
2380 /***************************************************************************//**
2381
2382 ********************************************************************************/
bind_fn(function_t & f,ulong arity,const QueryLoc & loc)2383 void static_context::bind_fn(
2384 function_t& f,
2385 ulong arity,
2386 const QueryLoc& loc)
2387 {
2388 store::Item* qname = f->getName();
2389
2390 if (!is_global_root_sctx() && lookup_local_fn(qname, arity) != NULL)
2391 {
2392 RAISE_ERROR(err::XQST0034, loc, ERROR_PARAMS(qname->getStringValue()));
2393 }
2394
2395 if (theFunctionMap == NULL)
2396 {
2397 ulong size = (is_global_root_sctx() ? 500 : 32);
2398 theFunctionMap = new FunctionMap(HashMapItemPointerCmp(0, NULL), size, false);
2399 }
2400
2401 FunctionInfo fi(f);
2402
2403 if (!theFunctionMap->insert(qname, fi))
2404 {
2405 // There is already a function F with the given qname in theFunctionMap.
2406 // First, check if F is the same as f, which implies that f is disabled.
2407 // In this case, re-enable f. Otherwise, we have to use theFunctionArityMap.
2408 if (fi.theFunction == f)
2409 {
2410 ZORBA_ASSERT(fi.theIsDisabled);
2411 fi.theIsDisabled = false;
2412 return;
2413 }
2414
2415 fi.theFunction = f;
2416 fi.theIsDisabled = false;
2417
2418 ZORBA_ASSERT(!f->isVariadic());
2419
2420 if (theFunctionArityMap == NULL)
2421 {
2422 theFunctionArityMap =
2423 new FunctionArityMap(HashMapItemPointerCmp(0, NULL), 16, false);
2424 }
2425
2426 std::vector<FunctionInfo>* fv = 0;
2427
2428 if (theFunctionArityMap->get(qname, fv))
2429 {
2430 csize numFunctions = fv->size();
2431 for (csize i = 0; i < numFunctions; ++i)
2432 {
2433 if ((*fv)[i].theFunction == f)
2434 {
2435 ZORBA_ASSERT((*fv)[i].theIsDisabled);
2436 (*fv)[i].theIsDisabled = false;
2437 return;
2438 }
2439 }
2440
2441 fv->push_back(fi);
2442 }
2443 else
2444 {
2445 fv = new std::vector<FunctionInfo>(1);
2446 (*fv)[0] = fi;
2447 theFunctionArityMap->insert(qname, fv);
2448 }
2449 }
2450 }
2451
2452
2453 /***************************************************************************//**
2454 Remove the function with the given qname and arity from the in-scope functions
2455 of this sctx.
2456 ********************************************************************************/
unbind_fn(const store::Item * qname,ulong arity)2457 void static_context::unbind_fn(
2458 const store::Item* qname,
2459 ulong arity)
2460 {
2461 ZORBA_ASSERT(!is_global_root_sctx());
2462
2463 function* f = lookup_fn(qname, arity);
2464
2465 if (f == NULL)
2466 return;
2467
2468 if (theFunctionMap == NULL)
2469 {
2470 theFunctionMap = new FunctionMap(HashMapItemPointerCmp(0, NULL), 32, false);
2471 }
2472
2473 FunctionInfo fi(f, true);
2474 store::Item* qname2 = const_cast<store::Item*>(f->getName());
2475
2476 if (theFunctionMap->get(qname2, fi))
2477 {
2478 if (fi.theFunction.getp() == f)
2479 {
2480 fi.theIsDisabled = true;
2481 theFunctionMap->update(qname2, fi);
2482 return;
2483 }
2484
2485 if (theFunctionArityMap == NULL)
2486 {
2487 theFunctionArityMap =
2488 new FunctionArityMap(HashMapItemPointerCmp(0, NULL), 16, false);
2489 }
2490
2491 std::vector<FunctionInfo>* fv = NULL;
2492
2493 if (theFunctionArityMap->get(qname2, fv))
2494 {
2495 csize numFunctions = fv->size();
2496 for (csize i = 0; i < numFunctions; ++i)
2497 {
2498 if ((*fv)[i].theFunction.getp() == f)
2499 {
2500 (*fv)[i].theIsDisabled = true;
2501 return;
2502 }
2503 }
2504 }
2505
2506 fv = new std::vector<FunctionInfo>(1);
2507 fi.theIsDisabled = true;
2508 fi.theFunction = f;
2509 (*fv)[0] = fi;
2510 theFunctionArityMap->insert(qname2, fv);
2511 }
2512 else
2513 {
2514 theFunctionMap->insert(qname2, fi);
2515 }
2516 }
2517
2518
2519 /***************************************************************************//**
2520 Search the static-context tree, starting from "this" and moving upwards,
2521 looking for the 1st sctx obj that contains a binding for a function with
2522 the given qname and arity. If no such binding is found return NULL. Otherwise,
2523 return the associated function object (which may be NULL if the function
2524 was disabled).
2525 ********************************************************************************/
lookup_fn(const store::Item * qname,ulong arity,bool skipDisabled)2526 function* static_context::lookup_fn(
2527 const store::Item* qname,
2528 ulong arity,
2529 bool skipDisabled)
2530 {
2531 FunctionInfo fi;
2532 store::Item* qname2 = const_cast<store::Item*>(qname);
2533
2534 static_context* sctx = this;
2535
2536 while (sctx != NULL)
2537 {
2538 if (sctx->theFunctionMap != NULL && sctx->theFunctionMap->get(qname2, fi))
2539 {
2540 function* f = fi.theFunction.getp();
2541
2542 if (f->getArity() == arity || f->isVariadic())
2543 {
2544 if (fi.theIsDisabled && skipDisabled)
2545 return NULL;
2546
2547 return f;
2548 }
2549
2550 std::vector<FunctionInfo>* fv = NULL;
2551
2552 if (sctx->theFunctionArityMap != NULL &&
2553 sctx->theFunctionArityMap->get(qname2, fv))
2554 {
2555 csize numFunctions = fv->size();
2556 for (csize i = 0; i < numFunctions; ++i)
2557 {
2558 if ((*fv)[i].theFunction->getArity() == arity)
2559 {
2560 if ((*fv)[i].theIsDisabled && skipDisabled)
2561 return NULL;
2562
2563 return (*fv)[i].theFunction.getp();
2564 }
2565 }
2566 }
2567 }
2568
2569 sctx = sctx->theParent;
2570 }
2571
2572 return NULL;
2573 }
2574
2575
2576 /***************************************************************************//**
2577 Search "this" static context a function with the given qname and arity. If no
2578 such function binding is found return NULL. Otherwise, return the associated
2579 function object (which may be NULL if the function was disabled).
2580 ********************************************************************************/
lookup_local_fn(const store::Item * qname,ulong arity,bool skipDisabled)2581 function* static_context::lookup_local_fn(
2582 const store::Item* qname,
2583 ulong arity,
2584 bool skipDisabled)
2585 {
2586 FunctionInfo fi;
2587 store::Item* qname2 = const_cast<store::Item*>(qname);
2588
2589 if (theFunctionMap != NULL && theFunctionMap->get(qname2, fi))
2590 {
2591 function* f = fi.theFunction.getp();
2592
2593 if (f->getArity() == arity || f->isVariadic())
2594 {
2595 if (fi.theIsDisabled && skipDisabled)
2596 return NULL;
2597
2598 return f;
2599 }
2600
2601 std::vector<FunctionInfo>* fv = NULL;
2602
2603 if (theFunctionArityMap != NULL && theFunctionArityMap->get(qname2, fv))
2604 {
2605 csize numFunctions = fv->size();
2606 for (csize i = 0; i < numFunctions; ++i)
2607 {
2608 if ((*fv)[i].theFunction->getArity() == arity)
2609 {
2610 if ((*fv)[i].theIsDisabled && skipDisabled)
2611 return NULL;
2612
2613 return (*fv)[i].theFunction.getp();
2614 }
2615 }
2616 }
2617 }
2618
2619 return NULL;
2620 }
2621
2622
2623 /***************************************************************************//**
2624 Find all the in-scope and non-disabled functions in this sctx and its ancestors.
2625 ********************************************************************************/
get_functions(std::vector<function * > & functions) const2626 void static_context::get_functions(
2627 std::vector<function *>& functions) const
2628 {
2629 std::vector<function*> disabled;
2630 std::vector<zstring> importedBuiltinModules;
2631
2632 const static_context* sctx = this;
2633
2634 while (sctx != NULL)
2635 {
2636 if (!sctx->theImportedBuiltinModules.empty())
2637 {
2638 std::vector<zstring>::const_iterator ite = sctx->theImportedBuiltinModules.begin();
2639 std::vector<zstring>::const_iterator end = sctx->theImportedBuiltinModules.end();
2640 for (; ite != end; ++ite)
2641 {
2642 importedBuiltinModules.push_back(*ite);
2643 }
2644 }
2645
2646 if (sctx->theFunctionMap != NULL)
2647 {
2648 FunctionMap::iterator ite = sctx->theFunctionMap->begin();
2649 FunctionMap::iterator end = sctx->theFunctionMap->end();
2650
2651 for (; ite != end; ++ite)
2652 {
2653 function* f = (*ite).second.theFunction.getp();
2654
2655 if (!(*ite).second.theIsDisabled)
2656 {
2657 if (std::find(disabled.begin(), disabled.end(), f) == disabled.end())
2658 {
2659 if (f->isBuiltin())
2660 {
2661 // Skip builtin functions that (a) are fn functions, or (b) are fn or
2662 // zorba operators (i.e., non user visible), or (c) their containing
2663 // module has not been imported.
2664
2665 assert(sctx->is_global_root_sctx());
2666
2667 const zstring& ns = f->getName()->getNamespace();
2668
2669 // if (ns != W3C_FN_NS)
2670 if ( ! utf8::begins_with(ns, W3C_FN_NS))
2671 {
2672 if (ns == XQUERY_OP_NS || ns == ZORBA_OP_NS)
2673 continue;
2674
2675 std::vector<zstring>::const_iterator ite = importedBuiltinModules.begin();
2676 std::vector<zstring>::const_iterator end = importedBuiltinModules.end();
2677 for (; ite != end; ++ite)
2678 {
2679 if (ns == *ite)
2680 break;
2681 }
2682
2683 if (ite == end)
2684 continue;
2685 }
2686 }
2687 else
2688 {
2689 assert(!sctx->is_global_root_sctx());
2690 }
2691
2692 functions.push_back(f);
2693 }
2694 }
2695 else
2696 {
2697 disabled.push_back(f);
2698 }
2699 }
2700 }
2701
2702 if (sctx->theFunctionArityMap != NULL)
2703 {
2704 FunctionArityMap::iterator ite = sctx->theFunctionArityMap->begin();
2705 FunctionArityMap::iterator end = sctx->theFunctionArityMap->end();
2706
2707 for (; ite != end; ++ite)
2708 {
2709 std::vector<FunctionInfo>* fv = (*ite).second;
2710
2711 ulong numFunctions = (ulong)fv->size();
2712 for (ulong i = 0; i < numFunctions; ++i)
2713 {
2714 function* f = (*fv)[i].theFunction.getp();
2715
2716 if (!(*fv)[i].theIsDisabled)
2717 {
2718 if (std::find(disabled.begin(), disabled.end(), f) == disabled.end())
2719 {
2720 if (f->isBuiltin())
2721 {
2722 assert(sctx->is_global_root_sctx());
2723
2724 const zstring& ns = f->getName()->getNamespace();
2725
2726 // if (ns != W3C_FN_NS)
2727 if ( ! utf8::begins_with(ns, W3C_FN_NS))
2728 {
2729 if (ns == XQUERY_OP_NS || ns == ZORBA_OP_NS)
2730 continue;
2731
2732 std::vector<zstring>::const_iterator ite = importedBuiltinModules.begin();
2733 std::vector<zstring>::const_iterator end = importedBuiltinModules.end();
2734 for (; ite != end; ++ite)
2735 {
2736 if (ns == *ite)
2737 break;
2738 }
2739
2740 if (ite == end)
2741 continue;
2742 }
2743 }
2744 else
2745 {
2746 assert(!sctx->is_global_root_sctx());
2747 }
2748
2749 functions.push_back(f);
2750 }
2751 }
2752 else
2753 {
2754 disabled.push_back(f);
2755 }
2756 }
2757 }
2758 }
2759
2760 sctx = sctx->theParent;
2761 }
2762 }
2763
2764
2765 /***************************************************************************//**
2766 Find all the functions with the given qname.
2767 ********************************************************************************/
find_functions(const store::Item * qname,std::vector<function * > & functions) const2768 void static_context::find_functions(
2769 const store::Item* qname,
2770 std::vector<function *>& functions) const
2771 {
2772 FunctionInfo fi;
2773 store::Item* qname2 = const_cast<store::Item*>(qname);
2774
2775 if (theFunctionMap != NULL && theFunctionMap->get(qname2, fi))
2776 {
2777 if (!fi.theIsDisabled)
2778 functions.push_back(fi.theFunction.getp());
2779 }
2780
2781 std::vector<FunctionInfo>* fv = NULL;
2782
2783 if (theFunctionArityMap != NULL && theFunctionArityMap->get(qname2, fv))
2784 {
2785 ulong numFunctions = (ulong)fv->size();
2786 for (ulong i = 0; i < numFunctions; ++i)
2787 {
2788 if (!(*fv)[i].theIsDisabled)
2789 functions.push_back((*fv)[i].theFunction.getp());
2790 }
2791 }
2792
2793 if (theParent != NULL)
2794 theParent->find_functions(qname2, functions);
2795 }
2796
2797
2798 /***************************************************************************//**
2799 Register an external module. This module can be used to retrieve external
2800 functions defined in the target namespace of the module.
2801
2802 If aDynamicallyLoaded is false, then the external module to register has been
2803 created and is provided directly by the application. Otherwise, it is an
2804 external module that is created and loaded dynamically by zorba from a lib
2805 file that is stored somewhere in the in-scope module paths (see
2806 DynamicLoader::getExternalModule method and how this method is
2807 invoked by the static_context::lookup_external_function method below).
2808 ********************************************************************************/
bind_external_module(ExternalModule * aModule,bool aDynamicallyLoaded)2809 void static_context::bind_external_module(
2810 ExternalModule* aModule,
2811 bool aDynamicallyLoaded)
2812 {
2813 if (theExternalModulesMap == NULL)
2814 {
2815 theExternalModulesMap = new ExternalModuleMap(8, false);
2816 }
2817
2818 zstring uri = Unmarshaller::getInternalString(aModule->getURI());
2819 ctx_module_t modinfo;
2820 modinfo.module = aModule;
2821 modinfo.dyn_loaded_module = aDynamicallyLoaded;
2822 modinfo.sctx = this;
2823
2824 if (!theExternalModulesMap->insert(uri, modinfo))
2825 {
2826 throw ZORBA_EXCEPTION(
2827 zerr::ZAPI0019_MODULE_ALREADY_REGISTERED, ERROR_PARAMS( uri )
2828 );
2829 }
2830 }
2831
2832
2833 /***************************************************************************//**
2834 Find and return the implementation of an external function, given its namespace
2835 URI and local name.
2836 ********************************************************************************/
lookup_external_function(const zstring & aURI,const zstring & aLocalName)2837 ExternalFunction* static_context::lookup_external_function(
2838 const zstring& aURI,
2839 const zstring& aLocalName)
2840 {
2841 // get the module for the given namespace
2842 bool found = false;
2843 ctx_module_t modinfo;
2844 const static_context* sctx = this;
2845
2846 while (sctx != NULL)
2847 {
2848 if (sctx->theExternalModulesMap != NULL &&
2849 sctx->theExternalModulesMap->get(aURI, modinfo))
2850 {
2851 found = true;
2852 break;
2853 }
2854
2855 sctx = sctx->theParent;
2856 }
2857
2858 ExternalModule* lModule = 0;
2859
2860 // If the module is not yet in the static context we try to get it from the
2861 // dynamic loader
2862 if (!found)
2863 {
2864 lModule = GENV_DYNAMIC_LOADER->getExternalModule(aURI, *this);
2865
2866 // no way to get the module
2867 if (!lModule)
2868 return NULL;
2869
2870 // remember the module for future use
2871 bind_external_module(lModule, true);
2872 }
2873 else
2874 {
2875 lModule = modinfo.module;
2876 }
2877
2878 // get the function from this module.
2879 // return 0 if not found
2880 return lModule->getExternalFunction(aLocalName.str());
2881 }
2882
2883
2884 /////////////////////////////////////////////////////////////////////////////////
2885 // //
2886 // Documents //
2887 // //
2888 /////////////////////////////////////////////////////////////////////////////////
2889
2890
2891 /***************************************************************************//**
2892 This method may be called only on an application-created sctx.
2893 ********************************************************************************/
bind_document(const zstring & uri,xqtref_t & type)2894 void static_context::bind_document(const zstring& uri, xqtref_t& type)
2895 {
2896 if (theDocumentMap == NULL)
2897 {
2898 theDocumentMap = new DocumentMap(16, false);
2899 }
2900
2901 if (!theDocumentMap->update(uri, type))
2902 {
2903 theDocumentMap->insert(uri, type);
2904 }
2905 }
2906
2907
2908 /***************************************************************************//**
2909
2910 ********************************************************************************/
lookup_document(const zstring & uri)2911 const XQType* static_context::lookup_document(const zstring& uri)
2912 {
2913 xqtref_t type;
2914
2915 static_context* sctx = this;
2916 while (sctx != NULL)
2917 {
2918 if (sctx->theDocumentMap && sctx->theDocumentMap->get(uri, type))
2919 return type.getp();
2920
2921 sctx = sctx->theParent;
2922 }
2923
2924 return NULL;
2925 }
2926
get_all_documents(std::vector<zstring> & documents)2927 void static_context::get_all_documents(std::vector<zstring>& documents)
2928 {
2929 static_context* sctx = this;
2930 documents.clear();
2931
2932 while (sctx != NULL)
2933 {
2934 if (sctx->theDocumentMap != NULL)
2935 {
2936 for(DocumentMap::iterator it = sctx->theDocumentMap->begin();
2937 it != sctx->theDocumentMap->end();
2938 ++it)
2939 documents.push_back(it.getKey());
2940 }
2941
2942 sctx = sctx->theParent;
2943 }
2944 }
2945
2946
2947 /////////////////////////////////////////////////////////////////////////////////
2948 // //
2949 // W3C Collections //
2950 // //
2951 /////////////////////////////////////////////////////////////////////////////////
2952
2953
2954 /***************************************************************************//**
2955 This method may be called only on an application-created sctx.
2956 ********************************************************************************/
bind_w3c_collection(zstring & uri,xqtref_t & type)2957 void static_context::bind_w3c_collection(zstring& uri, xqtref_t& type)
2958 {
2959 if (theW3CCollectionMap == NULL)
2960 {
2961 theW3CCollectionMap = new W3CCollectionMap(16, false);
2962 }
2963
2964 if (!theW3CCollectionMap->update(uri, type))
2965 {
2966 theW3CCollectionMap->insert(uri, type);
2967 }
2968 }
2969
2970
2971 /***************************************************************************//**
2972
2973 ********************************************************************************/
lookup_w3c_collection(const zstring & uri)2974 const XQType* static_context::lookup_w3c_collection(const zstring& uri)
2975 {
2976 xqtref_t type;
2977
2978 if (theW3CCollectionMap && theW3CCollectionMap->get(uri, type))
2979 return type.getp();
2980 else
2981 return (theParent == NULL ? 0 : theParent->lookup_w3c_collection(uri));
2982 }
2983
2984
2985 /***************************************************************************//**
2986
2987 ********************************************************************************/
set_default_w3c_collection_type(xqtref_t & t)2988 void static_context::set_default_w3c_collection_type(xqtref_t& t)
2989 {
2990 theDefaultW3CCollectionType = t;
2991 }
2992
2993
2994 /***************************************************************************//**
2995
2996 ********************************************************************************/
get_default_w3c_collection_type()2997 const XQType* static_context::get_default_w3c_collection_type()
2998 {
2999 static_context* sctx = this;
3000 while (sctx != NULL)
3001 {
3002 if (sctx->theDefaultW3CCollectionType != NULL)
3003 return sctx->theDefaultW3CCollectionType.getp();
3004
3005 sctx = sctx->theParent;
3006 }
3007
3008 return NULL;
3009 }
3010
3011
3012 /////////////////////////////////////////////////////////////////////////////////
3013 // //
3014 // XQDDF Collections //
3015 // //
3016 /////////////////////////////////////////////////////////////////////////////////
3017
3018
3019 /***************************************************************************//**
3020
3021 ********************************************************************************/
bind_collection(StaticallyKnownCollection_t & aCollection,const QueryLoc & aLoc)3022 void static_context::bind_collection(
3023 StaticallyKnownCollection_t& aCollection,
3024 const QueryLoc& aLoc)
3025 {
3026 if (lookup_collection(aCollection->getName()) != NULL)
3027 {
3028 throw XQUERY_EXCEPTION(
3029 zerr::ZDST0001_COLLECTION_ALREADY_DECLARED,
3030 ERROR_PARAMS( aCollection->getName()->getStringValue() ),
3031 ERROR_LOC( aLoc )
3032 );
3033 }
3034
3035 if (theCollectionMap == 0)
3036 theCollectionMap = new CollectionMap(HashMapItemPointerCmp(0, NULL), 8, false);
3037
3038 store::Item* qname = const_cast<store::Item*>(aCollection->getName());
3039 theCollectionMap->insert(qname, aCollection);
3040 }
3041
3042
3043 /***************************************************************************//**
3044
3045 ********************************************************************************/
lookup_collection(const store::Item * qname) const3046 const StaticallyKnownCollection* static_context::lookup_collection(
3047 const store::Item* qname) const
3048 {
3049 StaticallyKnownCollection_t lColl;
3050 store::Item* qname2 = const_cast<store::Item*>(qname);
3051
3052 if (theCollectionMap && theCollectionMap->get(qname2, lColl))
3053 return lColl.getp();
3054 else
3055 return (theParent == NULL ? 0 : theParent->lookup_collection(qname));
3056 }
3057
3058
3059 /***************************************************************************//**
3060
3061 ********************************************************************************/
collection_names() const3062 store::Iterator_t static_context::collection_names() const
3063 {
3064 return new SctxMapIterator<StaticallyKnownCollection>(
3065 this,
3066 &static_context::collection_map);
3067 }
3068
3069
3070 /////////////////////////////////////////////////////////////////////////////////
3071 // //
3072 // XQDDF Indexes //
3073 // //
3074 /////////////////////////////////////////////////////////////////////////////////
3075
3076
3077 /***************************************************************************//**
3078
3079 ********************************************************************************/
bind_index(IndexDecl_t & index,const QueryLoc & loc)3080 void static_context::bind_index(IndexDecl_t& index, const QueryLoc& loc)
3081 {
3082 store::Item* qname = const_cast<store::Item*>(index->getName());
3083
3084 if (lookup_index(qname) != NULL)
3085 {
3086 throw XQUERY_EXCEPTION(
3087 zerr::ZDST0021_INDEX_ALREADY_DECLARED,
3088 ERROR_PARAMS( qname->getStringValue() ),
3089 ERROR_LOC( loc )
3090 );
3091 }
3092
3093 if (theIndexMap == NULL)
3094 theIndexMap = new IndexMap(HashMapItemPointerCmp(0, NULL), 8, false);
3095
3096 theIndexMap->insert(qname, index);
3097 }
3098
3099
3100 /***************************************************************************//**
3101
3102 ********************************************************************************/
lookup_index(const store::Item * qname) const3103 IndexDecl* static_context::lookup_index(const store::Item* qname) const
3104 {
3105 IndexDecl_t index;
3106 store::Item* qname2 = const_cast<store::Item*>(qname);
3107
3108 if (theIndexMap && theIndexMap->get(qname2, index))
3109 return index.getp();
3110 else
3111 return (theParent == NULL ? NULL : theParent->lookup_index(qname));
3112 }
3113
3114
3115 /***************************************************************************//**
3116
3117 ********************************************************************************/
index_names() const3118 store::Iterator_t static_context::index_names() const
3119 {
3120 return new SctxMapIterator<IndexDecl>(this, &static_context::index_map);
3121 }
3122
3123
3124 /////////////////////////////////////////////////////////////////////////////////
3125 // //
3126 // XQDDF Integrity Constraints //
3127 // //
3128 /////////////////////////////////////////////////////////////////////////////////
3129
3130
3131 /***************************************************************************//**
3132
3133 ********************************************************************************/
bind_ic(ValueIC_t & vic,const QueryLoc & loc)3134 void static_context::bind_ic(
3135 ValueIC_t& vic,
3136 const QueryLoc& loc)
3137 {
3138 store::Item* qname = vic->getICName();
3139
3140 if (lookup_ic(qname) != NULL)
3141 {
3142 throw XQUERY_EXCEPTION(
3143 zerr::ZDST0041_IC_ALREADY_DECLARED,
3144 ERROR_PARAMS( qname->getStringValue() ),
3145 ERROR_LOC( loc )
3146 );
3147 }
3148
3149 if (theICMap == NULL)
3150 theICMap = new ICMap(HashMapItemPointerCmp(0, NULL), 8, false);
3151
3152 theICMap->insert(qname, vic);
3153 }
3154
3155
3156 /***************************************************************************//**
3157
3158 ********************************************************************************/
lookup_ic(const store::Item * qname) const3159 ValueIC_t static_context::lookup_ic(const store::Item* qname) const
3160 {
3161 ValueIC_t vic;
3162 store::Item* qname2 = const_cast<store::Item*>(qname);
3163
3164 if (theICMap != NULL && theICMap->get(qname2, vic))
3165 return vic;
3166 else
3167 return (theParent == NULL ? NULL : theParent->lookup_ic(qname));
3168 }
3169
3170
3171 /***************************************************************************//**
3172
3173 ********************************************************************************/
ic_names() const3174 store::Iterator_t static_context::ic_names() const
3175 {
3176 return new SctxMapIterator<ValueIC>(this, &static_context::ic_map);
3177 }
3178
3179
3180 /////////////////////////////////////////////////////////////////////////////////
3181 // //
3182 // Collations //
3183 // //
3184 /////////////////////////////////////////////////////////////////////////////////
3185
3186
3187 /***************************************************************************//**
3188 This method may be called only on the the zorba root sctx or an application-
3189 created sctx.
3190 ********************************************************************************/
add_collation(const std::string & uri,const QueryLoc & loc)3191 void static_context::add_collation(const std::string& uri, const QueryLoc& loc)
3192 {
3193 if (is_known_collation(uri))
3194 return;
3195
3196 std::string resolvedURI = resolve_relative_uri(uri).str();
3197
3198 XQPCollator* collator = CollationFactory::createCollator(resolvedURI);
3199
3200 if (collator == NULL)
3201 {
3202 throw XQUERY_EXCEPTION(err::FOCH0002, ERROR_PARAMS(uri), ERROR_LOC(loc));
3203 }
3204 else
3205 {
3206 if (theCollationMap == NULL)
3207 theCollationMap = new CollationMap();
3208
3209 (*theCollationMap)[resolvedURI] = collator;
3210 }
3211 }
3212
3213
3214 /***************************************************************************//**
3215
3216 ********************************************************************************/
is_known_collation(const std::string & uri) const3217 bool static_context::is_known_collation(const std::string& uri) const
3218 {
3219 std::string resolvedURI = resolve_relative_uri(uri).str();
3220
3221 const static_context* sctx = this;
3222
3223 while (sctx != NULL)
3224 {
3225 if (sctx->theCollationMap != NULL &&
3226 sctx->theCollationMap->find(resolvedURI) != sctx->theCollationMap->end())
3227 {
3228 return true;
3229 }
3230
3231 sctx = sctx->theParent;
3232 }
3233
3234 return false;
3235 }
3236
3237
3238 /***************************************************************************//**
3239
3240 ********************************************************************************/
get_collator(const std::string & uri,const QueryLoc & loc) const3241 XQPCollator* static_context::get_collator(
3242 const std::string& uri,
3243 const QueryLoc& loc) const
3244 {
3245 std::string resolvedURI = resolve_relative_uri(uri).str();
3246
3247 const static_context* sctx = this;
3248
3249 while (sctx != NULL)
3250 {
3251 if (sctx->theCollationMap != NULL)
3252 {
3253 CollationMap::iterator ite = sctx->theCollationMap->find(resolvedURI);
3254
3255 if (ite != sctx->theCollationMap->end())
3256 {
3257 return ite->second;
3258 }
3259 }
3260
3261 sctx = sctx->theParent;
3262 }
3263
3264 throw XQUERY_EXCEPTION(err::FOCH0002,
3265 ERROR_PARAMS(uri, ZED(NotInStaticCtx)),
3266 ERROR_LOC(loc));
3267 }
3268
3269
3270 /***************************************************************************//**
3271
3272 ********************************************************************************/
set_default_collation(const std::string & uri,const QueryLoc & loc)3273 void static_context::set_default_collation(
3274 const std::string& uri,
3275 const QueryLoc& loc)
3276 {
3277 if (theDefaultCollation != NULL || !is_known_collation(uri))
3278 throw XQUERY_EXCEPTION(err::XQST0038, ERROR_LOC(loc));
3279
3280 zstring resolvedUri = resolve_relative_uri(uri);
3281
3282 theDefaultCollation = new std::string(resolvedUri.c_str());
3283 }
3284
3285
3286 /***************************************************************************//**
3287
3288 ********************************************************************************/
get_default_collation(const QueryLoc & loc) const3289 const std::string& static_context::get_default_collation(const QueryLoc& loc) const
3290 {
3291 const static_context* sctx = this;
3292
3293 while (sctx != NULL)
3294 {
3295 if (sctx->theDefaultCollation != NULL)
3296 {
3297 return *sctx->theDefaultCollation;
3298 }
3299
3300 sctx = sctx->theParent;
3301 }
3302
3303 ZORBA_ASSERT(false);
3304 return *theDefaultCollation;
3305 }
3306
3307
3308 /***************************************************************************//**
3309
3310 ********************************************************************************/
get_default_collator(const QueryLoc & loc) const3311 XQPCollator* static_context::get_default_collator(const QueryLoc& loc) const
3312 {
3313 if (!theCachedDefaultCollator)
3314 {
3315 const std::string& default_collation = get_default_collation(loc);
3316 theCachedDefaultCollator = get_collator(default_collation, loc);
3317 }
3318 return theCachedDefaultCollator;
3319 }
3320
3321
3322 /***************************************************************************//**
3323
3324 ********************************************************************************/
get_collations(std::vector<std::string> & collations) const3325 void static_context::get_collations(std::vector<std::string>& collations) const
3326 {
3327 const static_context* sctx = this;
3328
3329 while (sctx != NULL)
3330 {
3331 if (theCollationMap != NULL)
3332 {
3333 CollationMap::const_iterator ite = theCollationMap->begin();
3334 CollationMap::const_iterator end = theCollationMap->end();
3335 for (; ite != end; ++ite)
3336 {
3337 collations.push_back(ite->first);
3338 }
3339 }
3340
3341 sctx = sctx->theParent;
3342 }
3343 }
3344
3345
3346 /////////////////////////////////////////////////////////////////////////////////
3347 // //
3348 // Options //
3349 // //
3350 /////////////////////////////////////////////////////////////////////////////////
3351
3352
3353 /***************************************************************************//**
3354
3355 ********************************************************************************/
bind_option(const store::Item * qname,const zstring & value,const QueryLoc & loc)3356 void static_context::bind_option(
3357 const store::Item* qname,
3358 const zstring& value,
3359 const QueryLoc& loc)
3360 {
3361 if (theOptionMap == NULL)
3362 {
3363 theOptionMap = new OptionMap(HashMapItemPointerCmp(0, NULL), 8, false);
3364 }
3365
3366 PrologOption option(qname, value);
3367
3368 store::Item* qname2 = option.theName.getp();
3369
3370 zstring lNamespace = qname2->getNamespace();
3371
3372 // If option namespace starts with zorba options namespace
3373 if ( lNamespace.find(ZORBA_OPTIONS_NS) == 0 )
3374 {
3375 zstring lLocalName = qname2->getLocalName();
3376
3377 if (lNamespace == ZORBA_OPTION_FEATURE_NS &&
3378 (lLocalName == "enable" || lLocalName == "disable"))
3379 {
3380 zstring lVal1 = value;
3381 zstring lVal2;
3382 bool lCommaFound = false;
3383 while (ztd::split(lVal1, ",", &lVal1, &lVal2))
3384 {
3385 process_feature_option(lVal1, lLocalName == "enable", loc);
3386 lCommaFound = true;
3387 }
3388 process_feature_option(lCommaFound ? lVal2 : lVal1,
3389 lLocalName == "enable",
3390 loc);
3391 }
3392 else if (qname2->getNamespace() == ZORBA_OPTION_OPTIM_NS &&
3393 (lLocalName == "enable" || lLocalName == "disable"))
3394 {
3395 zstring lVal1 = value;
3396 zstring lVal2;
3397 bool lCommaFound = false;
3398 while (ztd::split(lVal1, ",", &lVal1, &lVal2))
3399 {
3400 process_optim_option(lVal1, lLocalName == "enable", loc);
3401 lCommaFound = true;
3402 }
3403 process_optim_option(lCommaFound ? lVal2 : lVal1,
3404 lLocalName == "enable",
3405 loc);
3406 }
3407 else if (lNamespace == ZORBA_OPTION_WARN_NS &&
3408 (lLocalName == "enable" || lLocalName == "disable" || lLocalName == "error"))
3409 {
3410 zstring lVal1 = value;
3411 zstring lVal2;
3412 bool lCommaFound = false;
3413 while (ztd::split(lVal1, ",", &lVal1, &lVal2))
3414 {
3415 process_warning_option(lVal1, lLocalName, loc);
3416 lCommaFound = true;
3417 }
3418 process_warning_option(lCommaFound ? lVal2 : lVal1, lLocalName, loc);
3419 }
3420
3421 // process zorba-version option
3422 else if (qname2->getNamespace() == ZORBA_VERSIONING_NS &&
3423 ( lLocalName == ZORBA_OPTION_MODULE_VERSION ||
3424 lLocalName == ZORBA_OPTION_ZORBA_VERSION ) )
3425 {
3426 if ( qname2->getLocalName() == ZORBA_OPTION_ZORBA_VERSION )
3427 {
3428 // Re-use "ModuleVersion" class since it does 98% of the work for us;
3429 // just use a fake URI
3430 ModuleVersion lOptVersion(zstring(ZORBA_VERSIONING_NS) + "/corezorba", value);
3431 if (! lOptVersion.is_valid_version())
3432 {
3433 RAISE_ERROR(zerr::ZXQP0039_INVALID_VERSION_SPECIFICATION, loc,
3434 ERROR_PARAMS(value));
3435 }
3436
3437 ModuleVersion lZorbaVersion(zstring(ZORBA_VERSIONING_NS) + "/corezorba",
3438 ZORBA_VERSION);
3439
3440 if ( ! lZorbaVersion.satisfies(lOptVersion))
3441 {
3442 RAISE_ERROR(zerr::ZXQP0038_INAPPROPRIATE_ZORBA_VERSION, loc,
3443 ERROR_PARAMS(value, ZORBA_VERSION));
3444 }
3445 }
3446 }
3447
3448 // If the option is in (starts-with) Zorba's own namespace but not known,
3449 // we raise an error
3450 else
3451 {
3452 RAISE_ERROR(zerr::ZXQP0060_OPTION_NOT_KNOWN, loc,
3453 ERROR_PARAMS(qname2->getNamespace() + ":" + qname2->getLocalName()));
3454 }
3455 }
3456
3457 // in any case, we bind the option in the static context such that
3458 // external functions can also access them
3459 if (!theOptionMap->update(qname2, option))
3460 {
3461 theOptionMap->insert(qname2, option);
3462 }
3463
3464 }
3465
3466 store::Item_t
parse_and_expand_qname(const zstring & value,const char * default_ns,const QueryLoc & loc) const3467 static_context::parse_and_expand_qname(
3468 const zstring& value,
3469 const char* default_ns,
3470 const QueryLoc& loc) const
3471 {
3472 zstring lPrefix;
3473 zstring lLocalName;
3474
3475 zstring::size_type n = value.rfind(':');
3476
3477 if ( n == zstring::npos )
3478 {
3479 lLocalName = value;
3480 }
3481 else
3482 {
3483 lPrefix = value.substr( 0, n );
3484 lLocalName = value.substr( n+1 );
3485 }
3486 store::Item_t lQName;
3487 expand_qname( lQName, default_ns, lPrefix, lLocalName, loc );
3488
3489 return lQName;
3490 }
3491
3492
3493 /***************************************************************************//**
3494
3495 ********************************************************************************/
process_warning_option(const zstring & value,const zstring & name,const QueryLoc & loc)3496 void static_context::process_warning_option(
3497 const zstring& value,
3498 const zstring& name,
3499 const QueryLoc& loc)
3500 {
3501 store::Item_t lQName = parse_and_expand_qname( value, ZORBA_WARN_NS, loc );
3502
3503 std::vector<store::Item_t>::iterator lIter;
3504
3505 if ( name == "error" )
3506 {
3507 if ( lQName->getLocalName() == "all" )
3508 {
3509 theAllWarningsErrors = true;
3510 return;
3511 }
3512 for ( lIter = theWarningsAreErrors.begin();
3513 lIter != theWarningsAreErrors.end();
3514 ++lIter )
3515 {
3516 if ( lQName->equals( (*lIter) ) )
3517 {
3518 return;
3519 }
3520 }
3521 theWarningsAreErrors.push_back( lQName );
3522 }
3523 else if ( name == "disable" )
3524 {
3525 if ( lQName->getLocalName() == "all" )
3526 {
3527 theAllWarningsDisabled = true;
3528 return;
3529 }
3530 for ( lIter = theDisabledWarnings.begin();
3531 lIter != theDisabledWarnings.end();
3532 ++lIter )
3533 {
3534 if ( lQName->equals( (*lIter) ) )
3535 {
3536 return;
3537 }
3538 }
3539 theDisabledWarnings.push_back( lQName );
3540 }
3541 else if ( name == "enable" )
3542 {
3543 if ( lQName->getLocalName() == "all" )
3544 {
3545 theAllWarningsDisabled = false;
3546 return;
3547 }
3548 }
3549 }
3550
3551
3552 /***************************************************************************//**
3553
3554 ********************************************************************************/
process_feature_option(const zstring & value,bool enable,const QueryLoc & loc)3555 void static_context::process_feature_option(
3556 const zstring& value,
3557 bool enable,
3558 const QueryLoc& loc)
3559 {
3560 store::Item_t featureName = parse_and_expand_qname(value, ZORBA_FEATURES_NS, loc);
3561
3562 if (featureName->getNamespace() != ZORBA_FEATURES_NS)
3563 {
3564 RAISE_ERROR(zerr::ZDST0060_FEATURE_NOT_SUPPORTED, loc,
3565 ERROR_PARAMS(featureName->getStringValue(),
3566 ZED(ZDST0060_unknown_namespace),
3567 featureName->getNamespace()));
3568 }
3569
3570 feature::kind k;
3571 if (feature::kind_for(featureName->getLocalName().c_str(), k))
3572 {
3573 if (enable)
3574 set_feature(k);
3575 else
3576 unset_feature(k);
3577 }
3578 else
3579 {
3580 RAISE_ERROR(zerr::ZDST0060_FEATURE_NOT_SUPPORTED, loc,
3581 ERROR_PARAMS(featureName->getStringValue(),
3582 ZED(ZDST0060_unknown_localname),
3583 featureName->getLocalName()));
3584 }
3585 }
3586
3587
3588 /***************************************************************************//**
3589
3590 ********************************************************************************/
process_optim_option(const zstring & value,bool enable,const QueryLoc & loc)3591 void static_context::process_optim_option(
3592 const zstring& value,
3593 bool enable,
3594 const QueryLoc& loc)
3595 {
3596 if (value != "for-serialization-only")
3597 {
3598 RAISE_ERROR(zerr::ZDST0060_FEATURE_NOT_SUPPORTED, loc,
3599 ERROR_PARAMS(value, ZED(ZDST0060_unknown_localname), value));
3600 }
3601 }
3602
3603
3604 /***************************************************************************//**
3605
3606 ********************************************************************************/
lookup_option(const store::Item * qname,zstring & value) const3607 bool static_context::lookup_option(
3608 const store::Item* qname,
3609 zstring& value) const
3610 {
3611 store::Item* qname2 = const_cast<store::Item*>(qname);
3612 PrologOption option;
3613 const static_context* sctx = this;
3614 while (sctx != NULL)
3615 {
3616 if (sctx->theOptionMap && sctx->theOptionMap->get(qname2, option))
3617 {
3618 value = option.theValue;
3619 return true;
3620 }
3621 sctx = sctx->theParent;
3622 }
3623
3624 return false;
3625 }
3626
3627
3628 /////////////////////////////////////////////////////////////////////////////////
3629 // //
3630 // Auditing //
3631 // //
3632 /////////////////////////////////////////////////////////////////////////////////
3633
3634
3635 /***************************************************************************//**
3636
3637 ********************************************************************************/
set_audit_event(audit::Event * ae)3638 void static_context::set_audit_event(audit::Event* ae)
3639 {
3640 theAuditEvent = ae;
3641 }
3642
3643
3644 /***************************************************************************//**
3645
3646 ********************************************************************************/
get_audit_event() const3647 audit::Event* static_context::get_audit_event() const
3648 {
3649 const static_context* sctx = this;
3650 audit::Event* res = sctx->theAuditEvent;
3651 while (res == &zorba::audit::NOP_EVENT_IMPL && sctx != NULL)
3652 {
3653 sctx = sctx->theParent;
3654 if (sctx != NULL) {
3655 res = sctx->theAuditEvent;
3656 }
3657 }
3658 return res;
3659 }
3660
3661
3662 /////////////////////////////////////////////////////////////////////////////////
3663 // //
3664 // Miscellaneous //
3665 // //
3666 /////////////////////////////////////////////////////////////////////////////////
3667
3668
3669 /***************************************************************************//**
3670
3671 ********************************************************************************/
xquery_version() const3672 StaticContextConsts::xquery_version_t static_context::xquery_version() const
3673 {
3674 const static_context* sctx = this;
3675
3676 while (sctx != NULL)
3677 {
3678 if (sctx->theXQueryVersion != StaticContextConsts::xquery_version_unknown)
3679 return sctx->theXQueryVersion;
3680
3681 sctx = sctx->theParent;
3682 }
3683
3684 ZORBA_ASSERT(false);
3685 return StaticContextConsts::xquery_version_unknown;
3686 }
3687
3688
3689 /***************************************************************************//**
3690
3691 ********************************************************************************/
set_xquery_version(StaticContextConsts::xquery_version_t v)3692 void static_context::set_xquery_version(StaticContextConsts::xquery_version_t v)
3693 {
3694 theXQueryVersion = v;
3695 }
3696
3697
3698 /***************************************************************************//**
3699
3700 ********************************************************************************/
xpath_compatibility() const3701 StaticContextConsts::xpath_compatibility_t static_context::xpath_compatibility() const
3702 {
3703 const static_context* sctx = this;
3704
3705 while (sctx != NULL)
3706 {
3707 if (sctx->theXPathCompatibility != StaticContextConsts::xpath_unknown)
3708 return sctx->theXPathCompatibility;
3709
3710 sctx = sctx->theParent;
3711 }
3712
3713 ZORBA_ASSERT(false);
3714 return StaticContextConsts::xpath_unknown;
3715 }
3716
3717
3718 /***************************************************************************//**
3719
3720 ********************************************************************************/
set_xpath_compatibility(StaticContextConsts::xpath_compatibility_t v)3721 void static_context::set_xpath_compatibility(StaticContextConsts::xpath_compatibility_t v)
3722 {
3723 theXPathCompatibility = v;
3724 }
3725
3726
3727 /***************************************************************************//**
3728
3729 ********************************************************************************/
construction_mode() const3730 StaticContextConsts::construction_mode_t static_context::construction_mode() const
3731 {
3732 const static_context* sctx = this;
3733
3734 while (sctx != NULL)
3735 {
3736 if (sctx->theConstructionMode != StaticContextConsts::cons_unknown)
3737 return sctx->theConstructionMode;
3738
3739 sctx = sctx->theParent;
3740 }
3741
3742 ZORBA_ASSERT(false);
3743 return StaticContextConsts::cons_unknown;
3744 }
3745
3746
3747 /***************************************************************************//**
3748
3749 ********************************************************************************/
set_construction_mode(StaticContextConsts::construction_mode_t v)3750 void static_context::set_construction_mode(StaticContextConsts::construction_mode_t v)
3751 {
3752 theConstructionMode = v;
3753 }
3754
3755
3756 /***************************************************************************//**
3757
3758 ********************************************************************************/
inherit_ns() const3759 bool static_context::inherit_ns() const
3760 {
3761 return theInheritNamespaces;
3762 }
3763
3764
3765 /***************************************************************************//**
3766
3767 ********************************************************************************/
set_inherit_ns(bool v)3768 void static_context::set_inherit_ns(bool v)
3769 {
3770 theInheritNamespaces = v;
3771 }
3772
3773
3774 /***************************************************************************//**
3775
3776 ********************************************************************************/
preserve_ns() const3777 bool static_context::preserve_ns() const
3778 {
3779 return thePreserveNamespaces;
3780 }
3781
3782
3783 /***************************************************************************//**
3784
3785 ********************************************************************************/
set_preserve_ns(bool v)3786 void static_context::set_preserve_ns(bool v)
3787 {
3788 thePreserveNamespaces = v;
3789 }
3790
3791
3792 /***************************************************************************//**
3793
3794 ********************************************************************************/
ordering_mode() const3795 StaticContextConsts::ordering_mode_t static_context::ordering_mode() const
3796 {
3797 const static_context* sctx = this;
3798
3799 while (sctx != NULL)
3800 {
3801 if (sctx->theOrderingMode != StaticContextConsts::ordering_unknown)
3802 return sctx->theOrderingMode;
3803
3804 sctx = sctx->theParent;
3805 }
3806
3807 ZORBA_ASSERT(false);
3808 return StaticContextConsts::ordering_unknown;
3809 }
3810
3811
3812 /***************************************************************************//**
3813
3814 ********************************************************************************/
is_in_ordered_mode() const3815 bool static_context::is_in_ordered_mode() const
3816 {
3817 return ordering_mode() == StaticContextConsts::ordered;
3818 }
3819
3820
3821 /***************************************************************************//**
3822
3823 ********************************************************************************/
set_ordering_mode(StaticContextConsts::ordering_mode_t v)3824 void static_context::set_ordering_mode(StaticContextConsts::ordering_mode_t v)
3825 {
3826 theOrderingMode = v;
3827 }
3828
3829
3830 /***************************************************************************//**
3831
3832 ********************************************************************************/
empty_order_mode() const3833 StaticContextConsts::empty_order_mode_t static_context::empty_order_mode() const
3834 {
3835 const static_context* sctx = this;
3836
3837 while (sctx != NULL)
3838 {
3839 if (sctx->theEmptyOrderMode != StaticContextConsts::empty_order_unknown)
3840 return sctx->theEmptyOrderMode;
3841
3842 sctx = sctx->theParent;
3843 }
3844
3845 ZORBA_ASSERT(false);
3846 return StaticContextConsts::empty_order_unknown;
3847 }
3848
3849
3850 /***************************************************************************//**
3851
3852 ********************************************************************************/
set_empty_order_mode(StaticContextConsts::empty_order_mode_t v)3853 void static_context::set_empty_order_mode(StaticContextConsts::empty_order_mode_t v)
3854 {
3855 theEmptyOrderMode = v;
3856 }
3857
3858
3859 /***************************************************************************//**
3860
3861 ********************************************************************************/
boundary_space_mode() const3862 StaticContextConsts::boundary_space_mode_t static_context::boundary_space_mode() const
3863 {
3864 const static_context* sctx = this;
3865
3866 while (sctx != NULL)
3867 {
3868 if (sctx->theBoundarySpaceMode != StaticContextConsts::boundary_space_unknown)
3869 return sctx->theBoundarySpaceMode;
3870
3871 sctx = sctx->theParent;
3872 }
3873
3874 ZORBA_ASSERT(false);
3875 return StaticContextConsts::boundary_space_unknown;
3876 }
3877
3878
3879 /***************************************************************************//**
3880
3881 ********************************************************************************/
set_boundary_space_mode(StaticContextConsts::boundary_space_mode_t v)3882 void static_context::set_boundary_space_mode(StaticContextConsts::boundary_space_mode_t v)
3883 {
3884 theBoundarySpaceMode = v;
3885 }
3886
3887
3888 /***************************************************************************//**
3889
3890 ********************************************************************************/
validation_mode() const3891 StaticContextConsts::validation_mode_t static_context::validation_mode() const
3892 {
3893 const static_context* sctx = this;
3894
3895 while (sctx != NULL)
3896 {
3897 if (sctx->theValidationMode != StaticContextConsts::validation_unknown)
3898 return sctx->theValidationMode;
3899
3900 sctx = sctx->theParent;
3901 }
3902
3903 ZORBA_ASSERT(false);
3904 return StaticContextConsts::validation_unknown;
3905 }
3906
3907
3908 /***************************************************************************//**
3909
3910 ********************************************************************************/
set_validation_mode(StaticContextConsts::validation_mode_t v)3911 void static_context::set_validation_mode(StaticContextConsts::validation_mode_t v)
3912 {
3913 theValidationMode = v;
3914 }
3915
3916
3917 /***************************************************************************//**
3918
3919 ********************************************************************************/
add_decimal_format(const DecimalFormat_t & decimalFormat,const QueryLoc & loc)3920 void static_context::add_decimal_format(
3921 const DecimalFormat_t& decimalFormat,
3922 const QueryLoc& loc)
3923 {
3924 if (!theDecimalFormats.empty())
3925 {
3926 csize num = theDecimalFormats.size();
3927 for (csize i = 0; i < num; ++i)
3928 {
3929 const DecimalFormat_t& format = theDecimalFormats[i];
3930
3931 if (decimalFormat->isDefault() && format->isDefault())
3932 {
3933 RAISE_ERROR(err::XQST0111, loc,
3934 ERROR_PARAMS(ZED(TwoDefaultDecimalFormats)));
3935 }
3936
3937 if (!format->isDefault() &&
3938 !decimalFormat->isDefault() &&
3939 format->getName()->equals(decimalFormat->getName()))
3940 {
3941 RAISE_ERROR(err::XQST0111, loc,
3942 ERROR_PARAMS(ZED(TwoDecimalFormatsSameName_2),
3943 format->getName()->getStringValue()));
3944 }
3945 }
3946 }
3947
3948 theDecimalFormats.push_back(decimalFormat);
3949 }
3950
3951
3952 /***************************************************************************//**
3953
3954 ********************************************************************************/
get_decimal_format(const store::Item_t & qname)3955 DecimalFormat_t static_context::get_decimal_format(const store::Item_t& qname)
3956 {
3957 if (!theDecimalFormats.empty())
3958 {
3959 csize num = theDecimalFormats.size();
3960
3961 for (csize i = 0; i < num; ++i)
3962 {
3963 const DecimalFormat_t& format = theDecimalFormats[i];
3964
3965 if ((qname == NULL && format->isDefault()) ||
3966 (qname != NULL && !format->isDefault() && format->getName()->equals(qname)))
3967 {
3968 return format;
3969 }
3970 }
3971 }
3972
3973 return (theParent == NULL ? NULL : theParent->get_decimal_format(qname));
3974 }
3975
3976
3977 /////////////////////////////////////////////////////////////////////////////////
3978 // //
3979 // Warnings //
3980 // //
3981 /////////////////////////////////////////////////////////////////////////////////
3982
3983 /*******************************************************************************
3984
3985 ********************************************************************************/
disableWarning(store::Item_t qname)3986 void static_context::disableWarning(store::Item_t qname)
3987 {
3988 for (unsigned int i=0; i<theDisabledWarnings.size(); i++)
3989 if (qname->equals(theDisabledWarnings[i]))
3990 return;
3991
3992 theDisabledWarnings.push_back(qname);
3993 }
3994
3995 /*******************************************************************************
3996
3997 ********************************************************************************/
disableAllWarnings()3998 void static_context::disableAllWarnings()
3999 {
4000 theAllWarningsDisabled = true;
4001 }
4002
4003 /*******************************************************************************
4004
4005 ********************************************************************************/
setWarningAsError(store::Item_t qname)4006 void static_context::setWarningAsError(store::Item_t qname)
4007 {
4008 for (unsigned int i=0; i<theWarningsAreErrors.size(); i++)
4009 if (theWarningsAreErrors[i] )
4010 return;
4011
4012 theWarningsAreErrors.push_back(qname);
4013 }
4014
4015 /*******************************************************************************
4016
4017 ********************************************************************************/
isWarningDisabled(const char * ns,const char * localname)4018 bool static_context::isWarningDisabled(const char* ns, const char* localname)
4019 {
4020 for (unsigned int i=0; i<theDisabledWarnings.size(); i++)
4021 {
4022 if ( theDisabledWarnings[i]->getNamespace() == ns &&
4023 theDisabledWarnings[i]->getLocalName() == localname )
4024 return true;
4025 }
4026
4027 if (theAllWarningsDisabled)
4028 {
4029 return true;
4030 }
4031
4032 return (theParent == NULL ? false : theParent->isWarningDisabled(ns, localname));
4033 }
4034
4035 /*******************************************************************************
4036
4037 ********************************************************************************/
isWarningAnError(const char * ns,const char * localname)4038 bool static_context::isWarningAnError(const char* ns, const char* localname)
4039 {
4040 for (unsigned int i=0; i<theWarningsAreErrors.size(); i++)
4041 {
4042 if (theWarningsAreErrors[i]->getNamespace() == ns &&
4043 theWarningsAreErrors[i]->getLocalName() == localname)
4044 return true;
4045 }
4046 if ( theAllWarningsErrors )
4047 {
4048 return true;
4049 }
4050
4051 return (theParent == NULL ? false : theParent->isWarningAnError(ns, localname));
4052 }
4053
4054
4055 /////////////////////////////////////////////////////////////////////////////////
4056 // //
4057 // Module Import //
4058 // //
4059 /////////////////////////////////////////////////////////////////////////////////
4060
4061
4062 /***************************************************************************//**
4063 Merge the static context of a module with this static context. Only functions
4064 and variables defined in the module are included in this static context.
4065 ********************************************************************************/
import_module(const static_context * module,const QueryLoc & loc)4066 void static_context::import_module(const static_context* module, const QueryLoc& loc)
4067 {
4068 if (module->theVariablesMap)
4069 {
4070 if (theVariablesMap == NULL)
4071 {
4072 theVariablesMap = new VariableMap(HashMapItemPointerCmp(0, NULL),
4073 module->theVariablesMap->capacity(),
4074 false);
4075 }
4076
4077 VariableMap::iterator ite = module->theVariablesMap->begin();
4078 VariableMap::iterator end = module->theVariablesMap->end();
4079 for (; ite != end; ++ite)
4080 {
4081 var_expr* ve = (*ite).second->getVar();
4082
4083 if (!ve->is_private())
4084 {
4085 bind_var(ve, loc, err::XQST0049);
4086 }
4087 else
4088 {
4089 if (theImportedPrivateVariablesMap == NULL)
4090 {
4091 theImportedPrivateVariablesMap =
4092 new VariableMap(HashMapItemPointerCmp(0, NULL), 8, false);
4093 }
4094
4095 VarInfo_t vi = ve->get_var_info();
4096
4097 assert (vi != NULL);
4098
4099 if (!theImportedPrivateVariablesMap->insert(ve->get_name(), vi))
4100 {
4101 RAISE_ERROR(err::XQST0049, loc,
4102 ERROR_PARAMS(ve->get_name()->getStringValue()));
4103 }
4104 }
4105 }
4106 }
4107
4108 if (module->theFunctionMap)
4109 {
4110 if (theFunctionMap == NULL)
4111 {
4112 theFunctionMap = new FunctionMap(HashMapItemPointerCmp(0, NULL),
4113 (ulong)module->theFunctionMap->capacity(),
4114 false);
4115 }
4116
4117 FunctionMap::iterator ite = module->theFunctionMap->begin();
4118 FunctionMap::iterator end = module->theFunctionMap->end();
4119 for (; ite != end; ++ite)
4120 {
4121 function_t f = (*ite).second.theFunction;
4122 if (!f->isPrivate())
4123 bind_fn(f, f->getArity(), loc);
4124 }
4125 }
4126
4127 if (module->theFunctionArityMap)
4128 {
4129 if (theFunctionArityMap == NULL)
4130 {
4131 theFunctionArityMap =
4132 new FunctionArityMap(HashMapItemPointerCmp(0, NULL),
4133 (ulong)module->theFunctionArityMap->capacity(),
4134 false);
4135 }
4136
4137 FunctionArityMap::iterator ite = module->theFunctionArityMap->begin();
4138 FunctionArityMap::iterator end = module->theFunctionArityMap->end();
4139 for (; ite != end; ++ite)
4140 {
4141 std::vector<FunctionInfo>* fv = (*ite).second;
4142 csize num = fv->size();
4143 for (csize i = 0; i < num; ++i)
4144 {
4145 function_t f = (*fv)[i].theFunction;
4146 bind_fn(f, f->getArity(), loc);
4147 }
4148 }
4149 }
4150
4151 if (module->theCollectionMap)
4152 {
4153 if (theCollectionMap == 0)
4154 theCollectionMap = new CollectionMap(HashMapItemPointerCmp(0, 0), 8, false);
4155
4156 CollectionMap::iterator coll_iter = module->theCollectionMap->begin();
4157 CollectionMap::iterator coll_end = module->theCollectionMap->end();
4158 for (; coll_iter != coll_end; ++ coll_iter)
4159 {
4160 std::pair<store::Item*, StaticallyKnownCollection_t > pair = (*coll_iter);
4161
4162 if (!theCollectionMap->insert(pair.first, pair.second))
4163 {
4164 RAISE_ERROR(zerr::ZDST0002_COLLECTION_ALREADY_IMPORTED, loc,
4165 ERROR_PARAMS(pair.second->getName()->getStringValue(),
4166 module->get_module_namespace()));
4167 }
4168 }
4169 }
4170
4171 if (module->theIndexMap)
4172 {
4173 if (theIndexMap == NULL)
4174 theIndexMap = new IndexMap(HashMapItemPointerCmp(0, NULL), 8, false);
4175
4176 IndexMap::iterator idx_iter = module->theIndexMap->begin();
4177 IndexMap::iterator idx_end = module->theIndexMap->end();
4178 for (; idx_iter != idx_end; ++idx_iter)
4179 {
4180 std::pair<store::Item*, rchandle<IndexDecl> > pair = (*idx_iter);
4181
4182 if (lookup_index(pair.first) != NULL)
4183 {
4184 RAISE_ERROR(zerr::ZDST0022_INDEX_ALREADY_IMPORTED, loc,
4185 ERROR_PARAMS(pair.first->getStringValue(), module->get_module_namespace()));
4186 }
4187
4188 if (!theIndexMap->insert(pair.first, pair.second))
4189 {
4190 ZORBA_ASSERT(false);
4191 }
4192 }
4193 }
4194
4195 if (module->theICMap)
4196 {
4197 if (theICMap == NULL)
4198 {
4199 theICMap = new ICMap(HashMapItemPointerCmp(0, NULL), 8, false);
4200 }
4201
4202 ICMap::iterator ic_iter = module->theICMap->begin();
4203 ICMap::iterator ic_end = module->theICMap->end();
4204 for (; ic_iter != ic_end; ++ic_iter)
4205 {
4206 std::pair<store::Item*, rchandle<ValueIC> > pair = (*ic_iter);
4207
4208 if (!theICMap->insert(pair.first, pair.second))
4209 {
4210 RAISE_ERROR(zerr::ZDST0041_IC_ALREADY_DECLARED, loc,
4211 ERROR_PARAMS(pair.first->getStringValue()));
4212 }
4213 }
4214 }
4215 }
4216
4217 /***************************************************************************//**
4218
4219 ********************************************************************************/
clear_base_uri()4220 void static_context::clear_base_uri()
4221 {
4222 if (theBaseUriInfo)
4223 delete theBaseUriInfo;
4224
4225 theBaseUriInfo = new BaseUriInfo;
4226 }
4227
4228 } // namespace zorba
4229 /* vim:set et sw=2 ts=2: */
4230