Allow expressions for the type in object/template declarations

This commit is contained in:
Gunnar Beutner 2017-05-11 14:21:30 +02:00
parent cfe4a170c5
commit d05b7c4178
18 changed files with 72 additions and 71 deletions

View File

@ -143,7 +143,7 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
if (!success) if (!success)
return false; return false;
String appType = ScriptGlobal::Get("ApplicationType", &Empty); Type::Ptr appType = Type::GetByName(ScriptGlobal::Get("ApplicationType", &Empty));
if (ConfigItem::GetItems(appType).empty()) { if (ConfigItem::GetItems(appType).empty()) {
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(); ConfigItemBuilder::Ptr builder = new ConfigItemBuilder();

View File

@ -372,7 +372,7 @@ object:
context->m_Assign.push(0); context->m_Assign.push(0);
context->m_Ignore.push(0); context->m_Ignore.push(0);
} }
object_declaration identifier optional_rterm use_specifier default_specifier ignore_specifier object_declaration rterm optional_rterm use_specifier default_specifier ignore_specifier
{ {
BeginFlowControlBlock(context, FlowControlReturn, false); BeginFlowControlBlock(context, FlowControlReturn, false);
} }
@ -388,9 +388,6 @@ object:
if (!abstract && defaultTmpl) if (!abstract && defaultTmpl)
BOOST_THROW_EXCEPTION(ScriptError("'default' keyword is invalid for object definitions", DebugInfoRange(@2, @4))); BOOST_THROW_EXCEPTION(ScriptError("'default' keyword is invalid for object definitions", DebugInfoRange(@2, @4)));
String type = *$3;
delete $3;
bool seen_assign = context->m_SeenAssign.top(); bool seen_assign = context->m_SeenAssign.top();
context->m_SeenAssign.pop(); context->m_SeenAssign.pop();
@ -406,9 +403,6 @@ object:
Expression *filter = NULL; Expression *filter = NULL;
if (seen_assign) { if (seen_assign) {
if (!ObjectRule::IsValidSourceType(type))
BOOST_THROW_EXCEPTION(ScriptError("object rule 'assign' cannot be used for type '" + type + "'", DebugInfoRange(@2, @4)));
if (ignore) { if (ignore) {
Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5)); Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5));
@ -416,13 +410,10 @@ object:
} else } else
filter = assign; filter = assign;
} else if (seen_ignore) { } else if (seen_ignore) {
if (!ObjectRule::IsValidSourceType(type)) BOOST_THROW_EXCEPTION(ScriptError("object rule 'ignore where' cannot be used without 'assign where'", DebugInfoRange(@2, @4)));
BOOST_THROW_EXCEPTION(ScriptError("object rule 'ignore' cannot be used for type '" + type + "'", DebugInfoRange(@2, @4)));
else
BOOST_THROW_EXCEPTION(ScriptError("object rule 'ignore' is missing 'assign' for type '" + type + "'", DebugInfoRange(@2, @4)));
} }
$$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), context->GetPackage(), $5, $6, $7, $9, DebugInfoRange(@2, @7)); $$ = new ObjectExpression(abstract, $3, $4, filter, context->GetZone(), context->GetPackage(), $5, $6, $7, $9, DebugInfoRange(@2, @7));
} }
; ;

View File

