]> granicus.if.org Git - icinga2/commitdiff
Improve config compiler's memory usage
authorGunnar Beutner <gunnar@beutner.name>
Thu, 6 Nov 2014 18:35:47 +0000 (19:35 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Sat, 8 Nov 2014 12:21:51 +0000 (13:21 +0100)
33 files changed:
lib/base/dynamicobject.hpp
lib/base/dynamicobject.ti
lib/base/dynamictype.cpp
lib/base/dynamictype.hpp
lib/base/value.hpp
lib/cli/daemoncommand.cpp
lib/config/applyrule.cpp
lib/config/applyrule.hpp
lib/config/configcompilercontext.cpp
lib/config/configcompilercontext.hpp
lib/config/configitem.cpp
lib/config/configitem.hpp
lib/config/configitembuilder.cpp
lib/config/configitembuilder.hpp
lib/config/expression.cpp
lib/config/expression.hpp
lib/config/objectrule.cpp
lib/config/objectrule.hpp
lib/config/typerule.cpp
lib/icinga/command.cpp
lib/icinga/dependency-apply.cpp
lib/icinga/dependency.cpp
lib/icinga/dependency.ti
lib/icinga/notification-apply.cpp
lib/icinga/notification.cpp
lib/icinga/notification.ti
lib/icinga/scheduleddowntime-apply.cpp
lib/icinga/scheduleddowntime.cpp
lib/icinga/scheduleddowntime.ti
lib/icinga/service-apply.cpp
lib/icinga/service.cpp
lib/icinga/service.ti
tools/mkclass/classcompiler.cpp

index 31e76414692d28278ab2d9f751583170f0099f9b..9b355bf4c46d94af3b7a6d7ec283215d8c0b21e3 100644 (file)
@@ -101,7 +101,7 @@ private:
        DebugInfo m_DebugInfo;
 };
 
-#define DECLARE_OBJECTNAME(klass)                                              \
+#define DECLARE_OBJECTNAME(klass)                                      \
        inline static String GetTypeName(void)                          \
        {                                                               \
                return #klass;                                          \
index c92870d70f29ef40eb94b8b7b880e43108b4a2ee..55aad82487d3de9f437356084e0c3b17eceba645 100644 (file)
@@ -29,12 +29,14 @@ enum HAMode
 
 class NameComposer {
 public:
-       virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const = 0;
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const = 0;
 };
 }}}
 
 abstract class DynamicObject
 {
+       [protected] Object::Ptr __parent (ParentScope);
+
        [config, internal] String __name (Name);
        [config] String name (ShortName) {
                get {{{
index 024c59136cae33d3e70a74f582fd12754b62b064..a3449ce4f12e873b1102cc5935892a80fda0e0e8 100644 (file)
@@ -123,19 +123,6 @@ DynamicObject::Ptr DynamicType::GetObject(const String& name) const
        return nt->second;
 }
 
-DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate)
-{
-       ASSERT(!OwnsLock());
-
-       Type::Ptr type = Type::GetByName(m_Name);
-
-       Object::Ptr object = type->Instantiate();
-
-       Deserialize(object, serializedUpdate, true, FAConfig);
-
-       return static_pointer_cast<DynamicObject>(object);
-}
-
 boost::mutex& DynamicType::GetStaticMutex(void)
 {
        static boost::mutex mutex;
index fd5271f59a640eaae2f62f0fb7ad71dbd8ff8dff..6bac3d059e2076cf153496ad9234241e693f85ac 100644 (file)
@@ -44,7 +44,6 @@ public:
 
        static DynamicType::Ptr GetByName(const String& name);
 
-       DynamicObject::Ptr CreateObject(const Dictionary::Ptr& serializedUpdate);
        DynamicObject::Ptr GetObject(const String& name) const;
 
        void RegisterObject(const DynamicObject::Ptr& object);
index 6aa28eef46eed6ed631d0ec5e91c14a3575acdab..3326421dc578c5a06190f1f0721a7be2bdc4cc71 100644 (file)
@@ -97,6 +97,9 @@ public:
                if (IsEmpty())
                        return shared_ptr<T>();
 
+               if (!IsObject())
+                       BOOST_THROW_EXCEPTION(std::runtime_error("Cannot convert value to object."));
+
                Object::Ptr object = boost::get<Object::Ptr>(m_Value);
 
                ASSERT(object);
index ca4074d8b8475c7cb64d1b2ea7a2f586b6612e29..4dd8c856a263fe99ebc0e2c0c840122e09ea17eb 100644 (file)
@@ -81,6 +81,9 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
 {
        ConfigCompilerContext::GetInstance()->Reset();
 
+       if (!objectsFile.IsEmpty())
+               ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
+
        if (vm.count("config") > 0) {
                BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
                        ConfigCompiler::CompileFile(configPath);
@@ -109,7 +112,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
        ConfigItem::Ptr item = builder->Compile();
        item->Register();
 
-       bool result = ConfigItem::ValidateItems(objectsFile);
+       bool result = ConfigItem::ValidateItems();
 
        int warnings = 0, errors = 0;
 
@@ -149,6 +152,8 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
        if (!result)
                return false;
 
+       ConfigCompilerContext::GetInstance()->FinishObjectsFile();
+
        ScriptVariable::WriteVariablesFile(varsfile);
 
        return true;
index a8f24f720d980bffb3a40be8d92e35cb7a6c13cd..8509fd00d67176161952a83a78f710ea55f387d5 100644 (file)
@@ -29,7 +29,7 @@ ApplyRule::CallbackMap ApplyRule::m_Callbacks;
 
 ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
     const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm,
-    const DebugInfo& di, const Dictionary::Ptr& scope)
+    const DebugInfo& di, const Object::Ptr& scope)
        : m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar),
          m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope)
 { }
@@ -74,19 +74,19 @@ DebugInfo ApplyRule::GetDebugInfo(void) const
        return m_DebugInfo;
 }
 
-Dictionary::Ptr ApplyRule::GetScope(void) const
+Object::Ptr ApplyRule::GetScope(void) const
 {
        return m_Scope;
 }
 
 void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
     const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fkvar,
-    const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
+    const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope)
 {
        m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope));
 }
 
-bool ApplyRule::EvaluateFilter(const Dictionary::Ptr& scope) const
+bool ApplyRule::EvaluateFilter(const Object::Ptr& scope) const
 {
        return m_Filter->Evaluate(scope);
 }
index 1a5375fabad54c4c14776731bb932e8b98bd5746..4682bfe0f91d11a851405760b629ae479db667ac 100644 (file)
@@ -46,12 +46,12 @@ public:
        String GetFVVar(void) const;
        Expression::Ptr GetFTerm(void) const;
        DebugInfo GetDebugInfo(void) const;
-       Dictionary::Ptr GetScope(void) const;
+       Object::Ptr GetScope(void) const;
 
-       bool EvaluateFilter(const Dictionary::Ptr& scope) const;
+       bool EvaluateFilter(const Object::Ptr& scope) const;
 
        static void AddRule(const String& sourceType, const String& targetType, const String& name, const Expression::Ptr& expression,
-           const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
+           const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm, const DebugInfo& di, const Object::Ptr& scope);
        static void EvaluateRules(bool clear);
 
        static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
