summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-04-15 20:42:26 +0200
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2016-04-25 22:25:56 +0200
commit9d9b65691347ce84d124fcafad7a562f91884c15 (patch)
treedb4b83b33732d2ea569667f3f78736b9153ac76b /src/core
parent586b4486f4661681b8fe0c639830bd9db3986d5a (diff)
Implement resolution of referenced object
Diffstat (limited to 'src/core')
-rw-r--r--src/core/model/Typesystem.cpp27
-rw-r--r--src/core/parser/stack/DocumentHandler.cpp38
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;
}