]> granicus.if.org Git - icinga2/blob - lib/base/namespace.cpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / namespace.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "base/namespace.hpp"
4 #include "base/objectlock.hpp"
5 #include "base/debug.hpp"
6 #include "base/primitivetype.hpp"
7 #include "base/debuginfo.hpp"
8 #include "base/exception.hpp"
9 #include <sstream>
10
11 using namespace icinga;
12
13 template class std::map<icinga::String, std::shared_ptr<icinga::NamespaceValue> >;
14
15 REGISTER_PRIMITIVE_TYPE(Namespace, Object, Namespace::GetPrototype());
16
17 Namespace::Namespace(NamespaceBehavior *behavior)
18         : m_Behavior(std::unique_ptr<NamespaceBehavior>(behavior))
19 { }
20
21 Value Namespace::Get(const String& field) const
22 {
23         ObjectLock olock(this);
24
25         Value value;
26         if (!GetOwnField(field, &value))
27                 BOOST_THROW_EXCEPTION(ScriptError("Namespace does not contain field '" + field + "'"));
28         return value;
29 }
30
31 bool Namespace::Get(const String& field, Value *value) const
32 {
33         ObjectLock olock(this);
34
35         auto nsVal = GetAttribute(field);
36
37         if (!nsVal)
38                 return false;
39
40         *value =  nsVal->Get(DebugInfo());
41         return true;
42 }
43
44 void Namespace::Set(const String& field, const Value& value, bool overrideFrozen)
45 {
46         ObjectLock olock(this);
47
48         return SetFieldByName(field, value, overrideFrozen, DebugInfo());
49 }
50
51 bool Namespace::Contains(const String& field) const
52 {
53         ObjectLock olock(this);
54
55         return HasOwnField(field);
56 }
57
58 void Namespace::Remove(const String& field, bool overrideFrozen)
59 {
60         ObjectLock olock(this);
61
62         m_Behavior->Remove(this, field, overrideFrozen);
63 }
64
65 void Namespace::RemoveAttribute(const String& field)
66 {
67         ObjectLock olock(this);
68
69         Namespace::Iterator it;
70         it = m_Data.find(field);
71
72         if (it == m_Data.end())
73                 return;
74
75         m_Data.erase(it);
76 }
77
78 std::shared_ptr<NamespaceValue> Namespace::GetAttribute(const String& key) const
79 {
80         ObjectLock olock(this);
81
82         auto it = m_Data.find(key);
83
84         if (it == m_Data.end())
85                 return nullptr;
86
87         return it->second;
88 }
89
90 void Namespace::SetAttribute(const String& key, const std::shared_ptr<NamespaceValue>& nsVal)
91 {
92         ObjectLock olock(this);
93
94         m_Data[key] = nsVal;
95 }
96
97 Value Namespace::GetFieldByName(const String& field, bool, const DebugInfo& debugInfo) const
98 {
99         ObjectLock olock(this);
100
101         auto nsVal = GetAttribute(field);
102
103         if (nsVal)
104                 return nsVal->Get(debugInfo);
105         else
106                 return GetPrototypeField(const_cast<Namespace *>(this), field, false, debugInfo); /* Ignore indexer not found errors similar to the Dictionary class. */
107 }
108
109 void Namespace::SetFieldByName(const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
110 {
111         ObjectLock olock(this);
112
113         auto nsVal = GetAttribute(field);
114
115         if (!nsVal)
116                 m_Behavior->Register(this, field, value, overrideFrozen, debugInfo);
117         else
118                 nsVal->Set(value, overrideFrozen, debugInfo);
119 }
120
121 bool Namespace::HasOwnField(const String& field) const
122 {
123         ObjectLock olock(this);
124
125         return GetAttribute(field) != nullptr;
126 }
127
128 bool Namespace::GetOwnField(const String& field, Value *result) const
129 {
130         ObjectLock olock(this);
131
132         auto nsVal = GetAttribute(field);
133
134         if (!nsVal)
135                 return false;
136
137         *result = nsVal->Get(DebugInfo());
138         return true;
139 }
140
141 EmbeddedNamespaceValue::EmbeddedNamespaceValue(const Value& value)
142         : m_Value(value)
143 { }
144
145 Value EmbeddedNamespaceValue::Get(const DebugInfo& debugInfo) const
146 {
147         return m_Value;
148 }
149
150 void EmbeddedNamespaceValue::Set(const Value& value, bool, const DebugInfo&)
151 {
152         m_Value = value;
153 }
154
155 void ConstEmbeddedNamespaceValue::Set(const Value& value, bool overrideFrozen, const DebugInfo& debugInfo)
156 {
157         if (!overrideFrozen)
158                 BOOST_THROW_EXCEPTION(ScriptError("Constant must not be modified.", debugInfo));
159
160         EmbeddedNamespaceValue::Set(value, overrideFrozen, debugInfo);
161 }
162
163 void NamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const
164 {
165         ns->SetAttribute(field, std::make_shared<EmbeddedNamespaceValue>(value));
166 }
167
168 void NamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen)
169 {
170         if (!overrideFrozen) {
171                 auto attr = ns->GetAttribute(field);
172
173                 if (dynamic_pointer_cast<ConstEmbeddedNamespaceValue>(attr))
174                         BOOST_THROW_EXCEPTION(ScriptError("Constants must not be removed."));
175         }
176
177         ns->RemoveAttribute(field);
178 }
179
180 void ConstNamespaceBehavior::Register(const Namespace::Ptr& ns, const String& field, const Value& value, bool overrideFrozen, const DebugInfo& debugInfo) const
181 {
182         if (m_Frozen && !overrideFrozen)
183                 BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified.", debugInfo));
184
185         ns->SetAttribute(field, std::make_shared<ConstEmbeddedNamespaceValue>(value));
186 }
187
188 void ConstNamespaceBehavior::Remove(const Namespace::Ptr& ns, const String& field, bool overrideFrozen)
189 {
190         if (m_Frozen && !overrideFrozen)
191                 BOOST_THROW_EXCEPTION(ScriptError("Namespace is read-only and must not be modified."));
192
193         NamespaceBehavior::Remove(ns, field, overrideFrozen);
194 }
195
196 void ConstNamespaceBehavior::Freeze()
197 {
198         m_Frozen = true;
199 }
200
201 Namespace::Iterator Namespace::Begin()
202 {
203         ASSERT(OwnsLock());
204
205         return m_Data.begin();
206 }
207
208 Namespace::Iterator Namespace::End()
209 {
210         ASSERT(OwnsLock());
211
212         return m_Data.end();
213 }
214
215 Namespace::Iterator icinga::begin(const Namespace::Ptr& x)
216 {
217         return x->Begin();
218 }
219
220 Namespace::Iterator icinga::end(const Namespace::Ptr& x)
221 {
222         return x->End();
223 }
224