9 #include "Exceptions.h"
10 #include "TypeService.h"
12 #include <Atlas/Objects/Operation.h>
17 using Atlas::Objects::Root;
18 using 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;
184 void 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";
204 void 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);
226 void 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);
245 void 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);
305 void TypeInfo::validateBind()
311 if (!m_parent->
isBound())
return;
319 for (
auto child : m_children) {
320 child->validateBind();