diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-18 16:52:54 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-18 16:52:54 +0100 |
commit | 0fd65daf57959fe5409a624bffcd5998fc55d332 (patch) | |
tree | c91ca29c9be38df833b9c5cbe7604c839993ab82 /src | |
parent | 373c3489ed4b6927a9596882e9e4ff078624e943 (diff) |
improved Document validation process and added some test cases. Further tests are required, though.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/model/Document.cpp | 76 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 30 |
2 files changed, 73 insertions, 33 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index cf6ded3..b80cb5e 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -92,10 +92,27 @@ int DocumentEntity::getFieldDescriptorIndex( } } -DocumentEntity::DocumentEntity(Handle<Node> owner, +void DocumentEntity::addStructureNode(Handle<StructureNode> s, + const std::string &fieldName) +{ + if (subInst->isa(RttiTypes::StructuredEntity)) { + const StructuredEntity *s = + static_cast<const StructuredEntity *>(subInst); + s->invalidate(); + } else { + const AnnotationEntity *a = + static_cast<const AnnotationEntity *>(subInst); + a->invalidate(); + } + fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); +} + +DocumentEntity::DocumentEntity(Handle<Node> subInst, Handle<Descriptor> descriptor, Variant attributes) - : descriptor(owner->acquire(descriptor)), attributes(std::move(attributes)) + : subInst(subInst.get()), + descriptor(subInst->acquire(descriptor)), + attributes(std::move(attributes)) { // insert empty vectors for each field. if (!descriptor.isNull()) { @@ -107,7 +124,7 @@ DocumentEntity::DocumentEntity(Handle<Node> owner, fieldDescs = descriptor->getFieldDescriptors(); } for (size_t f = 0; f < fieldDescs.size(); f++) { - fields.push_back(NodeVector<StructureNode>(owner)); + fields.push_back(NodeVector<StructureNode>(subInst)); } } } @@ -120,6 +137,7 @@ bool DocumentEntity::doValidate(Logger &logger) const return false; } // TODO: check the validated form of Attributes + // TODO: Check if descriptor is registered at the Document? /* * generate the set of effective fields. This is trivial for @@ -150,8 +168,7 @@ bool DocumentEntity::doValidate(Logger &logger) const const size_t min = ac->getCardinality().min(); if (min > 0) { logger.error( - std::string("Field ") + - descriptor->getFieldDescriptors()[f]->getName() + + std::string("Field ") + fieldDescs[f]->getName() + " was empty but needs at least " + std::to_string(min) + " elements of class " + ac->getName() + " according to the definition of " + @@ -172,11 +189,11 @@ bool DocumentEntity::doValidate(Logger &logger) const // iterate over every actual child of this DocumentEntity for (auto &rc : fields[f]) { - if (!rc->isa(RttiTypes::Anchor)) { + if (rc->isa(RttiTypes::Anchor)) { // Anchors are uninteresting and can be ignored. continue; } - if (!rc->isa(RttiTypes::DocumentPrimitive)) { + if (rc->isa(RttiTypes::DocumentPrimitive)) { // For DocumentPrimitives we have to check the content type. // TODO: Do that! continue; @@ -281,6 +298,12 @@ bool StructuredEntity::doValidate(Logger &logger) const if (getParent() == nullptr) { return false; } + // check name + if (getName() != "") { + if (!validateName(logger)) { + return false; + } + } // check the validity as a DocumentEntity. return DocumentEntity::doValidate(logger); } @@ -317,6 +340,12 @@ bool AnnotationEntity::doValidate(Logger &logger) const logger.error("This annotation was not registered at the document."); return false; } + // check name + if (getName() != "") { + if (!validateName(logger)) { + return false; + } + } // check if the Anchors are part of the right document. if (!doc->hasChild(start)) { return false; @@ -344,26 +373,23 @@ void Document::doResolve(ResolutionState &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; - } + // An empty document is always invalid. TODO: Is this a smart choice? + if (root == nullptr) { + return false; } - // call validate on the AnnotationEntities - for (auto &a : annotations) { - if (!a->validate(logger)) { - return false; - } + // 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; } - return true; + // then call validate on the root + if (!root->validate(logger)) { + return false; + } + // call validate on the AnnotationEntities + return continueValidation(annotations, logger); } bool Document::hasChild(Handle<StructureNode> s) const diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index b4ee429..15d002c 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -144,6 +144,12 @@ class DocumentEntity { friend StructureNode; private: + /* + * this is a rather dirty method that should not be used in other cases: + * We store a pointer to the Node instance that inherits from + * DocumentEntity. + */ + const Node *subInst; Owned<Descriptor> descriptor; const Variant attributes; std::vector<NodeVector<StructureNode>> fields; @@ -156,10 +162,7 @@ private: protected: void addStructureNode(Handle<StructureNode> s, - const std::string &fieldName = "") - { - fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); - } + const std::string &fieldName = ""); bool doValidate(Logger &logger) const; @@ -169,7 +172,7 @@ public: * from Node. Therefore we need to have a handle to the subclass Node * instance to create NodeVectors and Owned references. * - * @param owner is a handle to the subclass instance + * @param subInst is a handle to the subclass instance * (e.g. StructuredEntity), such that the fields vectors * and the descriptor reference can be obtained. * @param descriptor is the Descriptor for this DocumentEntity, which will @@ -177,7 +180,7 @@ public: * @param attributes is a Map Variant adhering to the attribute StructType * in the given descriptor. */ - DocumentEntity(Handle<Node> owner, Handle<Descriptor> descriptor, + DocumentEntity(Handle<Node> subInst, Handle<Descriptor> descriptor, Variant attributes = {}); /** @@ -498,6 +501,8 @@ public: * */ class AnnotationEntity : public Node, public DocumentEntity { + friend DocumentEntity; + private: Owned<Anchor> start; Owned<Anchor> end; @@ -573,7 +578,11 @@ public: /** * Sets the root StructuredEntity of this Document. */ - void setRoot(Handle<StructuredEntity> root) { this->root = acquire(root); }; + void setRoot(Handle<StructuredEntity> root) + { + invalidate(); + this->root = acquire(root); + }; /** * Returns the root StructuredEntity of this Document. @@ -606,13 +615,18 @@ public: /** * Adds a Domain reference to this Document. */ - void addDomain(Handle<Domain> d) { domains.push_back(d); } + void addDomain(Handle<Domain> d) + { + invalidate(); + domains.push_back(d); + } /** * Adds multiple Domain references to this Document. */ void addDomains(const std::vector<Handle<Domain>> &d) { + invalidate(); domains.insert(domains.end(), d.begin(), d.end()); } |