From a7019614896fdd3e29b9a28f6a8cfd2c1b365983 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Sun, 1 Mar 2015 20:47:25 +0100 Subject: Renamed domain to ontology. --- src/core/parser/stack/OntologyHandler.cpp | 417 ++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 src/core/parser/stack/OntologyHandler.cpp (limited to 'src/core/parser/stack/OntologyHandler.cpp') diff --git a/src/core/parser/stack/OntologyHandler.cpp b/src/core/parser/stack/OntologyHandler.cpp new file mode 100644 index 0000000..8c0e4d9 --- /dev/null +++ b/src/core/parser/stack/OntologyHandler.cpp @@ -0,0 +1,417 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#include "DocumentHandler.hpp" +#include "OntologyHandler.hpp" +#include "State.hpp" +#include "TypesystemHandler.hpp" + +namespace ousia { +namespace parser_stack { + +/* OntologyHandler */ + +bool OntologyHandler::start(Variant::mapType &args) +{ + // Create the Ontology node + Rooted ontology = + context().getProject()->createOntology(args["name"].asString()); + ontology->setLocation(location()); + + // If the ontology is defined inside a document, add the reference to the + // document + Rooted document = scope().select(); + if (document != nullptr) { + document->reference(ontology); + } + + // Push the typesystem onto the scope, set the POST_HEAD flag to true + scope().push(ontology); + scope().setFlag(ParserFlag::POST_HEAD, false); + return true; +} + +void OntologyHandler::end() { scope().pop(logger()); } + +/* OntologyStructHandler */ + +bool OntologyStructHandler::start(Variant::mapType &args) +{ + scope().setFlag(ParserFlag::POST_HEAD, true); + + Rooted ontology = scope().selectOrThrow(); + + Rooted structuredClass = ontology->createStructuredClass( + args["name"].asString(), args["cardinality"].asCardinality(), nullptr, + args["transparent"].asBool(), args["isRoot"].asBool()); + structuredClass->setLocation(location()); + + const std::string &isa = args["isa"].asString(); + if (!isa.empty()) { + scope().resolve( + isa, structuredClass, logger(), + [](Handle superclass, Handle structuredClass, + Logger &logger) { + if (superclass != nullptr) { + structuredClass.cast()->setSuperclass( + superclass.cast(), logger); + } + }); + } + + scope().push(structuredClass); + return true; +} + +void OntologyStructHandler::end() { scope().pop(logger()); } + +/* OntologyAnnotationHandler */ +bool OntologyAnnotationHandler::start(Variant::mapType &args) +{ + scope().setFlag(ParserFlag::POST_HEAD, true); + + Rooted ontology = scope().selectOrThrow(); + + Rooted annotationClass = + ontology->createAnnotationClass(args["name"].asString()); + annotationClass->setLocation(location()); + + scope().push(annotationClass); + return true; +} + +void OntologyAnnotationHandler::end() { scope().pop(logger()); } + +/* OntologyAttributesHandler */ + +bool OntologyAttributesHandler::start(Variant::mapType &args) +{ + // Fetch the current typesystem and create the struct node + Rooted parent = scope().selectOrThrow(); + + Rooted attrDesc = parent->getAttributesDescriptor(); + attrDesc->setLocation(location()); + + scope().push(attrDesc); + return true; +} + +void OntologyAttributesHandler::end() { scope().pop(logger()); } + +/* OntologyFieldHandler */ + +bool OntologyFieldHandler::start(Variant::mapType &args) +{ + FieldDescriptor::FieldType type; + if (args["isSubtree"].asBool()) { + type = FieldDescriptor::FieldType::SUBTREE; + } else { + type = FieldDescriptor::FieldType::TREE; + } + + Rooted parent = scope().selectOrThrow(); + + auto res = parent->createFieldDescriptor( + logger(), type, args["name"].asString(), args["optional"].asBool()); + res.first->setLocation(location()); + if (res.second) { + logger().warning( + std::string("Field \"") + res.first->getName() + + "\" was declared after main field. The order of fields " + "was changed to make the main field the last field.", + *res.first); + } + + scope().push(res.first); + return true; +} + +void OntologyFieldHandler::end() { scope().pop(logger()); } + +/* OntologyFieldRefHandler */ + +bool OntologyFieldRefHandler::start(Variant::mapType &args) +{ + Rooted parent = scope().selectOrThrow(); + + const std::string &name = args["ref"].asString(); + + auto loc = location(); + + scope().resolveFieldDescriptor(name, parent, logger(), + [loc](Handle field, + Handle parent, Logger &logger) { + if (field != nullptr) { + if (parent.cast()->addFieldDescriptor( + field.cast(), logger)) { + logger.warning( + std::string("Field \"") + field->getName() + + "\" was referenced after main field was declared. The " + "order of fields was changed to make the main field " + "the last field.", + loc); + } + } + }); + return true; +} + +void OntologyFieldRefHandler::end() {} + +/* OntologyPrimitiveHandler */ + +bool OntologyPrimitiveHandler::start(Variant::mapType &args) +{ + Rooted parent = scope().selectOrThrow(); + + FieldDescriptor::FieldType fieldType; + if (args["isSubtree"].asBool()) { + fieldType = FieldDescriptor::FieldType::SUBTREE; + } else { + fieldType = FieldDescriptor::FieldType::TREE; + } + + auto res = parent->createPrimitiveFieldDescriptor( + new UnknownType(manager()), logger(), fieldType, + args["name"].asString(), args["optional"].asBool()); + res.first->setLocation(location()); + if (res.second) { + logger().warning( + std::string("Field \"") + res.first->getName() + + "\" was declared after main field. The order of fields " + "was changed to make the main field the last field.", + *res.first); + } + + const std::string &type = args["type"].asString(); + scope().resolveType(type, res.first, logger(), + [](Handle type, Handle field, + Logger &logger) { + if (type != nullptr) { + field.cast()->setPrimitiveType(type.cast()); + } + }); + + scope().push(res.first); + return true; +} + +void OntologyPrimitiveHandler::end() { scope().pop(logger()); } + +/* OntologyChildHandler */ + +bool OntologyChildHandler::start(Variant::mapType &args) +{ + Rooted field = scope().selectOrThrow(); + + const std::string &ref = args["ref"].asString(); + scope().resolve( + ref, field, logger(), + [](Handle child, Handle field, Logger &logger) { + if (child != nullptr) { + field.cast()->addChild( + child.cast()); + } + }); + return true; +} + +/* OntologyParentHandler */ + +bool OntologyParentHandler::start(Variant::mapType &args) +{ + Rooted strct = scope().selectOrThrow(); + + Rooted parent{ + new OntologyParent(strct->getManager(), args["ref"].asString(), strct)}; + parent->setLocation(location()); + scope().push(parent); + return true; +} + +void OntologyParentHandler::end() { scope().pop(logger()); } + +/* OntologyParentFieldHandler */ + +bool OntologyParentFieldHandler::start(Variant::mapType &args) +{ + Rooted parentNameNode = scope().selectOrThrow(); + FieldDescriptor::FieldType type; + if (args["isSubtree"].asBool()) { + type = FieldDescriptor::FieldType::SUBTREE; + } else { + type = FieldDescriptor::FieldType::TREE; + } + + const std::string &name = args["name"].asString(); + const bool optional = args["optional"].asBool(); + Rooted strct = + parentNameNode->getParent().cast(); + + // resolve the parent, create the declared field and add the declared + // StructuredClass as child to it. + scope().resolve( + parentNameNode->getName(), strct, logger(), + [type, name, optional](Handle parent, Handle strct, + Logger &logger) { + if (parent != nullptr) { + Rooted field = + (parent.cast()->createFieldDescriptor( + logger, type, name, optional)).first; + field->addChild(strct.cast()); + } + }); + return true; +} + +/* OntologyParentFieldRefHandler */ + +bool OntologyParentFieldRefHandler::start(Variant::mapType &args) +{ + Rooted parentNameNode = scope().selectOrThrow(); + + const std::string &name = args["ref"].asString(); + Rooted strct = + parentNameNode->getParent().cast(); + auto loc = location(); + + // resolve the parent, get the referenced field and add the declared + // StructuredClass as child to it. + scope().resolve( + parentNameNode->getName(), strct, logger(), + [name, loc](Handle parent, Handle strct, Logger &logger) { + if (parent != nullptr) { + Rooted field = + parent.cast()->getFieldDescriptor(name); + if (field == nullptr) { + logger.error( + std::string("Could not find referenced field ") + name, + loc); + return; + } + field->addChild(strct.cast()); + } + }); + return true; +} + +namespace States { +const State Ontology = StateBuilder() + .parents({&None, &Document}) + .createdNodeType(&RttiTypes::Ontology) + .elementHandler(OntologyHandler::create) + .arguments({Argument::String("name")}); + +const State OntologyStruct = + StateBuilder() + .parent(&Ontology) + .createdNodeType(&RttiTypes::StructuredClass) + .elementHandler(OntologyStructHandler::create) + .arguments({Argument::String("name"), + Argument::Cardinality("cardinality", Cardinality::any()), + Argument::Bool("isRoot", false), + Argument::Bool("transparent", false), + Argument::String("isa", "")}); + +const State OntologyAnnotation = + StateBuilder() + .parent(&Ontology) + .createdNodeType(&RttiTypes::AnnotationClass) + .elementHandler(OntologyAnnotationHandler::create) + .arguments({Argument::String("name")}); + +const State OntologyAttributes = + StateBuilder() + .parents({&OntologyStruct, &OntologyAnnotation}) + .createdNodeType(&RttiTypes::StructType) + .elementHandler(OntologyAttributesHandler::create) + .arguments({}); + +const State OntologyAttribute = + StateBuilder() + .parent(&OntologyAttributes) + .elementHandler(TypesystemStructFieldHandler::create) + .arguments({Argument::String("name"), Argument::String("type"), + Argument::Any("default", Variant::fromObject(nullptr))}); + +const State OntologyField = StateBuilder() + .parents({&OntologyStruct, &OntologyAnnotation}) + .createdNodeType(&RttiTypes::FieldDescriptor) + .elementHandler(OntologyFieldHandler::create) + .arguments({Argument::String("name", ""), + Argument::Bool("isSubtree", false), + Argument::Bool("optional", false)}); + +const State OntologyFieldRef = + StateBuilder() + .parents({&OntologyStruct, &OntologyAnnotation}) + .createdNodeType(&RttiTypes::FieldDescriptor) + .elementHandler(OntologyFieldRefHandler::create) + .arguments({Argument::String("ref", DEFAULT_FIELD_NAME)}); + +const State OntologyStructPrimitive = + StateBuilder() + .parents({&OntologyStruct, &OntologyAnnotation}) + .createdNodeType(&RttiTypes::FieldDescriptor) + .elementHandler(OntologyPrimitiveHandler::create) + .arguments( + {Argument::String("name", ""), Argument::Bool("isSubtree", false), + Argument::Bool("optional", false), Argument::String("type")}); + +const State OntologyStructChild = StateBuilder() + .parent(&OntologyField) + .elementHandler(OntologyChildHandler::create) + .arguments({Argument::String("ref")}); + +const State OntologyStructParent = + StateBuilder() + .parent(&OntologyStruct) + .createdNodeType(&RttiTypes::OntologyParent) + .elementHandler(OntologyParentHandler::create) + .arguments({Argument::String("ref")}); + +const State OntologyStructParentField = + StateBuilder() + .parent(&OntologyStructParent) + .createdNodeType(&RttiTypes::FieldDescriptor) + .elementHandler(OntologyParentFieldHandler::create) + .arguments({Argument::String("name", ""), + Argument::Bool("isSubtree", false), + Argument::Bool("optional", false)}); + +const State OntologyStructParentFieldRef = + StateBuilder() + .parent(&OntologyStructParent) + .createdNodeType(&RttiTypes::FieldDescriptor) + .elementHandler(OntologyParentFieldRefHandler::create) + .arguments({Argument::String("ref", DEFAULT_FIELD_NAME)}); +} +} + +namespace RttiTypes { +const Rtti OntologyParent = RttiBuilder( + "OntologyParent").parent(&Node); +} +} -- cgit v1.2.3