}
}
+ context.LinkItems();
+
/* Don't validate if we have already encountered at least one error. */
if (!hasError)
- context.Validate();
+ context.ValidateItems();
hasError = false;
return m_Unit;
}
-void ConfigCompilerContext::Validate(void)
+void ConfigCompilerContext::LinkItems(void)
+{
+ SetContext(this);
+
+ BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
+ item->Link();
+ }
+
+ SetContext(NULL);
+}
+
+void ConfigCompilerContext::ValidateItems(void)
{
SetContext(this);
ASSERT(m_Context == NULL);
Log(LogInformation, "config", "Activating config items in compilation unit '" + m_Unit + "'");
+ BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
+ item->Register();
+ }
+
BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
item->Commit();
}
String GetUnit(void) const;
- void Validate(void);
+ void LinkItems(void);
+ void ValidateItems(void);
void ActivateItems(void);
static void SetContext(ConfigCompilerContext *context);
const String& unit, bool abstract, const ExpressionList::Ptr& exprl,
const std::vector<String>& parents, const DebugInfo& debuginfo)
: m_Type(type), m_Name(name), m_Unit(unit), m_Abstract(abstract),
- m_ExpressionList(exprl), m_Parents(parents), m_DebugInfo(debuginfo)
+ m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo)
{
}
*
* @returns The list of parents.
*/
-std::vector<String> ConfigItem::GetParents(void) const
+std::vector<ConfigItem::Ptr> ConfigItem::GetParents(void) const
{
return m_Parents;
}
-Dictionary::Ptr ConfigItem::Link(void) const
-{
- Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
- InternalLink(attrs);
- return attrs;
-}
-
-/**
- * Calculates the object's properties based on parent objects and the object's
- * expression list.
- *
- * @param dictionary The dictionary that should be used to store the
- * properties.
- */
-void ConfigItem::InternalLink(const Dictionary::Ptr& dictionary) const
+void ConfigItem::Link(void)
{
ObjectLock olock(this);
- BOOST_FOREACH(const String& name, m_Parents) {
+ m_LinkedExpressionList = boost::make_shared<ExpressionList>();
+
+ m_Parents.clear();
+
+ BOOST_FOREACH(const String& name, m_ParentNames) {
ConfigItem::Ptr parent;
ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
BOOST_THROW_EXCEPTION(std::invalid_argument(message.str()));
}
- parent->InternalLink(dictionary);
+ parent->Link();
+
+ ExpressionList::Ptr pexprl = parent->GetLinkedExpressionList();
+ m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, pexprl, m_DebugInfo));
+
+ m_Parents.push_back(parent);
}
- m_ExpressionList->Execute(dictionary);
+ m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, m_ExpressionList, m_DebugInfo));
+}
+
+ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void) const
+{
+ ObjectLock olock(this);
+
+ return m_LinkedExpressionList;
}
/**
dobj = dtype->GetObject(m_Name);
/* Register this item with its parents. */
- BOOST_FOREACH(const String& parentName, m_Parents) {
- ConfigItem::Ptr parent = GetObject(m_Type, parentName);
+ BOOST_FOREACH(const ConfigItem::Ptr& parent, m_Parents) {
parent->m_ChildObjects.insert(self);
}
double tx = DynamicObject::GetCurrentTx();
- Dictionary::Ptr properties = Link();
+ Link();
+
+ Dictionary::Ptr properties = boost::make_shared<Dictionary>();
+ GetLinkedExpressionList()->Execute(properties);
{
ObjectLock olock(properties);
return dobj;
}
+/**
+ * Registers the configuration item.
+ */
+void ConfigItem::Register(void)
+{
+ ASSERT(!OwnsLock());
+
+ {
+ ObjectLock olock(this);
+
+ m_Items[std::make_pair(m_Type, m_Name)] = GetSelf();
+ }
+}
+
/**
* Unregisters the configuration item.
*/
{
ASSERT(OwnsLock());
- BOOST_FOREACH(const String& parentName, m_Parents) {
- ConfigItem::Ptr parent = GetObject(GetType(), parentName);
-
- if (parent)
- parent->m_ChildObjects.erase(GetSelf());
+ BOOST_FOREACH(const ConfigItem::Ptr& parent, m_Parents) {
+ parent->m_ChildObjects.erase(GetSelf());
}
}
fp << " inherits";
bool first = true;
- BOOST_FOREACH(const String& name, m_Parents) {
+ BOOST_FOREACH(const String& name, m_ParentNames) {
if (!first)
fp << ",";
else
String GetUnit(void) const;
bool IsAbstract(void) const;
- std::vector<String> GetParents(void) const;
+ std::vector<ConfigItem::Ptr> GetParents(void) const;
- ExpressionList::Ptr GetExpressionList(void) const;
+ void Link(void);
+ ExpressionList::Ptr GetLinkedExpressionList(void) const;
+
+ void GetProperties(void);
DynamicObject::Ptr Commit(void);
+ void Register(void);
void Unregister(void);
void Dump(std::ostream& fp) const;
DebugInfo GetDebugInfo(void) const;
- Dictionary::Ptr Link(void) const;
-
static ConfigItem::Ptr GetObject(const String& type,
const String& name);
static boost::signals2::signal<void (const ConfigItem::Ptr&)> OnRemoved;
private:
- void InternalLink(const Dictionary::Ptr& dictionary) const;
+ ExpressionList::Ptr GetExpressionList(void) const;
- void UnregisterFromParents(void);
+ void UnregisterFromParents(void);
- void OnParentCommitted(void);
+ void OnParentCommitted(void);
String m_Type; /**< The object type. */
String m_Name; /**< The name. */
bool m_Abstract; /**< Whether this is a template. */
ExpressionList::Ptr m_ExpressionList;
- std::vector<String> m_Parents; /**< The names of parent configuration
+ std::vector<String> m_ParentNames; /**< The names of parent configuration
items. */
+ std::vector<ConfigItem::Ptr> m_Parents;
DebugInfo m_DebugInfo; /**< Debug information. */
+ ExpressionList::Ptr m_LinkedExpressionList;
+
DynamicObject::WeakPtr m_DynamicObject; /**< The instantiated version
- * of this configuration
- * item */
- std::set<ConfigItem::WeakPtr> m_ChildObjects; /**< Instantiated items
+ * of this configuration item */
+ std::set<ConfigItem::WeakPtr> m_ChildObjects; /**< Instantiated items
* that inherit from this item */
static boost::mutex m_Mutex;
BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
}
- BOOST_FOREACH(const String& parent, m_Parents) {
- ConfigItem::Ptr item;
-
- ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
-
- if (context)
- item = context->GetItem(m_Type, parent);
-
- /* ignore already active objects while we're in the compiler
- * context and linking to existing items is disabled. */
- if (!item && (!context || (context->GetFlags() & CompilerLinkExisting)))
- item = ConfigItem::GetObject(m_Type, parent);
-
- if (!item) {
- std::ostringstream msgbuf;
- msgbuf << "The parent config item '" + parent + "' does not exist: " << m_DebugInfo;
- BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
- }
- }
-
ExpressionList::Ptr exprl = boost::make_shared<ExpressionList>();
Expression execExpr("", OperatorExecute, m_ExpressionList, m_DebugInfo);
void ConfigType::ValidateItem(const ConfigItem::Ptr& item) const
{
- Dictionary::Ptr attrs = item->Link();
-
/* Don't validate abstract items. */
if (item->IsAbstract())
return;
+ Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
+ item->GetLinkedExpressionList()->Execute(attrs);
+
std::vector<String> locations;
locations.push_back("Object '" + item->GetName() + "' (Type: '" + item->GetType() + "')");
fp << ", " << "\n";
}
+
+void Expression::Extract(const std::vector<String>& path, const ExpressionList::Ptr& result) const
+{
+ ASSERT(!path.empty());
+
+ if (path[0] == m_Key) {
+ if (path.size() > 1)
+ BOOST_THROW_EXCEPTION(std::invalid_argument("Specified path does not exist."));
+ else
+ result->AddExpression(*this);
+ } else if (m_Operator == OperatorExecute) {
+ ExpressionList::Ptr exprl = m_Value;
+ exprl->Extract(path, result);
+ }
+}
OperatorDivide
};
+class ExpressionList;
+
/**
* A configuration expression.
*
void Execute(const Dictionary::Ptr& dictionary) const;
void Dump(std::ostream& fp, int indent = 0) const;
+ void Extract(const std::vector<String>& path, const shared_ptr<ExpressionList>& result) const;
+
private:
String m_Key;
ExpressionOperator m_Operator;
expression.Dump(fp, indent);
}
}
+
+void ExpressionList::Extract(const std::vector<String>& path, const ExpressionList::Ptr& result) const
+{
+ BOOST_FOREACH(const Expression& expression, m_Expressions) {
+ expression.Extract(path, result);
+ }
+}
size_t GetLength(void) const;
+ void Extract(const std::vector<String>& path, const ExpressionList::Ptr& result) const;
+
private:
std::vector<Expression> m_Expressions;
};