@ -59,7 +59,7 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, run_with_activation_context, &ConfigItem::R
* @param exprl Expression list for the item. * @param exprl Expression list for the item.
* @param debuginfo Debug information. * @param debuginfo Debug information.
*/ */
ConfigItem::ConfigItem(const String& type, const String& name, ConfigItem::ConfigItem(const Type::Ptr& type, const String& name,
bool abstract, const boost::shared_ptr<Expression>& exprl, bool abstract, const boost::shared_ptr<Expression>& exprl,
const boost::shared_ptr<Expression>& filter, bool defaultTmpl, bool ignoreOnError, const boost::shared_ptr<Expression>& filter, bool defaultTmpl, bool ignoreOnError,
const DebugInfo& debuginfo, const Dictionary::Ptr& scope, const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
@ -77,7 +77,7 @@ ConfigItem::ConfigItem(const String& type, const String& name,
* *
* @returns The type. * @returns The type.
*/ */
String ConfigItem::GetType(void) const Type::Ptr ConfigItem::GetType(void) const
{ {
return m_Type; return m_Type;
} }
@ -157,7 +157,7 @@ class DefaultValidationUtils : public ValidationUtils
public: public:
virtual bool ValidateName(const String& type, const String& name) const override virtual bool ValidateName(const String& type, const String& name) const override
{ {
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, name); ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(Type::GetByName(type), name);
if (!item || (item && item->IsAbstract())) if (!item || (item && item->IsAbstract()))
return false; return false;
@ -180,7 +180,7 @@ ConfigObject::Ptr ConfigItem::Commit(bool discard)
#endif /* I2_DEBUG */ #endif /* I2_DEBUG */
/* Make sure the type is valid. */ /* Make sure the type is valid. */
Type::Ptr type = Type::GetByName(GetType()); Type::Ptr type = GetType();
if (!type || !ConfigObject::TypeInstance->IsAssignableFrom(type)) if (!type || !ConfigObject::TypeInstance->IsAssignableFrom(type))
BOOST_THROW_EXCEPTION(ScriptError("Type '" + GetType() + "' does not exist.", m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Type '" + GetType() + "' does not exist.", m_DebugInfo));
@ -320,15 +320,13 @@ ConfigObject::Ptr ConfigItem::Commit(bool discard)
*/ */
void ConfigItem::Register(void) void ConfigItem::Register(void)
{ {
Type::Ptr type = Type::GetByName(m_Type);
m_ActivationContext = ActivationContext::GetCurrentContext(); m_ActivationContext = ActivationContext::GetCurrentContext();
boost::mutex::scoped_lock lock(m_Mutex); boost::mutex::scoped_lock lock(m_Mutex);
/* If this is a non-abstract object with a composite name /* If this is a non-abstract object with a composite name
* we register it in m_UnnamedItems instead of m_Items. */ * we register it in m_UnnamedItems instead of m_Items. */
if (!m_Abstract && dynamic_cast<NameComposer *>(type.get())) if (!m_Abstract && dynamic_cast<NameComposer *>(m_Type.get()))
m_UnnamedItems.push_back(this); m_UnnamedItems.push_back(this);
else { else {
auto& items = m_Items[m_Type]; auto& items = m_Items[m_Type];
@ -337,7 +335,7 @@ void ConfigItem::Register(void)
if (it != items.end()) { if (it != items.end()) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "A configuration item of type '" << GetType() msgbuf << "A configuration item of type '" << m_Type->GetName()
<< "' and name '" << GetName() << "' already exists (" << "' and name '" << GetName() << "' already exists ("
<< it->second->GetDebugInfo() << "), new declaration: " << GetDebugInfo(); << it->second->GetDebugInfo() << "), new declaration: " << GetDebugInfo();
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str())); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str()));
@ -373,7 +371,7 @@ void ConfigItem::Unregister(void)
* @param name The name of the ConfigItem that is to be looked up. * @param name The name of the ConfigItem that is to be looked up.
* @returns The configuration item. * @returns The configuration item.
*/ */
ConfigItem::Ptr ConfigItem::GetByTypeAndName(const String& type, const String& name) ConfigItem::Ptr ConfigItem::GetByTypeAndName(const Type::Ptr& type, const String& name)
{ {
boost::mutex::scoped_lock lock(m_Mutex); boost::mutex::scoped_lock lock(m_Mutex);
@ -442,26 +440,26 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
if (upq.HasExceptions()) if (upq.HasExceptions())
return false; return false;
std::set<String> types; std::set<Type::Ptr> types;
for (const Type::Ptr& type : Type::GetAllTypes()) { for (const Type::Ptr& type : Type::GetAllTypes()) {
if (ConfigObject::TypeInstance->IsAssignableFrom(type)) if (ConfigObject::TypeInstance->IsAssignableFrom(type))
types.insert(type->GetName()); types.insert(type);
} }
std::set<String> completed_types; std::set<Type::Ptr> completed_types;
while (types.size() != completed_types.size()) { while (types.size() != completed_types.size()) {
for (const String& type : types) { for (const Type::Ptr& type : types) {
if (completed_types.find(type) != completed_types.end()) if (completed_types.find(type) != completed_types.end())
continue; continue;
Type::Ptr ptype = Type::GetByName(type);
bool unresolved_dep = false; bool unresolved_dep = false;
/* skip this type (for now) if there are unresolved load dependencies */ /* skip this type (for now) if there are unresolved load dependencies */
for (const String& loadDep : ptype->GetLoadDependencies()) { for (const String& loadDep : type->GetLoadDependencies()) {
if (types.find(loadDep) != types.end() && completed_types.find(loadDep) == completed_types.end()) { Type::Ptr pLoadDep = Type::GetByName(loadDep);
if (types.find(pLoadDep) != types.end() && completed_types.find(pLoadDep) == completed_types.end()) {
unresolved_dep = true; unresolved_dep = true;
break; break;
} }
@ -508,17 +506,17 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue
if (upq.HasExceptions()) if (upq.HasExceptions())
return false; return false;
for (const String& loadDep : ptype->GetLoadDependencies()) { for (const String& loadDep : type->GetLoadDependencies()) {
for (const ItemPair& ip : items) { for (const ItemPair& ip : items) {
const ConfigItem::Ptr& item = ip.first; const ConfigItem::Ptr& item = ip.first;
if (!item->m_Object) if (!item->m_Object)
continue; continue;
if (item->m_Type == loadDep) { if (item->m_Type->GetName() == loadDep) {
upq.Enqueue([&]() { upq.Enqueue([&]() {
ActivationScope ascope(item->m_ActivationContext); ActivationScope ascope(item->m_ActivationContext);
item->m_Object->CreateChildObjects(ptype); item->m_Object->CreateChildObjects(type);
}); });
} }
} }
@ -683,7 +681,7 @@ bool ConfigItem::RunWithActivationContext(const Function::Ptr& function)
return true; return true;
} }
std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const String& type) std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const Type::Ptr& type)
{ {
std::vector<ConfigItem::Ptr> items; std::vector<ConfigItem::Ptr> items;
@ -703,7 +701,7 @@ std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const String& type)
return items; return items;
} }
std::vector<ConfigItem::Ptr> ConfigItem::GetDefaultTemplates(const String& type) std::vector<ConfigItem::Ptr> ConfigItem::GetDefaultTemplates(const Type::Ptr& type)
{ {
std::vector<ConfigItem::Ptr> items; std::vector<ConfigItem::Ptr> items;

View File

@ -40,14 +40,14 @@ class I2_CONFIG_API ConfigItem : public Object {
public: public:
DECLARE_PTR_TYPEDEFS(ConfigItem); DECLARE_PTR_TYPEDEFS(ConfigItem);
ConfigItem(const String& type, const String& name, bool abstract, ConfigItem(const Type::Ptr& type, const String& name, bool abstract,
const boost::shared_ptr<Expression>& exprl, const boost::shared_ptr<Expression>& exprl,
const boost::shared_ptr<Expression>& filter, const boost::shared_ptr<Expression>& filter,
bool defaultTmpl, bool ignoreOnError, const DebugInfo& debuginfo, bool defaultTmpl, bool ignoreOnError, const DebugInfo& debuginfo,
const Dictionary::Ptr& scope, const String& zone, const Dictionary::Ptr& scope, const String& zone,
const String& package); const String& package);
String GetType(void) const; Type::Ptr GetType(void) const;
String GetName(void) const; String GetName(void) const;
bool IsAbstract(void) const; bool IsAbstract(void) const;
bool IsDefaultTemplate(void) const; bool IsDefaultTemplate(void) const;
@ -66,7 +66,7 @@ public:
ConfigObject::Ptr GetObject(void) const; ConfigObject::Ptr GetObject(void) const;
static ConfigItem::Ptr GetByTypeAndName(const String& type, static ConfigItem::Ptr GetByTypeAndName(const Type::Ptr& type,
const String& name); const String& name);
static bool CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems, bool silent = false); static bool CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems, bool silent = false);
@ -74,13 +74,13 @@ public:
static bool RunWithActivationContext(const Function::Ptr& function); static bool RunWithActivationContext(const Function::Ptr& function);
static std::vector<ConfigItem::Ptr> GetItems(const String& type); static std::vector<ConfigItem::Ptr> GetItems(const Type::Ptr& type);
static std::vector<ConfigItem::Ptr> GetDefaultTemplates(const String& type); static std::vector<ConfigItem::Ptr> GetDefaultTemplates(const Type::Ptr& type);
static void RemoveIgnoredItems(const String& allowedConfigPath); static void RemoveIgnoredItems(const String& allowedConfigPath);
private: private:
String m_Type; /**< The object type. */ Type::Ptr 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. */
@ -99,7 +99,7 @@ private:
static boost::mutex m_Mutex; static boost::mutex m_Mutex;
typedef std::map<String, ConfigItem::Ptr> ItemMap; typedef std::map<String, ConfigItem::Ptr> ItemMap;
typedef std::map<String, ItemMap> TypeMap; typedef std::map<Type::Ptr, ItemMap> TypeMap;
static TypeMap m_Items; /**< All registered configuration items. */ static TypeMap m_Items; /**< All registered configuration items. */
static TypeMap m_DefaultTemplates; static TypeMap m_DefaultTemplates;

View File

@ -39,7 +39,7 @@ ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo)
m_DebugInfo = debugInfo; m_DebugInfo = debugInfo;
} }
void ConfigItemBuilder::SetType(const String& type) void ConfigItemBuilder::SetType(const Type::Ptr& type)
{ {
m_Type = type; m_Type = type;
} }
@ -91,24 +91,23 @@ void ConfigItemBuilder::SetIgnoreOnError(bool ignoreOnError)
ConfigItem::Ptr ConfigItemBuilder::Compile(void) ConfigItem::Ptr ConfigItemBuilder::Compile(void)
{ {
if (m_Type.IsEmpty()) { if (!m_Type) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "The type name of an object may not be empty"; msgbuf << "The type of an object must be specified";
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo));
} }
Type::Ptr ptype = Type::GetByName(m_Type); ConfigType *ctype = dynamic_cast<ConfigType *>(m_Type.get());
ConfigType *ctype = dynamic_cast<ConfigType *>(ptype.get());
if (!ctype) { if (!ctype) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "The type '" + m_Type + "' is unknown"; msgbuf << "The type '" + m_Type->GetName() + "' cannot be used for config objects";
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo));
} }
if (m_Name.FindFirstOf("!") != String::NPos) { if (m_Name.FindFirstOf("!") != String::NPos) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Name for object '" << m_Name << "' of type '" << m_Type << "' is invalid: Object names may not contain '!'"; msgbuf << "Name for object '" << m_Name << "' of type '" << m_Type->GetName() << "' is invalid: Object names may not contain '!'";
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), m_DebugInfo));
} }

View File

@ -42,7 +42,7 @@ public:
ConfigItemBuilder(void); ConfigItemBuilder(void);
explicit ConfigItemBuilder(const DebugInfo& debugInfo); explicit ConfigItemBuilder(const DebugInfo& debugInfo);
void SetType(const String& type); void SetType(const Type::Ptr& 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 Dictionary::Ptr& scope);
@ -57,7 +57,7 @@ public:
ConfigItem::Ptr Compile(void); ConfigItem::Ptr Compile(void);
private: private:
String m_Type; /**< The object type. */ Type::Ptr m_Type; /**< The object type. */
String m_Name; /**< The name. */ String m_Name; /**< The name. */
bool m_Abstract; /**< Whether the item is abstract. */ bool m_Abstract; /**< Whether the item is abstract. */
std::vector<Expression *> m_Expressions; /**< Expressions for this item. */ std::vector<Expression *> m_Expressions; /**< Expressions for this item. */

View File

@ -745,7 +745,7 @@ ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi
if (!name.IsString()) if (!name.IsString())
BOOST_THROW_EXCEPTION(ScriptError("Template/object name must be a string", m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Template/object name must be a string", m_DebugInfo));
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, name); ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(Type::GetByName(type), name);
if (!item) if (!item)
BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Import references unknown template: '" + name + "'", m_DebugInfo));
@ -767,8 +767,9 @@ ExpressionResult ImportDefaultTemplatesExpression::DoEvaluate(ScriptFrame& frame
BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Imports are not allowed in sandbox mode.", m_DebugInfo));
String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo); String type = VMOps::GetField(frame.Self, "type", frame.Sandboxed, m_DebugInfo);
Type::Ptr ptype = Type::GetByName(type);
for (const ConfigItem::Ptr& item : ConfigItem::GetDefaultTemplates(type)) { for (const ConfigItem::Ptr& item : ConfigItem::GetDefaultTemplates(ptype)) {
Dictionary::Ptr scope = item->GetScope(); Dictionary::Ptr scope = item->GetScope();
if (scope) if (scope)
@ -803,6 +804,10 @@ ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi
if (frame.Sandboxed) if (frame.Sandboxed)
BOOST_THROW_EXCEPTION(ScriptError("Object definitions are not allowed in sandbox mode.", m_DebugInfo)); BOOST_THROW_EXCEPTION(ScriptError("Object definitions are not allowed in sandbox mode.", m_DebugInfo));
ExpressionResult typeres = m_Type->Evaluate(frame, dhint);
CHECK_RESULT(typeres);
Type::Ptr type = typeres.GetValue();
String name; String name;
if (m_Name) { if (m_Name) {
@ -812,7 +817,7 @@ ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi
name = nameres.GetValue(); name = nameres.GetValue();
} }
return VMOps::NewObject(frame, m_Abstract, m_Type, name, m_Filter, m_Zone, return VMOps::NewObject(frame, m_Abstract, type, name, m_Filter, m_Zone,
m_Package, m_DefaultTmpl, m_IgnoreOnError, m_ClosedVars, m_Expression, m_DebugInfo); m_Package, m_DefaultTmpl, m_IgnoreOnError, m_ClosedVars, m_Expression, m_DebugInfo);
} }

View File

@ -888,7 +888,7 @@ private:
class I2_CONFIG_API ObjectExpression : public DebuggableExpression class I2_CONFIG_API ObjectExpression : public DebuggableExpression
{ {
public: public:
ObjectExpression(bool abstract, const String& type, Expression *name, Expression *filter, ObjectExpression(bool abstract, Expression *type, Expression *name, Expression *filter,
const String& zone, const String& package, std::map<String, Expression *> *closedVars, const String& zone, const String& package, std::map<String, Expression *> *closedVars,
bool defaultTmpl, bool ignoreOnError, Expression *expression, const DebugInfo& debugInfo = DebugInfo()) bool defaultTmpl, bool ignoreOnError, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
: DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(type), : DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(type),
@ -915,7 +915,7 @@ protected:
private: private:
bool m_Abstract; bool m_Abstract;
String m_Type; Expression *m_Type;
Expression *m_Name; Expression *m_Name;
boost::shared_ptr<Expression> m_Filter; boost::shared_ptr<Expression> m_Filter;
String m_Zone; String m_Zone;

View File

@ -126,7 +126,7 @@ public:
return Empty; return Empty;
} }
static inline Value NewObject(ScriptFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter, static inline Value NewObject(ScriptFrame& frame, bool abstract, const Type::Ptr& type, const String& name, const boost::shared_ptr<Expression>& filter,
const String& zone, const String& package, bool defaultTmpl, bool ignoreOnError, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo()) const String& zone, const String& package, bool defaultTmpl, bool ignoreOnError, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
{ {
ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo); ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo);
@ -134,9 +134,7 @@ public:
String checkName = name; String checkName = name;
if (!abstract) { if (!abstract) {
Type::Ptr ptype = Type::GetByName(type); NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
NameComposer *nc = dynamic_cast<NameComposer *>(ptype.get());
if (nc) if (nc)
checkName = nc->MakeName(name, Dictionary::Ptr()); checkName = nc->MakeName(name, Dictionary::Ptr());
@ -147,11 +145,17 @@ public:
if (oldItem) { if (oldItem) {
std::ostringstream msgbuf; std::ostringstream msgbuf;
msgbuf << "Object '" << name << "' of type '" << type << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo(); msgbuf << "Object '" << name << "' of type '" << type->GetName() << "' re-defined: " << debugInfo << "; previous definition: " << oldItem->GetDebugInfo();
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo)); BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
} }
} }
if (filter && !ObjectRule::IsValidSourceType(type->GetName())) {
std::ostringstream msgbuf;
msgbuf << "Object '" << name << "' of type '" << type->GetName() << "' must not have 'assign where' and 'ignore where' rules: " << debugInfo;
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debugInfo));
}
item->SetType(type); item->SetType(type);
item->SetName(name); item->SetName(name);

View File

@ -50,7 +50,7 @@ bool Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, cons
#endif /* _DEBUG */ #endif /* _DEBUG */
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("Dependency"); builder->SetType(Dependency::TypeInstance);
builder->SetName(name); builder->SetName(name);
builder->SetScope(frame.Locals->ShallowClone()); builder->SetScope(frame.Locals->ShallowClone());
builder->SetIgnoreOnError(rule.GetIgnoreOnError()); builder->SetIgnoreOnError(rule.GetIgnoreOnError());

View File

@ -62,7 +62,7 @@ void HostGroup::EvaluateObjectRules(const Host::Ptr& host)
{ {
CONTEXT("Evaluating group memberships for host '" + host->GetName() + "'"); CONTEXT("Evaluating group memberships for host '" + host->GetName() + "'");
for (const ConfigItem::Ptr& group : ConfigItem::GetItems("HostGroup")) for (const ConfigItem::Ptr& group : ConfigItem::GetItems(HostGroup::TypeInstance))
{ {
if (!group->GetFilter()) if (!group->GetFilter())
continue; continue;

View File

@ -50,7 +50,7 @@ bool Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, co
#endif /* _DEBUG */ #endif /* _DEBUG */
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("Notification"); builder->SetType(Notification::TypeInstance);
builder->SetName(name); builder->SetName(name);
builder->SetScope(frame.Locals->ShallowClone()); builder->SetScope(frame.Locals->ShallowClone());
builder->SetIgnoreOnError(rule.GetIgnoreOnError()); builder->SetIgnoreOnError(rule.GetIgnoreOnError());

View File

@ -49,7 +49,7 @@ bool ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkabl
#endif /* _DEBUG */ #endif /* _DEBUG */
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("ScheduledDowntime"); builder->SetType(ScheduledDowntime::TypeInstance);
builder->SetName(name); builder->SetName(name);
builder->SetScope(frame.Locals->ShallowClone()); builder->SetScope(frame.Locals->ShallowClone());
builder->SetIgnoreOnError(rule.GetIgnoreOnError()); builder->SetIgnoreOnError(rule.GetIgnoreOnError());

View File

@ -48,7 +48,7 @@ bool Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& nam
#endif /* _DEBUG */ #endif /* _DEBUG */
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("Service"); builder->SetType(Service::TypeInstance);
builder->SetName(name); builder->SetName(name);
builder->SetScope(frame.Locals->ShallowClone()); builder->SetScope(frame.Locals->ShallowClone());
builder->SetIgnoreOnError(rule.GetIgnoreOnError()); builder->SetIgnoreOnError(rule.GetIgnoreOnError());

View File

@ -65,7 +65,7 @@ void ServiceGroup::EvaluateObjectRules(const Service::Ptr& service)
{ {
CONTEXT("Evaluating group membership for service '" + service->GetName() + "'"); CONTEXT("Evaluating group membership for service '" + service->GetName() + "'");
for (const ConfigItem::Ptr& group : ConfigItem::GetItems("ServiceGroup")) for (const ConfigItem::Ptr& group : ConfigItem::GetItems(ServiceGroup::TypeInstance))
{ {
if (!group->GetFilter()) if (!group->GetFilter())
continue; continue;

View File

@ -62,7 +62,7 @@ void UserGroup::EvaluateObjectRules(const User::Ptr& user)
{ {
CONTEXT("Evaluating group membership for user '" + user->GetName() + "'"); CONTEXT("Evaluating group membership for user '" + user->GetName() + "'");
for (const ConfigItem::Ptr& group : ConfigItem::GetItems("UserGroup")) for (const ConfigItem::Ptr& group : ConfigItem::GetItems(UserGroup::TypeInstance))
{ {
if (!group->GetFilter()) if (!group->GetFilter())
continue; continue;

View File

@ -195,7 +195,7 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
DeleteObjectHelper(parentObj, cascade, errors); DeleteObjectHelper(parentObj, cascade, errors);
} }
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type->GetName(), object->GetName()); ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, object->GetName());
try { try {
/* mark this object for cluster delete event */ /* mark this object for cluster delete event */

View File

@ -40,7 +40,7 @@ public:
{ {
Dictionary::Ptr target = new Dictionary(); Dictionary::Ptr target = new Dictionary();
target->Set("name", item->GetName()); target->Set("name", item->GetName());
target->Set("type", item->GetType()); target->Set("type", item->GetType()->GetName());
DebugInfo di = item->GetDebugInfo(); DebugInfo di = item->GetDebugInfo();
Dictionary::Ptr dinfo = new Dictionary(); Dictionary::Ptr dinfo = new Dictionary();
@ -57,7 +57,9 @@ public:
virtual void FindTargets(const String& type, virtual void FindTargets(const String& type,
const boost::function<void (const Value&)>& addTarget) const override const boost::function<void (const Value&)>& addTarget) const override
{ {
for (const ConfigItem::Ptr& item : ConfigItem::GetItems(type)) { Type::Ptr ptype = Type::GetByName(type);
for (const ConfigItem::Ptr& item : ConfigItem::GetItems(ptype)) {
if (item->IsAbstract()) if (item->IsAbstract())
addTarget(GetTargetForTemplate(item)); addTarget(GetTargetForTemplate(item));
} }
@ -65,7 +67,9 @@ public:
virtual Value GetTargetByName(const String& type, const String& name) const override virtual Value GetTargetByName(const String& type, const String& name) const override
{ {
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, name); Type::Ptr ptype = Type::GetByName(type);
ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(ptype, name);
if (!item || !item->IsAbstract()) if (!item || !item->IsAbstract())
BOOST_THROW_EXCEPTION(std::invalid_argument("Template does not exist.")); BOOST_THROW_EXCEPTION(std::invalid_argument("Template does not exist."));