diff --git a/lib/cli/daemonutility.cpp b/lib/cli/daemonutility.cpp index 178e9fa89..e89b40a9a 100644 --- a/lib/cli/daemonutility.cpp +++ b/lib/cli/daemonutility.cpp @@ -143,7 +143,7 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector& configs, if (!success) return false; - String appType = ScriptGlobal::Get("ApplicationType", &Empty); + Type::Ptr appType = Type::GetByName(ScriptGlobal::Get("ApplicationType", &Empty)); if (ConfigItem::GetItems(appType).empty()) { ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(); diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 69205a14e..a02bf2915 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -372,7 +372,7 @@ object: context->m_Assign.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); } @@ -388,9 +388,6 @@ object: if (!abstract && defaultTmpl) 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(); context->m_SeenAssign.pop(); @@ -406,9 +403,6 @@ object: Expression *filter = NULL; 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) { Expression *rex = new LogicalNegateExpression(ignore, DebugInfoRange(@2, @5)); @@ -416,13 +410,10 @@ object: } else filter = assign; } else if (seen_ignore) { - if (!ObjectRule::IsValidSourceType(type)) - 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))); + BOOST_THROW_EXCEPTION(ScriptError("object rule 'ignore where' cannot be used without 'assign where'", 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)); } ; diff --git a/lib/config/configitem.cpp b/lib/config/configitem.cpp index 91a8922f5..48639dfbe 100644 --- a/lib/config/configitem.cpp +++ b/lib/config/configitem.cpp @@ -59,7 +59,7 @@ REGISTER_SCRIPTFUNCTION_NS(Internal, run_with_activation_context, &ConfigItem::R * @param exprl Expression list for the item. * @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& exprl, const boost::shared_ptr& filter, bool defaultTmpl, bool ignoreOnError, const DebugInfo& debuginfo, const Dictionary::Ptr& scope, @@ -77,7 +77,7 @@ ConfigItem::ConfigItem(const String& type, const String& name, * * @returns The type. */ -String ConfigItem::GetType(void) const +Type::Ptr ConfigItem::GetType(void) const { return m_Type; } @@ -157,7 +157,7 @@ class DefaultValidationUtils : public ValidationUtils public: 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())) return false; @@ -180,7 +180,7 @@ ConfigObject::Ptr ConfigItem::Commit(bool discard) #endif /* I2_DEBUG */ /* Make sure the type is valid. */ - Type::Ptr type = Type::GetByName(GetType()); + Type::Ptr type = GetType(); if (!type || !ConfigObject::TypeInstance->IsAssignableFrom(type)) 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) { - Type::Ptr type = Type::GetByName(m_Type); - m_ActivationContext = ActivationContext::GetCurrentContext(); boost::mutex::scoped_lock lock(m_Mutex); /* If this is a non-abstract object with a composite name * we register it in m_UnnamedItems instead of m_Items. */ - if (!m_Abstract && dynamic_cast(type.get())) + if (!m_Abstract && dynamic_cast(m_Type.get())) m_UnnamedItems.push_back(this); else { auto& items = m_Items[m_Type]; @@ -337,7 +335,7 @@ void ConfigItem::Register(void) if (it != items.end()) { std::ostringstream msgbuf; - msgbuf << "A configuration item of type '" << GetType() + msgbuf << "A configuration item of type '" << m_Type->GetName() << "' and name '" << GetName() << "' already exists (" << it->second->GetDebugInfo() << "), new declaration: " << GetDebugInfo(); 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. * @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); @@ -442,26 +440,26 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue if (upq.HasExceptions()) return false; - std::set types; + std::set types; for (const Type::Ptr& type : Type::GetAllTypes()) { if (ConfigObject::TypeInstance->IsAssignableFrom(type)) - types.insert(type->GetName()); + types.insert(type); } - std::set completed_types; + std::set completed_types; 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()) continue; - Type::Ptr ptype = Type::GetByName(type); bool unresolved_dep = false; /* skip this type (for now) if there are unresolved load dependencies */ - for (const String& loadDep : ptype->GetLoadDependencies()) { - if (types.find(loadDep) != types.end() && completed_types.find(loadDep) == completed_types.end()) { + for (const String& loadDep : type->GetLoadDependencies()) { + Type::Ptr pLoadDep = Type::GetByName(loadDep); + if (types.find(pLoadDep) != types.end() && completed_types.find(pLoadDep) == completed_types.end()) { unresolved_dep = true; break; } @@ -508,17 +506,17 @@ bool ConfigItem::CommitNewItems(const ActivationContext::Ptr& context, WorkQueue if (upq.HasExceptions()) return false; - for (const String& loadDep : ptype->GetLoadDependencies()) { + for (const String& loadDep : type->GetLoadDependencies()) { for (const ItemPair& ip : items) { const ConfigItem::Ptr& item = ip.first; if (!item->m_Object) continue; - if (item->m_Type == loadDep) { + if (item->m_Type->GetName() == loadDep) { upq.Enqueue([&]() { 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; } -std::vector ConfigItem::GetItems(const String& type) +std::vector ConfigItem::GetItems(const Type::Ptr& type) { std::vector items; @@ -703,7 +701,7 @@ std::vector ConfigItem::GetItems(const String& type) return items; } -std::vector ConfigItem::GetDefaultTemplates(const String& type) +std::vector ConfigItem::GetDefaultTemplates(const Type::Ptr& type) { std::vector items; diff --git a/lib/config/configitem.hpp b/lib/config/configitem.hpp index 75ab63595..df5c1cddd 100644 --- a/lib/config/configitem.hpp +++ b/lib/config/configitem.hpp @@ -40,14 +40,14 @@ class I2_CONFIG_API ConfigItem : public Object { public: 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& exprl, const boost::shared_ptr& filter, bool defaultTmpl, bool ignoreOnError, const DebugInfo& debuginfo, const Dictionary::Ptr& scope, const String& zone, const String& package); - String GetType(void) const; + Type::Ptr GetType(void) const; String GetName(void) const; bool IsAbstract(void) const; bool IsDefaultTemplate(void) const; @@ -66,7 +66,7 @@ public: ConfigObject::Ptr GetObject(void) const; - static ConfigItem::Ptr GetByTypeAndName(const String& type, + static ConfigItem::Ptr GetByTypeAndName(const Type::Ptr& type, const String& name); static bool CommitItems(const ActivationContext::Ptr& context, WorkQueue& upq, std::vector& newItems, bool silent = false); @@ -74,13 +74,13 @@ public: static bool RunWithActivationContext(const Function::Ptr& function); - static std::vector GetItems(const String& type); - static std::vector GetDefaultTemplates(const String& type); + static std::vector GetItems(const Type::Ptr& type); + static std::vector GetDefaultTemplates(const Type::Ptr& type); static void RemoveIgnoredItems(const String& allowedConfigPath); private: - String m_Type; /**< The object type. */ + Type::Ptr m_Type; /**< The object type. */ String m_Name; /**< The name. */ bool m_Abstract; /**< Whether this is a template. */ @@ -99,7 +99,7 @@ private: static boost::mutex m_Mutex; typedef std::map ItemMap; - typedef std::map TypeMap; + typedef std::map TypeMap; static TypeMap m_Items; /**< All registered configuration items. */ static TypeMap m_DefaultTemplates; diff --git a/lib/config/configitembuilder.cpp b/lib/config/configitembuilder.cpp index 8e3f0d6bd..9e40c65b8 100644 --- a/lib/config/configitembuilder.cpp +++ b/lib/config/configitembuilder.cpp @@ -39,7 +39,7 @@ ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo) m_DebugInfo = debugInfo; } -void ConfigItemBuilder::SetType(const String& type) +void ConfigItemBuilder::SetType(const Type::Ptr& type) { m_Type = type; } @@ -91,24 +91,23 @@ void ConfigItemBuilder::SetIgnoreOnError(bool ignoreOnError) ConfigItem::Ptr ConfigItemBuilder::Compile(void) { - if (m_Type.IsEmpty()) { + if (!m_Type) { 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)); } - Type::Ptr ptype = Type::GetByName(m_Type); - ConfigType *ctype = dynamic_cast(ptype.get()); + ConfigType *ctype = dynamic_cast(m_Type.get()); if (!ctype) { 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)); } if (m_Name.FindFirstOf("!") != String::NPos) { 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)); } diff --git a/lib/config/configitembuilder.hpp b/lib/config/configitembuilder.hpp index f0d49607f..6a406ac3e 100644 --- a/lib/config/configitembuilder.hpp +++ b/lib/config/configitembuilder.hpp @@ -42,7 +42,7 @@ public: ConfigItemBuilder(void); explicit ConfigItemBuilder(const DebugInfo& debugInfo); - void SetType(const String& type); + void SetType(const Type::Ptr& type); void SetName(const String& name); void SetAbstract(bool abstract); void SetScope(const Dictionary::Ptr& scope); @@ -57,7 +57,7 @@ public: ConfigItem::Ptr Compile(void); private: - String m_Type; /**< The object type. */ + Type::Ptr m_Type; /**< The object type. */ String m_Name; /**< The name. */ bool m_Abstract; /**< Whether the item is abstract. */ std::vector m_Expressions; /**< Expressions for this item. */ diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index a3b00ff20..b0e1b6cad 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -745,7 +745,7 @@ ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi if (!name.IsString()) 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) 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)); 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(); if (scope) @@ -803,6 +804,10 @@ ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi if (frame.Sandboxed) 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; if (m_Name) { @@ -812,7 +817,7 @@ ExpressionResult ObjectExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi 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); } diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index 483f8e0ca..a4c46dc06 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -888,7 +888,7 @@ private: class I2_CONFIG_API ObjectExpression : public DebuggableExpression { 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 *closedVars, bool defaultTmpl, bool ignoreOnError, Expression *expression, const DebugInfo& debugInfo = DebugInfo()) : DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(type), @@ -915,7 +915,7 @@ protected: private: bool m_Abstract; - String m_Type; + Expression *m_Type; Expression *m_Name; boost::shared_ptr m_Filter; String m_Zone; diff --git a/lib/config/vmops.hpp b/lib/config/vmops.hpp index 0c1d45800..a8661faa3 100644 --- a/lib/config/vmops.hpp +++ b/lib/config/vmops.hpp @@ -126,7 +126,7 @@ public: return Empty; } - static inline Value NewObject(ScriptFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr& filter, + static inline Value NewObject(ScriptFrame& frame, bool abstract, const Type::Ptr& type, const String& name, const boost::shared_ptr& filter, const String& zone, const String& package, bool defaultTmpl, bool ignoreOnError, std::map *closedVars, const boost::shared_ptr& expression, const DebugInfo& debugInfo = DebugInfo()) { ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo); @@ -134,9 +134,7 @@ public: String checkName = name; if (!abstract) { - Type::Ptr ptype = Type::GetByName(type); - - NameComposer *nc = dynamic_cast(ptype.get()); + NameComposer *nc = dynamic_cast(type.get()); if (nc) checkName = nc->MakeName(name, Dictionary::Ptr()); @@ -147,11 +145,17 @@ public: if (oldItem) { 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)); } } + 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->SetName(name); diff --git a/lib/icinga/dependency-apply.cpp b/lib/icinga/dependency-apply.cpp index 7bf67b929..34b0cf93a 100644 --- a/lib/icinga/dependency-apply.cpp +++ b/lib/icinga/dependency-apply.cpp @@ -50,7 +50,7 @@ bool Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, cons #endif /* _DEBUG */ ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); - builder->SetType("Dependency"); + builder->SetType(Dependency::TypeInstance); builder->SetName(name); builder->SetScope(frame.Locals->ShallowClone()); builder->SetIgnoreOnError(rule.GetIgnoreOnError()); diff --git a/lib/icinga/hostgroup.cpp b/lib/icinga/hostgroup.cpp index 13fffb11f..d13e12522 100644 --- a/lib/icinga/hostgroup.cpp +++ b/lib/icinga/hostgroup.cpp @@ -62,7 +62,7 @@ void HostGroup::EvaluateObjectRules(const Host::Ptr& host) { 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()) continue; diff --git a/lib/icinga/notification-apply.cpp b/lib/icinga/notification-apply.cpp index 91b65ace4..bf01d04fd 100644 --- a/lib/icinga/notification-apply.cpp +++ b/lib/icinga/notification-apply.cpp @@ -50,7 +50,7 @@ bool Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, co #endif /* _DEBUG */ ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); - builder->SetType("Notification"); + builder->SetType(Notification::TypeInstance); builder->SetName(name); builder->SetScope(frame.Locals->ShallowClone()); builder->SetIgnoreOnError(rule.GetIgnoreOnError()); diff --git a/lib/icinga/scheduleddowntime-apply.cpp b/lib/icinga/scheduleddowntime-apply.cpp index 0c8bab59e..60028fe7f 100644 --- a/lib/icinga/scheduleddowntime-apply.cpp +++ b/lib/icinga/scheduleddowntime-apply.cpp @@ -49,7 +49,7 @@ bool ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkabl #endif /* _DEBUG */ ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); - builder->SetType("ScheduledDowntime"); + builder->SetType(ScheduledDowntime::TypeInstance); builder->SetName(name); builder->SetScope(frame.Locals->ShallowClone()); builder->SetIgnoreOnError(rule.GetIgnoreOnError()); diff --git a/lib/icinga/service-apply.cpp b/lib/icinga/service-apply.cpp index 09e85f9f9..6c2e594d3 100644 --- a/lib/icinga/service-apply.cpp +++ b/lib/icinga/service-apply.cpp @@ -48,7 +48,7 @@ bool Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& nam #endif /* _DEBUG */ ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); - builder->SetType("Service"); + builder->SetType(Service::TypeInstance); builder->SetName(name); builder->SetScope(frame.Locals->ShallowClone()); builder->SetIgnoreOnError(rule.GetIgnoreOnError()); diff --git a/lib/icinga/servicegroup.cpp b/lib/icinga/servicegroup.cpp index d3442ce69..250d1e8a3 100644 --- a/lib/icinga/servicegroup.cpp +++ b/lib/icinga/servicegroup.cpp @@ -65,7 +65,7 @@ void ServiceGroup::EvaluateObjectRules(const Service::Ptr& service) { 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()) continue; diff --git a/lib/icinga/usergroup.cpp b/lib/icinga/usergroup.cpp index ddd349f5e..24d3193db 100644 --- a/lib/icinga/usergroup.cpp +++ b/lib/icinga/usergroup.cpp @@ -62,7 +62,7 @@ void UserGroup::EvaluateObjectRules(const User::Ptr& user) { 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()) continue; diff --git a/lib/remote/configobjectutility.cpp b/lib/remote/configobjectutility.cpp index da090825c..77c2fb895 100644 --- a/lib/remote/configobjectutility.cpp +++ b/lib/remote/configobjectutility.cpp @@ -195,7 +195,7 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo DeleteObjectHelper(parentObj, cascade, errors); } - ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type->GetName(), object->GetName()); + ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, object->GetName()); try { /* mark this object for cluster delete event */ diff --git a/lib/remote/templatequeryhandler.cpp b/lib/remote/templatequeryhandler.cpp index 52e1c45e0..4d8124286 100644 --- a/lib/remote/templatequeryhandler.cpp +++ b/lib/remote/templatequeryhandler.cpp @@ -40,7 +40,7 @@ public: { Dictionary::Ptr target = new Dictionary(); target->Set("name", item->GetName()); - target->Set("type", item->GetType()); + target->Set("type", item->GetType()->GetName()); DebugInfo di = item->GetDebugInfo(); Dictionary::Ptr dinfo = new Dictionary(); @@ -57,7 +57,9 @@ public: virtual void FindTargets(const String& type, const boost::function& 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()) addTarget(GetTargetForTemplate(item)); } @@ -65,7 +67,9 @@ public: 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()) BOOST_THROW_EXCEPTION(std::invalid_argument("Template does not exist."));