@@ -68,14 +68,14 @@ private:
        String m_FVVar;
        Expression::Ptr m_FTerm;
        DebugInfo m_DebugInfo;
-       Dictionary::Ptr m_Scope;
+       Object::Ptr m_Scope;
 
        static CallbackMap m_Callbacks;
        static RuleMap m_Rules;
 
        ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
            const Expression::Ptr& filter, const String& fkvar, const String& fvvar, const Expression::Ptr& fterm,
-           const DebugInfo& di, const Dictionary::Ptr& scope);
+           const DebugInfo& di, const Object::Ptr& scope);
 };
 
 }
index b20684e6b90358638443b85c26736f366628173b..e5b95ce2573ead79a20d0757267bce53e9a03a77 100644 (file)
 
 #include "config/configcompilercontext.hpp"
 #include "base/singleton.hpp"
+#include "base/json.hpp"
+#include "base/netstring.hpp"
 #include <boost/foreach.hpp>
+#include <fstream>
 
 using namespace icinga;
 
@@ -61,3 +64,50 @@ ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
        return Singleton<ConfigCompilerContext>::GetInstance();
 }
 
+void ConfigCompilerContext::OpenObjectsFile(const String& filename)
+{
+       m_ObjectsPath = filename;
+
+       String tempFilename = m_ObjectsPath + ".tmp";
+
+       std::fstream *fp = new std::fstream();
+       fp->open(tempFilename.CStr(), std::ios_base::out);
+
+       if (!*fp)
+               BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));
+
+       m_ObjectsFP = make_shared<StdioStream>(fp, true);
+}
+
+void ConfigCompilerContext::WriteObject(const Dictionary::Ptr& object)
+{
+       if (!m_ObjectsFP)
+               return;
+
+       String json = JsonEncode(object);
+
+       {
+               boost::mutex::scoped_lock lock(m_Mutex);
+               NetString::WriteStringToStream(m_ObjectsFP, json);
+       }
+}
+
+void ConfigCompilerContext::FinishObjectsFile(void)
+{
+       m_ObjectsFP->Close();
+
+       String tempFilename = m_ObjectsPath + ".tmp";
+
+#ifdef _WIN32
+       _unlink(m_ObjectsPath.CStr());
+#endif /* _WIN32 */
+
+       if (rename(tempFilename.CStr(), m_ObjectsPath.CStr()) < 0) {
+               BOOST_THROW_EXCEPTION(posix_error()
+                   << boost::errinfo_api_function("rename")
+                   << boost::errinfo_errno(errno)
+                   << boost::errinfo_file_name(tempFilename));
+        }
+
+}
+
index 2a3401e0cbdc296bb08f3dd2fec2e8eebf69d89a..84091ba2f8301947f8704a5b677a9ac32e9b51e5 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "config/i2-config.hpp"
 #include "base/debuginfo.hpp"
+#include "base/stdiostream.hpp"
+#include "base/dictionary.hpp"
 #include <boost/thread/mutex.hpp>
 #include <vector>
 
@@ -51,10 +53,16 @@ public:
 
        void Reset(void);
 
+       void OpenObjectsFile(const String& filename);
+       void WriteObject(const Dictionary::Ptr& object);
+       void FinishObjectsFile(void);
+
        static ConfigCompilerContext *GetInstance(void);
 
 private:
        std::vector<ConfigCompilerMessage> m_Messages;
+       String m_ObjectsPath;
+       StdioStream::Ptr m_ObjectsFP;
 
        mutable boost::mutex m_Mutex;
 };
index 8dbde2dcc2a636c1fcb27133405f7f71c25a9154..8199e029fae37cb5ce9a0e61764d66ed55fb0a2e 100644 (file)
@@ -32,6 +32,7 @@
 #include "base/exception.hpp"
 #include "base/stdiostream.hpp"
 #include "base/netstring.hpp"
+#include "base/serializer.hpp"
 #include "base/json.hpp"
 #include "base/configerror.hpp"
 #include <sstream>
@@ -55,9 +56,9 @@ ConfigItem::ItemMap ConfigItem::m_Items;
  */
 ConfigItem::ConfigItem(const String& type, const String& name,
     bool abstract, const Expression::Ptr& exprl,
-    const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
+    const DebugInfo& debuginfo, const Object::Ptr& scope,
     const String& zone)
-       : m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
+       : m_Type(type), m_Name(name), m_Abstract(abstract),
          m_ExpressionList(exprl), m_DebugInfo(debuginfo),
          m_Scope(scope), m_Zone(zone)
 {
@@ -103,7 +104,7 @@ DebugInfo ConfigItem::GetDebugInfo(void) const
        return m_DebugInfo;
 }
 
-Dictionary::Ptr ConfigItem::GetScope(void) const
+Object::Ptr ConfigItem::GetScope(void) const
 {
        return m_Scope;
 }
@@ -118,62 +119,13 @@ Expression::Ptr ConfigItem::GetExpressionList(void) const
        return m_ExpressionList;
 }
 
-Dictionary::Ptr ConfigItem::GetProperties(void)
-{
-       ASSERT(!OwnsLock());
-       VERIFY(!IsAbstract());
-
-       ObjectLock olock(this);
-
-       if (!m_Properties) {
-               Dictionary::Ptr locals = make_shared<Dictionary>();
-               locals->Set("__parent", m_Scope);
-               locals->Set("name", m_Name);
-
-               m_Properties = make_shared<Dictionary>();
-               m_Properties->Set("type", m_Type);
-               if (!m_Zone.IsEmpty())
-                       m_Properties->Set("zone", m_Zone);
-               m_Properties->Set("__parent", locals);
-               GetExpressionList()->Evaluate(m_Properties, &m_DebugHints);
-               m_Properties->Remove("__parent");
-
-               String name = m_Name;
-
-               if (!m_Abstract) {
-                       shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(Type::GetByName(m_Type));
-
-                       if (nc) {
-                               name = nc->MakeName(m_Name, m_Properties);
-
-                               if (name.IsEmpty())
-                                       BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object"));
-                       }
-               }
-
-               if (name != m_Name)
-                       m_Properties->Set("name", m_Name);
-
-               m_Properties->Set("__name", name);
-
-               VERIFY(m_Properties->Get("type") == GetType());
-       }
-
-       return m_Properties;
-}
-
-const DebugHint& ConfigItem::GetDebugHints(void) const
-{
-       return m_DebugHints;
-}
-
 /**
  * Commits the configuration item by creating a DynamicObject
  * object.
  *
  * @returns The DynamicObject that was created/updated.
  */
