diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-18 13:48:45 +0100 | 
|---|---|---|
| committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-18 13:48:45 +0100 | 
| commit | 372c67e0844654362fc7d440b0b4a31500a6d02a (patch) | |
| tree | d677aa19bdc77486be02171de77e5675ce5f0f80 /src | |
| parent | db51a874964b038c69f1336a8a659ae40471e26b (diff) | |
| parent | 3e63d6539b9738018a4aca68d07a119e4402e9aa (diff) | |
Merge branch 'master' of somweyr.de:ousia
Conflicts:
	application/src/core/model/Domain.hpp
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/model/Document.cpp | 53 | ||||
| -rw-r--r-- | src/core/model/Document.hpp | 17 | ||||
| -rw-r--r-- | src/core/model/Domain.cpp | 78 | ||||
| -rw-r--r-- | src/core/model/Domain.hpp | 35 | ||||
| -rw-r--r-- | src/core/model/Node.cpp | 2 | 
5 files changed, 133 insertions, 52 deletions
| diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index ee15e31..5f0ad4c 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -92,7 +92,7 @@ int DocumentEntity::getFieldDescriptorIndex(  	}  } -bool DocumentEntity::validate(Logger &logger) const +bool DocumentEntity::doValidate(Logger &logger) const  {  	// TODO: check the validated form of Attributes  	// iterate over every field @@ -246,7 +246,7 @@ bool StructuredEntity::doValidate(Logger &logger) const  		return false;  	}  	// check the validity as a DocumentEntity. -	return DocumentEntity::validate(logger); +	return DocumentEntity::doValidate(logger);  }  /* Class AnnotationEntity */ @@ -281,12 +281,17 @@ bool AnnotationEntity::doValidate(Logger &logger) const  		logger.error("This annotation was not registered at the document.");  		return false;  	} - +	// check if the Anchors are part of the right document. +	if (!doc->hasChild(start)) { +		return false; +	} +	if (!doc->hasChild(end)) { +		return false; +	}  	// check the validity as a DocumentEntity. -	if (!DocumentEntity::validate(logger)) { +	if (!DocumentEntity::doValidate(logger)) {  		return false;  	} -	// TODO: then check if the anchors are in the correct document.  	return true;  } @@ -300,6 +305,44 @@ void Document::doResolve(ResolutionState &state)  	}  	continueResolveReferences(domains, 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; +		} +	} +	// call validate on the AnnotationEntities +	for (auto &a : annotations) { +		if (!a->validate(logger)) { +			return false; +		} +	} +	return true; +} + +bool Document::hasChild(Handle<StructureNode> s) const +{ +	Rooted<Managed> parent = s->getParent(); +	if (parent->isa(RttiTypes::StructureNode)) { +		return hasChild(parent.cast<StructureNode>()); +	} else if (parent->isa(RttiTypes::AnnotationEntity)) { +		Handle<AnnotationEntity> a = parent.cast<AnnotationEntity>(); +		return this == a->getParent(); +	} else if (parent->isa(RttiTypes::Document)) { +		return this == parent; +	} +	return false; +}  }  /* Type registrations */ diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index cb7f394..9410d17 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -161,7 +161,7 @@ protected:  		fields[getFieldDescriptorIndex(fieldName, true)].push_back(s);  	} -	bool validate(Logger &logger) const; +	bool doValidate(Logger &logger) const;  public:  	/** @@ -512,6 +512,7 @@ class AnnotationEntity : public Node, public DocumentEntity {  private:  	Owned<Anchor> start;  	Owned<Anchor> end; +  protected:  	bool doValidate(Logger &logger) const override; @@ -569,6 +570,9 @@ private:  	void doResolve(ResolutionState &state) override; +protected: +	bool doValidate(Logger &logger) const override; +  public:  	Document(Manager &mgr, std::string name)  	    // TODO: Can a document have a parent? @@ -622,6 +626,17 @@ public:  	{  		domains.insert(domains.end(), d.begin(), d.end());  	} + +	/** +	 * Returns true if and only if the given StructureNode is part of this +	 * document, meaning that there is a path of parent references in the +	 * Structure Tree leading from the given StructureNode to this Document. +	 * +	 * @param s is some StructureNode. +	 * @return  true if and only if the given StructureNode is part of this +	 *          document. +	 */ +	bool hasChild(Handle<StructureNode> s) const;  };  } diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp index bae0f4f..9a0ed0d 100644 --- a/src/core/model/Domain.cpp +++ b/src/core/model/Domain.cpp @@ -36,7 +36,7 @@ static void checkUniqueName(Handle<Node> parent, NodeVector<T> vec,  		childNames.insert(c->getName());  	}  	if (childNames.find(child->getName()) != childNames.end()) { -		//TODO: Do we really want to have an exception here? +		// TODO: Do we really want to have an exception here?  		throw OusiaException(std::string("The ") + parentClassName + " " +  		                     parent->getName() + " already has a " +  		                     childClassName + " with name " + child->getName()); @@ -97,10 +97,7 @@ std::vector<Rooted<Node>> Descriptor::pathTo(  }  bool Descriptor::continuePath(Handle<StructuredClass> target, -                              std::vector<Rooted<Node>> ¤tPath, -                              std::set<std::string> ignoredFields, -                              bool exploreSuperclass, -                              bool exploreSubclasses) const +                              std::vector<Rooted<Node>> ¤tPath) const  {  	// check if we are at the target already  	if (this == target) { @@ -111,11 +108,16 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,  	// the currently optimal path.  	std::vector<Rooted<Node>> optimum;  	// use recursive depth-first search from the top to reach the given child -	for (auto &fd : fieldDescriptors) { -		if (!(ignoredFields.insert(fd->getName()).second)) { -			// if we want to ignore that field, we continue. -			continue; -		} +	// get the list of effective FieldDescriptors. +	NodeVector<FieldDescriptor> fields; +	if (isa(RttiTypes::StructuredClass)) { +		const StructuredClass *tis = static_cast<const StructuredClass *>(this); +		fields = tis->getEffectiveFieldDescriptors(); +	} else { +		fields = getFieldDescriptors(); +	} + +	for (auto &fd : fields) {  		for (auto &c : fd->getChildren()) {  			// check if a child is the target node.  			if (c == target) { @@ -142,35 +144,17 @@ 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 (exploreSuperclass && tis->getSuperclass() != nullptr) { +		// if this is a StructuredClass we also can call the subclasses. +		for (auto &c : tis->getSubclasses()) {  			// copy the path.  			std::vector<Rooted<Node>> cPath = currentPath; -			if (tis->getSuperclass()->continuePath(target, cPath, ignoredFields, -			                                       true, false) && +			if (c->continuePath(target, cPath) &&  			    (!found || optimum.size() > cPath.size())) {  				// look if this path is better than the current optimum.  				optimum = std::move(cPath);  				found = true;  			}  		} - -		// we also can call the subclasses. -		if (exploreSubclasses) { -			for (auto &c : tis->getSubclasses()) { -				// copy the path. -				std::vector<Rooted<Node>> cPath = currentPath; -				if (c->continuePath(target, cPath, {}, false) && -				    (!found || optimum.size() > cPath.size())) { -					// look if this path is better than the current optimum. -					optimum = std::move(cPath); -					found = true; -				} -			} -		}  	}  	// put the optimum in the given path reference. @@ -219,16 +203,42 @@ StructuredClass::StructuredClass(Manager &mgr, std::string name,  	}  } -bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const{ -	if(c == nullptr || superclass == nullptr){ +bool StructuredClass::isSubclassOf(Handle<StructuredClass> c) const +{ +	if (c == nullptr || superclass == nullptr) {  		return false;  	} -	if(c == superclass){ +	if (c == superclass) {  		return true;  	}  	return superclass->isSubclassOf(c);  } +const void StructuredClass::gatherFieldDescriptors( +    NodeVector<FieldDescriptor> ¤t, +    std::set<std::string> &overriddenFields) const +{ +	// append all FieldDescriptors that are not overridden. +	for (auto &f : Descriptor::getFieldDescriptors()) { +		if (overriddenFields.insert(f->getName()).second) { +			current.push_back(f); +		} +	} +	if (superclass != nullptr) { +		superclass->gatherFieldDescriptors(current, overriddenFields); +	} +} + +NodeVector<FieldDescriptor> StructuredClass::getEffectiveFieldDescriptors() +    const +{ +	// in this case we return a NodeVector of Rooted entries without owner. +	NodeVector<FieldDescriptor> vec; +	std::set<std::string> overriddenFields; +	gatherFieldDescriptors(vec, overriddenFields); +	return std::move(vec); +} +  /* Class AnnotationClass */  AnnotationClass::AnnotationClass( diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index a8d4a9e..d1ba44f 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -380,22 +380,18 @@ public:   *   */  class Descriptor : public Node { - -friend FieldDescriptor; +	friend FieldDescriptor;  private:  	Owned<StructType> attributesDescriptor;  	NodeVector<FieldDescriptor> fieldDescriptors;  	bool continuePath(Handle<StructuredClass> target, -	                  std::vector<Rooted<Node>> &path, -	                  std::set<std::string> ignoredFields = {}, -	                  bool exploreSuperclass = true, -	                  bool exploreSubclasses = true) const; +	                  std::vector<Rooted<Node>> &path) const;  protected:  	void doResolve(ResolutionState &state) override; -	 +  	/**  	 * Adds a FieldDescriptor and checks for name uniqueness.  	 */ @@ -553,6 +549,13 @@ private:  	Owned<StructuredClass> superclass;  	NodeVector<StructuredClass> subclasses; +	/** +	 * Helper method for getFieldDescriptors. +	 */ +	const void gatherFieldDescriptors( +	    NodeVector<FieldDescriptor> ¤t, +	    std::set<std::string> &overriddenFields) const; +  public:  	const bool transparent;  	// TODO: Is it possible to have root=true and cardinality other than 1? @@ -606,7 +609,7 @@ public:  	 * @return the superclass of this StructuredClass.  	 */  	Rooted<StructuredClass> getSuperclass() const { return superclass; } -	 +  	/**  	 * 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. @@ -635,6 +638,17 @@ public:  	{  		return subclasses;  	} + +	/** +	 * 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 +	 * as well that have not been overridden in child classes. +	 * +	 * @return a const reference to the NodeVector of all FieldDescriptors of +	 * this StructuredClass. +	 */ +	NodeVector<FieldDescriptor> getEffectiveFieldDescriptors() const;  };  /** @@ -670,9 +684,8 @@ public:   * to certain Structures?   */  class Domain : public Node { - -friend StructuredClass; -friend AnnotationClass; +	friend StructuredClass; +	friend AnnotationClass;  private:  	NodeVector<StructuredClass> structuredClasses; diff --git a/src/core/model/Node.cpp b/src/core/model/Node.cpp index 1c627fc..bd023e1 100644 --- a/src/core/model/Node.cpp +++ b/src/core/model/Node.cpp @@ -430,7 +430,7 @@ 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("The given document is cyclic."); +			logger.error("This validation run lead to a cycle. As a fallback it is set to invalid!");  			return false;  	}  	return false; | 
