summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-18 14:49:50 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-18 14:49:50 +0100
commit94a60d364203f633370e1b0a77ec5b89428032e3 (patch)
treee9ef9970ec8dd93b5d302a6d52b6d90ae238eadb
parent93c065174e1aa306ee724dd523ef6b2254c1d388 (diff)
Hopefully implemented a working version of the Domain resolve mechanism.
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/core/Node.hpp5
-rw-r--r--src/core/model/Domain.cpp54
-rw-r--r--src/core/model/Domain.hpp26
-rw-r--r--test/core/model/DomainTest.cpp67
5 files changed, 152 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cddf159..077ac47 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -184,6 +184,7 @@ IF(TEST)
test/core/managed/ManagedContainerTest
test/core/managed/ManagedTest
test/core/managed/ManagerTest
+ test/core/model/DomainTest
test/core/model/DocumentTest
test/core/parser/ParserStackTest
# test/core/script/FunctionTest
diff --git a/src/core/Node.hpp b/src/core/Node.hpp
index 4bc95be..516da03 100644
--- a/src/core/Node.hpp
+++ b/src/core/Node.hpp
@@ -350,6 +350,11 @@ public:
* Returns the name of the node.
*/
std::string getName() const { return name; }
+
+ /**
+ * Returns a reference to the name of the node.
+ */
+ const std::string& getNameRef() const { return name; }
/**
* Specifies whether the node has a name, e.g. whether the current name is
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index bafd205..8eee86a 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -21,6 +21,60 @@
namespace ousia {
namespace model {
+void FieldDescriptor::doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path,
+ Filter filter, void *filterData, unsigned idx,
+ VisitorSet &visited)
+{
+ // We call resolve for the children, but give them the field name as
+ // alias.
+ for (auto &c : children) {
+ c->resolve(res, path, filter, filterData, idx, visited, &getNameRef());
+ }
+}
+
+// TODO: better alias?
+static std::string DESCRIPTOR_ATTRIBUTES_ALIAS {"attributes"};
+
+void Descriptor::doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path, Filter filter,
+ void *filterData, unsigned idx, VisitorSet &visited)
+{
+ // TODO: This could be a problem, because the name of the field might be
+ // needed in the path.
+ for (auto &fd : fieldDescriptors) {
+ fd->resolve(res, path, filter, filterData, idx, visited, nullptr);
+ }
+ // TODO: This throws a SEGFAULT for some reason.
+// attributesDescriptor->resolve(res, path, filter, filterData, idx, visited,
+// &DESCRIPTOR_ATTRIBUTES_ALIAS);
+}
+
+void StructuredClass::doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path,
+ Filter filter, void *filterData, unsigned idx,
+ VisitorSet &visited)
+{
+ Descriptor::doResolve(res, path, filter, filterData, idx, visited);
+ if(!isa.isNull()){
+ isa->doResolve(res, path, filter, filterData, idx, visited);
+ }
+}
+
+void Domain::doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path, Filter filter,
+ void *filterData, unsigned idx, VisitorSet &visited)
+{
+ for (auto &s : rootStructures) {
+ s->resolve(res, path, filter, filterData, idx, visited, nullptr);
+ }
+ for (auto &a : annotationClasses) {
+ a->resolve(res, path, filter, filterData, idx, visited, nullptr);
+ }
+ for (auto &t : typesystems) {
+ t->resolve(res, path, filter, filterData, idx, visited, nullptr);
+ }
+}
}
}
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index e348136..112f2fa 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -139,6 +139,12 @@ private:
FieldType fieldType;
Owned<Type> primitiveType;
+protected:
+ void doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path, Filter filter,
+ void *filterData, unsigned idx,
+ VisitorSet &visited) override;
+
public:
const bool optional;
@@ -220,7 +226,7 @@ public:
* the attribute specification of a descriptor is done by referencing an
* appropriate StructType that contains all permitted keys and value types.
*
- * TODO: What aout optional attributes?
+ * TODO: What about optional attributes?
*
* In XML terms the difference between primitive fields and attributes can be
* explained as the difference between node attributes and node children.
@@ -241,6 +247,12 @@ private:
Owned<StructType> attributesDescriptor;
ManagedVector<FieldDescriptor> fieldDescriptors;
+protected:
+ void doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path, Filter filter,
+ void *filterData, unsigned idx,
+ VisitorSet &visited) override;
+
public:
Descriptor(Manager &mgr, std::string name, Handle<Domain> domain,
// TODO: What would be a wise default value for attributes?
@@ -351,6 +363,12 @@ private:
Owned<StructuredClass> isa;
ManagedVector<FieldDescriptor> parents;
+protected:
+ void doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path, Filter filter,
+ void *filterData, unsigned idx,
+ VisitorSet &visited) override;
+
public:
const bool transparent;
@@ -399,6 +417,12 @@ private:
ManagedVector<AnnotationClass> annotationClasses;
ManagedVector<Typesystem> typesystems;
+protected:
+ void doResolve(std::vector<Rooted<Managed>> &res,
+ const std::vector<std::string> &path, Filter filter,
+ void *filterData, unsigned idx,
+ VisitorSet &visited) override;
+
public:
Domain(Manager &mgr, std::string name)
// TODO: Can a domain have a parent?
diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp
new file mode 100644
index 0000000..b1538cf
--- /dev/null
+++ b/test/core/model/DomainTest.cpp
@@ -0,0 +1,67 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+
+#include <core/model/Domain.hpp>
+
+#include "ModelTestUtils.hpp"
+
+namespace ousia {
+namespace model {
+
+void assert_path(std::vector<Rooted<Managed>> &result, size_t idx,
+ const std::type_info& expected_type,
+ std::vector<std::string> expected_path)
+{
+ ASSERT_TRUE(result.size() > idx);
+ // check class/type
+ ASSERT_EQ(expected_type, typeid(*result[idx]));
+ // transform to node
+ Managed *m = &(*result[idx]);
+ Node *n = dynamic_cast<Node *>(m);
+ ASSERT_TRUE(n);
+ // extract actual path
+ std::vector<std::string> actual_path = n->path();
+ // check path
+ ASSERT_EQ(expected_path, actual_path);
+}
+
+TEST(Document, testDomainResolving)
+{
+ // Construct Manager
+ Manager mgr{1};
+ // Get the domain.
+ Rooted<Domain> domain = constructBookDomain(mgr);
+
+ /*
+ * Start with the "book" search keyword. This should resolve to the domain
+ * itself (because it is called "book"), as well as the structure "book"
+ * node.
+ */
+ std::vector<Rooted<Managed>> res =
+ domain->resolve(std::vector<std::string>{"book"});
+ // First we expect the book domain.
+ assert_path(res, 0, typeid(Domain), {"book"});
+ // Then the book structure.
+ assert_path(res, 1, typeid(StructuredClass), {"book", "book"});
+}
+}
+}