-DynamicObject::Ptr ConfigItem::Commit(void)
+DynamicObject::Ptr ConfigItem::Commit(bool discard)
 {
        ASSERT(!OwnsLock());
 
@@ -183,16 +135,88 @@ DynamicObject::Ptr ConfigItem::Commit(void)
 #endif /* _DEBUG */
 
        /* Make sure the type is valid. */
-       DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
+       Type::Ptr type = Type::GetByName(GetType());
 
-       if (!dtype)
-               BOOST_THROW_EXCEPTION(std::runtime_error("Type '" + GetType() + "' does not exist."));
+       if (!type || !Type::GetByName("DynamicObject")->IsAssignableFrom(type))
+               BOOST_THROW_EXCEPTION(ConfigError("Type '" + GetType() + "' does not exist."));
 
        if (IsAbstract())
                return DynamicObject::Ptr();
 
-       DynamicObject::Ptr dobj = dtype->CreateObject(GetProperties());
+       DynamicObject::Ptr dobj = static_pointer_cast<DynamicObject>(type->Instantiate());
+
        dobj->SetDebugInfo(m_DebugInfo);
+       dobj->SetTypeName(m_Type);
+       dobj->SetZone(m_Zone);
+
+       Dictionary::Ptr locals = make_shared<Dictionary>();
+       locals->Set("__parent", m_Scope);
+       m_Scope.reset();
+       locals->Set("name", m_Name);
+
+       dobj->SetParentScope(locals);
+
+       DebugHint debugHints;
+
+       try {
+               m_ExpressionList->Evaluate(dobj, &debugHints);
+       } catch (const ConfigError& ex) {
+               const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
+               ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
+       } catch (const std::exception& ex) {
+               ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
+       }
+
+       if (discard)
+               m_ExpressionList.reset();
+
+       dobj->SetParentScope(Dictionary::Ptr());
+
+       String name = m_Name;
+
+       shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(type);
+
+       if (nc) {
+               name = nc->MakeName(m_Name, dobj);
+
+               if (name.IsEmpty())
+                       BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object"));
+       }
+
+       if (name != m_Name)
+               dobj->SetShortName(m_Name);
+
+       dobj->SetName(name);
+
+       Dictionary::Ptr attrs = Serialize(dobj, FAConfig);
+
+       Dictionary::Ptr persistentItem = make_shared<Dictionary>();
+
+       persistentItem->Set("type", GetType());
+       persistentItem->Set("name", GetName());
+       persistentItem->Set("properties", attrs);
+       persistentItem->Set("debug_hints", debugHints.ToDictionary());
+
+       ConfigCompilerContext::GetInstance()->WriteObject(persistentItem);
+
+       ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
+
+       if (!ctype)
+               ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
+       else {
+               TypeRuleUtilities utils;
+
+               try {
+                       attrs->Remove("name");
+                       ctype->ValidateItem(GetName(), attrs, GetDebugInfo(), &utils);
+               } catch (const ConfigError& ex) {
+                       const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
+                       ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
+               } catch (const std::exception& ex) {
+                       ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
+               }
+       }
+
        dobj->Register();
 
        m_Object = dobj;
@@ -207,20 +231,11 @@ void ConfigItem::Register(void)
 {
        String name = m_Name;
 
-       /* If this is a non-abstract object we need to figure out
-        * its real name now - or assign it a temporary name. */
-       if (!m_Abstract) {
-               shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(Type::GetByName(m_Type));
+       shared_ptr<NameComposer> nc = dynamic_pointer_cast<NameComposer>(Type::GetByName(m_Type));
 
-               if (nc) {
-                       name = nc->MakeName(m_Name, Dictionary::Ptr());
-
-                       ASSERT(name.IsEmpty() || name == m_Name);
-
-                       if (name.IsEmpty())
-                               name = Utility::NewUniqueID();
-               }
-       }
+       /* If this is a non-abstract object with a composite name we don't register it. */
+       if (!m_Abstract && nc)
+               return;
 
        std::pair<String, String> key = std::make_pair(m_Type, name);
        ConfigItem::Ptr self = GetSelf();
@@ -254,104 +269,17 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
        return ConfigItem::Ptr();
 }
 
-void ConfigItem::ValidateItem(void)
-{
-       if (m_Validated || IsAbstract())
-               return;
-
-       ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
-
-       if (!ctype) {
-               ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
-
-               return;
-       }
-
-       TypeRuleUtilities utils;
-       
-       try {
-               ctype->ValidateItem(GetName(), GetProperties(), GetDebugInfo(), &utils);
-       } catch (const ConfigError& ex) {
-               const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
-               ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
-       } catch (const std::exception& ex) {
-               ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
-       }
-
-       m_Validated = true;
-}
-
-void ConfigItem::WriteObjectsFile(const String& filename)
-{
-       Log(LogInformation, "ConfigItem")
-           << "Dumping config items to file '" << filename << "'";
-
-       String tempFilename = filename + ".tmp";
-
-       std::fstream fp;
-       fp.open(tempFilename.CStr(), std::ios_base::out);
-
-       if (!fp)
-               BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));
-
-       StdioStream::Ptr sfp = make_shared<StdioStream>(&fp, false);
-
-       BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
-               ConfigItem::Ptr item = kv.second;
-
-               if (item->IsAbstract())
-                       continue;
-
-               Dictionary::Ptr persistentItem = make_shared<Dictionary>();
-
-               persistentItem->Set("type", item->GetType());
-               persistentItem->Set("name", item->GetName());
-               persistentItem->Set("properties", item->GetProperties());
-               persistentItem->Set("debug_hints", item->GetDebugHints().ToDictionary());
-
-               String json = JsonEncode(persistentItem);
-
-               NetString::WriteStringToStream(sfp, json);
-       }
-
-       sfp->Close();
-
-       fp.close();
-
-#ifdef _WIN32
-       _unlink(filename.CStr());
-#endif /* _WIN32 */
-
-       if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
-               BOOST_THROW_EXCEPTION(posix_error()
-                   << boost::errinfo_api_function("rename")
-                   << boost::errinfo_errno(errno)
-                   << boost::errinfo_file_name(tempFilename));
-       }
-}
-
-bool ConfigItem::ValidateItems(const String& objectsFile)
+bool ConfigItem::ValidateItems(void)
 {
        if (ConfigCompilerContext::GetInstance()->HasErrors())
                return false;
 
        ParallelWorkQueue upq;
 
-       Log(LogInformation, "ConfigItem", "Validating config items (step 1)...");
-
-       BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
-               upq.Enqueue(boost::bind(&ConfigItem::ValidateItem, kv.second));
-       }
-
-       upq.Join();
-
-       if (ConfigCompilerContext::GetInstance()->HasErrors())
-               return false;
-
        Log(LogInformation, "ConfigItem", "Committing config items");
 
        BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
-               upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second));
+               upq.Enqueue(boost::bind(&ConfigItem::Commit, kv.second, false));
        }
 
        upq.Join();
@@ -381,17 +309,8 @@ bool ConfigItem::ValidateItems(const String& objectsFile)
        Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 2)...");
        ObjectRule::EvaluateRules(true);
 
-       Log(LogInformation, "ConfigItem", "Validating config items (step 2)...");
-
-       BOOST_FOREACH(const ItemMap::value_type& kv, m_Items) {
-               upq.Enqueue(boost::bind(&ConfigItem::ValidateItem, kv.second));
-       }
-
        upq.Join();
 
-       if (!objectsFile.IsEmpty())
-               ConfigItem::WriteObjectsFile(objectsFile);
-
        ConfigItem::DiscardItems();
        ConfigType::DiscardTypes();
 
