return;
}
- CheckResult::Ptr cr = Deserialize(params->Get("check_result"));
+ CheckResult::Ptr cr = Deserialize(params->Get("check_result"), true);
if (!cr)
return;
return;
}
- Comment::Ptr comment = Deserialize(params->Get("comment"));
+ Comment::Ptr comment = Deserialize(params->Get("comment"), true);
service->AddComment(comment->GetEntryType(), comment->GetAuthor(),
comment->GetText(), comment->GetExpireTime(), comment->GetId(), sender->GetName());
return;
}
- Downtime::Ptr downtime = Deserialize(params->Get("downtime"));
+ Downtime::Ptr downtime = Deserialize(params->Get("downtime"), true);
service->AddDowntime(downtime->GetAuthor(), downtime->GetComment(),
downtime->GetStartTime(), downtime->GetEndTime(),
#ifdef _DEBUG
Log(LogDebug, "base", "Restoring object '" + name + "' of type '" + type + "'.");
#endif /* _DEBUG */
- Deserialize(object, update, attributeTypes);
+ Deserialize(object, update, false, attributeTypes);
object->OnStateLoaded();
}
Object::Ptr object = type->Instantiate();
- Deserialize(object, serializedUpdate, FAConfig);
+ Deserialize(object, serializedUpdate, false, FAConfig);
return static_pointer_cast<DynamicObject>(object);
}
return fields;
}
-static Array::Ptr DeserializeArray(const Array::Ptr& input, int attributeTypes)
+static Array::Ptr DeserializeArray(const Array::Ptr& input, bool safe_mode, int attributeTypes)
{
Array::Ptr result = make_shared<Array>();
ObjectLock olock(input);
BOOST_FOREACH(const Value& value, input) {
- result->Add(Deserialize(value, attributeTypes));
+ result->Add(Deserialize(value, safe_mode, attributeTypes));
}
return result;
}
-static Dictionary::Ptr DeserializeDictionary(const Dictionary::Ptr& input, int attributeTypes)
+static Dictionary::Ptr DeserializeDictionary(const Dictionary::Ptr& input, bool safe_mode, int attributeTypes)
{
Dictionary::Ptr result = make_shared<Dictionary>();
return result;
}
-static Object::Ptr DeserializeObject(const Object::Ptr& object, const Dictionary::Ptr& input, int attributeTypes)
+static Object::Ptr DeserializeObject(const Object::Ptr& object, const Dictionary::Ptr& input, bool safe_mode, int attributeTypes)
{
const Type *type;
Object::Ptr instance = object;
- if (!instance)
+ if (!instance) {
+ if (safe_mode && !type->IsSafe())
+ BOOST_THROW_EXCEPTION(std::runtime_error("Tried to instantiate type '" + type->GetName() + "' which is not marked as safe."));
+
instance = type->Instantiate();
+ }
BOOST_FOREACH(const Dictionary::Pair& kv, input) {
if (kv.first.IsEmpty())
continue;
try {
- instance->SetField(fid, Deserialize(kv.second, attributeTypes));
+ instance->SetField(fid, Deserialize(kv.second, safe_mode, attributeTypes));
} catch (const std::exception&) {
instance->SetField(fid, Empty);
}
return SerializeObject(input, attributeTypes);
}
-Value icinga::Deserialize(const Value& value, int attributeTypes)
+Value icinga::Deserialize(const Value& value, bool safe_mode, int attributeTypes)
{
- return Deserialize(Object::Ptr(), value, attributeTypes);
+ return Deserialize(Object::Ptr(), value, safe_mode, attributeTypes);
}
-Value icinga::Deserialize(const Object::Ptr& object, const Value& value, int attributeTypes)
+Value icinga::Deserialize(const Object::Ptr& object, const Value& value, bool safe_mode, int attributeTypes)
{
if (!value.IsObject())
return value;
Array::Ptr array = dynamic_pointer_cast<Array>(input);
if (array != NULL)
- return DeserializeArray(array, attributeTypes);
+ return DeserializeArray(array, safe_mode, attributeTypes);
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(input);
ASSERT(dict != NULL);
if (!dict->Contains("__type"))
- return DeserializeDictionary(dict, attributeTypes);
+ return DeserializeDictionary(dict, safe_mode, attributeTypes);
- return DeserializeObject(object, dict, attributeTypes);
+ return DeserializeObject(object, dict, safe_mode, attributeTypes);
}
I2_BASE_API Value JsonDeserialize(const String& data);
I2_BASE_API Value Serialize(const Value& value, int attributeTypes = FAState);
-I2_BASE_API Value Deserialize(const Value& value, int attributeTypes = FAState);
-I2_BASE_API Value Deserialize(const Object::Ptr& object, const Value& value, int attributeTypes = FAState);
+I2_BASE_API Value Deserialize(const Value& value, bool safe_mode = false, int attributeTypes = FAState);
+I2_BASE_API Value Deserialize(const Object::Ptr& object, const Value& value, bool safe_mode = false, int attributeTypes = FAState);
}
return m_Factory();
}
+bool Type::IsAbstract(void) const
+{
+ return GetAttributes() & TAAbstract;
+}
+
+bool Type::IsSafe(void) const
+{
+ return GetAttributes() & TASafe;
+}
+
bool Type::IsAssignableFrom(const Type *other) const
{
for (const Type *t = other; t; t = t->GetBaseType()) {
{ }
};
+enum TypeAttribute
+{
+ TAAbstract = 1,
+ TASafe = 2
+};
+
class I2_BASE_API Type
{
public:
virtual String GetName(void) const = 0;
virtual const Type *GetBaseType(void) const = 0;
- virtual bool IsAbstract(void) const = 0;
+ virtual int GetAttributes(void) const = 0;
virtual int GetFieldId(const String& name) const = 0;
virtual Field GetFieldInfo(int id) const = 0;
virtual int GetFieldCount(void) const = 0;
bool IsAssignableFrom(const Type *other) const;
+ bool IsAbstract(void) const;
+ bool IsSafe(void) const;
+
static void Register(const Type *type);
static const Type *GetByName(const String& name);
};
}}}
-class CheckResult
+safe class CheckResult
{
[state] double schedule_start;
[state] double schedule_end;
};
}}}
-class Comment
+safe class Comment
{
[state] String id;
[state] double entry_time;
namespace icinga
{
-class Downtime
+safe class Downtime
{
[state] String id;
[state] double entry_time;
class { return T_CLASS; }
namespace { return T_NAMESPACE; }
code { return T_CODE; }
-abstract { return T_ABSTRACT; }
+abstract { yylval->num = TAAbstract; return T_CLASS_ATTRIBUTE; }
+safe { yylval->num = TASafe; return T_CLASS_ATTRIBUTE; }
config { yylval->num = FAConfig; return T_FIELD_ATTRIBUTE; }
state { yylval->num = FAState; return T_FIELD_ATTRIBUTE; }
enum { yylval->num = FAEnum; return T_FIELD_ATTRIBUTE; }
%token T_INCLUDE "include (T_INCLUDE)"
%token T_CLASS "class (T_CLASS)"
%token T_CODE "code (T_CODE)"
-%token T_ABSTRACT "abstract (T_ABSTRACT)"
%token T_NAMESPACE "namespace (T_NAMESPACE)"
%token T_STRING "string (T_STRING)"
%token T_ANGLE_STRING "angle_string (T_ANGLE_STRING)"
%token T_FIELD_ATTRIBUTE "field_attribute (T_FIELD_ATTRIBUTE)"
+%token T_CLASS_ATTRIBUTE "class_attribute (T_CLASS_ATTRIBUTE)"
%token T_IDENTIFIER "identifier (T_IDENTIFIER)"
%token T_GET "get (T_GET)"
%token T_SET "set (T_SET)"
%type <num> field_attributes
%type <num> field_attribute_list
%type <num> T_FIELD_ACCESSOR_TYPE
-%type <num> abstract_specifier
+%type <num> T_CLASS_ATTRIBUTE
+%type <num> class_attribute_list
%type <field> class_field
%type <fields> class_fields
%type <klass> class
}
;
-class: abstract_specifier T_CLASS T_IDENTIFIER inherits_specifier '{' class_fields '}' ';'
+class: class_attribute_list T_CLASS T_IDENTIFIER inherits_specifier '{' class_fields '}' ';'
{
$$ = new Klass();
free($4);
}
- $$->Abstract = $1;
+ $$->Attributes = $1;
$$->Fields = *$6;
delete $6;
}
;
-abstract_specifier: /* empty */
+class_attribute_list: /* empty */
{
- $$ = false;
+ $$ = 0;
}
- | T_ABSTRACT
+ | T_CLASS_ATTRIBUTE
{
- $$ = true;
+ $$ = $1;
+ }
+ | class_attribute_list T_CLASS_ATTRIBUTE
+ {
+ $$ = $1 | $2;
}
- ;
inherits_specifier: /* empty */
{
<< "\t\t" << "return \"" << klass.Name << "\";" << std::endl
<< "\t" << "}" << std::endl << std::endl;
- /* IsAbstract */
- std::cout << "\t" << "virtual bool IsAbstract(void) const" << std::endl
+ /* GetAttributes */
+ std::cout << "\t" << "virtual int GetAttributes(void) const" << std::endl
<< "\t" << "{" << std::endl
- << "\t\t" << "return " << (klass.Abstract ? "true" : "false") << ";" << std::endl
+ << "\t\t" << "return " << klass.Attributes << ";" << std::endl
<< "\t" << "}" << std::endl << std::endl;
/* GetBaseType */
std::cout << "};" << std::endl << std::endl;
/* FactoryHelper */
- if (klass.Abstract) {
+ if (klass.Attributes & TAAbstract) {
std::cout << "template<>" << std::endl
<< "struct FactoryHelper<" << klass.Name << ">" << std::endl
<< "{" << std::endl
}
};
+enum TypeAttribute
+{
+ TAAbstract = 1,
+ TASafe = 2
+};
+
struct Klass
{
std::string Name;
std::string Parent;
- bool Abstract;
+ int Attributes;
std::vector<Field> Fields;
};