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