summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/model/Document.cpp26
-rw-r--r--src/core/model/Document.hpp30
-rw-r--r--src/core/model/Domain.cpp117
-rw-r--r--src/core/model/Domain.hpp99
4 files changed, 164 insertions, 108 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index 022b91c..eca24e7 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -58,7 +58,8 @@ int DocumentEntity::getFieldDescriptorIndex(const std::string &fieldName,
}
}
if (enforce) {
- throw OusiaException("No field for the given name exists!");
+ throw OusiaException(descriptor->getName() +
+ " has no field with name " + fieldName);
} else {
return -1;
}
@@ -80,15 +81,27 @@ int DocumentEntity::getFieldDescriptorIndex(
f++;
}
if (enforce) {
- throw OusiaException(
- "The given FieldDescriptor is not specified in the Descriptor of "
- "this "
- "node.");
+ throw OusiaException(descriptor->getName() +
+ " has no field with name " +
+ fieldDescriptor->getName());
} else {
return -1;
}
}
+/* Class AnnotationEntity */
+
+AnnotationEntity::AnnotationEntity(Manager &mgr, Handle<Document> parent,
+ Handle<AnnotationClass> descriptor, Handle<Anchor> start,
+ Handle<Anchor> end, Variant attributes, std::string name)
+ : Node(mgr, std::move(name), parent),
+ DocumentEntity(this, descriptor, attributes),
+ start(acquire(start)),
+ end(acquire(end))
+{
+ parent->annotations.push_back(this);
+}
+
/* Class Document */
void Document::continueResolve(ResolutionState &state)
@@ -109,8 +122,7 @@ const Rtti<model::Document> Document =
const Rtti<model::StructureNode> StructureNode =
RttiBuilder("StructureNode").parent(&Node);
const Rtti<model::AnnotationEntity> AnnotationEntity =
- RttiBuilder("AnnotationEntity").parent(&Node).composedOf(
- &StructureNode);
+ RttiBuilder("AnnotationEntity").parent(&Node).composedOf(&StructureNode);
const Rtti<model::StructuredEntity> StructuredEntity =
RttiBuilder("StructuredEntity").parent(&StructureNode).composedOf(
{&StructureNode});
diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp
index 357b752..15a5ec8 100644
--- a/src/core/model/Document.hpp
+++ b/src/core/model/Document.hpp
@@ -427,7 +427,9 @@ public:
* The constructor for an AnnotationEntity.
*
* @param mgr is the Manager instance.
- * @param parent is the Document this AnnotationEntity is part of.
+ * @param parent is the Document this AnnotationEntity is part of. The
+ * constructor will automatically register this
+ * AnnotationEntity at that document.
* @param descriptor is the AnnotationClass of this AnnotationEntity.
* @param start is the start Anchor of this AnnotationEntity. It has to
* be part of the Document given as parent.
@@ -441,13 +443,7 @@ public:
AnnotationEntity(Manager &mgr, Handle<Document> parent,
Handle<AnnotationClass> descriptor, Handle<Anchor> start,
Handle<Anchor> end, Variant attributes = {},
- std::string name = "")
- : Node(mgr, std::move(name), parent),
- DocumentEntity(this, descriptor, attributes),
- start(acquire(start)),
- end(acquire(end))
- {
- }
+ std::string name = "");
/**
* Returns the start Anchor of this AnnotationEntity.
@@ -470,6 +466,9 @@ 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;
@@ -511,21 +510,6 @@ public:
}
/**
- * Adds an AnnotationEntity to this document. The Anchors used as start and
- * end of this AnnotationEntity have to be part of this document.
- */
- void addAnnotation(Handle<AnnotationEntity> a) { annotations.push_back(a); }
- /**
- * Adds multiple AnnotationEntities to this document. The Anchors used as
- * start and end of these AnnotationEntities have to be part of this
- * document.
- */
- void addAnnotations(const std::vector<Handle<AnnotationEntity>> &as)
- {
- annotations.insert(annotations.end(), as.begin(), as.end());
- }
-
- /**
* Returns a const reference to the NodeVector of Domains that are used
* within this Document.
*
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index be9aa05..f1b91cc 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -26,8 +26,48 @@
namespace ousia {
namespace model {
+template <class T>
+static void checkUniqueName(Handle<Node> parent, NodeVector<T> vec,
+ Handle<T> child,
+ const std::string &parentClassName,
+ const std::string &childClassName)
+{
+ std::set<std::string> childNames;
+ for (auto &c : vec) {
+ childNames.insert(c->getName());
+ }
+ if (childNames.find(child->getName()) != childNames.end()) {
+ throw OusiaException(std::string("The ") + parentClassName + " " +
+ parent->getName() + " already has a " +
+ childClassName + " with name " + child->getName());
+ }
+}
+
/* Class FieldDescriptor */
+FieldDescriptor::FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
+ Handle<Type> primitiveType, std::string name,
+ bool optional)
+ : Node(mgr, std::move(name), parent),
+ children(this),
+ fieldType(FieldType::PRIMITIVE),
+ primitiveType(acquire(primitiveType)),
+ optional(optional)
+{
+ parent->addFieldDescriptor(this);
+}
+
+FieldDescriptor::FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
+ FieldType fieldType, std::string name,
+ bool optional)
+ : Node(mgr, std::move(name), parent),
+ children(this),
+ fieldType(fieldType),
+ optional(optional)
+{
+ parent->addFieldDescriptor(this);
+}
+
/* Class Descriptor */
void Descriptor::continueResolve(ResolutionState &state)
@@ -41,6 +81,13 @@ void Descriptor::continueResolve(ResolutionState &state)
state);
}
+void Descriptor::addFieldDescriptor(Handle<FieldDescriptor> fd)
+{
+ checkUniqueName(this, fieldDescriptors, fd, "Descriptor",
+ "FieldDescriptor");
+ fieldDescriptors.push_back(fd);
+}
+
std::vector<Rooted<Node>> Descriptor::pathTo(
Handle<StructuredClass> target) const
{
@@ -111,8 +158,8 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,
if (isa(RttiTypes::StructuredClass)) {
const StructuredClass *tis = static_cast<const StructuredClass *>(this);
/*
- * if this is a StructuredClass, we can also use the super class (at
- * least for fields that are not overridden)
+ * if this is a StructuredClass, we can also use the super class
+ * (at least for fields that are not overridden)
*/
if (exploreSuperclass && !tis->getIsA().isNull()) {
// copy the path.
@@ -148,6 +195,60 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,
return found;
}
+void Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd)
+{
+ if (fd->getFieldType() == FieldDescriptor::FieldType::PRIMITIVE) {
+ /*
+ *To call the "new" operation is enough here, because the
+ * constructor will add the newly constructed FieldDescriptor to this
+ * Descriptor automatically.
+ */
+ new FieldDescriptor(getManager(), this,
+ fd->getPrimitiveType(),
+ fd->getName(), fd->optional);
+ } else {
+ new FieldDescriptor(getManager(), this,
+ fd->getFieldType(),
+ fd->getName(), fd->optional);
+ }
+}
+
+/* Class StructuredClass */
+
+StructuredClass::StructuredClass(Manager &mgr, std::string name,
+ Handle<Domain> domain,
+ const Cardinality &cardinality,
+ Handle<StructType> attributesDescriptor,
+ Handle<StructuredClass> isa, bool transparent,
+ bool root)
+ : Descriptor(mgr, std::move(name), domain, attributesDescriptor),
+ cardinality(cardinality),
+ isa(acquire(isa)),
+ subclasses(this),
+ transparent(transparent),
+ root(root)
+{
+ if (!isa.isNull()) {
+ isa->subclasses.push_back(this);
+ }
+ if (!domain.isNull()) {
+ domain->addStructuredClass(this);
+ }
+}
+
+/* Class AnnotationClass */
+
+AnnotationClass::AnnotationClass(
+ Manager &mgr, std::string name, Handle<Domain> domain,
+ // TODO: What would be a wise default value for attributes?
+ Handle<StructType> attributesDescriptor)
+ : Descriptor(mgr, std::move(name), domain, attributesDescriptor)
+{
+ if (!domain.isNull()) {
+ domain->addAnnotationClass(this);
+ }
+}
+
/* Class Domain */
void Domain::continueResolve(ResolutionState &state)
@@ -159,6 +260,18 @@ void Domain::continueResolve(ResolutionState &state)
continueResolveReferences(typesystems, state);
}
}
+
+void Domain::addStructuredClass(Handle<StructuredClass> s)
+{
+ checkUniqueName(this, structuredClasses, s, "Domain", "StructuredClass");
+ structuredClasses.push_back(s);
+}
+
+void Domain::addAnnotationClass(Handle<AnnotationClass> a)
+{
+ checkUniqueName(this, annotationClasses, a, "Domain", "AnnotationClass");
+ annotationClasses.push_back(a);
+}
}
/* Type registrations */
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 4b26917..791d563 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -292,14 +292,7 @@ public:
*/
FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
Handle<Type> primitiveType, std::string name = "",
- bool optional = false)
- : Node(mgr, std::move(name), parent),
- children(this),
- fieldType(FieldType::PRIMITIVE),
- primitiveType(acquire(primitiveType)),
- optional(optional)
- {
- }
+ bool optional = false);
/**
* This is the constructor for non-primitive fields. You have to provide
@@ -318,13 +311,7 @@ public:
*/
FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
FieldType fieldType = FieldType::TREE,
- std::string name = "", bool optional = false)
- : Node(mgr, std::move(name), parent),
- children(this),
- fieldType(fieldType),
- optional(optional)
- {
- }
+ std::string name = "", bool optional = false);
/**
* Returns a const reference to the NodeVector of StructuredClasses whose
@@ -389,6 +376,9 @@ public:
*
*/
class Descriptor : public Node {
+
+friend FieldDescriptor;
+
private:
Owned<StructType> attributesDescriptor;
NodeVector<FieldDescriptor> fieldDescriptors;
@@ -401,6 +391,11 @@ private:
protected:
void continueResolve(ResolutionState &state) override;
+
+ /**
+ * Adds a FieldDescriptor and checks for name uniqueness.
+ */
+ void addFieldDescriptor(Handle<FieldDescriptor> fd);
public:
Descriptor(Manager &mgr, std::string name, Handle<Domain> domain,
@@ -436,20 +431,11 @@ public:
}
/**
- * Adds a FieldDescriptor to this Descriptor.
+ * Copies a FieldDescriptor that belongs to another Descriptor to this
+ * Descriptor. This will throw an exception if a FieldDescriptor with the
+ * given name already exists.
*/
- void addFieldDescriptor(Handle<FieldDescriptor> fd)
- {
- fieldDescriptors.push_back(fd);
- }
-
- /**
- * Adds multiple FieldDescriptors to this Descriptor.
- */
- void addFieldDescriptors(const std::vector<Handle<FieldDescriptor>> &fds)
- {
- fieldDescriptors.insert(fieldDescriptors.end(), fds.begin(), fds.end());
- }
+ void copyFieldDescriptor(Handle<FieldDescriptor> fd);
/**
* This tries to construct the shortest possible path of this Descriptor
@@ -600,18 +586,7 @@ public:
Handle<StructType> attributesDescriptor = nullptr,
// TODO: What would be a wise default value for isa?
Handle<StructuredClass> isa = nullptr,
- bool transparent = false, bool root = false)
- : Descriptor(mgr, std::move(name), domain, attributesDescriptor),
- cardinality(cardinality),
- isa(acquire(isa)),
- subclasses(this),
- transparent(transparent),
- root(root)
- {
- if (!isa.isNull()) {
- isa->subclasses.push_back(this);
- }
- }
+ bool transparent = false, bool root = false);
/**
* Returns the Cardinality of this StructuredClass (as a RangeSet).
@@ -672,10 +647,7 @@ public:
*/
AnnotationClass(Manager &mgr, std::string name, Handle<Domain> domain,
// TODO: What would be a wise default value for attributes?
- Handle<StructType> attributesDescriptor)
- : Descriptor(mgr, std::move(name), domain, attributesDescriptor)
- {
- }
+ Handle<StructType> attributesDescriptor = nullptr);
};
/**
@@ -684,6 +656,10 @@ public:
* to certain Structures?
*/
class Domain : public Node {
+
+friend StructuredClass;
+friend AnnotationClass;
+
private:
NodeVector<StructuredClass> structuredClasses;
NodeVector<AnnotationClass> annotationClasses;
@@ -694,6 +670,9 @@ private:
protected:
void continueResolve(ResolutionState &state) override;
+ void addStructuredClass(Handle<StructuredClass> s);
+ void addAnnotationClass(Handle<AnnotationClass> a);
+
public:
/**
* The constructor for a new domain. Note that this is an empty Domain and
@@ -726,22 +705,6 @@ public:
}
/**
- * Adds a StructuredClass to this Domain.
- */
- void addStructuredClass(Handle<StructuredClass> s)
- {
- structuredClasses.push_back(s);
- }
-
- /**
- * Adds multiple StructuredClasses to this Domain.
- */
- void addStructuredClasses(const std::vector<Handle<StructuredClass>> &ss)
- {
- structuredClasses.insert(structuredClasses.end(), ss.begin(), ss.end());
- }
-
- /**
* Returns a const reference to the NodeVector of AnnotationClasses that are
* part of this Domain.
*
@@ -754,22 +717,6 @@ public:
}
/**
- * Adds an AnnotationClass to this Domain.
- */
- void addAnnotationClass(Handle<AnnotationClass> a)
- {
- annotationClasses.push_back(a);
- }
-
- /**
- * Adds multiple AnnotationClasses to this Domain.
- */
- void addAnnotationClasses(const std::vector<Handle<AnnotationClass>> &as)
- {
- annotationClasses.insert(annotationClasses.end(), as.begin(), as.end());
- }
-
- /**
* Returns a const reference to the NodeVector of TypeSystems that are
* references in this Domain.
*