DebugInfo m_DebugInfo;
};
-#define DECLARE_OBJECTNAME(klass) \
+#define DECLARE_OBJECTNAME(klass) \
inline static String GetTypeName(void) \
{ \
return #klass; \
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 {{{
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;
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);
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);
{
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);
ConfigItem::Ptr item = builder->Compile();
item->Register();
- bool result = ConfigItem::ValidateItems(objectsFile);
+ bool result = ConfigItem::ValidateItems();
int warnings = 0, errors = 0;
if (!result)
return false;
+ ConfigCompilerContext::GetInstance()->FinishObjectsFile();
+
ScriptVariable::WriteVariablesFile(varsfile);
return true;
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)
{ }
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);
}
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);
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);
};
}
#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;
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));
+ }
+
+}
+
#include "config/i2-config.hpp"
#include "base/debuginfo.hpp"
+#include "base/stdiostream.hpp"
+#include "base/dictionary.hpp"
#include <boost/thread/mutex.hpp>
#include <vector>
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;
};
#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>
*/
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)
{
return m_DebugInfo;
}
-Dictionary::Ptr ConfigItem::GetScope(void) const
+Object::Ptr ConfigItem::GetScope(void) const
{
return m_Scope;
}
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());
#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;
{
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();
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();
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();
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;
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;
m_Abstract = abstract;
}
-void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
+void ConfigItemBuilder::SetScope(const Object::Ptr& scope)
{
m_Scope = scope;
}
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);
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. */
};
#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;
: 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
}
#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;
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;
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;
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>();
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;
}
}
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);
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;
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)
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;
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);
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;
}
}
-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);
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;
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;
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);
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);
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())
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())
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));
{
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() + "'"));
+ }
+ }
+}
+
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;
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());
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)
{ }
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);
}
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);
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);
};
}
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) {
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.");
}
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr dependencyItem = builder->Compile();
- dependencyItem->Register();
DynamicObject::Ptr dobj = dependencyItem->Commit();
dobj->OnConfigLoaded();
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;
{
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.");
}
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;
};
}}}
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr notificationItem = builder->Compile();
- notificationItem->Register();
DynamicObject::Ptr dobj = notificationItem->Commit();
dobj->OnConfigLoaded();
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;
{
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.");
}
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;
};
}}}
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr downtimeItem = builder->Compile();
- downtimeItem->Register();
DynamicObject::Ptr dobj = downtimeItem->Commit();
dobj->OnConfigLoaded();
}
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;
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;
};
}}}
builder->AddExpression(rule.GetExpression());
ConfigItem::Ptr serviceItem = builder->Compile();
- serviceItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit();
dobj->OnConfigLoaded();
}
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)
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;
};
}}}
}
}
+ 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;
}