1 /*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "stdafx.h"
17
18 #include "context/namespace_context.h"
19 #include "context/static_context.h"
20
21 #include "compiler/parser/query_loc.h"
22
23
24 #include "zorbaserialization/serialize_template_types.h"
25 #include "zorbaserialization/serialize_zorba_types.h"
26
27
28 namespace zorba
29 {
30
SERIALIZABLE_CLASS_VERSIONS(namespace_context)31 SERIALIZABLE_CLASS_VERSIONS(namespace_context)
32
33
34
35 /*******************************************************************************
36
37 ********************************************************************************/
38 namespace_context::namespace_context(
39 const static_context* sctx,
40 store::NsBindings& bindings)
41 :
42 m_sctx(const_cast<static_context*>(sctx))
43 {
44 for (csize i = 0; i < bindings.size(); ++i)
45 {
46 bind_ns(bindings[i].first, bindings[i].second);
47 }
48 }
49
50
51 /*******************************************************************************
52
53 ********************************************************************************/
serialize(::zorba::serialization::Archiver & ar)54 void namespace_context::serialize(::zorba::serialization::Archiver& ar)
55 {
56 ar & m_sctx;
57 ar & m_parent;
58 ar & m_bindings;
59 }
60
61
62 /*******************************************************************************
63
64 ********************************************************************************/
bind_ns(const zstring & prefix,const zstring & ns)65 void namespace_context::bind_ns(
66 const zstring& prefix,
67 const zstring& ns)
68 {
69 m_bindings.push_back(std::pair<zstring, zstring>(prefix, ns));
70 }
71
72
73 /*******************************************************************************
74
75 ********************************************************************************/
findBinding(const zstring & aPrefix,zstring & aNamespace)76 bool namespace_context::findBinding(
77 const zstring& aPrefix,
78 zstring& aNamespace)
79 {
80 store::NsBindings::const_iterator lIter = m_bindings.begin();
81 store::NsBindings::const_iterator lEnd = m_bindings.end();
82 for (; lIter != lEnd ; ++lIter)
83 {
84 if ((*lIter).first == aPrefix)
85 {
86 if ((*lIter).second.empty())
87 {
88 // namespace is undeclared
89 //aNamespace.clear();
90 return false;
91 }
92 aNamespace = (*lIter).second;
93 return true;
94 }
95 }
96
97 if (m_parent != 0)
98 {
99 return m_parent->findBinding(aPrefix, aNamespace);
100 }
101 else
102 {
103 QueryLoc loc;
104 bool found = m_sctx->lookup_ns(aNamespace, aPrefix, loc, zerr::ZXQP0000_NO_ERROR);
105
106 if (!found && aPrefix.empty())
107 {
108 aNamespace = m_sctx->default_elem_type_ns();
109
110 if (!aNamespace.empty())
111 found = true;
112 }
113
114 return found;
115 }
116 }
117
118
119 /*******************************************************************************
120 Collect all the in-scope bindings into the given vector
121 ********************************************************************************/
getAllBindings(store::NsBindings & bindings) const122 void namespace_context::getAllBindings(store::NsBindings& bindings) const
123 {
124 bindings = m_bindings;
125
126 const namespace_context* parentContext = m_parent;
127
128 while (parentContext)
129 {
130 const store::NsBindings& parentBindings = parentContext->m_bindings;
131 ulong parentSize = (ulong)parentBindings.size();
132 ulong currSize = (ulong)bindings.size();
133
134 // for each parent binding, add it to the result, if it doesn't have the
135 // same prefix as another binding that is already in the result.
136 for (ulong i = 0; i < parentSize; ++i)
137 {
138 ulong j;
139 for (j = 0; j < currSize; ++j)
140 {
141 if (bindings[j].first == parentBindings[i].first)
142 break;
143 }
144
145 if (j == currSize)
146 {
147 bindings.push_back(parentBindings[i]);
148 }
149 }
150
151 parentContext = parentContext->m_parent;
152 }
153 }
154
155
156 }
157 /* vim:set et sw=2 ts=2: */
158