diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-04-15 20:42:26 +0200 | 
|---|---|---|
| committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2016-04-25 22:25:56 +0200 | 
| commit | 9d9b65691347ce84d124fcafad7a562f91884c15 (patch) | |
| tree | db4b83b33732d2ea569667f3f78736b9153ac76b /src | |
| parent | 586b4486f4661681b8fe0c639830bd9db3986d5a (diff) | |
Implement resolution of referenced object
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/model/Typesystem.cpp | 27 | ||||
| -rw-r--r-- | src/core/parser/stack/DocumentHandler.cpp | 38 | 
2 files changed, 55 insertions, 10 deletions
| diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp index 86ee811..97cb043 100644 --- a/src/core/model/Typesystem.cpp +++ b/src/core/model/Typesystem.cpp @@ -16,8 +16,9 @@      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ -#include "Typesystem.hpp" +#include "Document.hpp"  #include "Ontology.hpp" +#include "Typesystem.hpp"  #include <core/common/RttiBuilder.hpp>  #include <core/common/Utils.hpp> @@ -663,16 +664,34 @@ ReferenceType::ReferenceType(Manager &mgr, const std::string &name,  bool ReferenceType::doBuild(Variant &data, Logger &logger,                              const ResolveCallback &resolveCallback) const  { -	// Null references are valid references +	// Null references are valid references (these are mostly generated as a +	// result of errors)  	if (data.isNull()) {  		return true;  	}  	if (data.isObject()) { -		// TODO: Check: object is an instance of the entity descriptor +		// Fetch the descriptor of the given object +		Rooted<Managed> obj = data.asObject(); +		Rooted<Descriptor> objectDescriptor; +		if (obj->isa(&RttiTypes::AnnotationEntity)) { +			objectDescriptor = obj.cast<AnnotationEntity>()->getDescriptor(); +		} else if (obj->isa(&RttiTypes::StructuredEntity)) { +			objectDescriptor = obj.cast<StructuredEntity>()->getDescriptor(); +		} else { +			throw LoggableException("Reference targets wrong internal type \"" + +			                        obj->type()->name + "\"!"); +		} + +		// Make sure the referenced object has the correct type +		if (!objectDescriptor->inheritsFrom(descriptor)) { +			throw LoggableException( +			    "Referenced entity of type \"" + objectDescriptor->getName() + +			    "\" is not compatible to reference type \"" + +			    descriptor->getName() + "\""); +		}  		return true;  	} else if (data.isString()) { -		// TODO: Lookup referenced object  		if (!Utils::isNamespacedIdentifier(data.asString())) {  			throw LoggableException("Reference must be a valid identifier",  			                        data); diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp index 2228f11..e6b6d6a 100644 --- a/src/core/parser/stack/DocumentHandler.cpp +++ b/src/core/parser/stack/DocumentHandler.cpp @@ -768,9 +768,36 @@ bool DocumentChildHandler::convertData(Handle<FieldDescriptor> field,  	}  	// Now try to resolve the value for the primitive type -	return valid && -	       scope().resolveValue(data, field->getParent().cast<Node>(), type, -	                            logger); +	return valid && scope().resolveValue(data, type, logger); +} + +static void createPrimitive(ParserScope &scope, Logger &logger, +                            Handle<FieldDescriptor> field, +                            DocumentEntity *parent, const Variant &data, +                            ssize_t fieldIdx = -1) +{ +	// Create the primitive field +	Rooted<DocumentPrimitive> primitive; +	if (fieldIdx < 0) { +		primitive = parent->createChildDocumentPrimitive(data); +	} else { +		primitive = parent->createChildDocumentPrimitive(data, fieldIdx); +	} + +	// Fetch the primitive type, check whether it is a ReferenceType -- if yes, +	// resolve the referenced object and set it once the resolution has finished +	Rooted<Type> type = field->getPrimitiveType(); +	if (type->isa(&RttiTypes::ReferenceType)) { +		if (data.isString()) { +			scope.resolve( +			    &RttiTypes::DocumentNode, Utils::split(data.asString(), ':'), +			    primitive, logger, +			    [](Handle<Node> resolved, Handle<Node> owner, Logger &logger) { +				    owner.cast<DocumentPrimitive>()->getContent().setObject( +				        resolved, owner.get()); +				}); +		} +	}  }  bool DocumentChildHandler::data() @@ -799,8 +826,7 @@ bool DocumentChildHandler::data()  		if (!convertData(field, text, logger())) {  			return false;  		} - -		parent->createChildDocumentPrimitive(text, fieldIdx); +		createPrimitive(scope(), logger(), field, parent, text, fieldIdx);  		return true;  	} @@ -830,7 +856,7 @@ bool DocumentChildHandler::data()  		createPath(fieldIdx, path, parent);  		// Then create the primitive element -		parent->createChildDocumentPrimitive(text); +		createPrimitive(scope(), logger(), primitiveField, parent, text);  		return true;  	} | 