index a267b79d6464d3354a3c4ac6ea47240d844ca9c9..2c5e5ab2752a027bfe514c8e9f296ab68cf694e5 100644 (file)
@@ -39,7 +39,7 @@ public:
 
        ConfigItem(const String& type, const String& name, bool abstract,
            const Expression::Ptr& exprl, const DebugInfo& debuginfo,
-           const Dictionary::Ptr& scope, const String& zone);
+           const Object::Ptr& scope, const String& zone);
 
        String GetType(void) const;
        String GetName(void) const;
@@ -48,42 +48,33 @@ public:
        std::vector<ConfigItem::Ptr> GetParents(void) const;
 
        Expression::Ptr GetExpressionList(void) const;
-       Dictionary::Ptr GetProperties(void);
-       const DebugHint& GetDebugHints(void) const;
 
-       DynamicObject::Ptr Commit(void);
+       DynamicObject::Ptr Commit(bool discard = true);
        void Register(void);
 
        DebugInfo GetDebugInfo(void) const;
 
-       Dictionary::Ptr GetScope(void) const;
+       Object::Ptr GetScope(void) const;
 
        String GetZone(void) const;
 
        static ConfigItem::Ptr GetObject(const String& type,
            const String& name);
 
-       void ValidateItem(void);
-
-       static bool ValidateItems(const String& objectsFile = String());
+       static bool ValidateItems(void);
        static bool ActivateItems(void);
        static void DiscardItems(void);
 
-       static void WriteObjectsFile(const String& filename);
-
 private:
        String m_Type; /**< The object type. */
        String m_Name; /**< The name. */
        bool m_Abstract; /**< Whether this is a template. */
-       bool m_Validated; /** Whether this object has been validated. */
 
        Expression::Ptr m_ExpressionList;
-       Dictionary::Ptr m_Properties;
-       DebugHint m_DebugHints;
        std::vector<String> m_ParentNames; /**< The names of parent configuration
                                       items. */
        DebugInfo m_DebugInfo; /**< Debug information. */
-       Dictionary::Ptr m_Scope; /**< variable scope. */
+       Object::Ptr m_Scope; /**< variable scope. */
        String m_Zone; /**< The zone. */
 
        DynamicObject::Ptr m_Object;
index 16dab119446a672299c1c8927b5706ac6f066727..c843c9cb6893e00a4aceeef551da97774f059aa0 100644 (file)
@@ -54,7 +54,7 @@ void ConfigItemBuilder::SetAbstract(bool abstract)
        m_Abstract = abstract;
 }
 
-void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
+void ConfigItemBuilder::SetScope(const Object::Ptr& scope)
 {
        m_Scope = scope;
 }
index 30b16f0c901adfc9bbcaa235745ca52770997e7f..923ce138ffcf9089164c3f63f66a37b7be4d3713 100644 (file)
@@ -45,7 +45,7 @@ public:
        void SetType(const String& type);
        void SetName(const String& name);
        void SetAbstract(bool abstract);
-       void SetScope(const Dictionary::Ptr& scope);
+       void SetScope(const Object::Ptr& scope);
        void SetZone(const String& zone);
 
        void AddExpression(const Expression::Ptr& expr);
@@ -58,7 +58,7 @@ private:
        bool m_Abstract; /**< Whether the item is abstract. */
        Array::Ptr m_Expressions; /**< Expressions for this item. */
        DebugInfo m_DebugInfo; /**< Debug information. */
-       Dictionary::Ptr m_Scope; /**< variable scope. */
+       Object::Ptr m_Scope; /**< variable scope. */
        String m_Zone; /**< The zone. */
 };
 
index 01f26bf3595576a5883cff17586e3ee6887f1666..dab19f251d5362497826dc781b3f85cfb366b9a8 100644 (file)
@@ -33,6 +33,7 @@
 #include "base/configerror.hpp"
 #include <boost/foreach.hpp>
 #include <boost/exception_ptr.hpp>
+#include <boost/lexical_cast.hpp>
 #include <boost/exception/errinfo_nested_exception.hpp>
 
 using namespace icinga;
@@ -45,7 +46,7 @@ Expression::Expression(OpCallback op, const Value& operand1, const Value& operan
        : m_Operator(op), m_Operand1(operand1), m_Operand2(operand2), m_DebugInfo(di)
 { }
 
-Value Expression::Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint) const
+Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const
 {
        try {
 #ifdef _DEBUG
@@ -57,7 +58,7 @@ Value Expression::Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint) cons
                }
 #endif /* _DEBUG */
 
-               return m_Operator(this, locals, dhint);
+               return m_Operator(this, context, dhint);
        } catch (const std::exception& ex) {
                if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
                        throw;
@@ -99,125 +100,125 @@ void Expression::Dump(std::ostream& stream, int indent) const
        DumpOperand(stream, m_Operand2, indent + 1);
 }
 
-Value Expression::EvaluateOperand1(const Dictionary::Ptr& locals, DebugHint *dhint) const
+Value Expression::EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint) const
 {
-       return static_cast<Expression::Ptr>(m_Operand1)->Evaluate(locals, dhint);
+       return static_cast<Expression::Ptr>(m_Operand1)->Evaluate(context, dhint);
 }
 
-Value Expression::EvaluateOperand2(const Dictionary::Ptr& locals, DebugHint *dhint) const
+Value Expression::EvaluateOperand2(const Object::Ptr& context, DebugHint *dhint) const
 {
-       return static_cast<Expression::Ptr>(m_Operand2)->Evaluate(locals, dhint);
+       return static_cast<Expression::Ptr>(m_Operand2)->Evaluate(context, dhint);
 }
 
-Value Expression::OpLiteral(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
        return expr->m_Operand1;
 }
 
-Value Expression::OpVariable(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       Dictionary::Ptr scope = locals;
+       Object::Ptr scope = context;
 
        while (scope) {
-               if (scope->Contains(expr->m_Operand1))
-                       return scope->Get(expr->m_Operand1);
+               if (HasField(scope, expr->m_Operand1))
+                       return GetField(scope, expr->m_Operand1);
 
-               scope = scope->Get("__parent");
+               scope = GetField(scope, "__parent");
        }
 
        return ScriptVariable::Get(expr->m_Operand1);
 }
 
-Value Expression::OpNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return ~(long)expr->EvaluateOperand1(locals);
+       return ~(long)expr->EvaluateOperand1(context);
 }
 
-Value Expression::OpLogicalNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return !expr->EvaluateOperand1(locals).ToBool();
+       return !expr->EvaluateOperand1(context).ToBool();
 }
 
-Value Expression::OpAdd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) + expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) + expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpSubtract(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) - expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) - expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpMultiply(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) * expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) * expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpDivide(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) / expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) / expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpBinaryAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) & expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) & expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpBinaryOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) | expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) | expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpShiftLeft(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) << expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) << expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpShiftRight(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) >> expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) >> expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) == expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) == expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpNotEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) != expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) != expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpLessThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) < expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) < expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpGreaterThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) > expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) > expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpLessThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) <= expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) <= expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpGreaterThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals) >= expr->EvaluateOperand2(locals);
+       return expr->EvaluateOperand1(context) >= expr->EvaluateOperand2(context);
 }
 
