diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/model/Document.hpp | 4 | ||||
-rw-r--r-- | src/core/model/Domain.cpp | 91 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 39 |
3 files changed, 60 insertions, 74 deletions
diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index 2821e8c..357b752 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -379,14 +379,18 @@ public: * the markups "emphasized" and "strong". In HTML like markup languages these * concepts are handeled as structure elements, like this: * + * \code{.xml} * <em>emphasized</em> <em><strong>and</strong></em> <strong>strong</strong> + * \endcode * * which is neither intuitive nor semantically sound. Therefore we take the * approach of anchoring the Annotation entities in the text like this: * + * \code{.xml} * <Anchor id=1/>emphasized <Anchor id=2/>and<Anchor id=3/> strong<Anchor id=4/> * <AnnotationEntity class="emphasized" start=1 end=3/> * <AnnotationEntity class="strong" start=2 end=4/> + * \endcode * * Which signifies that indeed the text "emphasized and" is emphasized, not * the two text exerpts "emphasized" and "and" separately. diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index 1fb057e..d664809 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -47,7 +47,7 @@ std::vector<Rooted<Node>> Descriptor::pathTo( return path; } -static bool pathEquals(const Descriptor& a, const Descriptor& b) +static bool pathEquals(const Descriptor &a, const Descriptor &b) { // We assume that two Descriptors are equal if their names and domain names // are equal. @@ -59,57 +59,68 @@ static bool pathEquals(const Descriptor& a, const Descriptor& b) return aDom->getName() == bDom->getName(); } -//TODO: isa-handling. bool Descriptor::continuePath(Handle<StructuredClass> target, std::vector<Rooted<Node>> &path) const { - // look if our current node is reachable using the parent references - for (auto &pfd : target->getParents()) { - Handle<Descriptor> p = pfd->getParent().cast<Descriptor>(); - if (pathEquals(*this, *p)) { - // if we have made the connection, stop the search. - path.push_back(pfd); - return true; - } - // look for transparent intermediate nodes. - if (!p->isa(RttiTypes::StructuredClass)) { - continue; - } - Handle<StructuredClass> pc = p.cast<StructuredClass>(); - if (pc->transparent) { - // recursion - std::vector<Rooted<Node>> cPath = path; - if (continuePath(pc, cPath)) { - path = std::move(cPath); - path.push_back(pc); - path.push_back(pfd); - return true; - } - } - } + bool found = false; // use recursive depth-first search from the top to reach the given child - for (auto &fd : fieldDescriptors) { - for (auto &c : fd->getChildren()) { - if (pathEquals(*c, *target)) { - // if we have made the connection, stop the search. - path.push_back(fd); - return true; + if (fieldDescriptors.size() > 0) { + for (auto &fd : fieldDescriptors) { + for (auto &c : fd->getChildren()) { + if (pathEquals(*c, *target)) { + // if we have made the connection, stop the search. + path.push_back(fd); + return true; + } + // look for transparent intermediate nodes. + if (c->transparent) { + // copy the path. + std::vector<Rooted<Node>> cPath = path; + cPath.push_back(fd); + cPath.push_back(c); + // recursion. + if (c->continuePath(target, cPath) && + (!found || path.size() > cPath.size())) { + // look if this path is better than the current optimum. + path = std::move(cPath); + found = true; + } + } } - // look for transparent intermediate nodes. - if (c->transparent) { + } + } else { + // if this is a StructuredClass and if it did not formulate own + // fieldDescriptors (overriding the parent), we can also use the + // (inheritance-wise) parent + if (isa(RttiTypes::StructuredClass)) { + const StructuredClass *tis = + static_cast<const StructuredClass *>(this); + if (!tis->getIsA().isNull()) { // copy the path. std::vector<Rooted<Node>> cPath = path; - cPath.push_back(fd); - cPath.push_back(c); - // recursion. - if (c->continuePath(target, cPath)) { + if (tis->getIsA()->continuePath(target, cPath) && + (found || path.size() > cPath.size())) { + // look if this path is better than the current optimum. path = std::move(cPath); - return true; + found = true; } } } } - return false; + // either way we can try to find the targets parent (inheritance-wise) + // instead of the target itself. + if (!target->getIsA().isNull()) { + // copy the path. + std::vector<Rooted<Node>> cPath = path; + if (continuePath(target->getIsA(), cPath) && + (!found || path.size() > cPath.size())) { + // look if this path is better than the current optimum. + path = std::move(cPath); + found = true; + } + } + // return if we found something. + return found; } /* Class Domain */ diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index 755ff52..1f65242 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -233,7 +233,7 @@ class Domain; * As an example consider the "paragraph" StructuredClass, which might allow * the actual text content. Here is the according XML: * - * \code{*.xml} + * \code{.xml} * <struct name="paragraph" transparent="true" role="paragraph"> * <fields> * <field> @@ -376,7 +376,7 @@ public: * explained as the difference between node attributes and node children. * Consider the XML * - * \code{*.xml} + * \code{.xml} * <A key="value"> * <key>value</key> * </A> @@ -490,7 +490,7 @@ typedef RangeSet<size_t> Cardinality; * defining itself as a viable child in one existing field. Consider the * example of the "heading" domain from the header documentation again: * - * \code{*.xml} + * \code{.xml} * <domain name="headings"> * <head> * <import rel="domain" src="book.oxm"/> @@ -522,7 +522,7 @@ typedef RangeSet<size_t> Cardinality; * If we go back to our example a user would (without transparency) have to * explicitly declare: * - * \code{*.xml} + * \code{.xml} * <book> * <section> * <paragraph>Text.</paragraph> @@ -532,7 +532,7 @@ typedef RangeSet<size_t> Cardinality; * * But in our mind the document * - * \code{*.xml} + * \code{.xml} * <book> * <section> * Text. @@ -558,7 +558,6 @@ class StructuredClass : public Descriptor { private: const Cardinality cardinality; Owned<StructuredClass> isa; - NodeVector<FieldDescriptor> parents; public: const bool transparent; @@ -599,7 +598,6 @@ public: : Descriptor(mgr, std::move(name), domain, attributesDescriptor), cardinality(cardinality), isa(acquire(isa)), - parents(this), transparent(transparent), root(root) { @@ -620,33 +618,6 @@ public: * hierarchy (!). */ Rooted<StructuredClass> getIsA() const { return isa; } - - /** - * Returns a const reference to the NodeVector of FieldDescriptors that - * should allow an instance of this StructuredClass as child in the - * Structure Tree. This enables you to "invade" other domains as described - * in the StructuredClass documentation. - * - * @return a const reference to the NodeVector of FieldDescriptors that - * should allow an instance of this StructuredClass as child in the - * Structure Tree. - */ - const NodeVector<FieldDescriptor> &getParents() const { return parents; } - - /** - * Adds a FieldDescriptor that should allow an instance of this - * StructuredClass as a child in the Structure Tree. - */ - void addParent(Handle<FieldDescriptor> p) { parents.push_back(p); } - - /** - * Adds multiple FieldDescriptors that should allow an instance of this - * StructuredClass as a child in the Structure Tree. - */ - void addParents(const std::vector<Handle<FieldDescriptor>> &ps) - { - parents.insert(parents.end(), ps.begin(), ps.end()); - } }; /** |