summaryrefslogtreecommitdiff
path: root/src/core/model/Document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/model/Document.cpp')
-rw-r--r--src/core/model/Document.cpp106
1 files changed, 80 insertions, 26 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp
index 66b36b0..e6fe1f3 100644
--- a/src/core/model/Document.cpp
+++ b/src/core/model/Document.cpp
@@ -105,21 +105,36 @@ DocumentEntity::DocumentEntity(Handle<Node> subInst,
Handle<Descriptor> descriptor,
Variant attributes)
: subInst(subInst),
- descriptor(subInst->acquire(descriptor)),
+ // initialize descriptor as nullptr first and then set it right
attributes(std::move(attributes))
{
// insert empty vectors for each field.
- if (!descriptor.isNull()) {
- NodeVector<FieldDescriptor> fieldDescs;
- if (descriptor->isa(RttiTypes::StructuredClass)) {
- fieldDescs = descriptor.cast<StructuredClass>()
- ->getEffectiveFieldDescriptors();
- } else {
- fieldDescs = descriptor->getFieldDescriptors();
- }
- for (size_t f = 0; f < fieldDescs.size(); f++) {
- fields.push_back(NodeVector<StructureNode>(subInst));
- }
+ if (descriptor != nullptr) {
+ setDescriptor(descriptor);
+ }
+}
+
+void DocumentEntity::setDescriptor(Handle<Descriptor> d)
+{
+ // check if we have to do anything.
+ if (descriptor == d) {
+ return;
+ }
+ invalidateSubInstance();
+ descriptor = subInst->acquire(d);
+ // get the effective field descriptors in the descriptor.
+ NodeVector<FieldDescriptor> fieldDescs;
+ if (descriptor->isa(RttiTypes::StructuredClass)) {
+ fieldDescs =
+ descriptor.cast<StructuredClass>()->getEffectiveFieldDescriptors();
+ } else {
+ fieldDescs = descriptor->getFieldDescriptors();
+ }
+ // clear the fields vector.
+ fields.clear();
+ // fill it again.
+ for (size_t f = 0; f < fieldDescs.size(); f++) {
+ fields.push_back(NodeVector<StructureNode>(subInst));
}
}
@@ -303,37 +318,44 @@ void DocumentEntity::setAttributes(const Variant &a)
attributes = a;
}
+void DocumentEntity::addStructureNode(Handle<StructureNode> s, const int &i)
+{
+ invalidateSubInstance();
+ fields[i].push_back(s);
+ if (s->getParent() != subInst) {
+ s->setParent(subInst);
+ }
+}
+
void DocumentEntity::addStructureNode(Handle<StructureNode> s,
const std::string &fieldName)
{
- invalidateSubInstance();
- fields[getFieldDescriptorIndex(fieldName, true)].push_back(s);
+ addStructureNode(s, getFieldDescriptorIndex(fieldName, true));
}
void DocumentEntity::addStructureNodes(
const std::vector<Handle<StructureNode>> &ss, const std::string &fieldName)
{
- invalidateSubInstance();
- NodeVector<StructureNode> &field =
- fields[getFieldDescriptorIndex(fieldName, true)];
- field.insert(field.end(), ss.begin(), ss.end());
+ const int i = getFieldDescriptorIndex(fieldName, true);
+ for (Handle<StructureNode> s : ss) {
+ addStructureNode(s, i);
+ }
}
void DocumentEntity::addStructureNode(Handle<StructureNode> s,
Handle<FieldDescriptor> fieldDescriptor)
{
- invalidateSubInstance();
- fields[getFieldDescriptorIndex(fieldDescriptor, true)].push_back(s);
+ addStructureNode(s, getFieldDescriptorIndex(fieldDescriptor, true));
}
void DocumentEntity::addStructureNodes(
const std::vector<Handle<StructureNode>> &ss,
Handle<FieldDescriptor> fieldDescriptor)
{
- invalidateSubInstance();
- NodeVector<StructureNode> &field =
- fields[getFieldDescriptorIndex(fieldDescriptor, true)];
- field.insert(field.end(), ss.begin(), ss.end());
+ const int i = getFieldDescriptorIndex(fieldDescriptor, true);
+ for (Handle<StructureNode> s : ss) {
+ addStructureNode(s, i);
+ }
}
/* Class StructureNode */
@@ -362,6 +384,14 @@ StructuredEntity::StructuredEntity(Manager &mgr, Handle<Document> doc,
doc->setRoot(this);
}
+StructuredEntity::StructuredEntity(Manager &mgr, Handle<Node> parent,
+ Handle<StructuredClass> descriptor,
+ Variant attributes, std::string name)
+ : StructureNode(mgr, std::move(name), parent),
+ DocumentEntity(this, descriptor, std::move(attributes))
+{
+}
+
bool StructuredEntity::doValidate(Logger &logger) const
{
bool valid = true;
@@ -389,8 +419,9 @@ AnnotationEntity::AnnotationEntity(Manager &mgr, Handle<Document> parent,
start(acquire(start)),
end(acquire(end))
{
- parent->annotations.push_back(this);
- parent->invalidate();
+ if (parent != nullptr) {
+ parent->addAnnotation(this);
+ }
}
bool AnnotationEntity::doValidate(Logger &logger) const
@@ -457,6 +488,7 @@ bool Document::doValidate(Logger &logger) const
// An empty document is always invalid. TODO: Is this a smart choice?
bool valid = true;
if (root == nullptr) {
+ logger.error("This document is empty (it has no root)!");
valid = false;
} else {
// check if the root is allowed to be a root.
@@ -468,6 +500,12 @@ bool Document::doValidate(Logger &logger) const
"\" is not allowed to be the Document root!");
valid = false;
}
+ // check if it has this document as parent.
+ if (root->getParent() != this) {
+ logger.error(
+ "The document root does not have the document as parent!");
+ valid = false;
+ }
// then call validate on the root
valid = valid & root->validate(logger);
}
@@ -475,6 +513,22 @@ bool Document::doValidate(Logger &logger) const
return valid & continueValidation(annotations, logger);
}
+void Document::addAnnotation(Handle<AnnotationEntity> a)
+{
+ invalidate();
+ annotations.push_back(a);
+ if (a->getParent() != this) {
+ a->setParent(this);
+ }
+}
+
+void Document::addAnnotations(std::vector<Handle<AnnotationEntity>> as)
+{
+ for (Handle<AnnotationEntity> a : as) {
+ addAnnotation(a);
+ }
+}
+
bool Document::hasChild(Handle<StructureNode> s) const
{
Rooted<Managed> parent = s->getParent();