1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "base/type.hpp"
4 #include "base/scriptglobal.hpp"
5 #include "base/namespace.hpp"
6 #include "base/objectlock.hpp"
8 using namespace icinga;
10 Type::Ptr Type::TypeInstance;
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;
20 String Type::ToString() const
22 return "type '" + GetName() + "'";
25 void Type::Register(const Type::Ptr& type)
27 ScriptGlobal::Set("Types." + type->GetName(), type, true);
30 Type::Ptr Type::GetByName(const String& name)
32 Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
38 if (!typesNS->Get(name, &ptype))
41 if (!ptype.IsObjectType<Type>())
47 std::vector<Type::Ptr> Type::GetAllTypes()
49 std::vector<Type::Ptr> types;
51 Namespace::Ptr typesNS = ScriptGlobal::Get("Types", &Empty);
54 ObjectLock olock(typesNS);
56 for (const Namespace::Pair& kv : typesNS) {
57 Value value = kv.second->Get();
59 if (value.IsObjectType<Type>())
60 types.push_back(value);
67 String Type::GetPluralName() const
69 String name = GetName();
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";
78 Object::Ptr Type::Instantiate(const std::vector<Value>& args) const
80 ObjectFactory factory = GetFactory();
83 BOOST_THROW_EXCEPTION(std::runtime_error("Type does not have a factory function."));
88 bool Type::IsAbstract() const
90 return ((GetAttributes() & TAAbstract) != 0);
93 bool Type::IsAssignableFrom(const Type::Ptr& other) const
95 for (Type::Ptr t = other; t; t = t->GetBaseType()) {
103 Object::Ptr Type::GetPrototype() const
108 void Type::SetPrototype(const Object::Ptr& object)
110 m_Prototype = object;
113 void Type::SetField(int id, const Value& value, bool suppress_events, const Value& cookie)
120 Object::SetField(id, value, suppress_events, cookie);
123 Value Type::GetField(int id) const
125 int real_id = id - Object::TypeInstance->GetFieldCount();
127 return Object::GetField(id);
131 else if (real_id == 1)
132 return GetPrototype();
133 else if (real_id == 2)
134 return GetBaseType();
136 BOOST_THROW_EXCEPTION(std::runtime_error("Invalid field ID."));
139 std::vector<String> Type::GetLoadDependencies() const
141 return std::vector<String>();
144 int Type::GetActivationPriority() const
149 void Type::RegisterAttributeHandler(int fieldId, const AttributeHandler& callback)
151 throw std::runtime_error("Invalid field ID.");
154 String TypeType::GetName() const
159 Type::Ptr TypeType::GetBaseType() const
161 return Object::TypeInstance;
164 int TypeType::GetAttributes() const
169 int TypeType::GetFieldId(const String& name) const
171 int base_field_count = GetBaseType()->GetFieldCount();
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;
180 return GetBaseType()->GetFieldId(name);
183 Field TypeType::GetFieldInfo(int id) const
185 int real_id = id - GetBaseType()->GetFieldCount();
187 return GetBaseType()->GetFieldInfo(id);
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);
196 throw std::runtime_error("Invalid field ID.");
199 int TypeType::GetFieldCount() const
201 return GetBaseType()->GetFieldCount() + 3;
204 ObjectFactory TypeType::GetFactory() const