diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-18 13:48:45 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-18 13:48:45 +0100 |
commit | 372c67e0844654362fc7d440b0b4a31500a6d02a (patch) | |
tree | d677aa19bdc77486be02171de77e5675ce5f0f80 | |
parent | db51a874964b038c69f1336a8a659ae40471e26b (diff) | |
parent | 3e63d6539b9738018a4aca68d07a119e4402e9aa (diff) |
Merge branch 'master' of somweyr.de:ousia
Conflicts:
application/src/core/model/Domain.hpp
-rw-r--r-- | src/core/model/Document.cpp | 53 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 17 | ||||
-rw-r--r-- | src/core/model/Domain.cpp | 78 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 35 | ||||
-rw-r--r-- | src/core/model/Node.cpp | 2 |
5 files changed, 133 insertions, 52 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index ee15e31..5f0ad4c 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -92,7 +92,7 @@ int DocumentEntity::getFieldDescriptorIndex( } } -bool DocumentEntity::validate(Logger &logger) const +bool DocumentEntity::doValidate(Logger &logger) const { // TODO: check the validated form of Attributes // iterate over every field @@ -246,7 +246,7 @@ bool StructuredEntity::doValidate(Logger &logger) const return false; } // check the validity as a DocumentEntity. - return DocumentEntity::validate(logger); + return DocumentEntity::doValidate(logger); } /* Class AnnotationEntity */ @@ -281,12 +281,17 @@ bool AnnotationEntity::doValidate(Logger &logger) const logger.error("This annotation was not registered at the document."); return false; } - + // check if the Anchors are part of the right document. + if (!doc->hasChild(start)) { + return false; + } + if (!doc->hasChild(end)) { + return false; + } // check the validity as a DocumentEntity. - if (!DocumentEntity::validate(logger)) { + if (!DocumentEntity::doValidate(logger)) { return false; } - // TODO: then check if the anchors are in the correct document. return true; } @@ -300,6 +305,44 @@ void Document::doResolve(ResolutionState &state) } continueResolveReferences(domains, state); } + +bool Document::doValidate(Logger &logger) const +{ + if (root != nullptr) { + // check if the root is allowed to be a root. + if (!root->getDescriptor().cast<StructuredClass>()->root) { + logger.error(std::string("A node of type ") + + root->getDescriptor()->getName() + + " is not allowed to be the Document root!"); + return false; + } + // then call validate on the root + if (!root->validate(logger)) { + return false; + } + } + // call validate on the AnnotationEntities + for (auto &a : annotations) { + if (!a->validate(logger)) { + return false; + } + } + return true; +} + +bool Document::hasChild(Handle<StructureNode> s) const +{ + Rooted<Managed> parent = s->getParent(); + if (parent->isa(RttiTypes::StructureNode)) { + return hasChild(parent.cast<StructureNode>()); + } else if (parent->isa(RttiTypes::AnnotationEntity)) { + Handle<AnnotationEntity> a = parent.cast<AnnotationEntity>(); + return this == a->getParent(); + } else if (parent->isa(RttiTypes::Document)) { + return this == parent; + } + return false; +} } /* Type registrations */ diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index cb7f394..9410d17 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -161,7 +161,7 @@ protected: fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); } - bool validate(Logger &logger) const; + bool doValidate(Logger &logger) const; public: /** @@ -512,6 +512,7 @@ class AnnotationEntity : public Node, public DocumentEntity { private: Owned<Anchor> start; Owned<Anchor> end; + protected: bool doValidate(Logger &logger) const override; @@ -569,6 +570,9 @@ private: void doResolve(ResolutionState &state) override; +protected: + bool doValidate(Logger &logger) const override; + public: Document(Manager &mgr, std::string name) // TODO: Can a document have a parent? @@ -622,6 +626,17 @@ public: { domains.insert(domains.end(), d.begin(), d.end()); } + + /** + * Returns true if and only if the given StructureNode is part of this + * document, meaning that there is a path of parent references in the + * Structure Tree leading from the given StructureNode to this Document. + * + * @param s is some StructureNode. + * @return true if and only if the given StructureNode is part of this + * document. + */ + bool hasChild(Handle<StructureNode> s) const; }; } diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index bae0f4f..9a0ed0d 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -36,7 +36,7 @@ static void checkUniqueName(Handle<Node> parent, NodeVector<T> vec, childNames.insert(c->getName()); } if (childNames.find(child->getName()) != childNames.end()) { - //TODO: Do we really want to have an exception here? + // TODO: Do we really want to have an exception here? throw OusiaException(std::string("The ") + parentClassName + " " + parent->getName() + " already has a " + childClassName + " with name " + child->getName()); @@ -97,10 +97,7 @@ std::vector<Rooted<Node>> Descriptor::pathTo( } bool Descriptor::continuePath(Handle<StructuredClass> target, - std::vector<Rooted<Node>> ¤tPath, - std::set<std::string> ignoredFields, - bool exploreSuperclass, - bool exploreSubclasses) const + std::vector<Rooted<Node>> ¤tPath) const { // check if we are at the target already if (this == target) { @@ -111,11 +108,16 @@ bool Descriptor::continuePath(Handle<StructuredClass> target, // the currently optimal path. std::vector<Rooted<Node>> optimum; // use recursive depth-first search from the top to reach the given child - for (auto &fd : fieldDescriptors) { - if (!(ignoredFields.insert(fd->getName()).second)) { - // if we want to ignore that field, we continue. - continue; - } + // get the list of effective FieldDescriptors. + NodeVector<FieldDescriptor> fields; + if (isa(RttiTypes::StructuredClass)) { + const StructuredClass *tis = static_cast<const StructuredClass *>(this); + fields = tis->getEffectiveFieldDescriptors(); + } else { + fields = getFieldDescriptors(); + } + + for (auto &fd : fields) { for (auto &c : fd->getChildren()) { // check if a child is the target node. if (c == target) { @@ -142,35 +144,17 @@ bool Descriptor::continuePath(Handle<StructuredClass> target, if (isa(RttiTypes::StructuredClass)) { const StructuredClass *tis = static_cast<const StructuredClass *>(this); - /* - * if this is a StructuredClass, we can also use the super class - * (at least for fields that are not overridden) - */ - if (exploreSuperclass && tis->getSuperclass() != nullptr) { + // if this is a StructuredClass we also can call the subclasses. + for (auto &c : tis->getSubclasses()) { // copy the path. std::vector<Rooted<Node>> cPath = currentPath; - if (tis->getSuperclass()->continuePath(target, cPath, ignoredFields, - true, false) && + if (c->continuePath(target, cPath) && (!found || optimum.size() > cPath.size())) { // look if this path is better than the current optimum. optimum = std::move(cPath); found = true; } } - - // we also can call the subclasses. - if (exploreSubclasses) { - for (auto &c : tis->getSubclasses()) { - // copy the path. - std::vector<Rooted<Node>> cPath = currentPath; - if (c->continuePath(target, cPath, {}, false) && - (!found || optimum.size() > cPath.size())) { - // look if this path is better than the current optimum. - optimum = std::move(cPath); - found = true; - } - } - } } // put the optimum in the given path reference. @@ -219,16 +203,42 @@ StructuredClass::StructuredClass(Manager &mgr, std::string name, } } -bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const{ - if(c == nullptr || superclass == nullptr){ +bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const +{ + if (c == nullptr || superclass == nullptr) { return false; } - if(c == superclass){ + if (c == superclass) { return true; } return superclass->isSubclassOf(c); } +const void StructuredClass::gatherFieldDescriptors( + NodeVector<FieldDescriptor> ¤t, + std::set<std::string> &overriddenFields) const +{ + // append all FieldDescriptors that are not overridden. + for (auto &f : Descriptor::getFieldDescriptors()) { + if (overriddenFields.insert(f->getName()).second) { + current.push_back(f); + } + } + if (superclass != nullptr) { + superclass->gatherFieldDescriptors(current, overriddenFields); + } +} + +NodeVector<FieldDescriptor> StructuredClass::getEffectiveFieldDescriptors() + const +{ + // in this case we return a NodeVector of Rooted entries without owner. + NodeVector<FieldDescriptor> vec; + std::set<std::string> overriddenFields; + gatherFieldDescriptors(vec, overriddenFields); + return std::move(vec); +} + /* Class AnnotationClass */ AnnotationClass::AnnotationClass( diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index a8d4a9e..d1ba44f 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -380,22 +380,18 @@ public: * */ class Descriptor : public Node { - -friend FieldDescriptor; + friend FieldDescriptor; private: Owned<StructType> attributesDescriptor; NodeVector<FieldDescriptor> fieldDescriptors; bool continuePath(Handle<StructuredClass> target, - std::vector<Rooted<Node>> &path, - std::set<std::string> ignoredFields = {}, - bool exploreSuperclass = true, - bool exploreSubclasses = true) const; + std::vector<Rooted<Node>> &path) const; protected: void doResolve(ResolutionState &state) override; - + /** * Adds a FieldDescriptor and checks for name uniqueness. */ @@ -553,6 +549,13 @@ private: Owned<StructuredClass> superclass; NodeVector<StructuredClass> subclasses; + /** + * Helper method for getFieldDescriptors. + */ + const void gatherFieldDescriptors( + NodeVector<FieldDescriptor> ¤t, + std::set<std::string> &overriddenFields) const; + public: const bool transparent; // TODO: Is it possible to have root=true and cardinality other than 1? @@ -606,7 +609,7 @@ public: * @return the superclass of this StructuredClass. */ Rooted<StructuredClass> getSuperclass() const { return superclass; } - + /** * Returns true if this class is a subclass of the given class. It does not * return true if the other class is equal to the given class. @@ -635,6 +638,17 @@ public: { return subclasses; } + + /** + * Returns a const reference to the NodeVector of all FieldDescriptors of + * this StructuredClass. This does more than the getter for FieldDescriptor, + * because in this method we gather the FieldDescriptors of all superclasses + * as well that have not been overridden in child classes. + * + * @return a const reference to the NodeVector of all FieldDescriptors of + * this StructuredClass. + */ + NodeVector<FieldDescriptor> getEffectiveFieldDescriptors() const; }; /** @@ -670,9 +684,8 @@ public: * to certain Structures? */ class Domain : public Node { - -friend StructuredClass; -friend AnnotationClass; + friend StructuredClass; + friend AnnotationClass; private: NodeVector<StructuredClass> structuredClasses; diff --git a/src/core/model/Node.cpp b/src/core/model/Node.cpp index 1c627fc..bd023e1 100644 --- a/src/core/model/Node.cpp +++ b/src/core/model/Node.cpp @@ -430,7 +430,7 @@ bool Node::validate(Logger &logger) const case ValidationState::VALIDATING: // We've run into recursion -- a circular structure cannot be // properly validated, so return false - logger.error("The given document is cyclic."); + logger.error("This validation run lead to a cycle. As a fallback it is set to invalid!"); return false; } return false; |