-Value Expression::OpIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       Value right = expr->EvaluateOperand2(locals);
+       Value right = expr->EvaluateOperand2(context);
 
        if (right.IsEmpty())
                return false;
        else if (!right.IsObjectType<Array>())
                BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right)));
 
-       Value left = expr->EvaluateOperand1(locals);
+       Value left = expr->EvaluateOperand1(context);
                
        Array::Ptr arr = right;
        bool found = false;
@@ -232,24 +233,24 @@ Value Expression::OpIn(const Expression *expr, const Dictionary::Ptr& locals, De
        return found;
 }
 
-Value Expression::OpNotIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return !OpIn(expr, locals, dhint);
+       return !OpIn(expr, context, dhint);
 }
 
-Value Expression::OpLogicalAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals).ToBool() && expr->EvaluateOperand2(locals).ToBool();
+       return expr->EvaluateOperand1(context).ToBool() && expr->EvaluateOperand2(context).ToBool();
 }
 
-Value Expression::OpLogicalOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       return expr->EvaluateOperand1(locals).ToBool() || expr->EvaluateOperand2(locals).ToBool();
+       return expr->EvaluateOperand1(context).ToBool() || expr->EvaluateOperand2(context).ToBool();
 }
 
-Value Expression::OpFunctionCall(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       Value funcName = expr->EvaluateOperand1(locals);
+       Value funcName = expr->EvaluateOperand1(context);
 
        ScriptFunction::Ptr func;
 
@@ -261,17 +262,17 @@ Value Expression::OpFunctionCall(const Expression *expr, const Dictionary::Ptr&
        if (!func)
                BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
 
-       Array::Ptr arr = expr->EvaluateOperand2(locals);
+       Array::Ptr arr = expr->EvaluateOperand2(context);
        std::vector<Value> arguments;
        for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
                const Expression::Ptr& aexpr = arr->Get(index);
-               arguments.push_back(aexpr->Evaluate(locals));
+               arguments.push_back(aexpr->Evaluate(context));
        }
 
        return func->Invoke(arguments);
 }
 
-Value Expression::OpArray(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr arr = expr->m_Operand1;
        Array::Ptr result = make_shared<Array>();
@@ -279,28 +280,28 @@ Value Expression::OpArray(const Expression *expr, const Dictionary::Ptr& locals,
        if (arr) {
                for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
                        const Expression::Ptr& aexpr = arr->Get(index);
-                       result->Add(aexpr->Evaluate(locals));
+                       result->Add(aexpr->Evaluate(context));
                }
        }
 
        return result;
 }
 
-Value Expression::OpDict(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr arr = expr->m_Operand1;
        bool in_place = expr->m_Operand2;
        Dictionary::Ptr result = make_shared<Dictionary>();
 
-       result->Set("__parent", locals);
+       result->Set("__parent", context);
 
        if (arr) {
                for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
                        const Expression::Ptr& aexpr = arr->Get(index);
-                       Dictionary::Ptr alocals = in_place ? locals : result;
-                       aexpr->Evaluate(alocals, dhint);
+                       Object::Ptr acontext = in_place ? context : result;
+                       aexpr->Evaluate(acontext, dhint);
 
-                       if (alocals->Contains("__result"))
+                       if (HasField(acontext, "__result"))
                                break;
                }
        }
@@ -310,7 +311,7 @@ Value Expression::OpDict(const Expression *expr, const Dictionary::Ptr& locals,
        return xresult;
 }
 
-Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr left = expr->m_Operand1;
        Array::Ptr indexer = left->Get(0);
@@ -323,14 +324,14 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
 
        for (Array::SizeType i = 0; i < indexer->GetLength(); i++) {
                Expression::Ptr indexExpr = indexer->Get(i);
-               String tempindex = indexExpr->Evaluate(locals, dhint);
+               String tempindex = indexExpr->Evaluate(context, dhint);
 
                if (i == indexer->GetLength() - 1)
                        index = tempindex;
 
                if (i == 0) {
-                       parent = locals;
-                       object = locals->Get(tempindex);
+                       parent = context;
+                       object = GetField(context, tempindex);
                } else {
                        parent = object;
 
@@ -338,7 +339,7 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
                        Expression::Ptr eindex = make_shared<Expression>(&Expression::OpLiteral, tempindex, expr->m_DebugInfo);
 
                        Expression::Ptr eip = make_shared<Expression>(&Expression::OpIndexer, eparent, eindex, expr->m_DebugInfo);
-                       object = eip->Evaluate(locals, dhint);
+                       object = eip->Evaluate(context, dhint);
                }
 
                if (sdhint)
@@ -347,12 +348,11 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
                if (i != indexer->GetLength() - 1 && object.IsEmpty()) {
                        object = make_shared<Dictionary>();
 
-                       Dictionary::Ptr pdict = parent;
-                       pdict->Set(tempindex, object);
+                       SetField(parent, tempindex, object);
                }
        }
 
-       Value right = expr->EvaluateOperand2(locals, dhint);
+       Value right = expr->EvaluateOperand2(context, dhint);
 
        if (csop != OpSetLiteral) {
                Expression::OpCallback op;
@@ -379,11 +379,10 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
                    make_shared<Expression>(&Expression::OpLiteral, right, expr->m_DebugInfo),
                    expr->m_DebugInfo);
 
-               right = ecp->Evaluate(locals, dhint);
+               right = ecp->Evaluate(context, dhint);
        }
 
-       Dictionary::Ptr pdict = parent;
-       pdict->Set(index, right);
+       SetField(parent, index, right);
 
        if (sdhint)
                sdhint->AddMessage("=", expr->m_DebugInfo);
@@ -391,10 +390,10 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
        return right;
 }
 
-Value Expression::OpIndexer(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       Value value = expr->EvaluateOperand1(locals);
-       Value index = expr->EvaluateOperand2(locals);
+       Value value = expr->EvaluateOperand1(context);
+       Value index = expr->EvaluateOperand2(context);
 
        if (value.IsObjectType<Dictionary>()) {
                Dictionary::Ptr dict = value;
@@ -422,44 +421,44 @@ Value Expression::OpIndexer(const Expression *expr, const Dictionary::Ptr& local
        }
 }
 
-Value Expression::OpImport(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint)
 {
-       Value type = expr->EvaluateOperand1(locals);
-       Value name = expr->EvaluateOperand2(locals);
+       Value type = expr->EvaluateOperand1(context);
+       Value name = expr->EvaluateOperand2(context);
 
        ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
 
        if (!item)
                BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
 
-       item->GetExpressionList()->Evaluate(locals, dhint);
+       item->GetExpressionList()->Evaluate(context, dhint);
 
        return Empty;
 }
 
-Value Expression::FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs, const Expression::Ptr& expr, const Dictionary::Ptr& scope)
+Value Expression::FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs, const Expression::Ptr& expr, const Object::Ptr& scope)
 {
        if (arguments.size() < funcargs->GetLength())
                BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function"));
 
-       Dictionary::Ptr locals = make_shared<Dictionary>();
-       locals->Set("__parent", scope);
+       Dictionary::Ptr context = make_shared<Dictionary>();
+       context->Set("__parent", scope);
 
        for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs->GetLength()); i++)
