diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-20 01:52:30 +0100 | 
|---|---|---|
| committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-20 01:52:30 +0100 | 
| commit | 90047e6e1df4f32c7c935639df122136dccb3aa1 (patch) | |
| tree | 562c77b13b1bd87064ee665a208dec55eb244e3e /src/core/model | |
| parent | d98161ba6b7453932958e05ffa10a2e1a6a52d0a (diff) | |
| parent | 57a1ea659ae125934c541951113c0c3a38b10971 (diff) | |
Merge branch 'master' of somweyr.de:ousia
Diffstat (limited to 'src/core/model')
| -rw-r--r-- | src/core/model/Document.cpp | 106 | ||||
| -rw-r--r-- | src/core/model/Document.hpp | 94 | ||||
| -rw-r--r-- | src/core/model/Node.cpp | 10 | ||||
| -rw-r--r-- | src/core/model/Node.hpp | 17 | 
4 files changed, 180 insertions, 47 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(); diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index d89ade8..4147847 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -139,8 +139,6 @@ class StructureNode;   *   */  class DocumentEntity { -	friend StructureNode; -  private:  	/*  	 * this is a rather dirty method that should not be used in other cases: @@ -162,6 +160,8 @@ private:  	void invalidateSubInstance(); +	void addStructureNode(Handle<StructureNode> s, const int &i); +  protected:  	bool doValidate(Logger &logger) const; @@ -190,6 +190,13 @@ public:  	Rooted<Descriptor> getDescriptor() const { return descriptor; }  	/** +	 * Sets the Descriptor for this DocumentEntity. +	 * +	 * @param d is the new Descriptor for this DocumentEntity. +	 */ +	void setDescriptor(Handle<Descriptor> d); + +	/**  	 * Returns a Map Variant adhering to the attribute StructType in the given  	 * descriptor.  	 * @@ -270,6 +277,9 @@ public:  	 *  	 * If the name is unknown an exception is thrown.  	 * +	 * This method also changes the parent of the newly added StructureNode if +	 * it is not set to this DocumentEntity already. +	 *  	 * @param s         is the StructureNode that shall be added.  	 * @param fieldName is the name of a field as specified in the  	 *                  FieldDescriptor in the Domain description. @@ -285,6 +295,9 @@ public:  	 *  	 * If the name is unknown an exception is thrown.  	 * +	 * This method also changes the parent of each newly added StructureNode if +	 * it is not set to this DocumentEntity already. +	 *  	 * @param ss        are the StructureNodes that shall be added.  	 * @param fieldName is the name of a field as specified in the  	 *                  FieldDescriptor in the Domain description. @@ -298,6 +311,9 @@ public:  	 * If the FieldDescriptor does not belong to the Descriptor of this node  	 * an exception is thrown.  	 * +	 * This method also changes the parent of the newly added StructureNode if +	 * it is not set to this DocumentEntity already. +	 *  	 * @param s               is the StructureNode that shall be added.  	 * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for  	 *                        this DocumentEntity. @@ -312,6 +328,9 @@ public:  	 * If the FieldDescriptor does not belong to the Descriptor of this node  	 * an exception is thrown.  	 * +	 * This method also changes the parent of each newly added StructureNode if +	 * it is not set to this DocumentEntity already. +	 *  	 * @param ss              are the StructureNodes that shall be added.  	 * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for  	 *                        this DocumentEntity. @@ -329,18 +348,19 @@ class StructureNode : public Node {  public:  	/** -	 * Constructor for a StructureNode at the root. -	 */ -	StructureNode(Manager &mgr, std::string name, Handle<Document> doc) -	    : Node(mgr, std::move(name), doc) -	{ -	} - -	/**  	 * Constructor for a StructureNode in the StructureTree.  	 */  	StructureNode(Manager &mgr, std::string name, Handle<Node> parent,  	              const std::string &fieldName); + +	/** +	 * Constructor for an empty StructureNode. +	 */ +	StructureNode(Manager &mgr, std::string name = "", +	              Handle<Node> parent = nullptr) +	    : Node(mgr, std::move(name), parent) +	{ +	}  };  /** @@ -394,6 +414,23 @@ public:  	StructuredEntity(Manager &mgr, Handle<Document> doc,  	                 Handle<StructuredClass> descriptor,  	                 Variant attributes = {}, std::string name = ""); + +	/** +	 * Constructor for an empty StructuredEntity that is not yet connected. +	 * +	 * @param mgr        is the Manager instance. +	 * @param parent     is the parent Document of this StructuredEntity. Note +	 *                   that this StructuredEntity will automatically register +	 *                   itself as child of this Document. +	 * @param descriptor is the StructuredClass of this StructuredEntity. +	 * @param attributes is a Map Variant containing attribute fillings for this +	 *                   StructuredEntity. It is empty per default. +	 * @param name       is some name for this StructuredEntity that may be used +	 *                   for later reference. It is empty per default. +	 */ +	StructuredEntity(Manager &mgr, Handle<Node> parent = nullptr, +	                 Handle<StructuredClass> descriptor = nullptr, +	                 Variant attributes = {}, std::string name = "");  };  /** @@ -527,8 +564,8 @@ public:  	 * @param name       is some name for this AnnotationEntity that might be  	 *                   used for references later on. It is empty per default.  	 */ -	AnnotationEntity(Manager &mgr, Handle<Document> parent, -	                 Handle<AnnotationClass> descriptor, +	AnnotationEntity(Manager &mgr, Handle<Document> parent = nullptr, +	                 Handle<AnnotationClass> descriptor = nullptr,  	                 Handle<Anchor> start = nullptr,  	                 Handle<Anchor> end = nullptr, Variant attributes = {},  	                 std::string name = ""); @@ -565,6 +602,7 @@ public:  	 */  	void setEnd(Handle<Anchor> e)  	{ +		invalidate();  		end = acquire(e);  	}  }; @@ -575,8 +613,6 @@ 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; @@ -589,18 +625,29 @@ protected:  	bool doValidate(Logger &logger) const override;  public: +	/** +	 * This sets up an empty document. +	 * +	 * @param mgr  is the Manager instance. +	 * @param name is a name for this Document. +	 */  	Document(Manager &mgr, std::string name)  	    : Node(mgr, std::move(name), nullptr), annotations(this)  	{  	}  	/** -	 * Sets the root StructuredEntity of this Document. +	 * Sets the root StructuredEntity of this Document. This also sets the +	 * parent of the given StructuredEntity if it is not set to this Document +	 * already.  	 */  	void setRoot(Handle<StructuredEntity> root)  	{  		invalidate();  		this->root = acquire(root); +		if (root->getParent() != this) { +			root->setParent(this); +		}  	};  	/** @@ -623,6 +670,23 @@ public:  	}  	/** +	 * Adds an AnnotationEntity to this document. This also sets the parent +	 * of the given AnnotationEntity if it is not set to this document already. +	 * +	 * @param a is some AnnotationEntity +	 */ +	void addAnnotation(Handle<AnnotationEntity> a); + +	/** +	 * Adds multiple AnnotationEntities to this document. This also sets the +	 * parent of each given AnnotationEntity if it is not set to this document +	 * already. +	 * +	 * @param as is a vector of AnnotationEntities. +	 */ +	void addAnnotations(std::vector<Handle<AnnotationEntity>> as); + +	/**  	 * Returns a const reference to the NodeVector of Domains that are used  	 * within this Document.  	 * diff --git a/src/core/model/Node.cpp b/src/core/model/Node.cpp index 5867fa3..71d59ce 100644 --- a/src/core/model/Node.cpp +++ b/src/core/model/Node.cpp @@ -430,12 +430,20 @@ bool Node::validate(Logger &logger) const  		case ValidationState::VALIDATING:  			// We've run into recursion -- a circular structure cannot be  			// properly validated, so return false -			logger.error("This validation run lead to a cycle. As a fallback it is set to invalid!"); +			logger.error( +			    "This validation run lead to a cycle. As a fallback it is set " +			    "to invalid!");  			return false;  	}  	return false;  } +void Node::setParent(Handle<Node> p) +{ +	invalidate(); +	parent = acquire(p); +} +  /* RTTI type registrations */  namespace RttiTypes {  const Rtti Node = diff --git a/src/core/model/Node.hpp b/src/core/model/Node.hpp index 3e778a6..6b13c30 100644 --- a/src/core/model/Node.hpp +++ b/src/core/model/Node.hpp @@ -451,6 +451,13 @@ public:  	Rooted<Managed> getParent() const { return parent; }  	/** +	 * Sets the parent node. +	 * +	 * @param parent is a Handle to the parent node. +	 */ +	void setParent(Handle<Node> parent); + +	/**  	 * Returns true, if the node does not have a parent. Root nodes may either  	 * be the root element of the complete DOM tree  	 * @@ -522,8 +529,8 @@ class NodeVector      : public ManagedGenericList<T, std::vector<Handle<T>>,                                  ListAccessor<Handle<T>>, Listener> {  public: -	using Base = ManagedGenericList<T, std::vector<Handle<T>>, ListAccessor<Handle<T>>, -	                         Listener>; +	using Base = ManagedGenericList<T, std::vector<Handle<T>>, +	                                ListAccessor<Handle<T>>, Listener>;  	using Base::Base;  	/** @@ -553,9 +560,9 @@ class NodeMap      : public ManagedGenericMap<K, T, std::map<K, Handle<T>>,                                 MapAccessor<std::pair<K, Handle<T>>>, Listener> {  public: -	using Base = ManagedGenericMap<K, T, std::map<K, Handle<T>>, -	                        MapAccessor<std::pair<K, Handle<T>>>, -	                        Listener>; +	using Base = +	    ManagedGenericMap<K, T, std::map<K, Handle<T>>, +	                      MapAccessor<std::pair<K, Handle<T>>>, Listener>;  	using Base::Base;  	/**  | 
