From bde5535f84ee56f7e9007238708b96965187e920 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Tue, 4 Aug 2015 14:47:44 +0200 Subject: [PATCH] Implement modified attribute methods for DynamicObject refs #9081 refs #9093 --- lib/base/CMakeLists.txt | 14 +++++++++----- lib/base/dynamicobject.cpp | 35 ++++++++++++++++++++++++++++++++++- lib/base/dynamicobject.hpp | 5 +++++ lib/base/dynamicobject.ti | 1 + lib/base/type.hpp | 14 ++++++++++++++ 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 900d3535be7..37a510e856f 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -23,11 +23,15 @@ mkclass_target(streamlogger.ti streamlogger.tcpp streamlogger.thpp) mkclass_target(sysloglogger.ti sysloglogger.tcpp sysloglogger.thpp) set(base_SOURCES - application.cpp application.thpp application-version.cpp array.cpp array-script.cpp boolean.cpp boolean-script.cpp console.cpp context.cpp - convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp - exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp json-script.cpp loader.cpp logger.cpp logger.thpp math-script.cpp - netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp object-script.cpp primitivetype.cpp process.cpp - ringbuffer.cpp scriptframe.cpp function.cpp function-script.cpp functionwrapper.cpp scriptglobal.cpp + application.cpp application.thpp application-version.cpp array.cpp + array-script.cpp boolean.cpp boolean-script.cpp console.cpp context.cpp + convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp + dynamicobject.cpp dynamicobject.thpp dynamicobject-script.cpp dynamictype.cpp + exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp + json-script.cpp loader.cpp logger.cpp logger.thpp math-script.cpp + netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp + object-script.cpp primitivetype.cpp process.cpp ringbuffer.cpp scriptframe.cpp + function.cpp function-script.cpp functionwrapper.cpp scriptglobal.cpp scriptutils.cpp serializer.cpp socket.cpp socketevents.cpp stacktrace.cpp statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp string-script.cpp sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index 6c500628866..ef82d2166ec 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -41,7 +41,7 @@ using namespace icinga; -REGISTER_TYPE(DynamicObject); +REGISTER_TYPE_WITH_PROTOTYPE(DynamicObject, DynamicObject::GetPrototype()); boost::signals2::signal DynamicObject::OnStarted; boost::signals2::signal DynamicObject::OnStopped; @@ -99,6 +99,39 @@ void DynamicObject::ClearExtension(const String& key) extensions->Remove(key); } +void DynamicObject::ModifyAttribute(const String& attr, const Value& value) +{ + Dictionary::Ptr original_attributes = GetOriginalAttributes(); + + if (!original_attributes) { + original_attributes = new Dictionary(); + SetOriginalAttributes(original_attributes); + } + + int field = GetReflectionType()->GetFieldId(attr); + + Value attrVal = GetField(field); + + if (!original_attributes->Contains(attr)) + original_attributes->Set(attr, attrVal); + + SetField(field, value); + //TODO: validation, vars.os +} + +void DynamicObject::RestoreAttribute(const String& attr) +{ + Dictionary::Ptr original_attributes = GetOriginalAttributes(); + + if (!original_attributes || !original_attributes->Contains(attr)) + return; + + Value attrVal = original_attributes->Get(attr); + + SetField(GetReflectionType()->GetFieldId(attr), attrVal); + original_attributes->Remove(attr); +} + void DynamicObject::Register(void) { ASSERT(!OwnsLock()); diff --git a/lib/base/dynamicobject.hpp b/lib/base/dynamicobject.hpp index 881bd525d05..f5182a97ae2 100644 --- a/lib/base/dynamicobject.hpp +++ b/lib/base/dynamicobject.hpp @@ -57,6 +57,9 @@ class I2_BASE_API DynamicObject : public ObjectImpl Value GetExtension(const String& key); void ClearExtension(const String& key); + void ModifyAttribute(const String& attr, const Value& value); + void RestoreAttribute(const String& attr); + void Register(void); void Activate(void); @@ -86,6 +89,8 @@ class I2_BASE_API DynamicObject : public ObjectImpl static void RestoreObjects(const String& filename, int attributeTypes = FAState); static void StopObjects(void); + static Object::Ptr GetPrototype(void); + protected: explicit DynamicObject(void); diff --git a/lib/base/dynamicobject.ti b/lib/base/dynamicobject.ti index 4351c90cabb..2d503b78b0c 100644 --- a/lib/base/dynamicobject.ti +++ b/lib/base/dynamicobject.ti @@ -83,6 +83,7 @@ abstract class DynamicObject : DynamicObjectBase [protected] Dictionary::Ptr extensions; [protected] bool state_loaded; + Dictionary::Ptr original_attributes; }; } diff --git a/lib/base/type.hpp b/lib/base/type.hpp index b825b440d6e..c722057b9ca 100644 --- a/lib/base/type.hpp +++ b/lib/base/type.hpp @@ -137,6 +137,20 @@ class TypeImpl } } \ DEFINE_TYPE_INSTANCE(type) +#define REGISTER_TYPE_WITH_PROTOTYPE(type, prototype) \ + namespace { namespace UNIQUE_NAME(rt) { \ + void RegisterType ## type(void) \ + { \ + icinga::Type::Ptr t = new TypeImpl(); \ + t->SetPrototype(prototype); \ + type::TypeInstance = t; \ + icinga::Type::Register(t); \ + } \ + \ + INITIALIZE_ONCE_WITH_PRIORITY(RegisterType ## type, 10); \ + } } \ + DEFINE_TYPE_INSTANCE(type) + #define DEFINE_TYPE_INSTANCE(type) \ Type::Ptr type::TypeInstance