summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-20 12:51:29 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-01-20 12:51:29 +0100
commit070094c6411f4c6b17ad4420538a7d7121988c73 (patch)
treed1c510b6b7d645fbe3e72adc15e9fd88d654bf02 /src
parent86f911a8a068059db9a30b36738172339d011860 (diff)
completed setters for Domain classes. setSuperclass even has move semantics!
Diffstat (limited to 'src')
-rw-r--r--src/core/model/Domain.cpp71
-rw-r--r--src/core/model/Domain.hpp158
2 files changed, 193 insertions, 36 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index f76c988..0fc078f 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -37,7 +37,9 @@ FieldDescriptor::FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
primitiveType(acquire(primitiveType)),
optional(optional)
{
- parent->addFieldDescriptor(this);
+ if (parent != nullptr) {
+ parent->addFieldDescriptor(this);
+ }
}
FieldDescriptor::FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
@@ -48,7 +50,9 @@ FieldDescriptor::FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
fieldType(fieldType),
optional(optional)
{
- parent->addFieldDescriptor(this);
+ if (parent != nullptr) {
+ parent->addFieldDescriptor(this);
+ }
}
/* Class Descriptor */
@@ -173,13 +177,28 @@ StructuredClass::StructuredClass(Manager &mgr, std::string name,
root(root)
{
if (superclass != nullptr) {
- superclass->subclasses.push_back(this);
+ superclass->addSubclass(this);
}
- if (!domain.isNull()) {
+ if (domain != nullptr) {
domain->addStructuredClass(this);
}
}
+void StructuredClass::setSuperclass(Handle<StructuredClass> sup)
+{
+ if (superclass == sup) {
+ return;
+ }
+ invalidate();
+ if (sup != nullptr) {
+ sup->addSubclass(this);
+ }
+ if (superclass != nullptr) {
+ superclass->removeSubclass(this);
+ }
+ superclass = acquire(sup);
+}
+
bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const
{
if (c == nullptr || superclass == nullptr) {
@@ -191,6 +210,33 @@ bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const
return superclass->isSubclassOf(c);
}
+void StructuredClass::addSubclass(Handle<StructuredClass> sc)
+{
+ // check if we already have that class.
+ if (subclasses.find(sc) != subclasses.end()) {
+ return;
+ }
+ invalidate();
+ subclasses.push_back(sc);
+ sc->setSuperclass(this);
+}
+
+void StructuredClass::removeSubclass(Handle<StructuredClass> sc)
+{
+ // if we don't have this subclass we can return directly.
+ if (sc == nullptr) {
+ return;
+ }
+ auto it = subclasses.find(sc);
+ if (it == subclasses.end()) {
+ return;
+ }
+ // otherwise we have to erase it.
+ invalidate();
+ subclasses.erase(it);
+ sc->setSuperclass(nullptr);
+}
+
const void StructuredClass::gatherFieldDescriptors(
NodeVector<FieldDescriptor> &current,
std::set<std::string> &overriddenFields) const
@@ -245,12 +291,18 @@ void Domain::addStructuredClass(Handle<StructuredClass> s)
{
invalidate();
structuredClasses.push_back(s);
+ if (s->getParent() != this) {
+ s->setParent(this);
+ }
}
void Domain::addAnnotationClass(Handle<AnnotationClass> a)
{
invalidate();
annotationClasses.push_back(a);
+ if (a->getParent() != this) {
+ a->setParent(this);
+ }
}
}
/* Type registrations */
@@ -261,13 +313,14 @@ const Rtti FieldDescriptor =
const Rtti Descriptor =
RttiBuilder<model::Descriptor>("Descriptor").parent(&Node);
const Rtti StructuredClass =
- RttiBuilder<model::StructuredClass>("StructuredClass").parent(&Descriptor).composedOf(
- &FieldDescriptor);
+ RttiBuilder<model::StructuredClass>("StructuredClass")
+ .parent(&Descriptor)
+ .composedOf(&FieldDescriptor);
const Rtti AnnotationClass =
RttiBuilder<model::AnnotationClass>("AnnotationClass").parent(&Descriptor);
-const Rtti Domain =
- RttiBuilder<model::Domain>("Domain").parent(&Node).composedOf(
- {&StructuredClass, &AnnotationClass});
+const Rtti Domain = RttiBuilder<model::Domain>("Domain")
+ .parent(&Node)
+ .composedOf({&StructuredClass, &AnnotationClass});
}
}
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 4d33a91..e4a6967 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -271,8 +271,14 @@ private:
Owned<Type> primitiveType;
bool optional;
+ /*
+ * TODO: doValidate with:
+ * # primitive and primitiveType set and no children XOR other FieldType and
+ * no primitive type set
+ * # namecheck
+ * # parent typecheck
+ */
public:
- // TODO: What about the name of default fields?
/**
* This is the constructor for primitive fields. The type is automatically
* set to "PRIMITIVE".
@@ -293,7 +299,7 @@ public:
/**
* This is the constructor for non-primitive fields. You have to provide
- * children here.
+ * children here later on.
*
* @param mgr is the global Manager instance.
* @param parent is a handle of the Descriptor node that has this
@@ -306,7 +312,7 @@ public:
* filled in order for an instance of the parent
* Descriptor to be valid.
*/
- FieldDescriptor(Manager &mgr, Handle<Descriptor> parent,
+ FieldDescriptor(Manager &mgr, Handle<Descriptor> parent = nullptr,
FieldType fieldType = FieldType::TREE,
std::string name = "", bool optional = false);
@@ -321,10 +327,6 @@ public:
*/
const NodeVector<StructuredClass> &getChildren() const { return children; }
- /*
- *TODO: This should check whether another class is permitted that is a
- * superclass of this one.
- */
/**
* Adds a StructuredClass whose instances shall be allowed as children in
* the StructureTree of instances of this field.
@@ -347,14 +349,14 @@ public:
/**
* Returns the type of this field (not to be confused with the primitive
- *type of this field).
+ * type of this field).
*
* @return the type of this field.
*/
FieldType getFieldType() const { return fieldType; }
/**
* Sets the type of this field (not to be confused with the primitive type
- *of this field).
+ * of this field).
*
* @param ft is the new type of this field.
*/
@@ -421,8 +423,6 @@ public:
* the attribute specification of a descriptor is done by referencing an
* appropriate StructType that contains all permitted keys and value types.
*
- * 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.
* Consider the XML
@@ -451,10 +451,17 @@ private:
protected:
void doResolve(ResolutionState &state) override;
+ /*
+ * TODO: doValidate with:
+ * # namecheck
+ * # FieldDescriptor name uniqueness
+ * # do all FieldDescriptors have this Descriptor as parent?
+ * # is the parent a domain?
+ * # is the attributes descriptor either not set or a StructType?
+ */
public:
Descriptor(Manager &mgr, std::string name, Handle<Domain> domain,
- // TODO: What would be a wise default value for attributes?
Handle<StructType> attributesDescriptor)
: Node(mgr, std::move(name), domain),
attributesDescriptor(acquire(attributesDescriptor)),
@@ -473,6 +480,18 @@ public:
{
return attributesDescriptor;
}
+
+ /**
+ * Sets the StructType that specifies the attributes of this Descriptor.
+ *
+ * @param t some StructType.
+ */
+ void setAttributesDescriptor(Handle<StructType> t)
+ {
+ invalidate();
+ attributesDescriptor = acquire(t);
+ }
+
/**
* Returns a const reference to the NodeVector of all FieldDescriptors of
* this Descriptor.
@@ -486,7 +505,13 @@ public:
}
/**
- * Adds the given FieldDescriptor to this Descriptor.
+ * Adds the given FieldDescriptor to this Descriptor. This also sets the
+ * parent of the given FieldDescriptor if it is not set to this Descriptor
+ * already.
+ *
+ * This should not be used if the given FieldDescriptor is a field of
+ * another Descriptor already. Use copyFieldDescriptor in that case.
+ * TODO: But this could get move semantics.
*
* @param fd is a FieldDescriptor.
*/
@@ -494,22 +519,31 @@ public:
{
invalidate();
fieldDescriptors.push_back(fd);
+ if (fd->getParent() != this) {
+ fd->setParent(this);
+ }
}
/**
- * Adds the given FieldDescriptors to this Descriptor.
+ * Adds the given FieldDescriptors to this Descriptor. This also sets the
+ * parent of each given FieldDescriptor if it is not set to this Descriptor
+ * already.
*
* @param fds are FieldDescriptors.
*/
- void addFieldDescriptors(std::vector<Handle<FieldDescriptor>> fds)
+ void addFieldDescriptors(const std::vector<Handle<FieldDescriptor>> &fds)
{
invalidate();
- fieldDescriptors.insert(fieldDescriptors.end(), fds.begin(), fds.end());
+ for (Handle<FieldDescriptor> fd : fds) {
+ addFieldDescriptor(fd);
+ }
}
/**
* Copies a FieldDescriptor that belongs to another Descriptor to this
* Descriptor.
+ *
+ * @param fd some FieldDescriptor belonging to another Descriptor.
*/
void copyFieldDescriptor(Handle<FieldDescriptor> fd);
@@ -550,6 +584,19 @@ public:
*/
typedef RangeSet<size_t> Cardinality;
+
+/**
+ * This is the default cardinality.
+ */
+
+static Cardinality createAny(){
+ Cardinality any;
+ any.merge(Range<size_t>::typeRangeFrom(0));
+ return std::move(any);
+}
+
+static const Cardinality AnyCardinality = createAny();
+
/**
* A StructuredClass specifies nodes in the StructureTree of a document that
* implements this domain. For more information on the StructureTree please
@@ -638,6 +685,15 @@ private:
NodeVector<FieldDescriptor> &current,
std::set<std::string> &overriddenFields) const;
+
+
+ /*
+ * TODO: doValidate with
+ * # does the subclasses have this class as superclass?
+ * # are the subclasses and the superclass valid?
+ * # is this a valid descriptor?
+ */
+
public:
/**
* The constructor for a StructuredClass.
@@ -649,7 +705,9 @@ public:
* @param cardinality specifies how often an element of this type
* may occur at a specific point in the
* StructureTree. For example: A document should
- * have at least one author.
+ * have at least one author. This is set to *
+ * per default, meaning that any number of
+ * of instances is valid, including zero.
* @param attributesDescriptor is a StructType that specifies the attribute
* keys as well as value domains for this
* Descriptor.
@@ -666,10 +724,10 @@ public:
* @param root specifies whether this StructuredClass is
* allowed to be at the root of a Document.
*/
- StructuredClass(Manager &mgr, std::string name, Handle<Domain> domain,
- const Cardinality &cardinality,
+ StructuredClass(Manager &mgr, std::string name = "",
+ Handle<Domain> domain = nullptr,
+ const Cardinality &cardinality = AnyCardinality,
Handle<StructType> attributesDescriptor = nullptr,
- // TODO: What would be a wise default value for isa?
Handle<StructuredClass> superclass = nullptr,
bool transparent = false, bool root = false);
@@ -689,6 +747,18 @@ public:
Rooted<StructuredClass> getSuperclass() const { return superclass; }
/**
+ * Sets the superclass of this StructuredClass. This is not the same as
+ * the parents in the Structure Tree!
+ *
+ * This will also register this class as a subclass at the given superclass
+ * and unregister it at the previous superclass.
+ *
+ * @parem sup some StructuredClass that shall be the new superclass of this
+ * StructuredClass.
+ */
+ void setSuperclass(Handle<StructuredClass> sup);
+
+ /**
* Returns true if this class is a subclass of the given class. It does not
* return true if the other class is equal to the given class.
*
@@ -718,6 +788,22 @@ public:
}
/**
+ * Adds a subclass to this StructuredClass. This also calls setSuperclass
+ * on the given subclass.
+ *
+ * @param sc is some StructuredClass.
+ */
+ void addSubclass(Handle<StructuredClass> sc);
+
+ /**
+ * Removes a subclass from this StructuredClass. This also calls
+ * setSuperclass(nullptr) on the given subclass.
+ *
+ * @param sc is some StructuredClass.
+ */
+ void removeSubclass(Handle<StructuredClass> sc);
+
+ /**
* Returns a const reference to the NodeVector of all FieldDescriptors of
* this StructuredClass. This does more than the getter for FieldDescriptor,
* because in this method we gather the FieldDescriptors of all superclasses
@@ -790,7 +876,13 @@ private:
protected:
void doResolve(ResolutionState &state) override;
-
+ /*
+ * TODO: doValidate with:
+ * # namecheck
+ * # are all structureclasses valid and have a unique name?
+ * # are all annotationclasses valid and have a unique name?
+ * # are all typesystems valid?
+ */
public:
/**
* The constructor for a new domain. Note that this is an empty Domain and
@@ -800,7 +892,7 @@ public:
* @param name is a name for this domain which will be used for later
* references to this Domain.
*/
- Domain(Manager &mgr, std::string name)
+ Domain(Manager &mgr, std::string name = "")
: Node(mgr, std::move(name), nullptr),
structuredClasses(this),
annotationClasses(this),
@@ -817,7 +909,7 @@ public:
* @param name is a name for this domain which will be used for later
* references to this Domain.
*/
- Domain(Manager &mgr, Handle<SystemTypesystem> sys, std::string name)
+ Domain(Manager &mgr, Handle<SystemTypesystem> sys, std::string name = "")
: Domain(mgr, std::move(name))
{
includeTypesystem(sys);
@@ -834,6 +926,14 @@ public:
{
return structuredClasses;
}
+ /**
+ * Adds a StructuredClass to this domain. This also sets the parent of the
+ * given StructuredClass if it is not set to this Domain already.
+ * TODO: This could have move semantics.
+ *
+ * @param s is some StructuredClass.
+ */
+ void addStructuredClass(Handle<StructuredClass> s);
/**
* Returns a const reference to the NodeVector of AnnotationClasses that are
@@ -846,6 +946,14 @@ public:
{
return annotationClasses;
}
+ /**
+ * Adds an AnnotationClass to this domain. This also sets the parent of the
+ * given AnnotationClass if it is not set to this Domain already.
+ * TODO: This could have move semantics.
+ *
+ * @param a is some AnnotationClass.
+ */
+ void addAnnotationClass(Handle<AnnotationClass> a);
/**
* Returns a const reference to the NodeVector of TypeSystems that are
@@ -868,10 +976,6 @@ public:
{
typesystems.insert(typesystems.end(), ts.begin(), ts.end());
}
-
-
- void addStructuredClass(Handle<StructuredClass> s);
- void addAnnotationClass(Handle<AnnotationClass> a);
};
}