summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-19 00:29:55 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-19 00:29:55 +0100
commit23e593eb69f6d0beb197f33ae31b479c60d9316f (patch)
tree77046b5372b178ed08bdce398841b3eb0de11cea /src
parent55d363bea503c0607c80604280c26c235a5d7ee1 (diff)
added convenience function for document construction and tested them.
Diffstat (limited to 'src')
-rw-r--r--src/core/model/Document.cpp104
-rw-r--r--src/core/model/Document.hpp100
2 files changed, 200 insertions, 4 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index 31b22e3..709981b 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -58,7 +58,7 @@ int DocumentEntity::getFieldDescriptorIndex(const std::string &fieldName)
}
void DocumentEntity::getField(ManagedVector<StructuredEntity> &res,
- const std::string &fieldName)
+ const std::string &fieldName)
{
int f = getFieldDescriptorIndex(fieldName);
if (f < 0) {
@@ -85,6 +85,108 @@ ManagedVector<StructuredEntity> &DocumentEntity::getField(
"The given FieldDescriptor is not specified in the Descriptor of this "
"node.");
}
+
+static Rooted<StructuredClass> resolveDescriptor(
+ std::vector<Handle<Domain>> domains, const std::string &className)
+{
+ // iterate over all domains.
+ for (auto &d : domains) {
+ // use the actual resolve method.
+ std::vector<Rooted<Managed>> resolved = d->resolve(className);
+ // if we don't find anything, continue.
+ if (resolved.size() == 0) {
+ continue;
+ }
+ // Otherwise take the first valid result.
+ for (auto &r : resolved) {
+ Managed *m = &(*r);
+ StructuredClass *c = dynamic_cast<StructuredClass *>(m);
+ if (c != nullptr) {
+ return Rooted<StructuredClass>(c);
+ }
+ }
+ }
+ return {nullptr};
+}
+
+Rooted<StructuredEntity> StructuredEntity::buildRootEntity(
+ Handle<Document> document, std::vector<Handle<Domain>> domains,
+ const std::string &className, Variant attributes, std::string name)
+{
+ // If the parent is not set, we can not build the entity.
+ if (document == nullptr) {
+ return {nullptr};
+ }
+ // If we can not find the correct descriptor, we can not build the entity
+ // either.
+ Rooted<StructuredClass> descriptor = resolveDescriptor(domains, className);
+ if (descriptor == nullptr) {
+ return {nullptr};
+ }
+ // Then construct the StructuredEntity itself.
+ Rooted<StructuredEntity> root{
+ new StructuredEntity(document->getManager(), document, descriptor,
+ attributes, std::move(name))};
+ // append it to the document.
+ document->setRoot(root);
+ // and return it.
+ return root;
+}
+
+Rooted<StructuredEntity> StructuredEntity::buildEntity(
+ Handle<DocumentEntity> parent, std::vector<Handle<Domain>> domains,
+ const std::string &className, const std::string &fieldName,
+ Variant attributes, std::string name)
+{
+ // If the parent is not set, we can not build the entity.
+ if (parent == nullptr) {
+ return {nullptr};
+ }
+ // If we can not find the correct descriptor, we can not build the entity
+ // either.
+ Rooted<StructuredClass> descriptor = resolveDescriptor(domains, className);
+ if (descriptor == nullptr) {
+ return {nullptr};
+ }
+ // Then construct the StructuredEntity itself.
+ Rooted<StructuredEntity> entity{new StructuredEntity(
+ parent->getManager(), parent, descriptor, attributes, std::move(name))};
+ // if the field does not exist, return null handle as well.
+ if (!parent->hasField(fieldName)) {
+ return {nullptr};
+ }
+ // append the new entity to the right field.
+ ManagedVector<StructuredEntity> field{parent};
+ parent->getField(field, fieldName);
+ field.push_back(entity);
+
+ // and return it.
+ return entity;
+}
+
+Rooted<DocumentPrimitive> DocumentPrimitive::buildEntity(
+ Handle<DocumentEntity> parent, Variant content,
+ const std::string &fieldName)
+{
+ // If the parent is not set, we can not build the entity.
+ if (parent == nullptr) {
+ return {nullptr};
+ }
+ // Then construct the StructuredEntity itself.
+ Rooted<DocumentPrimitive> entity{
+ new DocumentPrimitive(parent->getManager(), parent, content)};
+ // if the field does not exist, return null handle as well.
+ if (!parent->hasField(fieldName)) {
+ return {nullptr};
+ }
+ // append the new entity to the right field.
+ ManagedVector<StructuredEntity> field{parent};
+ parent->getField(field, fieldName);
+ field.push_back(entity);
+
+ // and return it.
+ return entity;
+}
}
}
diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp
index a31e52f..15a4599 100644
--- a/src/core/model/Document.hpp
+++ b/src/core/model/Document.hpp
@@ -80,6 +80,7 @@ namespace model {
class StructuredEntity;
class AnnotationEntity;
+class Document;
/**
* A DocumentEntity is the common superclass for StructuredEntities and
@@ -110,8 +111,11 @@ public:
{
// TODO: Validation at construction time?
// insert empty vectors for each field.
- for (size_t f = 0; f < descriptor->getFieldDescriptors().size(); f++) {
- fields.push_back(ManagedVector<StructuredEntity>(this));
+ if (!descriptor.isNull()) {
+ for (size_t f = 0; f < descriptor->getFieldDescriptors().size();
+ f++) {
+ fields.push_back(ManagedVector<StructuredEntity>(this));
+ }
}
}
@@ -202,6 +206,57 @@ public:
}
ManagedVector<AnnotationEntity> &getAnnotations() { return annotations; }
+
+ /**
+ * This builds the root StructuredEntity for the given document. It
+ * automatically appends the newly build entity to the given document.
+ *
+ * @param document is the document this entity shall be build for. The
+ * resulting entity will automatically be appended to that
+ * document. Also the manager of that document will be
+ * used to register the new node.
+ * @param domains are the domains that are used to find the
+ * StructuredClass for the new node. The domains will be
+ * searched in the given order.
+ * @param className is the name of the StructuredClass.
+ * @param attributes are the attributes of the new node in terms of a Struct
+ * variant (empty per default).
+ * @param name is the name of this StructuredEntity (empty per
+ * default).
+ * @return the newly created StructuredEntity or a nullptr if some
+ * input handle was empty or the given domains did not
+ * contain a StructuredClass with the given name.
+ */
+ static Rooted<StructuredEntity> buildRootEntity(
+ Handle<Document> document, std::vector<Handle<Domain>> domains,
+ const std::string &className, Variant attributes = Variant(),
+ std::string name = "");
+
+ /**
+ * This builds a StructuredEntity as child of the given DocumentEntity. It
+ * automatically appends the newly build entity to its parent.
+ *
+ * @param parent is the parent DocumentEntity. The newly constructed
+ * StructuredEntity will automatically be appended to it.
+ * @param domains are the domains that are used to find the
+ * StructuredClass for the new node. The domains will be
+ * searched in the given order.
+ * @param className is the name of the StructuredClass.
+ * @param fieldName is the name of the field where the newly constructed
+ * StructuredEntity shall be appended.
+ * @param attributes are the attributes of the new node in terms of a Struct
+ * variant (empty per default).
+ * @param name is the name of this StructuredEntity (empty per
+ * default).
+ *
+ * @return the newly created StructuredEntity or a nullptr if some
+ * input handle was empty or the given domains did not
+ * contain a StructuredClass with the given name.
+ */
+ static Rooted<StructuredEntity> buildEntity(
+ Handle<DocumentEntity> parent, std::vector<Handle<Domain>> domains,
+ const std::string &className, const std::string &fieldName = "",
+ Variant attributes = Variant(), std::string name = "");
};
/**
@@ -211,7 +266,7 @@ public:
*/
class DocumentPrimitive : public StructuredEntity {
public:
- DocumentPrimitive(Manager &mgr, Handle<StructuredEntity> parent,
+ DocumentPrimitive(Manager &mgr, Handle<DocumentEntity> parent,
Variant content)
: StructuredEntity(mgr, parent, nullptr, std::move(content))
{
@@ -220,6 +275,25 @@ public:
Variant getContent() const { return getAttributes(); }
// TODO: Override such methods like "getField" to disable them?
+
+ /**
+ * This builds a DocumentPrimitive as child of the given DocumentEntity. It
+ * automatically appends the newly build entity to its parent.
+ *
+ * @param parent is the parent DocumentEntity. The newly constructed
+ * DocumentPrimitive will automatically be appended to it.
+ * @param content is the primitive content of the new node in terms of a
+ * Struct variant.
+ * @param fieldName is the name of the field where the newly constructed
+ * StructuredEntity shall be appended.
+ *
+ * @return the newly created StructuredEntity or a nullptr if some
+ * input handle was empty or the given domains did not
+ * contain a StructuredClass with the given name.
+ */
+ static Rooted<DocumentPrimitive> buildEntity(
+ Handle<DocumentEntity> parent,
+ Variant content, const std::string &fieldName = "");
};
/**
@@ -284,6 +358,26 @@ public:
Rooted<Anchor> getEnd() { return end; }
};
+
+/**
+ * A Document is mainly a wrapper for the Root structure node of the Document
+ * Graph.
+ */
+class Document : public Node {
+private:
+ Owned<StructuredEntity> root;
+
+public:
+ Document(Manager &mgr, std::string name)
+ // TODO: Can a document have a parent?
+ : Node(mgr, std::move(name), nullptr)
+ {
+ }
+
+ void setRoot(Handle<StructuredEntity> root) { root = acquire(root); };
+
+ Rooted<StructuredEntity> getRoot() const { return root; }
+};
}
}