]> granicus.if.org Git - icinga2/blob - lib/base/type.cpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / type.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "base/type.hpp"
4 #include "base/scriptglobal.hpp"
5 #include "base/namespace.hpp"
6 #include "base/objectlock.hpp"
7
8 using namespace icinga;
9
10 Type::Ptr Type::TypeInstance;
11
12 /* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
13 INITIALIZE_ONCE_WITH_PRIORITY([]() {
14         Type::Ptr type = new TypeType();
15         type->SetPrototype(TypeType::GetPrototype());
16         Type::TypeInstance = type;
17         Type::Register(type);
18 }, 20);
19
20 String Type::ToString() const
21 {
22         return "type '" + GetName() + "'";
23 }
24
25 void Type::Register(const Type::Ptr& type)
26 {
27         ScriptGlobal::Set("Types." + type->GetName(), type, true);
28 }
29
30 Type::Ptr Type::GetByName(const String& name)
31 {
32         Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
33
34         if (!typesNS)
35                 return nullptr;
36
37         Value ptype;
38         if (!typesNS->Get(name, &ptype))
39                 return nullptr;
40
41         if (!ptype.IsObjectType<Type>())
42                 return nullptr;
43
44         return ptype;
45 }
46
47 std::vector<Type::Ptr> Type::GetAllTypes()
48 {
49         std::vector<Type::Ptr> types;
50
51         Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
52
53         if (typesNS) {
54                 ObjectLock olock(typesNS);
55
56                 for (const Namespace::Pair& kv : typesNS) {
57                         Value value = kv.second->Get();
58
59                         if (value.IsObjectType<Type>())
60                                 types.push_back(value);
61                 }
62         }
63
64         return types;
65 }
66
67 String Type::GetPluralName() const
68 {
69         String name = GetName();
70
71         if (name.GetLength() >= 2 && name[name.GetLength() - 1] == 'y' &&
72                 name.SubStr(name.GetLength() - 2, 1).FindFirstOf("aeiou") == String::NPos)
73                 return name.SubStr(0, name.GetLength() - 1) + "ies";
74         else
75                 return name + "s";
76 }
77
78 Object::Ptr Type::Instantiate(const std::vector<Value>& args) const
79 {
80         ObjectFactory factory = GetFactory();
81
82         if (!factory)
83                 BOOST_THROW_EXCEPTION(std::runtime_error("Type does not have a factory function."));
84
85         return factory(args);
86 }
87
88 bool Type::IsAbstract() const
89 {
90         return ((GetAttributes() & TAAbstract) != 0);
91 }
92
93 bool Type::IsAssignableFrom(const Type::Ptr& other) const
94 {
95         for (Type::Ptr t = other; t; t = t->GetBaseType()) {
96                 if (t.get() == this)
97                         return true;
98         }
99
100         return false;
101 }
102
103 Object::Ptr Type::GetPrototype() const
104 {
105         return m_Prototype;
106 }
107
108 void Type::SetPrototype(const Object::Ptr& object)
109 {
110         m_Prototype = object;
111 }
112
113 void Type::SetField(int id, const Value& value, bool suppress_events, const Value& cookie)
114 {
115         if (id == 1) {
116                 SetPrototype(value);
117                 return;
118         }
119
120         Object::SetField(id, value, suppress_events, cookie);
121 }
122
123 Value Type::GetField(int id) const
124 {
125         int real_id = id - Object::TypeInstance->GetFieldCount();
126         if (real_id < 0)
127                 return Object::GetField(id);
128
129         if (real_id == 0)
130                 return GetName();
131         else if (real_id == 1)
132                 return GetPrototype();
133         else if (real_id == 2)
134                 return GetBaseType();
135
136         BOOST_THROW_EXCEPTION(std::runtime_error("Invalid field ID."));
137 }
138
139 std::vector<String> Type::GetLoadDependencies() const
140 {
141         return std::vector<String>();
142 }
143
144 int Type::GetActivationPriority() const
145 {
146         return 0;
147 }
148
149 void Type::RegisterAttributeHandler(int fieldId, const AttributeHandler& callback)
150 {
151         throw std::runtime_error("Invalid field ID.");
152 }
153
154 String TypeType::GetName() const
155 {
156         return "Type";
157 }
158
159 Type::Ptr TypeType::GetBaseType() const
160 {
161         return Object::TypeInstance;
162 }
163
164 int TypeType::GetAttributes() const
165 {
166         return 0;
167 }
168
169 int TypeType::GetFieldId(const String& name) const
170 {
171         int base_field_count = GetBaseType()->GetFieldCount();
172
173         if (name == "name")
174                 return base_field_count + 0;
175         else if (name == "prototype")
176                 return base_field_count + 1;
177         else if (name == "base")
178                 return base_field_count + 2;
179
180         return GetBaseType()->GetFieldId(name);
181 }
182
183 Field TypeType::GetFieldInfo(int id) const
184 {
185         int real_id = id - GetBaseType()->GetFieldCount();
186         if (real_id < 0)
187                 return GetBaseType()->GetFieldInfo(id);
188
189         if (real_id == 0)
190                 return {0, "String", "name", "", nullptr, 0, 0};
191         else if (real_id == 1)
192                 return Field(1, "Object", "prototype", "", nullptr, 0, 0);
193         else if (real_id == 2)
194                 return Field(2, "Type", "base", "", nullptr, 0, 0);
195
196         throw std::runtime_error("Invalid field ID.");
197 }
198
199 int TypeType::GetFieldCount() const
200 {
201         return GetBaseType()->GetFieldCount() + 3;
202 }
203
204 ObjectFactory TypeType::GetFactory() const
205 {
206         return nullptr;
207 }
208