summaryrefslogtreecommitdiff
path: root/src/core/model/Domain.cpp
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-15 12:13:18 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-15 12:13:18 +0100
commit496c4e527852d0fd64a24bd5ac2506e50ba0afc7 (patch)
treedfcd496dd09e203849d0c4a557f48f355fbfc9c4 /src/core/model/Domain.cpp
parent86885e5a63c10d264bac822cb054607c27c0f734 (diff)
supported more automatic registration behaviour, checked for internal name consistency regarding FieldDescriptors, AnnotationClasses and StructuredClasses and made adding methods for automatically registered references protected.
Diffstat (limited to 'src/core/model/Domain.cpp')
-rw-r--r--src/core/model/Domain.cpp117
1 files changed, 115 insertions, 2 deletions
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 */