diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-13 17:51:03 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-13 17:51:03 +0100 |
commit | c99b5932ef47a5d74b5bccffb52c1ccabac6ae53 (patch) | |
tree | 40ee309ecba2408cb72eb44454db7b928be48fa0 /src/plugins | |
parent | 28f58e33e49a18d86592ca38fc44c106f54d7cec (diff) |
refactored handler classes of XMLParser into own files in core/parser/stack.
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/xml/XmlParser.cpp | 929 |
1 files changed, 5 insertions, 924 deletions
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index 9ef08a5..6dfad49 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -16,7 +16,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <algorithm> #include <iostream> #include <map> #include <sstream> @@ -25,940 +24,22 @@ #include <expat.h> #include <core/common/CharReader.hpp> -#include <core/common/RttiBuilder.hpp> #include <core/common/Utils.hpp> #include <core/common/VariantReader.hpp> -#include <core/parser/ParserStack.hpp> #include <core/parser/ParserScope.hpp> +#include <core/parser/ParserStack.hpp> +#include <core/parser/stack/DocumentHandler.hpp> +#include <core/parser/stack/DomainHandler.hpp> +#include <core/parser/stack/ImportIncludeHandler.hpp> +#include <core/parser/stack/TypesystemHandler.hpp> #include <core/model/Document.hpp> #include <core/model/Domain.hpp> -#include <core/model/Project.hpp> -#include <core/model/RootNode.hpp> #include <core/model/Typesystem.hpp> #include "XmlParser.hpp" namespace ousia { -/* HeadNode Helper class */ - -namespace { -class HeadNode : public Node { -public: - using Node::Node; -}; -} - -namespace RttiTypes { -static Rtti HeadNode = RttiBuilder<ousia::HeadNode>("HeadNode"); -} - -/* Element Handler Classes */ - -class DocumentHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<Document> document = - project()->createDocument(args["name"].asString()); - document->setLocation(location()); - scope().push(document); - scope().setFlag(ParserFlag::POST_HEAD, false); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DocumentHandler{handlerData}; - } -}; - -class DocumentField : public Node { -public: - DocumentField(Manager &mgr, std::string name, Handle<Node> parent) - : Node(mgr, name, parent) - { - } -}; - -namespace RttiTypes { -const Rtti DocumentField = - RttiBuilder<ousia::DocumentField>("DocumentField").parent(&Node); -} - -class DocumentChildHandler : public Handler { -public: - using Handler::Handler; - - void preamble(Handle<Node> parentNode, std::string &fieldName, - DocumentEntity *&parent, bool &inField) - { - // check if the parent in the structure tree was an explicit field - // reference. - inField = parentNode->isa(&RttiTypes::DocumentField); - if (inField) { - fieldName = parentNode->getName(); - parentNode = scope().selectOrThrow( - {&RttiTypes::StructuredEntity, &RttiTypes::AnnotationEntity}); - } else { - // if it wasn't an explicit reference, we use the default field. - fieldName = DEFAULT_FIELD_NAME; - } - // reference the parent entity explicitly. - parent = nullptr; - if (parentNode->isa(&RttiTypes::StructuredEntity)) { - parent = static_cast<DocumentEntity *>( - parentNode.cast<StructuredEntity>().get()); - } else if (parentNode->isa(&RttiTypes::AnnotationEntity)) { - parent = static_cast<DocumentEntity *>( - parentNode.cast<AnnotationEntity>().get()); - } - } - - void createPath(const NodeVector<Node> &path, DocumentEntity *&parent) - { - size_t S = path.size(); - for (size_t p = 1; p < S; p = p + 2) { - parent = static_cast<DocumentEntity *>( - parent->createChildStructuredEntity( - path[p].cast<StructuredClass>(), Variant::mapType{}, - path[p - 1]->getName(), "").get()); - } - } - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - Rooted<Node> parentNode = scope().selectOrThrow( - {&RttiTypes::Document, &RttiTypes::StructuredEntity, - &RttiTypes::AnnotationEntity, &RttiTypes::DocumentField}); - - std::string fieldName; - DocumentEntity *parent; - bool inField; - - preamble(parentNode, fieldName, parent, inField); - - // try to find a FieldDescriptor for the given tag if we are not in a - // field already. This does _not_ try to construct transparent paths - // in between. - if (!inField && parent != nullptr && - parent->getDescriptor()->hasField(name())) { - Rooted<DocumentField> field{new DocumentField( - parentNode->getManager(), fieldName, parentNode)}; - field->setLocation(location()); - scope().push(field); - return; - } - - // Otherwise create a new StructuredEntity - // TODO: Consider Anchors and AnnotationEntities - Rooted<StructuredClass> strct = scope().resolve<StructuredClass>( - Utils::split(name(), ':'), logger()); - if (strct == nullptr) { - // if we could not resolve the name, throw an exception. - throw LoggableException( - std::string("\"") + name() + "\" could not be resolved.", - location()); - } - - std::string name; - auto it = args.find("name"); - if (it != args.end()) { - name = it->second.asString(); - args.erase(it); - } - - Rooted<StructuredEntity> entity; - if (parentNode->isa(&RttiTypes::Document)) { - entity = parentNode.cast<Document>()->createRootStructuredEntity( - strct, args, name); - } else { - // calculate a path if transparent entities are needed in between. - auto path = parent->getDescriptor()->pathTo(strct, logger()); - if (path.empty()) { - throw LoggableException( - std::string("An instance of \"") + strct->getName() + - "\" is not allowed as child of an instance of \"" + - parent->getDescriptor()->getName() + "\"", - location()); - } - - // create all transparent entities until the last field. - createPath(path, parent); - entity = parent->createChildStructuredEntity(strct, args, fieldName, - name); - } - entity->setLocation(location()); - scope().push(entity); - } - - void end() override { scope().pop(); } - - std::pair<bool, Variant> convertData(Handle<FieldDescriptor> field, - Logger &logger, - const std::string &data) - { - // if the content is supposed to be of type string, we can finish - // directly. - auto vts = field->getPrimitiveType()->getVariantTypes(); - if (std::find(vts.begin(), vts.end(), VariantType::STRING) != vts.end()) { - return std::make_pair(true, Variant::fromString(data)); - } - - // then try to parse the content using the type specification. - auto res = field->getPrimitiveType()->read( - data, logger, location().getSourceId(), location().getStart()); - return res; - } - - void data(const std::string &data, int fieldIdx) override - { - Rooted<Node> parentNode = scope().selectOrThrow( - {&RttiTypes::StructuredEntity, &RttiTypes::AnnotationEntity, - &RttiTypes::DocumentField}); - - std::string fieldName; - DocumentEntity *parent; - bool inField; - - preamble(parentNode, fieldName, parent, inField); - - Rooted<Descriptor> desc = parent->getDescriptor(); - /* - * We distinguish two cases here: One for fields that are given. - */ - if (fieldName != DEFAULT_FIELD_NAME) { - // retrieve the actual FieldDescriptor - Rooted<FieldDescriptor> field = desc->getFieldDescriptor(fieldName); - if (field == nullptr) { - logger().error( - std::string( - "Can't handle data because no field with name \"") + - fieldName + "\" exists in descriptor\"" + - desc->getName() + "\".", - location()); - return; - } - // if it is not primitive at all, we can't parse the content. - if (!field->isPrimitive()) { - logger().error( - std::string("Can't handle data because field \"") + - fieldName + "\" of descriptor \"" + desc->getName() + - "\" is not primitive!", - location()); - return; - } - // then try to parse the content using the type specification. - auto res = convertData(field, logger(), data); - // add it as primitive content. - if (res.first) { - parent->createChildDocumentPrimitive(res.second, fieldName); - } - } else { - /* - * The second case is for primitive fields. Here we search through - * all FieldDescriptors that allow primitive content at this point - * and could be constructed via transparent intermediate entities. - * We then try to parse the data using the type specified by the - * respective field. If that does not work we proceed to the next - * possible field. - */ - // retrieve all fields. - NodeVector<FieldDescriptor> fields = desc->getDefaultFields(); - for (auto field : fields) { - // then try to parse the content using the type specification. - LoggerFork loggerFork = logger().fork(); - auto res = convertData(field, loggerFork, data); - if (res.first) { - loggerFork.commit(); - // if that worked, construct the necessary path. - auto pathRes = desc->pathTo(field, logger()); - assert(pathRes.second); - NodeVector<Node> path = pathRes.first; - createPath(path, parent); - // then create the primitive element. - parent->createChildDocumentPrimitive(res.second, fieldName); - return; - } - } - logger().error( - "Could not read the data with any of the possible fields.", - location()); - } - } - - static Handler *create(const HandlerData &handlerData) - { - return new DocumentChildHandler{handlerData}; - } -}; - -class TypesystemHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - // Create the typesystem instance - Rooted<Typesystem> typesystem = - project()->createTypesystem(args["name"].asString()); - typesystem->setLocation(location()); - - // Push the typesystem onto the scope, set the POST_HEAD flag to true - scope().push(typesystem); - scope().setFlag(ParserFlag::POST_HEAD, false); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new TypesystemHandler{handlerData}; - } -}; - -class TypesystemEnumHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - - // Fetch the current typesystem and create the enum node - Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>(); - Rooted<EnumType> enumType = - typesystem->createEnumType(args["name"].asString()); - enumType->setLocation(location()); - - scope().push(enumType); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new TypesystemEnumHandler{handlerData}; - } -}; - -class TypesystemEnumEntryHandler : public Handler { -public: - using Handler::Handler; - - std::string entry; - - void start(Variant::mapType &args) override {} - - void end() override - { - Rooted<EnumType> enumType = scope().selectOrThrow<EnumType>(); - enumType->addEntry(entry, logger()); - } - - void data(const std::string &data, int field) override - { - if (field != 0) { - // TODO: This should be stored in the HandlerData - logger().error("Enum entry only has one field."); - return; - } - entry.append(data); - } - - static Handler *create(const HandlerData &handlerData) - { - return new TypesystemEnumEntryHandler{handlerData}; - } -}; - -class TypesystemStructHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - - // Fetch the arguments used for creating this type - const std::string &name = args["name"].asString(); - const std::string &parent = args["parent"].asString(); - - // Fetch the current typesystem and create the struct node - Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>(); - Rooted<StructType> structType = typesystem->createStructType(name); - structType->setLocation(location()); - - // Try to resolve the parent type and set it as parent structure - if (!parent.empty()) { - scope().resolve<StructType>( - parent, structType, logger(), - [](Handle<Node> parent, Handle<Node> structType, - Logger &logger) { - if (parent != nullptr) { - structType.cast<StructType>()->setParentStructure( - parent.cast<StructType>(), logger); - } - }); - } - scope().push(structType); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new TypesystemStructHandler{handlerData}; - } -}; - -class TypesystemStructFieldHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - // Read the argument values - const std::string &name = args["name"].asString(); - const std::string &type = args["type"].asString(); - const Variant &defaultValue = args["default"]; - const bool optional = - !(defaultValue.isObject() && defaultValue.asObject() == nullptr); - - Rooted<StructType> structType = scope().selectOrThrow<StructType>(); - Rooted<Attribute> attribute = - structType->createAttribute(name, defaultValue, optional, logger()); - attribute->setLocation(location()); - - // Try to resolve the type and default value - if (optional) { - scope().resolveTypeWithValue( - type, attribute, attribute->getDefaultValue(), logger(), - [](Handle<Node> type, Handle<Node> attribute, Logger &logger) { - if (type != nullptr) { - attribute.cast<Attribute>()->setType(type.cast<Type>(), - logger); - } - }); - } else { - scope().resolveType( - type, attribute, logger(), - [](Handle<Node> type, Handle<Node> attribute, Logger &logger) { - if (type != nullptr) { - attribute.cast<Attribute>()->setType(type.cast<Type>(), - logger); - } - }); - } - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new TypesystemStructFieldHandler{handlerData}; - } -}; - -class TypesystemConstantHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - - // Read the argument values - const std::string &name = args["name"].asString(); - const std::string &type = args["type"].asString(); - const Variant &value = args["value"]; - - Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>(); - Rooted<Constant> constant = typesystem->createConstant(name, value); - constant->setLocation(location()); - - // Try to resolve the type - scope().resolveTypeWithValue( - type, constant, constant->getValue(), logger(), - [](Handle<Node> type, Handle<Node> constant, Logger &logger) { - if (type != nullptr) { - constant.cast<Constant>()->setType(type.cast<Type>(), - logger); - } - }); - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new TypesystemConstantHandler{handlerData}; - } -}; - -/* - * Domain Handlers - */ - -class DomainHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<Domain> domain = - project()->createDomain(args["name"].asString()); - domain->setLocation(location()); - - scope().push(domain); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainHandler{handlerData}; - } -}; - -class DomainStructHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - - Rooted<Domain> domain = scope().selectOrThrow<Domain>(); - - Rooted<StructuredClass> structuredClass = domain->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); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainStructHandler{handlerData}; - } -}; - -class DomainAnnotationHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - - Rooted<Domain> domain = scope().selectOrThrow<Domain>(); - - Rooted<AnnotationClass> annotationClass = - domain->createAnnotationClass(args["name"].asString()); - annotationClass->setLocation(location()); - - scope().push(annotationClass); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainAnnotationHandler{handlerData}; - } -}; - -class DomainAttributesHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - // 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); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainAttributesHandler{handlerData}; - } -}; - -class DomainFieldHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - FieldDescriptor::FieldType type; - if (args["isSubtree"].asBool()) { - type = FieldDescriptor::FieldType::SUBTREE; - } else { - type = FieldDescriptor::FieldType::TREE; - } - - Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>(); - - Rooted<FieldDescriptor> field = parent->createFieldDescriptor( - logger(), type, args["name"].asString(), args["optional"].asBool()); - field->setLocation(location()); - - scope().push(field); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainFieldHandler{handlerData}; - } -}; - -class DomainFieldRefHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>(); - - const std::string &name = args["ref"].asString(); - scope().resolveFieldDescriptor( - name, parent, logger(), - [](Handle<Node> field, Handle<Node> parent, Logger &logger) { - if (field != nullptr) { - parent.cast<StructuredClass>()->addFieldDescriptor( - field.cast<FieldDescriptor>(), logger); - } - }); - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new DomainFieldRefHandler{handlerData}; - } -}; - -class DomainPrimitiveHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>(); - - FieldDescriptor::FieldType fieldType; - if (args["isSubtree"].asBool()) { - fieldType = FieldDescriptor::FieldType::SUBTREE; - } else { - fieldType = FieldDescriptor::FieldType::TREE; - } - - Rooted<FieldDescriptor> field = parent->createPrimitiveFieldDescriptor( - nullptr, logger(), fieldType, args["name"].asString(), - args["optional"].asBool()); - field->setLocation(location()); - - const std::string &type = args["type"].asString(); - scope().resolve<Type>( - type, field, logger(), - [](Handle<Node> type, Handle<Node> field, Logger &logger) { - if (type != nullptr) { - field.cast<FieldDescriptor>()->setPrimitiveType( - type.cast<Type>()); - } - }); - - scope().push(field); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainPrimitiveHandler{handlerData}; - } -}; - -class DomainChildHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - 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>()); - } - }); - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new DomainChildHandler{handlerData}; - } -}; - -class DomainParent : public Node { -public: - DomainParent(Manager &mgr, std::string name, Handle<Node> parent) - : Node(mgr, name, parent) - { - } -}; - -namespace RttiTypes { -const Rtti DomainParent = - RttiBuilder<ousia::DomainParent>("DomainParent").parent(&Node); -} - -class DomainParentHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<StructuredClass> strct = - scope().selectOrThrow<StructuredClass>(); - - Rooted<DomainParent> parent{new DomainParent( - strct->getManager(), args["ref"].asString(), strct)}; - parent->setLocation(location()); - scope().push(parent); - } - - void end() override { scope().pop(); } - - static Handler *create(const HandlerData &handlerData) - { - return new DomainParentHandler{handlerData}; - } -}; - -class DomainParentFieldHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<DomainParent> parentNameNode = - scope().selectOrThrow<DomainParent>(); - 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); - field->addChild(strct.cast<StructuredClass>()); - } - }); - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new DomainParentFieldHandler{handlerData}; - } -}; - -class DomainParentFieldRefHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - Rooted<DomainParent> parentNameNode = - scope().selectOrThrow<DomainParent>(); - - 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>()); - } - }); - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new DomainParentFieldRefHandler{handlerData}; - } -}; - -/* - * Import and Include Handler - */ - -class ImportIncludeHandler : public Handler { -public: - using Handler::Handler; - - bool srcInArgs = false; - std::string rel; - std::string type; - std::string src; - - void start(Variant::mapType &args) override - { - rel = args["rel"].asString(); - type = args["type"].asString(); - src = args["src"].asString(); - srcInArgs = !src.empty(); - } - - void data(const std::string &data, int field) override - { - if (srcInArgs) { - logger().error("\"src\" attribute has already been set"); - return; - } - if (field != 0) { - logger().error("Command has only one field."); - return; - } - src.append(data); - } -}; - -class ImportHandler : public ImportIncludeHandler { -public: - using ImportIncludeHandler::ImportIncludeHandler; - - void start(Variant::mapType &args) override - { - ImportIncludeHandler::start(args); - - // Make sure imports are still possible - if (scope().getFlag(ParserFlag::POST_HEAD)) { - logger().error("Imports must be listed before other commands.", - location()); - return; - } - } - - void end() override - { - // Fetch the last node and check whether an import is valid at this - // position - Rooted<Node> leaf = scope().getLeaf(); - if (leaf == nullptr || !leaf->isa(&RttiTypes::RootNode)) { - logger().error( - "Import not supported here, must be inside a document, domain " - "or typesystem command.", - location()); - return; - } - Rooted<RootNode> leafRootNode = leaf.cast<RootNode>(); - - // Perform the actual import, register the imported node within the leaf - // node - Rooted<Node> imported = - context().import(src, type, rel, leafRootNode->getReferenceTypes()); - if (imported != nullptr) { - leafRootNode->reference(imported); - } - } - - static Handler *create(const HandlerData &handlerData) - { - return new ImportHandler{handlerData}; - } -}; - -class IncludeHandler : public ImportIncludeHandler { -public: - using ImportIncludeHandler::ImportIncludeHandler; - - void start(Variant::mapType &args) override - { - ImportIncludeHandler::start(args); - } - - void end() override - { - context().include(src, type, rel, {&RttiTypes::Node}); - } - - static Handler *create(const HandlerData &handlerData) - { - return new IncludeHandler{handlerData}; - } -}; - namespace ParserStates { /* Document states */ static const ParserState Document = |