diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-08 19:37:51 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-08 19:37:51 +0100 |
commit | 5eca67b6cab7031d8203b1403ba5cddaef833e76 (patch) | |
tree | ddb626aa00a0da75d038b08025e4c4fd7760ec5c /src/core/model | |
parent | c2b9597c49abeef3f333b1bf7221a51019d53668 (diff) |
restructured the FieldDescriptor mechanism.
Diffstat (limited to 'src/core/model')
-rw-r--r-- | src/core/model/Document.cpp | 161 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 58 | ||||
-rw-r--r-- | src/core/model/Domain.cpp | 37 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 64 |
4 files changed, 170 insertions, 150 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index de73bb8..4579383 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -28,53 +28,6 @@ namespace ousia { /* Class DocumentEntity */ -int DocumentEntity::getFieldDescriptorIndex(const std::string &fieldName, - bool enforce) const -{ - const NodeVector<FieldDescriptor> &fds = descriptor->getFieldDescriptors(); - unsigned int f = 0; - - // otherwise we return the FieldDescriptor with the correct name (if - // such a descriptor exists). - for (auto &fd : fds) { - if (fd->getName() == fieldName) { - return f; - } - f++; - } - - if (enforce) { - throw OusiaException(std::string("\"") + descriptor->getName() + - "\" has no field with name \"" + fieldName + "\""); - } else { - return -1; - } -} - -int DocumentEntity::getFieldDescriptorIndex( - Handle<FieldDescriptor> fieldDescriptor, bool enforce) const -{ - if (fieldDescriptor.isNull()) { - throw OusiaException("The given FieldDescriptor handle is null!"); - } - const NodeVector<FieldDescriptor> &fds = descriptor->getFieldDescriptors(); - int f = 0; - for (auto &fd : fds) { - if (fd->getName() == fieldDescriptor->getName() && - fd->getFieldType() == fieldDescriptor->getFieldType()) { - return f; - } - f++; - } - if (enforce) { - throw OusiaException(std::string("\"") + descriptor->getName() + - "\" has no field with name \"" + - fieldDescriptor->getName() + "\""); - } else { - return -1; - } -} - void DocumentEntity::invalidateSubInstance() { if (subInst->isa(&RttiTypes::StructuredEntity)) { @@ -105,18 +58,10 @@ void DocumentEntity::setDescriptor(Handle<Descriptor> d) } 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++) { + for (size_t f = 0; f < descriptor->getFieldDescriptors().size(); f++) { fields.push_back(NodeVector<StructureNode>(subInst)); } } @@ -148,13 +93,7 @@ bool DocumentEntity::doValidate(Logger &logger) const * gather all fields of superclasses as well, that have not been * overridden in the subclasses. */ - NodeVector<FieldDescriptor> fieldDescs; - if (descriptor->isa(&RttiTypes::StructuredClass)) { - fieldDescs = - descriptor.cast<StructuredClass>()->getEffectiveFieldDescriptors(); - } else { - fieldDescs = descriptor->getFieldDescriptors(); - } + NodeVector<FieldDescriptor> fieldDescs = descriptor->getFieldDescriptors(); // iterate over every field for (unsigned int f = 0; f < fields.size(); f++) { // we have a special check for primitive fields. @@ -332,6 +271,43 @@ void DocumentEntity::setAttributes(const Variant &a) attributes = a; } +static int enforceGetFieldDescriptorIndex(Handle<Descriptor> desc, + const std::string &fieldName) +{ + int idx = desc->getFieldDescriptorIndex(fieldName); + if (idx == -1) { + throw OusiaException( + std::string("Descriptor \"") + desc->getName() + + "\" has no field with the name \"" + fieldName + "\""); + } + return idx; +} + +static int enforceGetFieldDescriptorIndex( + Handle<Descriptor> desc, Handle<FieldDescriptor> fieldDescriptor) +{ + int idx = desc->getFieldDescriptorIndex(fieldDescriptor); + if (idx == -1) { + throw OusiaException(std::string("Descriptor \"") + + desc->getName() + + "\" does not reference the given field \"" + + fieldDescriptor->getName() + "\""); + } + return idx; +} + +const NodeVector<StructureNode> &DocumentEntity::getField( + const std::string &fieldName) const +{ + return fields[enforceGetFieldDescriptorIndex(descriptor, fieldName)]; +} + +const NodeVector<StructureNode> &DocumentEntity::getField( + Handle<FieldDescriptor> fieldDescriptor) const +{ + return fields[enforceGetFieldDescriptorIndex(descriptor, fieldDescriptor)]; +} + void DocumentEntity::addStructureNode(Handle<StructureNode> s, const int &i) { // only add the new node if we don't have it already. @@ -354,62 +330,63 @@ void DocumentEntity::addStructureNode(Handle<StructureNode> s, const int &i) } } -bool DocumentEntity::removeStructureNodeFromField(Handle<StructureNode> s, - const int &i) +void DocumentEntity::addStructureNode(Handle<StructureNode> s, + Handle<FieldDescriptor> fieldDescriptor) { - auto it = fields[i].find(s); - if (it != fields[i].end()) { - invalidateSubInstance(); - fields[i].erase(it); - s->setParent(nullptr); - return true; + addStructureNode( + s, enforceGetFieldDescriptorIndex(descriptor, fieldDescriptor)); +} + +void DocumentEntity::addStructureNodes( + const std::vector<Handle<StructureNode>> &ss, + Handle<FieldDescriptor> fieldDescriptor) +{ + const int i = enforceGetFieldDescriptorIndex(descriptor, fieldDescriptor); + for (Handle<StructureNode> s : ss) { + addStructureNode(s, i); } - return false; } void DocumentEntity::addStructureNode(Handle<StructureNode> s, const std::string &fieldName) { - addStructureNode(s, getFieldDescriptorIndex(fieldName, true)); + addStructureNode(s, enforceGetFieldDescriptorIndex(descriptor, fieldName)); } void DocumentEntity::addStructureNodes( const std::vector<Handle<StructureNode>> &ss, const std::string &fieldName) { - const int i = getFieldDescriptorIndex(fieldName, true); + const int idx = enforceGetFieldDescriptorIndex(descriptor, fieldName); for (Handle<StructureNode> s : ss) { - addStructureNode(s, i); + addStructureNode(s, idx); } } bool DocumentEntity::removeStructureNodeFromField(Handle<StructureNode> s, - const std::string &fieldName) -{ - return removeStructureNodeFromField( - s, getFieldDescriptorIndex(fieldName, true)); -} - -void DocumentEntity::addStructureNode(Handle<StructureNode> s, - Handle<FieldDescriptor> fieldDescriptor) + const int &i) { - addStructureNode(s, getFieldDescriptorIndex(fieldDescriptor, true)); + auto it = fields[i].find(s); + if (it != fields[i].end()) { + invalidateSubInstance(); + fields[i].erase(it); + s->setParent(nullptr); + return true; + } + return false; } -void DocumentEntity::addStructureNodes( - const std::vector<Handle<StructureNode>> &ss, - Handle<FieldDescriptor> fieldDescriptor) +bool DocumentEntity::removeStructureNodeFromField(Handle<StructureNode> s, + const std::string &fieldName) { - const int i = getFieldDescriptorIndex(fieldDescriptor, true); - for (Handle<StructureNode> s : ss) { - addStructureNode(s, i); - } + return removeStructureNodeFromField( + s, enforceGetFieldDescriptorIndex(descriptor, fieldName)); } bool DocumentEntity::removeStructureNodeFromField( Handle<StructureNode> s, Handle<FieldDescriptor> fieldDescriptor) { return removeStructureNodeFromField( - s, getFieldDescriptorIndex(fieldDescriptor, true)); + s, enforceGetFieldDescriptorIndex(descriptor, fieldDescriptor)); } bool DocumentEntity::removeStructureNode(Handle<StructureNode> s) diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index 4be3494..b41393e 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -153,18 +153,8 @@ private: Variant attributes; std::vector<NodeVector<StructureNode>> fields; - int getFieldDescriptorIndex(const std::string &fieldName, - bool enforce) const; - - int getFieldDescriptorIndex(Handle<FieldDescriptor> fieldDescriptor, - bool enforce) const; - void invalidateSubInstance(); - void addStructureNode(Handle<StructureNode> s, const int &i); - - bool removeStructureNodeFromField(Handle<StructureNode> s, const int &i); - protected: bool doValidate(Logger &logger) const; @@ -218,19 +208,6 @@ public: void setAttributes(const Variant &a); /** - * This returns true if there is a FieldDescriptor in the Descriptor for - * this DocumentEntity which has the given name. - * - * @param fieldName is the name of a field as specified in the - * FieldDescriptor in the Domain description. - * @return true if this FieldDescriptor exists. - */ - bool hasField(const std::string &fieldName = DEFAULT_FIELD_NAME) const - { - return getFieldDescriptorIndex(fieldName, false) != -1; - } - - /** * This returns the vector of entities containing all members of the field * with the given name. * @@ -241,10 +218,7 @@ public: * @return a NodeVector of all StructuredEntities in that field. */ const NodeVector<StructureNode> &getField( - const std::string &fieldName = DEFAULT_FIELD_NAME) const - { - return fields[getFieldDescriptorIndex(fieldName, true)]; - } + const std::string &fieldName = DEFAULT_FIELD_NAME) const; /** * This returns the vector of entities containing all members of the field @@ -259,12 +233,21 @@ public: * field. */ const NodeVector<StructureNode> &getField( - Handle<FieldDescriptor> fieldDescriptor) const - { - return fields[getFieldDescriptorIndex(fieldDescriptor, true)]; - } + Handle<FieldDescriptor> fieldDescriptor) const; /** + * This adds a StructureNode to the field with the given index. + * + * This method also changes the parent of the newly added StructureNode if + * it is not set to this DocumentEntity already and removes it from the + * old parent. + * + * @param s is the StructureNode that shall be added. + * @param fieldIdx is the index of a field as specified in the + * FieldDescriptor in the Domain description. + */ + void addStructureNode(Handle<StructureNode> s, const int &fieldIdx); + /** * This adds a StructureNode to the field with the given name. * * If the name is unknown an exception is thrown. @@ -296,6 +279,19 @@ public: void addStructureNodes(const std::vector<Handle<StructureNode>> &ss, const std::string &fieldName = DEFAULT_FIELD_NAME); /** + * This removes a StructureNode from the field with the given index. + * + * This method also changes the parent of the removed StructureNode to null. + * + * @param s is the StructureNode that shall be removed. + * @param fieldIdx is the index of a field as specified in the + * FieldDescriptor in the Domain description. + * @return true if this StructureNode was a child here and false if + * if was not found. + */ + bool removeStructureNodeFromField(Handle<StructureNode> s, + const int &fieldIdx); + /** * This removes a StructureNode from the field with the given name. * * If the name is unknown an exception is thrown. diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index 55f05b3..f45bd27 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -179,13 +179,7 @@ bool Descriptor::continuePath(Handle<StructuredClass> target, std::vector<Rooted<Node>> optimum; // use recursive depth-first search from the top to reach the given child // 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(); - } + NodeVector<FieldDescriptor> fields = getFieldDescriptors(); for (auto &fd : fields) { for (auto &c : fd->getChildren()) { @@ -234,6 +228,30 @@ bool Descriptor::continuePath(Handle<StructuredClass> target, return found; } +int Descriptor::getFieldDescriptorIndex(const std::string &name) const +{ + int f = 0; + for (auto &fd : getFieldDescriptors()) { + if (fd->getName() == name) { + return f; + } + f++; + } + return -1; +} + +int Descriptor::getFieldDescriptorIndex(Handle<FieldDescriptor> fd) const +{ + int f = 0; + for (auto &fd2 : getFieldDescriptors()) { + if (fd == fd2) { + return f; + } + f++; + } + return -1; +} + void Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd) { // only add it if we need to. @@ -444,14 +462,13 @@ const void StructuredClass::gatherFieldDescriptors( } } -NodeVector<FieldDescriptor> StructuredClass::getEffectiveFieldDescriptors() - const +NodeVector<FieldDescriptor> StructuredClass::getFieldDescriptors() 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); + return vec; } /* Class AnnotationClass */ diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index 53579bd..63f4c5d 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -485,18 +485,52 @@ public: } /** - * Returns a const reference to the NodeVector of all FieldDescriptors of - * this Descriptor. + * Returns the NodeVector of all FieldDescriptors of this Descriptor. * - * @return a const reference to the NodeVector of all FieldDescriptors of - * this Descriptor. + * @return the NodeVector of all FieldDescriptors of this Descriptor. */ - const NodeVector<FieldDescriptor> &getFieldDescriptors() const + virtual NodeVector<FieldDescriptor> getFieldDescriptors() const { return fieldDescriptors; } /** + * Returns the index of the FieldDescriptor with the given name or -1 if no + * such FieldDescriptor was found. + * + * @param name the name of a FieldDescriptor. + + * @return the index of the FieldDescriptor with the given name or -1 if + * no such FieldDescriptor was found. + */ + int getFieldDescriptorIndex( + const std::string &name = DEFAULT_FIELD_NAME) const; + /** + * Returns the index of the given FieldDescriptor or -1 of the given + * FieldDescriptor is not registered at this Descriptor. + * + * @param fd a FieldDescriptor. + + * @return the index of the given FieldDescriptor or -1 of the given + * FieldDescriptor is not registered at this Descriptor. + */ + int getFieldDescriptorIndex(Handle<FieldDescriptor> fd) const; + + /** + * This returns true if this Descriptor has a FieldDescriptor with the + * given name. + * + * @param name the name of a FieldDescriptor. + + * @return true if this Descriptor has a FieldDescriptor with the given + * name + */ + bool hasField(const std::string &fieldName = DEFAULT_FIELD_NAME) const + { + return getFieldDescriptorIndex(fieldName) != -1; + } + + /** * Adds the given FieldDescriptor to this Descriptor. This also sets the * parent of the given FieldDescriptor if it is not set yet. * @@ -697,10 +731,7 @@ public: * Finally we allow StructuredClasses to inherit attributes of other * StructuredClasses. Inheritance also implies that instance of the inheriting * class can be used wherever an instance of the inherited class is allowed. - * Inheritance therefore also goes for fields. TODO: What is the specification - * for field inheritance? Is the child allowed to specify children at all? - * Is that interpreted as overriding the parent fields or constructing a union? - * What about the cardinality? + * Inheritance therefore also goes for fields. */ class StructuredClass : public Descriptor { friend Domain; @@ -825,7 +856,7 @@ public: * new subclasses AttributesDescriptor will be written into * this logger. */ - void addSubclass(Handle<StructuredClass> sc, Logger& logger); + void addSubclass(Handle<StructuredClass> sc, Logger &logger); /** * Removes a subclass from this StructuredClass. This also calls @@ -836,18 +867,17 @@ public: * removed subclasses AttributesDescriptor will be written * into this logger. */ - void removeSubclass(Handle<StructuredClass> sc, Logger& logger); + void removeSubclass(Handle<StructuredClass> sc, Logger &logger); /** * 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. + * this StructuredClass. This also merges the FieldDescriptors directly + * belonging to this StructuredClass with all FieldDescritptors of its + * Superclass (and so on recurvively). * - * @return a const reference to the NodeVector of all FieldDescriptors of - * this StructuredClass. + * @return a NodeVector of all FieldDescriptors of this StructuredClass. */ - NodeVector<FieldDescriptor> getEffectiveFieldDescriptors() const; + NodeVector<FieldDescriptor> getFieldDescriptors() const override; bool isTransparent() const { return transparent; } |