-               locals->Set(funcargs->Get(i), arguments[i]);
+               context->Set(funcargs->Get(i), arguments[i]);
 
-       expr->Evaluate(locals);
-       return locals->Get("__result");
+       expr->Evaluate(context);
+       return context->Get("__result");
 }
 
-Value Expression::OpFunction(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr left = expr->m_Operand1;
        Expression::Ptr aexpr = left->Get(1);
        String name = left->Get(0);
 
        Array::Ptr funcargs = expr->m_Operand2;
-       ScriptFunction::Ptr func = make_shared<ScriptFunction>(boost::bind(&Expression::FunctionWrapper, _1, funcargs, aexpr, locals));
+       ScriptFunction::Ptr func = make_shared<ScriptFunction>(boost::bind(&Expression::FunctionWrapper, _1, funcargs, aexpr, context));
 
        if (!name.IsEmpty())
                ScriptFunction::Register(name, func);
@@ -467,7 +466,7 @@ Value Expression::OpFunction(const Expression* expr, const Dictionary::Ptr& loca
        return func;
 }
 
-Value Expression::OpApply(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr left = expr->m_Operand1;
        Expression::Ptr exprl = expr->m_Operand2;
@@ -479,14 +478,14 @@ Value Expression::OpApply(const Expression* expr, const Dictionary::Ptr& locals,
        String fvvar = left->Get(5);
        Expression::Ptr fterm = left->Get(6);
 
-       String name = aname->Evaluate(locals, dhint);
+       String name = aname->Evaluate(context, dhint);
 
-       ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, locals);
+       ApplyRule::AddRule(type, target, name, exprl, filter, fkvar, fvvar, fterm, expr->m_DebugInfo, context);
 
        return Empty;
 }
 
-Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr left = expr->m_Operand1;
        Expression::Ptr exprl = expr->m_Operand2;
@@ -496,7 +495,7 @@ Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals
        Expression::Ptr filter = left->Get(3);
        String zone = left->Get(4);
 
-       String name = aname->Evaluate(locals, dhint);
+       String name = aname->Evaluate(context, dhint);
 
        ConfigItemBuilder::Ptr item = make_shared<ConfigItemBuilder>(expr->m_DebugInfo);
 
@@ -531,16 +530,16 @@ Value Expression::OpObject(const Expression* expr, const Dictionary::Ptr& locals
 
        item->AddExpression(exprl);
        item->SetAbstract(abstract);
-       item->SetScope(locals);
+       item->SetScope(context);
        item->SetZone(zone);
        item->Compile()->Register();
 
-       ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, locals);
+       ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, context);
 
        return Empty;
 }
 
-Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint)
+Value Expression::OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint)
 {
        Array::Ptr left = expr->m_Operand1;
        String kvar = left->Get(0);
@@ -548,7 +547,7 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
        Expression::Ptr aexpr = left->Get(2);
        Expression::Ptr ascope = expr->m_Operand2;
 
-       Value value = aexpr->Evaluate(locals, dhint);
+       Value value = aexpr->Evaluate(context, dhint);
 
        if (value.IsObjectType<Array>()) {
                if (!vvar.IsEmpty())
@@ -558,11 +557,11 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
 
                ObjectLock olock(arr);
                BOOST_FOREACH(const Value& value, arr) {
-                       Dictionary::Ptr xlocals = make_shared<Dictionary>();
-                       xlocals->Set("__parent", locals);
-                       xlocals->Set(kvar, value);
+                       Dictionary::Ptr xcontext = make_shared<Dictionary>();
+                       xcontext->Set("__parent", context);
+                       xcontext->Set(kvar, value);
 
-                       ascope->Evaluate(xlocals, dhint);
+                       ascope->Evaluate(xcontext, dhint);
                }
        } else if (value.IsObjectType<Dictionary>()) {
                if (vvar.IsEmpty())
@@ -572,12 +571,12 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
 
                ObjectLock olock(dict);
                BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
-                       Dictionary::Ptr xlocals = make_shared<Dictionary>();
-                       xlocals->Set("__parent", locals);
-                       xlocals->Set(kvar, kv.first);
-                       xlocals->Set(vvar, kv.second);
+                       Dictionary::Ptr xcontext = make_shared<Dictionary>();
+                       xcontext->Set("__parent", context);
+                       xcontext->Set(kvar, kv.first);
+                       xcontext->Set(vvar, kv.second);
 
-                       ascope->Evaluate(xlocals, dhint);
+                       ascope->Evaluate(xcontext, dhint);
                }
        } else
                BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(expr->m_DebugInfo));
@@ -620,3 +619,68 @@ Expression::Ptr icinga::MakeLiteral(const Value& lit)
 {
        return make_shared<Expression>(&Expression::OpLiteral, lit, DebugInfo());
 }
+
+bool Expression::HasField(const Object::Ptr& context, const String& field)
+{
+       Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
+
+       if (dict)
+               return dict->Contains(field);
+       else {
+               Type::Ptr type = context->GetReflectionType();
+
+               if (!type)
+                       return false;
+
+               return type->GetFieldId(field) != -1;
+       }
+}
+
+Value Expression::GetField(const Object::Ptr& context, const String& field)
+{
+       Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
+
+       if (dict)
+               return dict->Get(field);
+       else {
+               Type::Ptr type = context->GetReflectionType();
+
+               if (!type)
+                       return Empty;
+
+               int fid = type->GetFieldId(field);
+
+               if (fid == -1)
+                       return Empty;
+
+               return context->GetField(fid);
+       }
+}
+
+void Expression::SetField(const Object::Ptr& context, const String& field, const Value& value)
+{
+       Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(context);
+
+       if (dict)
+               dict->Set(field, value);
+       else {
+               Type::Ptr type = context->GetReflectionType();
+
+               if (!type)
+                       BOOST_THROW_EXCEPTION(ConfigError("Cannot set field on object."));
+
+               int fid = type->GetFieldId(field);
+
+               if (fid == -1)
+                       BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' does not exist."));
+
+               try {
+                       context->SetField(fid, value);
+               } catch (const boost::bad_lexical_cast&) {
+                       BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'"));
+               } catch (const std::bad_cast&) {
+                       BOOST_THROW_EXCEPTION(ConfigError("Attribute '" + field + "' cannot be set to value of type '" + value.GetTypeName() + "'"));
+               }
+       }
+}
+
index 3ef66761d713f838c040595b9d563e321c8f8d1b..0a6a7348c29fe04060f91f785e0dc2e2dee40598 100644 (file)
@@ -63,49 +63,49 @@ class I2_CONFIG_API Expression : public Object
 public:
        DECLARE_PTR_TYPEDEFS(Expression);
        
-       typedef Value (*OpCallback)(const Expression *, const Dictionary::Ptr&, DebugHint *dhint);
+       typedef Value (*OpCallback)(const Expression *, const Object::Ptr&, DebugHint *dhint);
 
        Expression(OpCallback op, const Value& operand1, const DebugInfo& di);
        Expression(OpCallback op, const Value& operand1, const Value& operand2, const DebugInfo& di);
 
