mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-16 18:24:31 +02:00
Improve config compiler's memory usage
This commit is contained in:
parent
85a380c443
commit
e1c95d4fa0
@ -29,12 +29,14 @@ enum HAMode
|
|||||||
|
|
||||||
class NameComposer {
|
class NameComposer {
|
||||||
public:
|
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
|
abstract class DynamicObject
|
||||||
{
|
{
|
||||||
|
[protected] Object::Ptr __parent (ParentScope);
|
||||||
|
|
||||||
[config, internal] String __name (Name);
|
[config, internal] String __name (Name);
|
||||||
[config] String name (ShortName) {
|
[config] String name (ShortName) {
|
||||||
get {{{
|
get {{{
|
||||||
|
@ -123,19 +123,6 @@ DynamicObject::Ptr DynamicType::GetObject(const String& name) const
|
|||||||
return nt->second;
|
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)
|
boost::mutex& DynamicType::GetStaticMutex(void)
|
||||||
{
|
{
|
||||||
static boost::mutex mutex;
|
static boost::mutex mutex;
|
||||||
|
@ -44,7 +44,6 @@ public:
|
|||||||
|
|
||||||
static DynamicType::Ptr GetByName(const String& name);
|
static DynamicType::Ptr GetByName(const String& name);
|
||||||
|
|
||||||
DynamicObject::Ptr CreateObject(const Dictionary::Ptr& serializedUpdate);
|
|
||||||
DynamicObject::Ptr GetObject(const String& name) const;
|
DynamicObject::Ptr GetObject(const String& name) const;
|
||||||
|
|
||||||
void RegisterObject(const DynamicObject::Ptr& object);
|
void RegisterObject(const DynamicObject::Ptr& object);
|
||||||
|
@ -97,6 +97,9 @@ public:
|
|||||||
if (IsEmpty())
|
if (IsEmpty())
|
||||||
return shared_ptr<T>();
|
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);
|
Object::Ptr object = boost::get<Object::Ptr>(m_Value);
|
||||||
|
|
||||||
ASSERT(object);
|
ASSERT(object);
|
||||||
|
@ -81,6 +81,9 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||||||
{
|
{
|
||||||
ConfigCompilerContext::GetInstance()->Reset();
|
ConfigCompilerContext::GetInstance()->Reset();
|
||||||
|
|
||||||
|
if (!objectsFile.IsEmpty())
|
||||||
|
ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
|
||||||
|
|
||||||
if (vm.count("config") > 0) {
|
if (vm.count("config") > 0) {
|
||||||
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
|
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
|
||||||
ConfigCompiler::CompileFile(configPath);
|
ConfigCompiler::CompileFile(configPath);
|
||||||
@ -109,7 +112,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||||||
ConfigItem::Ptr item = builder->Compile();
|
ConfigItem::Ptr item = builder->Compile();
|
||||||
item->Register();
|
item->Register();
|
||||||
|
|
||||||
bool result = ConfigItem::ValidateItems(objectsFile);
|
bool result = ConfigItem::ValidateItems();
|
||||||
|
|
||||||
int warnings = 0, errors = 0;
|
int warnings = 0, errors = 0;
|
||||||
|
|
||||||
@ -149,6 +152,8 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
ConfigCompilerContext::GetInstance()->FinishObjectsFile();
|
||||||
|
|
||||||
ScriptVariable::WriteVariablesFile(varsfile);
|
ScriptVariable::WriteVariablesFile(varsfile);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,7 +29,7 @@ ApplyRule::CallbackMap ApplyRule::m_Callbacks;
|
|||||||
|
|
||||||
ApplyRule::ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
|
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 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_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)
|
m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope)
|
||||||
{ }
|
{ }
|
||||||
@ -74,19 +74,19 @@ DebugInfo ApplyRule::GetDebugInfo(void) const
|
|||||||
return m_DebugInfo;
|
return m_DebugInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr ApplyRule::GetScope(void) const
|
Object::Ptr ApplyRule::GetScope(void) const
|
||||||
{
|
{
|
||||||
return m_Scope;
|
return m_Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
|
void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
|
||||||
const Expression::Ptr& expression, const Expression::Ptr& filter, const String& fkvar,
|
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));
|
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);
|
return m_Filter->Evaluate(scope);
|
||||||
}
|
}
|
||||||
|
@ -46,12 +46,12 @@ public:
|
|||||||
String GetFVVar(void) const;
|
String GetFVVar(void) const;
|
||||||
Expression::Ptr GetFTerm(void) const;
|
Expression::Ptr GetFTerm(void) const;
|
||||||
DebugInfo GetDebugInfo(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,
|
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 EvaluateRules(bool clear);
|
||||||
|
|
||||||
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
|
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes, const ApplyRule::Callback& callback);
|
||||||
@ -68,14 +68,14 @@ private:
|
|||||||
String m_FVVar;
|
String m_FVVar;
|
||||||
Expression::Ptr m_FTerm;
|
Expression::Ptr m_FTerm;
|
||||||
DebugInfo m_DebugInfo;
|
DebugInfo m_DebugInfo;
|
||||||
Dictionary::Ptr m_Scope;
|
Object::Ptr m_Scope;
|
||||||
|
|
||||||
static CallbackMap m_Callbacks;
|
static CallbackMap m_Callbacks;
|
||||||
static RuleMap m_Rules;
|
static RuleMap m_Rules;
|
||||||
|
|
||||||
ApplyRule(const String& targetType, const String& name, const Expression::Ptr& expression,
|
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 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,10 @@
|
|||||||
|
|
||||||
#include "config/configcompilercontext.hpp"
|
#include "config/configcompilercontext.hpp"
|
||||||
#include "base/singleton.hpp"
|
#include "base/singleton.hpp"
|
||||||
|
#include "base/json.hpp"
|
||||||
|
#include "base/netstring.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
@ -61,3 +64,50 @@ ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
|
|||||||
return Singleton<ConfigCompilerContext>::GetInstance();
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include "config/i2-config.hpp"
|
#include "config/i2-config.hpp"
|
||||||
#include "base/debuginfo.hpp"
|
#include "base/debuginfo.hpp"
|
||||||
|
#include "base/stdiostream.hpp"
|
||||||
|
#include "base/dictionary.hpp"
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -51,10 +53,16 @@ public:
|
|||||||
|
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
|
||||||
|
void OpenObjectsFile(const String& filename);
|
||||||
|
void WriteObject(const Dictionary::Ptr& object);
|
||||||
|
void FinishObjectsFile(void);
|
||||||
|
|
||||||
static ConfigCompilerContext *GetInstance(void);
|
static ConfigCompilerContext *GetInstance(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ConfigCompilerMessage> m_Messages;
|
std::vector<ConfigCompilerMessage> m_Messages;
|
||||||
|
String m_ObjectsPath;
|
||||||
|
StdioStream::Ptr m_ObjectsFP;
|
||||||
|
|
||||||
mutable boost::mutex m_Mutex;
|
mutable boost::mutex m_Mutex;
|
||||||
};
|
};
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/stdiostream.hpp"
|
#include "base/stdiostream.hpp"
|
||||||
#include "base/netstring.hpp"
|
#include "base/netstring.hpp"
|
||||||
|
#include "base/serializer.hpp"
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/configerror.hpp"
|
#include "base/configerror.hpp"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -55,9 +56,9 @@ ConfigItem::ItemMap ConfigItem::m_Items;
|
|||||||
*/
|
*/
|
||||||
ConfigItem::ConfigItem(const String& type, const String& name,
|
ConfigItem::ConfigItem(const String& type, const String& name,
|
||||||
bool abstract, const Expression::Ptr& exprl,
|
bool abstract, const Expression::Ptr& exprl,
|
||||||
const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
|
const DebugInfo& debuginfo, const Object::Ptr& scope,
|
||||||
const String& zone)
|
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_ExpressionList(exprl), m_DebugInfo(debuginfo),
|
||||||
m_Scope(scope), m_Zone(zone)
|
m_Scope(scope), m_Zone(zone)
|
||||||
{
|
{
|
||||||
@ -103,7 +104,7 @@ DebugInfo ConfigItem::GetDebugInfo(void) const
|
|||||||
return m_DebugInfo;
|
return m_DebugInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr ConfigItem::GetScope(void) const
|
Object::Ptr ConfigItem::GetScope(void) const
|
||||||
{
|
{
|
||||||
return m_Scope;
|
return m_Scope;
|
||||||
}
|
}
|
||||||
@ -118,62 +119,13 @@ Expression::Ptr ConfigItem::GetExpressionList(void) const
|
|||||||
return m_ExpressionList;
|
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
|
* Commits the configuration item by creating a DynamicObject
|
||||||
* object.
|
* object.
|
||||||
*
|
*
|
||||||
* @returns The DynamicObject that was created/updated.
|
* @returns The DynamicObject that was created/updated.
|
||||||
*/
|
*/
|
||||||
DynamicObject::Ptr ConfigItem::Commit(void)
|
DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
||||||
{
|
{
|
||||||
ASSERT(!OwnsLock());
|
ASSERT(!OwnsLock());
|
||||||
|
|
||||||
@ -183,16 +135,88 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
/* Make sure the type is valid. */
|
/* Make sure the type is valid. */
|
||||||
DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
|
Type::Ptr type = Type::GetByName(GetType());
|
||||||
|
|
||||||
if (!dtype)
|
if (!type || !Type::GetByName("DynamicObject")->IsAssignableFrom(type))
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("Type '" + GetType() + "' does not exist."));
|
BOOST_THROW_EXCEPTION(ConfigError("Type '" + GetType() + "' does not exist."));
|
||||||
|
|
||||||
if (IsAbstract())
|
if (IsAbstract())
|
||||||
return DynamicObject::Ptr();
|
return DynamicObject::Ptr();
|
||||||
|
|
||||||
DynamicObject::Ptr dobj = dtype->CreateObject(GetProperties());
|
DynamicObject::Ptr dobj = static_pointer_cast<DynamicObject>(type->Instantiate());
|
||||||
|
|
||||||
dobj->SetDebugInfo(m_DebugInfo);
|
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();
|
dobj->Register();
|
||||||
|
|
||||||
m_Object = dobj;
|
m_Object = dobj;
|
||||||
@ -207,20 +231,11 @@ void ConfigItem::Register(void)
|
|||||||
{
|
{
|
||||||
String name = m_Name;
|
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) {
|
/* If this is a non-abstract object with a composite name we don't register it. */
|
||||||
name = nc->MakeName(m_Name, Dictionary::Ptr());
|
if (!m_Abstract && nc)
|
||||||
|
return;
|
||||||
ASSERT(name.IsEmpty() || name == m_Name);
|
|
||||||
|
|
||||||
if (name.IsEmpty())
|
|
||||||
name = Utility::NewUniqueID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<String, String> key = std::make_pair(m_Type, name);
|
std::pair<String, String> key = std::make_pair(m_Type, name);
|
||||||
ConfigItem::Ptr self = GetSelf();
|
ConfigItem::Ptr self = GetSelf();
|
||||||
@ -254,104 +269,17 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
|||||||
return ConfigItem::Ptr();
|
return ConfigItem::Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigItem::ValidateItem(void)
|
bool ConfigItem::ValidateItems(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)
|
|
||||||
{
|
{
|
||||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ParallelWorkQueue upq;
|
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");
|
Log(LogInformation, "ConfigItem", "Committing config items");
|
||||||
|
|
||||||
BOOST_FOREACH(const ItemMap::value_type& kv, m_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();
|
upq.Join();
|
||||||
@ -381,17 +309,8 @@ bool ConfigItem::ValidateItems(const String& objectsFile)
|
|||||||
Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 2)...");
|
Log(LogInformation, "ConfigItem", "Evaluating 'object' rules (step 2)...");
|
||||||
ObjectRule::EvaluateRules(true);
|
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();
|
upq.Join();
|
||||||
|
|
||||||
if (!objectsFile.IsEmpty())
|
|
||||||
ConfigItem::WriteObjectsFile(objectsFile);
|
|
||||||
|
|
||||||
ConfigItem::DiscardItems();
|
ConfigItem::DiscardItems();
|
||||||
ConfigType::DiscardTypes();
|
ConfigType::DiscardTypes();
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
|
|
||||||
ConfigItem(const String& type, const String& name, bool abstract,
|
ConfigItem(const String& type, const String& name, bool abstract,
|
||||||
const Expression::Ptr& exprl, const DebugInfo& debuginfo,
|
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 GetType(void) const;
|
||||||
String GetName(void) const;
|
String GetName(void) const;
|
||||||
@ -48,42 +48,33 @@ public:
|
|||||||
std::vector<ConfigItem::Ptr> GetParents(void) const;
|
std::vector<ConfigItem::Ptr> GetParents(void) const;
|
||||||
|
|
||||||
Expression::Ptr GetExpressionList(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);
|
void Register(void);
|
||||||
|
|
||||||
DebugInfo GetDebugInfo(void) const;
|
DebugInfo GetDebugInfo(void) const;
|
||||||
|
|
||||||
Dictionary::Ptr GetScope(void) const;
|
Object::Ptr GetScope(void) const;
|
||||||
|
|
||||||
String GetZone(void) const;
|
String GetZone(void) const;
|
||||||
|
|
||||||
static ConfigItem::Ptr GetObject(const String& type,
|
static ConfigItem::Ptr GetObject(const String& type,
|
||||||
const String& name);
|
const String& name);
|
||||||
|
|
||||||
void ValidateItem(void);
|
static bool ValidateItems(void);
|
||||||
|
|
||||||
static bool ValidateItems(const String& objectsFile = String());
|
|
||||||
static bool ActivateItems(void);
|
static bool ActivateItems(void);
|
||||||
static void DiscardItems(void);
|
static void DiscardItems(void);
|
||||||
|
|
||||||
static void WriteObjectsFile(const String& filename);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_Type; /**< The object type. */
|
String m_Type; /**< The object type. */
|
||||||
String m_Name; /**< The name. */
|
String m_Name; /**< The name. */
|
||||||
bool m_Abstract; /**< Whether this is a template. */
|
bool m_Abstract; /**< Whether this is a template. */
|
||||||
bool m_Validated; /** Whether this object has been validated. */
|
|
||||||
|
|
||||||
Expression::Ptr m_ExpressionList;
|
Expression::Ptr m_ExpressionList;
|
||||||
Dictionary::Ptr m_Properties;
|
|
||||||
DebugHint m_DebugHints;
|
|
||||||
std::vector<String> m_ParentNames; /**< The names of parent configuration
|
std::vector<String> m_ParentNames; /**< The names of parent configuration
|
||||||
items. */
|
items. */
|
||||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||||
Dictionary::Ptr m_Scope; /**< variable scope. */
|
Object::Ptr m_Scope; /**< variable scope. */
|
||||||
String m_Zone; /**< The zone. */
|
String m_Zone; /**< The zone. */
|
||||||
|
|
||||||
DynamicObject::Ptr m_Object;
|
DynamicObject::Ptr m_Object;
|
||||||
|
@ -54,7 +54,7 @@ void ConfigItemBuilder::SetAbstract(bool abstract)
|
|||||||
m_Abstract = abstract;
|
m_Abstract = abstract;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
|
void ConfigItemBuilder::SetScope(const Object::Ptr& scope)
|
||||||
{
|
{
|
||||||
m_Scope = scope;
|
m_Scope = scope;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
void SetType(const String& type);
|
void SetType(const String& type);
|
||||||
void SetName(const String& name);
|
void SetName(const String& name);
|
||||||
void SetAbstract(bool abstract);
|
void SetAbstract(bool abstract);
|
||||||
void SetScope(const Dictionary::Ptr& scope);
|
void SetScope(const Object::Ptr& scope);
|
||||||
void SetZone(const String& zone);
|
void SetZone(const String& zone);
|
||||||
|
|
||||||
void AddExpression(const Expression::Ptr& expr);
|
void AddExpression(const Expression::Ptr& expr);
|
||||||
@ -58,7 +58,7 @@ private:
|
|||||||
bool m_Abstract; /**< Whether the item is abstract. */
|
bool m_Abstract; /**< Whether the item is abstract. */
|
||||||
Array::Ptr m_Expressions; /**< Expressions for this item. */
|
Array::Ptr m_Expressions; /**< Expressions for this item. */
|
||||||
DebugInfo m_DebugInfo; /**< Debug information. */
|
DebugInfo m_DebugInfo; /**< Debug information. */
|
||||||
Dictionary::Ptr m_Scope; /**< variable scope. */
|
Object::Ptr m_Scope; /**< variable scope. */
|
||||||
String m_Zone; /**< The zone. */
|
String m_Zone; /**< The zone. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "base/configerror.hpp"
|
#include "base/configerror.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/exception_ptr.hpp>
|
#include <boost/exception_ptr.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/exception/errinfo_nested_exception.hpp>
|
#include <boost/exception/errinfo_nested_exception.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
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)
|
: 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 {
|
try {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -57,7 +58,7 @@ Value Expression::Evaluate(const Dictionary::Ptr& locals, DebugHint *dhint) cons
|
|||||||
}
|
}
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
return m_Operator(this, locals, dhint);
|
return m_Operator(this, context, dhint);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
|
if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
|
||||||
throw;
|
throw;
|
||||||
@ -99,125 +100,125 @@ void Expression::Dump(std::ostream& stream, int indent) const
|
|||||||
DumpOperand(stream, m_Operand2, indent + 1);
|
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;
|
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) {
|
while (scope) {
|
||||||
if (scope->Contains(expr->m_Operand1))
|
if (HasField(scope, expr->m_Operand1))
|
||||||
return scope->Get(expr->m_Operand1);
|
return GetField(scope, expr->m_Operand1);
|
||||||
|
|
||||||
scope = scope->Get("__parent");
|
scope = GetField(scope, "__parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ScriptVariable::Get(expr->m_Operand1);
|
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())
|
if (right.IsEmpty())
|
||||||
return false;
|
return false;
|
||||||
else if (!right.IsObjectType<Array>())
|
else if (!right.IsObjectType<Array>())
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right)));
|
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;
|
Array::Ptr arr = right;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -232,24 +233,24 @@ Value Expression::OpIn(const Expression *expr, const Dictionary::Ptr& locals, De
|
|||||||
return found;
|
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;
|
ScriptFunction::Ptr func;
|
||||||
|
|
||||||
@ -261,17 +262,17 @@ Value Expression::OpFunctionCall(const Expression *expr, const Dictionary::Ptr&
|
|||||||
if (!func)
|
if (!func)
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
|
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;
|
std::vector<Value> arguments;
|
||||||
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
||||||
const Expression::Ptr& aexpr = arr->Get(index);
|
const Expression::Ptr& aexpr = arr->Get(index);
|
||||||
arguments.push_back(aexpr->Evaluate(locals));
|
arguments.push_back(aexpr->Evaluate(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
return func->Invoke(arguments);
|
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 arr = expr->m_Operand1;
|
||||||
Array::Ptr result = make_shared<Array>();
|
Array::Ptr result = make_shared<Array>();
|
||||||
@ -279,28 +280,28 @@ Value Expression::OpArray(const Expression *expr, const Dictionary::Ptr& locals,
|
|||||||
if (arr) {
|
if (arr) {
|
||||||
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
||||||
const Expression::Ptr& aexpr = arr->Get(index);
|
const Expression::Ptr& aexpr = arr->Get(index);
|
||||||
result->Add(aexpr->Evaluate(locals));
|
result->Add(aexpr->Evaluate(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
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;
|
Array::Ptr arr = expr->m_Operand1;
|
||||||
bool in_place = expr->m_Operand2;
|
bool in_place = expr->m_Operand2;
|
||||||
Dictionary::Ptr result = make_shared<Dictionary>();
|
Dictionary::Ptr result = make_shared<Dictionary>();
|
||||||
|
|
||||||
result->Set("__parent", locals);
|
result->Set("__parent", context);
|
||||||
|
|
||||||
if (arr) {
|
if (arr) {
|
||||||
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
for (Array::SizeType index = 0; index < arr->GetLength(); index++) {
|
||||||
const Expression::Ptr& aexpr = arr->Get(index);
|
const Expression::Ptr& aexpr = arr->Get(index);
|
||||||
Dictionary::Ptr alocals = in_place ? locals : result;
|
Object::Ptr acontext = in_place ? context : result;
|
||||||
aexpr->Evaluate(alocals, dhint);
|
aexpr->Evaluate(acontext, dhint);
|
||||||
|
|
||||||
if (alocals->Contains("__result"))
|
if (HasField(acontext, "__result"))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,7 +311,7 @@ Value Expression::OpDict(const Expression *expr, const Dictionary::Ptr& locals,
|
|||||||
return xresult;
|
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 left = expr->m_Operand1;
|
||||||
Array::Ptr indexer = left->Get(0);
|
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++) {
|
for (Array::SizeType i = 0; i < indexer->GetLength(); i++) {
|
||||||
Expression::Ptr indexExpr = indexer->Get(i);
|
Expression::Ptr indexExpr = indexer->Get(i);
|
||||||
String tempindex = indexExpr->Evaluate(locals, dhint);
|
String tempindex = indexExpr->Evaluate(context, dhint);
|
||||||
|
|
||||||
if (i == indexer->GetLength() - 1)
|
if (i == indexer->GetLength() - 1)
|
||||||
index = tempindex;
|
index = tempindex;
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
parent = locals;
|
parent = context;
|
||||||
object = locals->Get(tempindex);
|
object = GetField(context, tempindex);
|
||||||
} else {
|
} else {
|
||||||
parent = object;
|
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 eindex = make_shared<Expression>(&Expression::OpLiteral, tempindex, expr->m_DebugInfo);
|
||||||
|
|
||||||
Expression::Ptr eip = make_shared<Expression>(&Expression::OpIndexer, eparent, eindex, 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)
|
if (sdhint)
|
||||||
@ -347,12 +348,11 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||||||
if (i != indexer->GetLength() - 1 && object.IsEmpty()) {
|
if (i != indexer->GetLength() - 1 && object.IsEmpty()) {
|
||||||
object = make_shared<Dictionary>();
|
object = make_shared<Dictionary>();
|
||||||
|
|
||||||
Dictionary::Ptr pdict = parent;
|
SetField(parent, tempindex, object);
|
||||||
pdict->Set(tempindex, object);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value right = expr->EvaluateOperand2(locals, dhint);
|
Value right = expr->EvaluateOperand2(context, dhint);
|
||||||
|
|
||||||
if (csop != OpSetLiteral) {
|
if (csop != OpSetLiteral) {
|
||||||
Expression::OpCallback op;
|
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),
|
make_shared<Expression>(&Expression::OpLiteral, right, expr->m_DebugInfo),
|
||||||
expr->m_DebugInfo);
|
expr->m_DebugInfo);
|
||||||
|
|
||||||
right = ecp->Evaluate(locals, dhint);
|
right = ecp->Evaluate(context, dhint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr pdict = parent;
|
SetField(parent, index, right);
|
||||||
pdict->Set(index, right);
|
|
||||||
|
|
||||||
if (sdhint)
|
if (sdhint)
|
||||||
sdhint->AddMessage("=", expr->m_DebugInfo);
|
sdhint->AddMessage("=", expr->m_DebugInfo);
|
||||||
@ -391,10 +390,10 @@ Value Expression::OpSet(const Expression *expr, const Dictionary::Ptr& locals, D
|
|||||||
return right;
|
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 value = expr->EvaluateOperand1(context);
|
||||||
Value index = expr->EvaluateOperand2(locals);
|
Value index = expr->EvaluateOperand2(context);
|
||||||
|
|
||||||
if (value.IsObjectType<Dictionary>()) {
|
if (value.IsObjectType<Dictionary>()) {
|
||||||
Dictionary::Ptr dict = value;
|
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 type = expr->EvaluateOperand1(context);
|
||||||
Value name = expr->EvaluateOperand2(locals);
|
Value name = expr->EvaluateOperand2(context);
|
||||||
|
|
||||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
||||||
|
|
||||||
if (!item)
|
if (!item)
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
|
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
|
||||||
|
|
||||||
item->GetExpressionList()->Evaluate(locals, dhint);
|
item->GetExpressionList()->Evaluate(context, dhint);
|
||||||
|
|
||||||
return Empty;
|
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())
|
if (arguments.size() < funcargs->GetLength())
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function"));
|
BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function"));
|
||||||
|
|
||||||
Dictionary::Ptr locals = make_shared<Dictionary>();
|
Dictionary::Ptr context = make_shared<Dictionary>();
|
||||||
locals->Set("__parent", scope);
|
context->Set("__parent", scope);
|
||||||
|
|
||||||
for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs->GetLength()); i++)
|
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);
|
expr->Evaluate(context);
|
||||||
return locals->Get("__result");
|
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;
|
Array::Ptr left = expr->m_Operand1;
|
||||||
Expression::Ptr aexpr = left->Get(1);
|
Expression::Ptr aexpr = left->Get(1);
|
||||||
String name = left->Get(0);
|
String name = left->Get(0);
|
||||||
|
|
||||||
Array::Ptr funcargs = expr->m_Operand2;
|
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())
|
if (!name.IsEmpty())
|
||||||
ScriptFunction::Register(name, func);
|
ScriptFunction::Register(name, func);
|
||||||
@ -467,7 +466,7 @@ Value Expression::OpFunction(const Expression* expr, const Dictionary::Ptr& loca
|
|||||||
return func;
|
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;
|
Array::Ptr left = expr->m_Operand1;
|
||||||
Expression::Ptr exprl = expr->m_Operand2;
|
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);
|
String fvvar = left->Get(5);
|
||||||
Expression::Ptr fterm = left->Get(6);
|
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;
|
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;
|
Array::Ptr left = expr->m_Operand1;
|
||||||
Expression::Ptr exprl = expr->m_Operand2;
|
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);
|
Expression::Ptr filter = left->Get(3);
|
||||||
String zone = left->Get(4);
|
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);
|
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->AddExpression(exprl);
|
||||||
item->SetAbstract(abstract);
|
item->SetAbstract(abstract);
|
||||||
item->SetScope(locals);
|
item->SetScope(context);
|
||||||
item->SetZone(zone);
|
item->SetZone(zone);
|
||||||
item->Compile()->Register();
|
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;
|
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;
|
Array::Ptr left = expr->m_Operand1;
|
||||||
String kvar = left->Get(0);
|
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 aexpr = left->Get(2);
|
||||||
Expression::Ptr ascope = expr->m_Operand2;
|
Expression::Ptr ascope = expr->m_Operand2;
|
||||||
|
|
||||||
Value value = aexpr->Evaluate(locals, dhint);
|
Value value = aexpr->Evaluate(context, dhint);
|
||||||
|
|
||||||
if (value.IsObjectType<Array>()) {
|
if (value.IsObjectType<Array>()) {
|
||||||
if (!vvar.IsEmpty())
|
if (!vvar.IsEmpty())
|
||||||
@ -558,11 +557,11 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
|
|||||||
|
|
||||||
ObjectLock olock(arr);
|
ObjectLock olock(arr);
|
||||||
BOOST_FOREACH(const Value& value, arr) {
|
BOOST_FOREACH(const Value& value, arr) {
|
||||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
Dictionary::Ptr xcontext = make_shared<Dictionary>();
|
||||||
xlocals->Set("__parent", locals);
|
xcontext->Set("__parent", context);
|
||||||
xlocals->Set(kvar, value);
|
xcontext->Set(kvar, value);
|
||||||
|
|
||||||
ascope->Evaluate(xlocals, dhint);
|
ascope->Evaluate(xcontext, dhint);
|
||||||
}
|
}
|
||||||
} else if (value.IsObjectType<Dictionary>()) {
|
} else if (value.IsObjectType<Dictionary>()) {
|
||||||
if (vvar.IsEmpty())
|
if (vvar.IsEmpty())
|
||||||
@ -572,12 +571,12 @@ Value Expression::OpFor(const Expression* expr, const Dictionary::Ptr& locals, D
|
|||||||
|
|
||||||
ObjectLock olock(dict);
|
ObjectLock olock(dict);
|
||||||
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
|
||||||
Dictionary::Ptr xlocals = make_shared<Dictionary>();
|
Dictionary::Ptr xcontext = make_shared<Dictionary>();
|
||||||
xlocals->Set("__parent", locals);
|
xcontext->Set("__parent", context);
|
||||||
xlocals->Set(kvar, kv.first);
|
xcontext->Set(kvar, kv.first);
|
||||||
xlocals->Set(vvar, kv.second);
|
xcontext->Set(vvar, kv.second);
|
||||||
|
|
||||||
ascope->Evaluate(xlocals, dhint);
|
ascope->Evaluate(xcontext, dhint);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
BOOST_THROW_EXCEPTION(ConfigError("Invalid type in __for expression: " + value.GetTypeName()) << errinfo_debuginfo(expr->m_DebugInfo));
|
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());
|
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() + "'"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -63,49 +63,49 @@ class I2_CONFIG_API Expression : public Object
|
|||||||
public:
|
public:
|
||||||
DECLARE_PTR_TYPEDEFS(Expression);
|
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 DebugInfo& di);
|
||||||
Expression(OpCallback op, const Value& operand1, const Value& operand2, 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 MakeInline(void);
|
||||||
|
|
||||||
void Dump(std::ostream& stream, int indent = 0) const;
|
void Dump(std::ostream& stream, int indent = 0) const;
|
||||||
|
|
||||||
static Value OpLiteral(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 Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpVariable(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpLogicalNegate(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpLogicalNegate(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpAdd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpAdd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpSubtract(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpSubtract(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpMultiply(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpMultiply(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpDivide(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpDivide(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpBinaryAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpBinaryAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpBinaryOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpBinaryOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpShiftLeft(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpShiftLeft(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpShiftRight(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpShiftRight(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpNotEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpNotEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpLessThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpLessThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpGreaterThan(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpGreaterThan(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpLessThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpLessThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpGreaterThanOrEqual(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpGreaterThanOrEqual(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpNotIn(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpNotIn(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpLogicalAnd(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpLogicalAnd(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpLogicalOr(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpLogicalOr(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpFunctionCall(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpFunctionCall(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpArray(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpArray(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpDict(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpDict(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpSet(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpSet(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpIndexer(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpIndexer(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpImport(const Expression *expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpImport(const Expression *expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpFunction(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpFunction(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpApply(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpApply(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpObject(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpObject(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
static Value OpFor(const Expression* expr, const Dictionary::Ptr& locals, DebugHint *dhint);
|
static Value OpFor(const Expression* expr, const Object::Ptr& context, DebugHint *dhint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OpCallback m_Operator;
|
OpCallback m_Operator;
|
||||||
@ -113,13 +113,17 @@ private:
|
|||||||
Value m_Operand2;
|
Value m_Operand2;
|
||||||
DebugInfo m_DebugInfo;
|
DebugInfo m_DebugInfo;
|
||||||
|
|
||||||
Value EvaluateOperand1(const Dictionary::Ptr& locals, DebugHint *dhint = NULL) const;
|
Value EvaluateOperand1(const Object::Ptr& context, DebugHint *dhint = NULL) const;
|
||||||
Value EvaluateOperand2(const Dictionary::Ptr& locals, 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 void DumpOperand(std::ostream& stream, const Value& operand, int indent);
|
||||||
|
|
||||||
static Value FunctionWrapper(const std::vector<Value>& arguments, const Array::Ptr& funcargs,
|
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());
|
I2_CONFIG_API Expression::Ptr MakeLiteral(const Value& lit = Value());
|
||||||
|
@ -27,7 +27,7 @@ ObjectRule::RuleMap ObjectRule::m_Rules;
|
|||||||
ObjectRule::CallbackMap ObjectRule::m_Callbacks;
|
ObjectRule::CallbackMap ObjectRule::m_Callbacks;
|
||||||
|
|
||||||
ObjectRule::ObjectRule(const String& name, const Expression::Ptr& expression,
|
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)
|
: 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;
|
return m_DebugInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr ObjectRule::GetScope(void) const
|
Object::Ptr ObjectRule::GetScope(void) const
|
||||||
{
|
{
|
||||||
return m_Scope;
|
return m_Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectRule::AddRule(const String& sourceType, const String& name,
|
void ObjectRule::AddRule(const String& sourceType, const String& name,
|
||||||
const Expression::Ptr& expression, const Expression::Ptr& filter,
|
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));
|
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);
|
return m_Filter->Evaluate(scope);
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,12 @@ public:
|
|||||||
Expression::Ptr GetExpression(void) const;
|
Expression::Ptr GetExpression(void) const;
|
||||||
Expression::Ptr GetFilter(void) const;
|
Expression::Ptr GetFilter(void) const;
|
||||||
DebugInfo GetDebugInfo(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,
|
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 EvaluateRules(bool clear);
|
||||||
|
|
||||||
static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback);
|
static void RegisterType(const String& sourceType, const ObjectRule::Callback& callback);
|
||||||
@ -58,13 +58,13 @@ private:
|
|||||||
Expression::Ptr m_Expression;
|
Expression::Ptr m_Expression;
|
||||||
Expression::Ptr m_Filter;
|
Expression::Ptr m_Filter;
|
||||||
DebugInfo m_DebugInfo;
|
DebugInfo m_DebugInfo;
|
||||||
Dictionary::Ptr m_Scope;
|
Object::Ptr m_Scope;
|
||||||
|
|
||||||
static CallbackMap m_Callbacks;
|
static CallbackMap m_Callbacks;
|
||||||
static RuleMap m_Rules;
|
static RuleMap m_Rules;
|
||||||
|
|
||||||
ObjectRule(const String& name, const Expression::Ptr& expression,
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
bool TypeRuleUtilities::ValidateName(const String& type, const String& name, String *hint) const
|
||||||
{
|
{
|
||||||
|
if (name.IsEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
@ -46,7 +46,7 @@ void Command::SetModifiedAttributes(int flags, const MessageOrigin& origin)
|
|||||||
|
|
||||||
void Command::ValidateAttributes(const String& location, const Dictionary::Ptr& attrs)
|
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 " +
|
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||||
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.");
|
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.");
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,6 @@ void Dependency::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, c
|
|||||||
builder->AddExpression(rule.GetExpression());
|
builder->AddExpression(rule.GetExpression());
|
||||||
|
|
||||||
ConfigItem::Ptr dependencyItem = builder->Compile();
|
ConfigItem::Ptr dependencyItem = builder->Compile();
|
||||||
dependencyItem->Register();
|
|
||||||
DynamicObject::Ptr dobj = dependencyItem->Commit();
|
DynamicObject::Ptr dobj = dependencyItem->Commit();
|
||||||
dobj->OnConfigLoaded();
|
dobj->OnConfigLoaded();
|
||||||
|
|
||||||
|
@ -29,15 +29,17 @@ using namespace icinga;
|
|||||||
REGISTER_TYPE(Dependency);
|
REGISTER_TYPE(Dependency);
|
||||||
REGISTER_SCRIPTFUNCTION(ValidateDependencyFilters, &Dependency::ValidateFilters);
|
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 "";
|
return "";
|
||||||
|
|
||||||
String name = props->Get("child_host_name");
|
String name = dependency->GetChildHostName();
|
||||||
|
|
||||||
if (props->Contains("child_service_name"))
|
if (!dependency->GetChildServiceName().IsEmpty())
|
||||||
name += "!" + props->Get("child_service_name");
|
name += "!" + dependency->GetChildServiceName();
|
||||||
|
|
||||||
name += "!" + shortName;
|
name += "!" + shortName;
|
||||||
|
|
||||||
@ -205,12 +207,12 @@ void Dependency::ValidateFilters(const String& location, const Dictionary::Ptr&
|
|||||||
{
|
{
|
||||||
int sfilter = FilterArrayToInt(attrs->Get("state_filter"), 0);
|
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 " +
|
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||||
location + ": State filter is invalid for host dependency.");
|
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 " +
|
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||||
location + ": State filter is invalid for service dependency.");
|
location + ": State filter is invalid for service dependency.");
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ code {{{
|
|||||||
class I2_ICINGA_API DependencyNameComposer : public NameComposer
|
class I2_ICINGA_API DependencyNameComposer : public NameComposer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||||
};
|
};
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -82,7 +82,6 @@ void Notification::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable,
|
|||||||
builder->AddExpression(rule.GetExpression());
|
builder->AddExpression(rule.GetExpression());
|
||||||
|
|
||||||
ConfigItem::Ptr notificationItem = builder->Compile();
|
ConfigItem::Ptr notificationItem = builder->Compile();
|
||||||
notificationItem->Register();
|
|
||||||
DynamicObject::Ptr dobj = notificationItem->Commit();
|
DynamicObject::Ptr dobj = notificationItem->Commit();
|
||||||
dobj->OnConfigLoaded();
|
dobj->OnConfigLoaded();
|
||||||
|
|
||||||
|
@ -39,15 +39,17 @@ INITIALIZE_ONCE(&Notification::StaticInitialize);
|
|||||||
|
|
||||||
boost::signals2::signal<void (const Notification::Ptr&, double, const MessageOrigin&)> Notification::OnNextNotificationChanged;
|
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 "";
|
return "";
|
||||||
|
|
||||||
String name = props->Get("host_name");
|
String name = notification->GetHostName();
|
||||||
|
|
||||||
if (props->Contains("service_name"))
|
if (!notification->GetServiceName().IsEmpty())
|
||||||
name += "!" + props->Get("service_name");
|
name += "!" + notification->GetServiceName();
|
||||||
|
|
||||||
name += "!" + shortName;
|
name += "!" + shortName;
|
||||||
|
|
||||||
@ -450,12 +452,12 @@ void Notification::ValidateFilters(const String& location, const Dictionary::Ptr
|
|||||||
{
|
{
|
||||||
int sfilter = FilterArrayToInt(attrs->Get("states"), 0);
|
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 " +
|
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||||
location + ": State filter is invalid.");
|
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 " +
|
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
||||||
location + ": State filter is invalid.");
|
location + ": State filter is invalid.");
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ code {{{
|
|||||||
class I2_ICINGA_API NotificationNameComposer : public NameComposer
|
class I2_ICINGA_API NotificationNameComposer : public NameComposer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||||
};
|
};
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& check
|
|||||||
builder->AddExpression(rule.GetExpression());
|
builder->AddExpression(rule.GetExpression());
|
||||||
|
|
||||||
ConfigItem::Ptr downtimeItem = builder->Compile();
|
ConfigItem::Ptr downtimeItem = builder->Compile();
|
||||||
downtimeItem->Register();
|
|
||||||
DynamicObject::Ptr dobj = downtimeItem->Commit();
|
DynamicObject::Ptr dobj = downtimeItem->Commit();
|
||||||
dobj->OnConfigLoaded();
|
dobj->OnConfigLoaded();
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,17 @@ INITIALIZE_ONCE(&ScheduledDowntime::StaticInitialize);
|
|||||||
|
|
||||||
static Timer::Ptr l_Timer;
|
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 "";
|
return "";
|
||||||
|
|
||||||
String name = props->Get("host_name");
|
String name = downtime->GetHostName();
|
||||||
|
|
||||||
if (props->Contains("service_name"))
|
if (!downtime->GetServiceName().IsEmpty())
|
||||||
name += "!" + props->Get("service_name");
|
name += "!" + downtime->GetServiceName();
|
||||||
|
|
||||||
name += "!" + shortName;
|
name += "!" + shortName;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ code {{{
|
|||||||
class I2_ICINGA_API ScheduledDowntimeNameComposer : public NameComposer
|
class I2_ICINGA_API ScheduledDowntimeNameComposer : public NameComposer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||||
};
|
};
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ void Service::EvaluateApplyRuleOneInstance(const Host::Ptr& host, const String&
|
|||||||
builder->AddExpression(rule.GetExpression());
|
builder->AddExpression(rule.GetExpression());
|
||||||
|
|
||||||
ConfigItem::Ptr serviceItem = builder->Compile();
|
ConfigItem::Ptr serviceItem = builder->Compile();
|
||||||
serviceItem->Register();
|
|
||||||
DynamicObject::Ptr dobj = serviceItem->Commit();
|
DynamicObject::Ptr dobj = serviceItem->Commit();
|
||||||
dobj->OnConfigLoaded();
|
dobj->OnConfigLoaded();
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,14 @@ using namespace icinga;
|
|||||||
|
|
||||||
REGISTER_TYPE(Service);
|
REGISTER_TYPE(Service);
|
||||||
|
|
||||||
String ServiceNameComposer::MakeName(const String& shortName, const Dictionary::Ptr& props) const {
|
String ServiceNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||||
if (!props)
|
{
|
||||||
|
Service::Ptr service = dynamic_pointer_cast<Service>(context);
|
||||||
|
|
||||||
|
if (!service)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return props->Get("host_name") + "!" + shortName;
|
return service->GetHostName() + "!" + shortName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::OnConfigLoaded(void)
|
void Service::OnConfigLoaded(void)
|
||||||
|
@ -29,7 +29,7 @@ code {{{
|
|||||||
class I2_ICINGA_API ServiceNameComposer : public NameComposer
|
class I2_ICINGA_API ServiceNameComposer : public NameComposer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual String MakeName(const String& shortName, const Dictionary::Ptr& props) const;
|
virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
|
||||||
};
|
};
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
@ -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;
|
std::cout << "};" << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user