diff options
| author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-18 16:52:54 +0100 | 
|---|---|---|
| committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-18 16:52:54 +0100 | 
| commit | 0fd65daf57959fe5409a624bffcd5998fc55d332 (patch) | |
| tree | c91ca29c9be38df833b9c5cbe7604c839993ab82 /src | |
| parent | 373c3489ed4b6927a9596882e9e4ff078624e943 (diff) | |
improved Document validation process and added some test cases. Further tests are required, though.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/model/Document.cpp | 76 | ||||
| -rw-r--r-- | src/core/model/Document.hpp | 30 | 
2 files changed, 73 insertions, 33 deletions
| diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index cf6ded3..b80cb5e 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -92,10 +92,27 @@ int DocumentEntity::getFieldDescriptorIndex(  	}  } -DocumentEntity::DocumentEntity(Handle<Node> owner, +void DocumentEntity::addStructureNode(Handle<StructureNode> s, +                                      const std::string &fieldName) +{ +	if (subInst->isa(RttiTypes::StructuredEntity)) { +		const StructuredEntity *s = +		    static_cast<const StructuredEntity *>(subInst); +		s->invalidate(); +	} else { +		const AnnotationEntity *a = +		    static_cast<const AnnotationEntity *>(subInst); +		a->invalidate(); +	} +	fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); +} + +DocumentEntity::DocumentEntity(Handle<Node> subInst,                                 Handle<Descriptor> descriptor,                                 Variant attributes) -    : descriptor(owner->acquire(descriptor)), attributes(std::move(attributes)) +    : subInst(subInst.get()), +      descriptor(subInst->acquire(descriptor)), +      attributes(std::move(attributes))  {  	// insert empty vectors for each field.  	if (!descriptor.isNull()) { @@ -107,7 +124,7 @@ DocumentEntity::DocumentEntity(Handle<Node> owner,  			fieldDescs = descriptor->getFieldDescriptors();  		}  		for (size_t f = 0; f < fieldDescs.size(); f++) { -			fields.push_back(NodeVector<StructureNode>(owner)); +			fields.push_back(NodeVector<StructureNode>(subInst));  		}  	}  } @@ -120,6 +137,7 @@ bool DocumentEntity::doValidate(Logger &logger) const  		return false;  	}  	// TODO: check the validated form of Attributes +	// TODO: Check if descriptor is registered at the Document?  	/*  	 * generate the set of effective fields. This is trivial for @@ -150,8 +168,7 @@ bool DocumentEntity::doValidate(Logger &logger) const  				const size_t min = ac->getCardinality().min();  				if (min > 0) {  					logger.error( -					    std::string("Field ") + -					    descriptor->getFieldDescriptors()[f]->getName() + +					    std::string("Field ") + fieldDescs[f]->getName() +  					    " was empty but needs at least " + std::to_string(min) +  					    " elements of class " + ac->getName() +  					    " according to the definition of " + @@ -172,11 +189,11 @@ bool DocumentEntity::doValidate(Logger &logger) const  		// iterate over every actual child of this DocumentEntity  		for (auto &rc : fields[f]) { -			if (!rc->isa(RttiTypes::Anchor)) { +			if (rc->isa(RttiTypes::Anchor)) {  				// Anchors are uninteresting and can be ignored.  				continue;  			} -			if (!rc->isa(RttiTypes::DocumentPrimitive)) { +			if (rc->isa(RttiTypes::DocumentPrimitive)) {  				// For DocumentPrimitives we have to check the content type.  				// TODO: Do that!  				continue; @@ -281,6 +298,12 @@ bool StructuredEntity::doValidate(Logger &logger) const  	if (getParent() == nullptr) {  		return false;  	} +	// check name +	if (getName() != "") { +		if (!validateName(logger)) { +			return false; +		} +	}  	// check the validity as a DocumentEntity.  	return DocumentEntity::doValidate(logger);  } @@ -317,6 +340,12 @@ bool AnnotationEntity::doValidate(Logger &logger) const  		logger.error("This annotation was not registered at the document.");  		return false;  	} +	// check name +	if (getName() != "") { +		if (!validateName(logger)) { +			return false; +		} +	}  	// check if the Anchors are part of the right document.  	if (!doc->hasChild(start)) {  		return false; @@ -344,26 +373,23 @@ void Document::doResolve(ResolutionState &state)  bool Document::doValidate(Logger &logger) const  { -	if (root != nullptr) { -		// check if the root is allowed to be a root. -		if (!root->getDescriptor().cast<StructuredClass>()->root) { -			logger.error(std::string("A node of type ") + -			             root->getDescriptor()->getName() + -			             " is not allowed to be the Document root!"); -			return false; -		} -		// then call validate on the root -		if (!root->validate(logger)) { -			return false; -		} +	// An empty document is always invalid. TODO: Is this a smart choice? +	if (root == nullptr) { +		return false;  	} -	// call validate on the AnnotationEntities -	for (auto &a : annotations) { -		if (!a->validate(logger)) { -			return false; -		} +	// check if the root is allowed to be a root. +	if (!root->getDescriptor().cast<StructuredClass>()->root) { +		logger.error(std::string("A node of type ") + +		             root->getDescriptor()->getName() + +		             " is not allowed to be the Document root!"); +		return false;  	} -	return true; +	// then call validate on the root +	if (!root->validate(logger)) { +		return false; +	} +	// call validate on the AnnotationEntities +	return continueValidation(annotations, logger);  }  bool Document::hasChild(Handle<StructureNode> s) const diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index b4ee429..15d002c 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -144,6 +144,12 @@ class DocumentEntity {  	friend StructureNode;  private: +	/* +	 * this is a rather dirty method that should not be used in other cases: +	 * We store a pointer to the Node instance that inherits from +	 * DocumentEntity. +	 */ +	const Node *subInst;  	Owned<Descriptor> descriptor;  	const Variant attributes;  	std::vector<NodeVector<StructureNode>> fields; @@ -156,10 +162,7 @@ private:  protected:  	void addStructureNode(Handle<StructureNode> s, -	                      const std::string &fieldName = "") -	{ -		fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); -	} +	                      const std::string &fieldName = "");  	bool doValidate(Logger &logger) const; @@ -169,7 +172,7 @@ public:  	 * from Node. Therefore we need to have a handle to the subclass Node  	 * instance to create NodeVectors and Owned references.  	 * -	 * @param owner      is a handle to the subclass instance +	 * @param subInst    is a handle to the subclass instance  	 *                   (e.g. StructuredEntity), such that the fields vectors  	 *                   and the descriptor reference can be obtained.  	 * @param descriptor is the Descriptor for this DocumentEntity, which will @@ -177,7 +180,7 @@ public:  	 * @param attributes is a Map Variant adhering to the attribute StructType  	 *                   in the given descriptor.  	 */ -	DocumentEntity(Handle<Node> owner, Handle<Descriptor> descriptor, +	DocumentEntity(Handle<Node> subInst, Handle<Descriptor> descriptor,  	               Variant attributes = {});  	/** @@ -498,6 +501,8 @@ public:   *   */  class AnnotationEntity : public Node, public DocumentEntity { +	friend DocumentEntity; +  private:  	Owned<Anchor> start;  	Owned<Anchor> end; @@ -573,7 +578,11 @@ public:  	/**  	 * Sets the root StructuredEntity of this Document.  	 */ -	void setRoot(Handle<StructuredEntity> root) { this->root = acquire(root); }; +	void setRoot(Handle<StructuredEntity> root) +	{ +		invalidate(); +		this->root = acquire(root); +	};  	/**  	 * Returns the root StructuredEntity of this Document. @@ -606,13 +615,18 @@ public:  	/**  	 * Adds a Domain reference to this Document.  	 */ -	void addDomain(Handle<Domain> d) { domains.push_back(d); } +	void addDomain(Handle<Domain> d) +	{ +		invalidate(); +		domains.push_back(d); +	}  	/**  	 * Adds multiple Domain references to this Document.  	 */  	void addDomains(const std::vector<Handle<Domain>> &d)  	{ +		invalidate();  		domains.insert(domains.end(), d.begin(), d.end());  	} | 