-       Value Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
+       Value Evaluate(const Object::Ptr& context, DebugHint *dhint = NULL) const;
 
        void MakeInline(void);
        
        void Dump(std::ostream& stream, int indent = 0) const;
 
-       static Value OpLiteral(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpVariable(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpLogicalNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpAdd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpSubtract(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpMultiply(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpDivide(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpBinaryAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpBinaryOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpShiftLeft(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpShiftRight(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpNotEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpLessThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpGreaterThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpLessThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpGreaterThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpNotIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpLogicalAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpLogicalOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpFunctionCall(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpArray(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpDict(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpSet(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpIndexer(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpImport(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpFunction(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpApply(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpObject(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
-       static Value OpFor(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
+       static Value OpLiteral(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
+       static Value OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
 
 private:
        OpCallback m_Operator;
@@ -113,13 +113,17 @@ private:
        Value m_Operand2;
        DebugInfo m_DebugInfo;
 
-       Value EvaluateOperand1(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
-       Value EvaluateOperand2(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
+       Value EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint = NULL) const;
+       Value EvaluateOperand2(const Object::Ptr& context, DebugHint *dhint = NULL) const;
 
        static void DumpOperand(std::ostream& stream, const Value& operand, int indent);
 
        static Value FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs,
-           const Expression::Ptr& expr, const Dictionary::Ptr& scope);
+           const Expression::Ptr& expr, const Object::Ptr& scope);
+
+       static bool HasField(const Object::Ptr& context, const String& field);
+       static Value GetField(const Object::Ptr& context, const String& field);
+       static void SetField(const Object::Ptr& context, const String& field, const Value& value);
 };
 
 I2_CONFIG_API Expression::Ptr MakeLiteral(const Value& lit = Value());
index de6247a4a25ed1fdba777b4f1e2f2b3be123766c..7fc03e3e5a93a13051e4f9a4cd6a075321e432d6 100644 (file)
@@ -27,7 +27,7 @@ ObjectRule::RuleMap ObjectRule::m_Rules;
 ObjectRule::CallbackMap ObjectRule::m_Callbacks;
 
 ObjectRule::ObjectRule(const String& name, const Expression::Ptr& expression,
-    const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope)
+    const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope)
        : m_Name(name), m_Expression(expression), m_Filter(filter), m_DebugInfo(di), m_Scope(scope)
 { }
 
@@ -51,19 +51,19 @@ DebugInfo ObjectRule::GetDebugInfo(void) const
        return m_DebugInfo;
 }
 
-Dictionary::Ptr ObjectRule::GetScope(void) const
+Object::Ptr ObjectRule::GetScope(void) const
 {
        return m_Scope;
 }
 
 void ObjectRule::AddRule(const String& sourceType, const String& name,
     const Expression::Ptr& expression, const Expression::Ptr& filter,
-    const DebugInfo& di, const Dictionary::Ptr& scope)
+    const DebugInfo& di, const Object::Ptr& scope)
 {
        m_Rules[sourceType].push_back(ObjectRule(name, expression, filter, di, scope));
 }
 
-bool ObjectRule::EvaluateFilter(const Dictionary::Ptr& scope) const
+bool ObjectRule::EvaluateFilter(const Object::Ptr& scope) const
 {
        return m_Filter->Evaluate(scope);
 }
index 079a38983d081d590b2ddc53bb58f5faa5928ab0..3a0b5637befd30d150e08729dccd04c69e5547c3 100644 (file)
@@ -42,12 +42,12 @@ public:
        Expression::Ptr GetExpression(void) const;
        Expression::Ptr GetFilter(void) const;
        DebugInfo GetDebugInfo(void) const;
-       Dictionary::Ptr GetScope(void) const;
+       Object::Ptr GetScope(void) const;
 
-       bool EvaluateFilter(const Dictionary::Ptr& scope) const;
+       bool EvaluateFilter(const Object::Ptr& scope) const;
 
        static void AddRule(const String& sourceType, const String& name, const Expression::Ptr& expression,
-           const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope);
+           const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope);
        static void EvaluateRules(bool clear);
 
        static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback);
@@ -58,13 +58,13 @@ private:
        Expression::Ptr m_Expression;
        Expression::Ptr m_Filter;
        DebugInfo m_DebugInfo;
-       Dictionary::Ptr m_Scope;
+       Object::Ptr m_Scope;
 
        static CallbackMap m_Callbacks;
        static RuleMap m_Rules;
 
        ObjectRule(const String& name, const Expression::Ptr& expression,
-           const Expression::Ptr& filter, const DebugInfo& di, const Dictionary::Ptr& scope);
+           const Expression::Ptr& filter, const DebugInfo& di, const Object::Ptr& scope);
 };
 
 }
index 4a0c3940fe8900f86c9dd436c0617b3124c89375..8020af32393886d3d3b4fd71e592e2d3168a5b19 100644 (file)
@@ -86,6 +86,9 @@ bool TypeRule::MatchValue(const Value& value, String *hint, const TypeRuleUtilit
 
 bool TypeRuleUtilities::ValidateName(const String& type, const String& name, String *hint) const
 {
+       if (name.IsEmpty())
+               return true;
+
        ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
 
        if (!item) {
index b7d979da24b9ac1b5a39b3e776261b13e41cbc8f..ab0c72c48b456571eca56fdc541d4607b4184144 100644 (file)
@@ -46,7 +46,7 @@ void Command::SetModifiedAttributes(int flags, const MessageOrigin& origin)
 
 void Command::ValidateAttributes(const String& location, const Dictionary::Ptr& attrs)
 {
-       if (attrs->Contains("arguments") && !attrs->Get("command").IsObjectType<Array>()) {
+       if (attrs->Get("arguments") != Empty && !attrs->Get("command").IsObjectType<Array>()) {
                ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
                    location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.");
        }
index 5a2ef9c1af048866a6507daf6d95e9227c92cb1e..097f64ebf94af0c21926fe33959d93c70ad1114f 100644 (file)
@@ -87,7 +87,6 @@ void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, c
        builder->AddExpression(rule.GetExpression());
 
        ConfigItem::Ptr dependencyItem = builder->Compile();
-       dependencyItem->Register();
        DynamicObject::Ptr dobj = dependencyItem->Commit();
        dobj->OnConfigLoaded();
 
index 09310e0bc9625f2907954307b3bdd17cf361e203..842d7ec526a14d4107a3377c3f4a39925fa612ab 100644 (file)
@@ -29,15 +29,17 @@ using namespace icinga;
 REGISTER_TYPE(Dependency);
 REGISTER_SCRIPTFUNCTION(ValidateDependencyFilters, &Dependency::ValidateFilters);
 
-String DependencyNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const
+String DependencyNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
 {
-       if (!props)
+       Dependency::Ptr dependency = dynamic_pointer_cast<Dependency>(context);
+
+       if (!dependency)
                return "";
 
-       String name = props->Get("child_host_name");
+       String name = dependency->GetChildHostName();
 
-       if (props->Contains("child_service_name"))
-               name += "!" + props->Get("child_service_name");
+       if (!dependency->GetChildServiceName().IsEmpty())
+               name += "!" + dependency->GetChildServiceName();
 
        name += "!" + shortName;
 
@@ -205,12 +207,12 @@ void Dependency::ValidateFilters(const String& location, const Dictionary::Ptr&
 {
        int sfilter = FilterArrayToInt(attrs->Get("state_filter"), 0);
 
-       if (!attrs->Contains("parent_service_name") && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
+       if (attrs->Get("parent_service_name") == Empty && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
                ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
                    location + ": State filter is invalid for host dependency.");
        }
 
-       if (attrs->Contains("parent_service_name") && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
+       if (attrs->Get("parent_service_name") != Empty && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
                ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
                    location + ": State filter is invalid for service dependency.");
        }
index f3b05230ee7233c8ea0af73ee1442b220f0d9721..da27eea031621d49a1b06418b7a121b80f18f787 100644 (file)
@@ -27,7 +27,7 @@ code {{{
 class I2_ICINGA_API DependencyNameComposer : public NameComposer
 {
 public:
-       virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
 };
 }}}
 
index 3cabfde8986f04abb2519968d90bc95349bcf504..f9765c10b33c6dd2a6f09ff8cf81daea79fd64a7 100644 (file)
@@ -82,7 +82,6 @@ void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable,
        builder->AddExpression(rule.GetExpression());
 
        ConfigItem::Ptr notificationItem = builder->Compile();
-       notificationItem->Register();
        DynamicObject::Ptr dobj = notificationItem->Commit();
        dobj->OnConfigLoaded();
        
index c7602b6880eb8a406910da99e9e1e3f6fb2a2363..eefe413d0cbc08aabfce227d6a13bf47440a19b3 100644 (file)
@@ -39,15 +39,17 @@ INITIALIZE_ONCE(&Notification::StaticInitialize);
 
 boost::signals2::signal<void (const Notification::Ptr&, double, const MessageOrigin&)> Notification::OnNextNotificationChanged;
 
-String NotificationNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const
+String NotificationNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
 {
-       if (!props)
+       Notification::Ptr notification = dynamic_pointer_cast<Notification>(context);
+
+       if (!notification)
                return "";
 
-       String name = props->Get("host_name");
+       String name = notification->GetHostName();
 
-       if (props->Contains("service_name"))
-               name += "!" + props->Get("service_name");
+       if (!notification->GetServiceName().IsEmpty())
+               name += "!" + notification->GetServiceName();
 
        name += "!" + shortName;
 
@@ -450,12 +452,12 @@ void Notification::ValidateFilters(const String& location, const Dictionary::Ptr
 {
        int sfilter = FilterArrayToInt(attrs->Get("states"), 0);
 
-       if (!attrs->Contains("service_name") && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
+       if (attrs->Get("service_name") == Empty && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
                ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
                    location + ": State filter is invalid.");
        }
 
-       if (attrs->Contains("service_name") && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
+       if (attrs->Get("service_name") != Empty && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
                ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
                    location + ": State filter is invalid.");
        }
index 2db5f316c639b34eddf7e213757523483c0ff6ad..dfe6be4bed1cc583004286903d01e1e15089c94a 100644 (file)
@@ -26,7 +26,7 @@ code {{{
 class I2_ICINGA_API NotificationNameComposer : public NameComposer
 {
 public:
-       virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
 };
 }}}
 
index a31710ce9976715e685e26dd09adae1ffd098a76..63fa43b409a81404ad6959d3202414a61ad52a8f 100644 (file)
@@ -81,7 +81,6 @@ void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& check
        builder->AddExpression(rule.GetExpression());
 
        ConfigItem::Ptr downtimeItem = builder->Compile();
-       downtimeItem->Register();
        DynamicObject::Ptr dobj = downtimeItem->Commit();
        dobj->OnConfigLoaded();
 }
index 34f6582f5a5ff978322edefe0f89869e8650f976..b9af506c97dd7803811df0aaabcba46d2222d847 100644 (file)
@@ -39,15 +39,17 @@ INITIALIZE_ONCE(&ScheduledDowntime::StaticInitialize);
 
 static Timer::Ptr l_Timer;
 
-String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const
+String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
 {
-       if (!props)
+       ScheduledDowntime::Ptr downtime = dynamic_pointer_cast<ScheduledDowntime>(context);
+
+       if (!downtime)
                return "";
 
-       String name = props->Get("host_name");
+       String name = downtime->GetHostName();
 
-       if (props->Contains("service_name"))
-               name += "!" + props->Get("service_name");
+       if (!downtime->GetServiceName().IsEmpty())
+               name += "!" + downtime->GetServiceName();
 
        name += "!" + shortName;
 
index f79d47d6adbd0c0f5502927f2768b1a733ef1cbb..d463bdfa0bc92960d53877eb384a75813433008a 100644 (file)
@@ -26,7 +26,7 @@ code {{{
 class I2_ICINGA_API ScheduledDowntimeNameComposer : public NameComposer
 {
 public:
-       virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
 };
 }}}
 
index 079ddd59a83e96fc47869aea97b42766a2aa8947..de9027a24d6fc33e2891833067e78fcdf0b9e19e 100644 (file)
@@ -74,7 +74,6 @@ void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String&
        builder->AddExpression(rule.GetExpression());
 
        ConfigItem::Ptr serviceItem = builder->Compile();
-       serviceItem->Register();
        DynamicObject::Ptr dobj = serviceItem->Commit();
        dobj->OnConfigLoaded();
 }
index ca498f0bf3f13dcdb94c2c09de9569dc10e03b94..43240596772306dd03acd63e9b9c2124bffb77ff 100644 (file)
@@ -30,11 +30,14 @@ using namespace icinga;
 
 REGISTER_TYPE(Service);
 
-String ServiceNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const {
-       if (!props)
+String ServiceNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
+{
+       Service::Ptr service = dynamic_pointer_cast<Service>(context);
+
+       if (!service)
                return "";
 
-       return props->Get("host_name") + "!" + shortName;
+       return service->GetHostName() + "!" + shortName;
 }
 
 void Service::OnConfigLoaded(void)
index 3cf29aaa102a5db22ea04642d3eb25c56de3c365..a3713009c3a078e4a56c58dbd5fbafa3dc4eb772 100644 (file)
@@ -29,7 +29,7 @@ code {{{
 class I2_ICINGA_API ServiceNameComposer : public NameComposer
 {
 public:
-       virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
 };
 }}}
 
index 5387b394f107da1dd37c6640740d594267960db6..f2fe69102f3093bcc06c94aa24becefee281d31b 100644 (file)
@@ -514,6 +514,12 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
                }
        }
 
+       if (klass.Name == "DynamicObject")
+               std::cout << "\t" << "friend class ConfigItem;" << std::endl;
+
+       if (!klass.TypeBase.empty())
+               std::cout << "\t" << "friend class " << klass.TypeBase << ";" << std::endl;
+
        std::cout << "};" << std::endl << std::endl;
 }