summaryrefslogtreecommitdiff
path: root/src/core/parser/stack/OntologyHandler.cpp
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-03-01 20:47:25 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-03-01 20:47:25 +0100
commita7019614896fdd3e29b9a28f6a8cfd2c1b365983 (patch)
tree8a9f102649e88ebf24de0a07cf5f348804a6212d /src/core/parser/stack/OntologyHandler.cpp
parent0d4ce5c555a1ba3a87cb9a1e350854eda7a243e1 (diff)
Renamed domain to ontology.
Diffstat (limited to 'src/core/parser/stack/OntologyHandler.cpp')
-rw-r--r--src/core/parser/stack/OntologyHandler.cpp417
1 files changed, 417 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <core/common/RttiBuilder.hpp>
+#include <core/model/Document.hpp>
+#include <core/model/Ontology.hpp>
+#include <core/model/Project.hpp>
+#include <core/parser/ParserScope.hpp>
+#include <core/parser/ParserContext.hpp>
+
+#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> 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> document = scope().select<Document>();
+ 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> ontology = scope().selectOrThrow<Ontology>();
+
+ Rooted<StructuredClass> 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<StructuredClass>(
+ isa, structuredClass, logger(),
+ [](Handle<Node> superclass, Handle<Node> structuredClass,
+ Logger &logger) {
+ if (superclass != nullptr) {
+ structuredClass.cast<StructuredClass>()->setSuperclass(
+ superclass.cast<StructuredClass>(), 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> ontology = scope().selectOrThrow<Ontology>();
+
+ Rooted<AnnotationClass> 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<Descriptor> parent = scope().selectOrThrow<Descriptor>();
+
+ Rooted<StructType> 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<Descriptor> parent = scope().selectOrThrow<Descriptor>();
+
+ 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<Descriptor> parent = scope().selectOrThrow<Descriptor>();
+
+ const std::string &name = args["ref"].asString();
+
+ auto loc = location();
+
+ scope().resolveFieldDescriptor(name, parent, logger(),
+ [loc](Handle<Node> field,
+ Handle<Node> parent, Logger &logger) {
+ if (field != nullptr) {
+ if (parent.cast<StructuredClass>()->addFieldDescriptor(
+ field.cast<FieldDescriptor>(), 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<Descriptor> parent = scope().selectOrThrow<Descriptor>();
+
+ 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<Node> type, Handle<Node> field,
+ Logger &logger) {
+ if (type != nullptr) {
+ field.cast<FieldDescriptor>()->setPrimitiveType(type.cast<Type>());
+ }
+ });
+
+ scope().push(res.first);
+ return true;
+}
+
+void OntologyPrimitiveHandler::end() { scope().pop(logger()); }
+
+/* OntologyChildHandler */
+
+bool OntologyChildHandler::start(Variant::mapType &args)
+{
+ Rooted<FieldDescriptor> field = scope().selectOrThrow<FieldDescriptor>();
+
+ const std::string &ref = args["ref"].asString();
+ scope().resolve<StructuredClass>(
+ ref, field, logger(),
+ [](Handle<Node> child, Handle<Node> field, Logger &logger) {
+ if (child != nullptr) {
+ field.cast<FieldDescriptor>()->addChild(
+ child.cast<StructuredClass>());
+ }
+ });
+ return true;
+}
+
+/* OntologyParentHandler */
+
+bool OntologyParentHandler::start(Variant::mapType &args)
+{
+ Rooted<StructuredClass> strct = scope().selectOrThrow<StructuredClass>();
+
+ Rooted<OntologyParent> 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<OntologyParent> parentNameNode = scope().selectOrThrow<OntologyParent>();
+ 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<StructuredClass> strct =
+ parentNameNode->getParent().cast<StructuredClass>();
+
+ // resolve the parent, create the declared field and add the declared
+ // StructuredClass as child to it.
+ scope().resolve<Descriptor>(
+ parentNameNode->getName(), strct, logger(),
+ [type, name, optional](Handle<Node> parent, Handle<Node> strct,
+ Logger &logger) {
+ if (parent != nullptr) {
+ Rooted<FieldDescriptor> field =
+ (parent.cast<Descriptor>()->createFieldDescriptor(
+ logger, type, name, optional)).first;
+ field->addChild(strct.cast<StructuredClass>());
+ }
+ });
+ return true;
+}
+
+/* OntologyParentFieldRefHandler */
+
+bool OntologyParentFieldRefHandler::start(Variant::mapType &args)
+{
+ Rooted<OntologyParent> parentNameNode = scope().selectOrThrow<OntologyParent>();
+
+ const std::string &name = args["ref"].asString();
+ Rooted<StructuredClass> strct =
+ parentNameNode->getParent().cast<StructuredClass>();
+ auto loc = location();
+
+ // resolve the parent, get the referenced field and add the declared
+ // StructuredClass as child to it.
+ scope().resolve<Descriptor>(
+ parentNameNode->getName(), strct, logger(),
+ [name, loc](Handle<Node> parent, Handle<Node> strct, Logger &logger) {
+ if (parent != nullptr) {
+ Rooted<FieldDescriptor> field =
+ parent.cast<Descriptor>()->getFieldDescriptor(name);
+ if (field == nullptr) {
+ logger.error(
+ std::string("Could not find referenced field ") + name,
+ loc);
+ return;
+ }
+ field->addChild(strct.cast<StructuredClass>());
+ }
+ });
+ 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<ousia::parser_stack::OntologyParent>(
+ "OntologyParent").parent(&Node);
+}
+}