diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-20 01:24:11 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-20 01:24:11 +0100 |
commit | 20d3e71f26ca884271ed5d372a8459394554c147 (patch) | |
tree | 82f4b40e989205dbbbd03b70446ca8b02bf1908f | |
parent | 7c64a0770a4800d80c5a53eea2243c46301f7749 (diff) |
finished setter revival in Document classes, hopefully.
-rw-r--r-- | src/core/model/Document.cpp | 106 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 94 | ||||
-rw-r--r-- | src/core/model/Node.cpp | 10 | ||||
-rw-r--r-- | src/core/model/Node.hpp | 17 |
4 files changed, 180 insertions, 47 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index 66b36b0..e6fe1f3 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -105,21 +105,36 @@ DocumentEntity::DocumentEntity(Handle<Node> subInst, Handle<Descriptor> descriptor, Variant attributes) : subInst(subInst), - descriptor(subInst->acquire(descriptor)), + // initialize descriptor as nullptr first and then set it right attributes(std::move(attributes)) { // insert empty vectors for each field. - if (!descriptor.isNull()) { - NodeVector<FieldDescriptor> fieldDescs; - if (descriptor->isa(RttiTypes::StructuredClass)) { - fieldDescs = descriptor.cast<StructuredClass>() - ->getEffectiveFieldDescriptors(); - } else { - fieldDescs = descriptor->getFieldDescriptors(); - } - for (size_t f = 0; f < fieldDescs.size(); f++) { - fields.push_back(NodeVector<StructureNode>(subInst)); - } + if (descriptor != nullptr) { + setDescriptor(descriptor); + } +} + +void DocumentEntity::setDescriptor(Handle<Descriptor> d) +{ + // check if we have to do anything. + if (descriptor == d) { + return; + } + invalidateSubInstance(); + descriptor = subInst->acquire(d); + // get the effective field descriptors in the descriptor. + NodeVector<FieldDescriptor> fieldDescs; + if (descriptor->isa(RttiTypes::StructuredClass)) { + fieldDescs = + descriptor.cast<StructuredClass>()->getEffectiveFieldDescriptors(); + } else { + fieldDescs = descriptor->getFieldDescriptors(); + } + // clear the fields vector. + fields.clear(); + // fill it again. + for (size_t f = 0; f < fieldDescs.size(); f++) { + fields.push_back(NodeVector<StructureNode>(subInst)); } } @@ -303,37 +318,44 @@ void DocumentEntity::setAttributes(const Variant &a) attributes = a; } +void DocumentEntity::addStructureNode(Handle<StructureNode> s, const int &i) +{ + invalidateSubInstance(); + fields[i].push_back(s); + if (s->getParent() != subInst) { + s->setParent(subInst); + } +} + void DocumentEntity::addStructureNode(Handle<StructureNode> s, const std::string &fieldName) { - invalidateSubInstance(); - fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); + addStructureNode(s, getFieldDescriptorIndex(fieldName, true)); } void DocumentEntity::addStructureNodes( const std::vector<Handle<StructureNode>> &ss, const std::string &fieldName) { - invalidateSubInstance(); - NodeVector<StructureNode> &field = - fields[getFieldDescriptorIndex(fieldName, true)]; - field.insert(field.end(), ss.begin(), ss.end()); + const int i = getFieldDescriptorIndex(fieldName, true); + for (Handle<StructureNode> s : ss) { + addStructureNode(s, i); + } } void DocumentEntity::addStructureNode(Handle<StructureNode> s, Handle<FieldDescriptor> fieldDescriptor) { - invalidateSubInstance(); - fields[getFieldDescriptorIndex(fieldDescriptor, true)].push_back(s); + addStructureNode(s, getFieldDescriptorIndex(fieldDescriptor, true)); } void DocumentEntity::addStructureNodes( const std::vector<Handle<StructureNode>> &ss, Handle<FieldDescriptor> fieldDescriptor) { - invalidateSubInstance(); - NodeVector<StructureNode> &field = - fields[getFieldDescriptorIndex(fieldDescriptor, true)]; - field.insert(field.end(), ss.begin(), ss.end()); + const int i = getFieldDescriptorIndex(fieldDescriptor, true); + for (Handle<StructureNode> s : ss) { + addStructureNode(s, i); + } } /* Class StructureNode */ @@ -362,6 +384,14 @@ StructuredEntity::StructuredEntity(Manager &mgr, Handle<Document> doc, doc->setRoot(this); } +StructuredEntity::StructuredEntity(Manager &mgr, Handle<Node> parent, + Handle<StructuredClass> descriptor, + Variant attributes, std::string name) + : StructureNode(mgr, std::move(name), parent), + DocumentEntity(this, descriptor, std::move(attributes)) +{ +} + bool StructuredEntity::doValidate(Logger &logger) const { bool valid = true; @@ -389,8 +419,9 @@ AnnotationEntity::AnnotationEntity(Manager &mgr, Handle<Document> parent, start(acquire(start)), end(acquire(end)) { - parent->annotations.push_back(this); - parent->invalidate(); + if (parent != nullptr) { + parent->addAnnotation(this); + } } bool AnnotationEntity::doValidate(Logger &logger) const @@ -457,6 +488,7 @@ bool Document::doValidate(Logger &logger) const // An empty document is always invalid. TODO: Is this a smart choice? bool valid = true; if (root == nullptr) { + logger.error("This document is empty (it has no root)!"); valid = false; } else { // check if the root is allowed to be a root. @@ -468,6 +500,12 @@ bool Document::doValidate(Logger &logger) const "\" is not allowed to be the Document root!"); valid = false; } + // check if it has this document as parent. + if (root->getParent() != this) { + logger.error( + "The document root does not have the document as parent!"); + valid = false; + } // then call validate on the root valid = valid & root->validate(logger); } @@ -475,6 +513,22 @@ bool Document::doValidate(Logger &logger) const return valid & continueValidation(annotations, logger); } +void Document::addAnnotation(Handle<AnnotationEntity> a) +{ + invalidate(); + annotations.push_back(a); + if (a->getParent() != this) { + a->setParent(this); + } +} + +void Document::addAnnotations(std::vector<Handle<AnnotationEntity>> as) +{ + for (Handle<AnnotationEntity> a : as) { + addAnnotation(a); + } +} + bool Document::hasChild(Handle<StructureNode> s) const { Rooted<Managed> parent = s->getParent(); diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index d89ade8..4147847 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -139,8 +139,6 @@ class StructureNode; * */ class DocumentEntity { - friend StructureNode; - private: /* * this is a rather dirty method that should not be used in other cases: @@ -162,6 +160,8 @@ private: void invalidateSubInstance(); + void addStructureNode(Handle<StructureNode> s, const int &i); + protected: bool doValidate(Logger &logger) const; @@ -190,6 +190,13 @@ public: Rooted<Descriptor> getDescriptor() const { return descriptor; } /** + * Sets the Descriptor for this DocumentEntity. + * + * @param d is the new Descriptor for this DocumentEntity. + */ + void setDescriptor(Handle<Descriptor> d); + + /** * Returns a Map Variant adhering to the attribute StructType in the given * descriptor. * @@ -270,6 +277,9 @@ public: * * If the name is unknown an exception is thrown. * + * This method also changes the parent of the newly added StructureNode if + * it is not set to this DocumentEntity already. + * * @param s is the StructureNode that shall be added. * @param fieldName is the name of a field as specified in the * FieldDescriptor in the Domain description. @@ -285,6 +295,9 @@ public: * * If the name is unknown an exception is thrown. * + * This method also changes the parent of each newly added StructureNode if + * it is not set to this DocumentEntity already. + * * @param ss are the StructureNodes that shall be added. * @param fieldName is the name of a field as specified in the * FieldDescriptor in the Domain description. @@ -298,6 +311,9 @@ public: * If the FieldDescriptor does not belong to the Descriptor of this node * an exception is thrown. * + * This method also changes the parent of the newly added StructureNode if + * it is not set to this DocumentEntity already. + * * @param s is the StructureNode that shall be added. * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for * this DocumentEntity. @@ -312,6 +328,9 @@ public: * If the FieldDescriptor does not belong to the Descriptor of this node * an exception is thrown. * + * This method also changes the parent of each newly added StructureNode if + * it is not set to this DocumentEntity already. + * * @param ss are the StructureNodes that shall be added. * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for * this DocumentEntity. @@ -329,18 +348,19 @@ class StructureNode : public Node { public: /** - * Constructor for a StructureNode at the root. - */ - StructureNode(Manager &mgr, std::string name, Handle<Document> doc) - : Node(mgr, std::move(name), doc) - { - } - - /** * Constructor for a StructureNode in the StructureTree. */ StructureNode(Manager &mgr, std::string name, Handle<Node> parent, const std::string &fieldName); + + /** + * Constructor for an empty StructureNode. + */ + StructureNode(Manager &mgr, std::string name = "", + Handle<Node> parent = nullptr) + : Node(mgr, std::move(name), parent) + { + } }; /** @@ -394,6 +414,23 @@ public: StructuredEntity(Manager &mgr, Handle<Document> doc, Handle<StructuredClass> descriptor, Variant attributes = {}, std::string name = ""); + + /** + * Constructor for an empty StructuredEntity that is not yet connected. + * + * @param mgr is the Manager instance. + * @param parent is the parent Document of this StructuredEntity. Note + * that this StructuredEntity will automatically register + * itself as child of this Document. + * @param descriptor is the StructuredClass of this StructuredEntity. + * @param attributes is a Map Variant containing attribute fillings for this + * StructuredEntity. It is empty per default. + * @param name is some name for this StructuredEntity that may be used + * for later reference. It is empty per default. + */ + StructuredEntity(Manager &mgr, Handle<Node> parent = nullptr, + Handle<StructuredClass> descriptor = nullptr, + Variant attributes = {}, std::string name = ""); }; /** @@ -527,8 +564,8 @@ public: * @param name is some name for this AnnotationEntity that might be * used for references later on. It is empty per default. */ - AnnotationEntity(Manager &mgr, Handle<Document> parent, - Handle<AnnotationClass> descriptor, + AnnotationEntity(Manager &mgr, Handle<Document> parent = nullptr, + Handle<AnnotationClass> descriptor = nullptr, Handle<Anchor> start = nullptr, Handle<Anchor> end = nullptr, Variant attributes = {}, std::string name = ""); @@ -565,6 +602,7 @@ public: */ void setEnd(Handle<Anchor> e) { + invalidate(); end = acquire(e); } }; @@ -575,8 +613,6 @@ public: * document and the AnnotationEntities that span over Anchors in this Document. */ class Document : public Node { - friend AnnotationEntity; - private: // TODO: Might there be several roots? E.g. metadata? Owned<StructuredEntity> root; @@ -589,18 +625,29 @@ protected: bool doValidate(Logger &logger) const override; public: + /** + * This sets up an empty document. + * + * @param mgr is the Manager instance. + * @param name is a name for this Document. + */ Document(Manager &mgr, std::string name) : Node(mgr, std::move(name), nullptr), annotations(this) { } /** - * Sets the root StructuredEntity of this Document. + * Sets the root StructuredEntity of this Document. This also sets the + * parent of the given StructuredEntity if it is not set to this Document + * already. */ void setRoot(Handle<StructuredEntity> root) { invalidate(); this->root = acquire(root); + if (root->getParent() != this) { + root->setParent(this); + } }; /** @@ -623,6 +670,23 @@ public: } /** + * Adds an AnnotationEntity to this document. This also sets the parent + * of the given AnnotationEntity if it is not set to this document already. + * + * @param a is some AnnotationEntity + */ + void addAnnotation(Handle<AnnotationEntity> a); + + /** + * Adds multiple AnnotationEntities to this document. This also sets the + * parent of each given AnnotationEntity if it is not set to this document + * already. + * + * @param as is a vector of AnnotationEntities. + */ + void addAnnotations(std::vector<Handle<AnnotationEntity>> as); + + /** * Returns a const reference to the NodeVector of Domains that are used * within this Document. * diff --git a/src/core/model/Node.cpp b/src/core/model/Node.cpp index 5867fa3..71d59ce 100644 --- a/src/core/model/Node.cpp +++ b/src/core/model/Node.cpp @@ -430,12 +430,20 @@ 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("This validation run lead to a cycle. As a fallback it is set to invalid!"); + logger.error( + "This validation run lead to a cycle. As a fallback it is set " + "to invalid!"); return false; } return false; } +void Node::setParent(Handle<Node> p) +{ + invalidate(); + parent = acquire(p); +} + /* RTTI type registrations */ namespace RttiTypes { const Rtti Node = diff --git a/src/core/model/Node.hpp b/src/core/model/Node.hpp index 3e778a6..6b13c30 100644 --- a/src/core/model/Node.hpp +++ b/src/core/model/Node.hpp @@ -451,6 +451,13 @@ public: Rooted<Managed> getParent() const { return parent; } /** + * Sets the parent node. + * + * @param parent is a Handle to the parent node. + */ + void setParent(Handle<Node> parent); + + /** * Returns true, if the node does not have a parent. Root nodes may either * be the root element of the complete DOM tree * @@ -522,8 +529,8 @@ class NodeVector : public ManagedGenericList<T, std::vector<Handle<T>>, ListAccessor<Handle<T>>, Listener> { public: - using Base = ManagedGenericList<T, std::vector<Handle<T>>, ListAccessor<Handle<T>>, - Listener>; + using Base = ManagedGenericList<T, std::vector<Handle<T>>, + ListAccessor<Handle<T>>, Listener>; using Base::Base; /** @@ -553,9 +560,9 @@ class NodeMap : public ManagedGenericMap<K, T, std::map<K, Handle<T>>, MapAccessor<std::pair<K, Handle<T>>>, Listener> { public: - using Base = ManagedGenericMap<K, T, std::map<K, Handle<T>>, - MapAccessor<std::pair<K, Handle<T>>>, - Listener>; + using Base = + ManagedGenericMap<K, T, std::map<K, Handle<T>>, + MapAccessor<std::pair<K, Handle<T>>>, Listener>; using Base::Base; /** |