10#include "TypeService.h"
12#include <Atlas/Objects/Operation.h>
17using Atlas::Objects::Root;
18using namespace Atlas::Objects::Operation;
27 m_name(std::move(id)),
30 if (m_name ==
"root") {
38 m_name(atype->getId()),
41 if (m_name ==
"root") {
51 warning() <<
"calling isA on unbound type " << m_name;
59 return m_ancestors.find(tp) != m_ancestors.end();
65 warning() <<
"calling isA on unbound type " << m_name;
67 if (m_name == typeName) {
71 auto I = std::find_if(m_ancestors.begin(), m_ancestors.end(), [&](
const TypeInfo* typeInfo){ return typeInfo->m_name == typeName;});
72 return I != m_ancestors.end();
78 return !m_unresolvedChildren.empty();
83 if (m_unresolvedChildren.empty()) {
84 error() <<
"Type " << m_name <<
" has no unresolved children";
88 auto uchildren = m_unresolvedChildren;
89 for (
const auto& child : uchildren) {
93 assert(m_unresolvedChildren.empty());
99 if (atype->getId() != m_name) {
100 error() <<
"mis-targeted INFO operation for " << atype->getId() <<
" arrived at " << m_name;
105 if (atype->hasAttr(
"children"))
107 const Atlas::Message::Element childElem(atype->getAttr(
"children"));
108 if (!childElem.isList()) {
109 warning() <<
"'children' element is not of list type when processing entity type " << m_name <<
".";
111 const Atlas::Message::ListType & children(childElem.asList());
113 for (
const auto& childElement : children) {
114 if (childElement.isString()) {
117 if (child && m_children.find(child) != m_children.end()) {
121 m_unresolvedChildren.insert(childElement.String());
129 Atlas::Message::Element entitiesElement;
130 if (atype->copyAttr(
"entities", entitiesElement) == 0) {
131 if (entitiesElement.isList()) {
132 m_entities = std::move(entitiesElement.List());
140 m_objType = atype->getObjtype();
142 extractDefaultProperties(atype);
148 auto oldProperties = std::move(m_properties);
150 extractDefaultProperties(atype);
152 for (
auto& entry : m_properties) {
153 auto oldEntryI = oldProperties.find(entry.first);
154 if (oldEntryI == oldProperties.end() || oldEntryI->second != entry.second) {
158 if (oldEntryI != oldProperties.end()) {
159 oldProperties.erase(oldEntryI);
164 for (
auto& entry : oldProperties) {
173 if (&m_typeService != &x.m_typeService)
174 warning() <<
"comparing TypeInfos from different type services, bad";
176 return (m_name == x.m_name);
181 return m_name < x.m_name;
184void TypeInfo::setParent(
TypeInfo* tp)
192 if (m_ancestors.count(tp)) {
193 error() <<
"Adding " << tp->m_name <<
" as parent of " << m_name <<
", but already marked as ancestor";
204void TypeInfo::addChild(TypeInfo* tp)
208 error() <<
"Attempt to add " <<
getName() <<
" as a child if itself";
211 if (tp->getName() == this->getName()) {
212 error() <<
"Attempt to add " <<
getName() <<
" as child to identical parent ";
216 if (m_children.count(tp)) {
219 m_unresolvedChildren.erase(tp->getName());
221 m_children.insert(tp);
226void TypeInfo::addAncestor(TypeInfo* tp)
231 assert(m_children.count(tp) == 0);
232 assert(m_ancestors.count(tp) == 0);
234 m_ancestors.insert(tp);
236 auto& parentAncestors = tp->m_ancestors;
237 m_ancestors.insert(parentAncestors.begin(), parentAncestors.end());
240 for (
auto child : m_children) {
241 child->addAncestor(tp);
245void TypeInfo::extractDefaultProperties(
const Atlas::Objects::Root& atype)
248 if (atype->hasAttr(
"properties")) {
249 auto propertiesElement = atype->getAttr(
"properties");
250 if (!propertiesElement.isMap()) {
251 warning() <<
"'properties' element is not of map type when processing entity type " << m_name <<
".";
253 m_properties = propertiesElement.Map();
262 auto A = m_properties.find(propertyName);
263 if (A != m_properties.end()) {
280 auto I = m_properties.find(propertyName);
281 if (I == m_properties.end()) {
282 m_properties.insert(Atlas::Message::MapType::value_type(propertyName, element));
293 Atlas::Message::MapType::const_iterator J = child->m_properties.find(propertyName);
294 if (J == child->m_properties.end()) {
295 child->onPropertyChanges(propertyName, element);
305void TypeInfo::validateBind()
311 if (!m_parent->
isBound())
return;
319 for (
auto child : m_children) {
320 child->validateBind();
The representation of an Atlas type (i.e a class or operation definition). This class supports effice...
bool operator<(const TypeInfo &x) const
efficent ordering of type (uses type ids if possible)
bool isA(TypeInfo *ti) const
Test whether this type inherits (directly or indirectly) from the specific class. If this type is not...
const std::string & getName() const
the unique type name (matches the Atlas type)
bool operator==(const TypeInfo &x) const
efficent comparisom of types (uses type ids if possible)
void processTypeData(const Atlas::Objects::Root &atype)
process the INFO data
void refresh()
Request update to the type info from the server.
const Atlas::Message::Element * getProperty(const std::string &propertyName) const
Gets the value of the named property. This method will search through both this instance and all of i...
void setProperty(const std::string &propertyName, const Atlas::Message::Element &element)
Sets a property.
sigc::signal< void, const std::string &, const Atlas::Message::Element & > PropertyChanges
Emitted before an property changes. The first parameter is the name of the property,...
const TypeInfo * getParent() const
Gets the currently resolved parent TypeInfo instances.
sigc::signal< void > Bound
Emitted when the type is bound, i.e there is an unbroken graph of TypeInfo instances through every an...
TypeInfo(std::string id, TypeService &)
forward constructor, when data is not available
bool isBound() const
Check the bound flag for this node; if false then recursivley check parents until an authorative is f...
const std::set< TypeInfo * > & getChildren() const
Gets the currently resolved child TypeInfo instances.
bool hasUnresolvedChildren() const
Test if there are child types of the type, which have not yet been retrieved from the server.
void onPropertyChanges(const std::string &propertyName, const Atlas::Message::Element &element)
Called before the PropertyChanges signal is emitted. This call is made before an property is changed....
void resolveChildren()
Retrive all child types from the server. This will log an error and do nothing if no unresolved child...
void sendRequest(const std::string &id)
TypeInfo * findTypeByName(const std::string &tynm)
sigc::signal< void, TypeInfo * > BoundType
TypeInfo * getTypeByName(const std::string &tynm)