/* 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 . */ #ifndef _MODEL_TEST_DOCUMENT_BUILDER_HPP_ #define _MODEL_TEST_DOCUMENT_BUILDER_HPP_ #include #include #include #include #include namespace ousia { typedef std::vector Path; /* Class StructuredEntity */ static std::string getPathString(const Path &path) { std::stringstream ss; ss << path[0]; for (size_t i = 1; i < path.size(); i++) { ss << '.'; ss << path[i]; } return std::move(ss.str()); } static Rooted resolveDescriptor(Handle doc, Logger &logger, const Path &path, const Rtti &type) { // use the actual resolve method. std::vector resolved = doc->resolve(type, path); // if we don't find anything, log an error if (resolved.size() == 0) { logger.error(std::string("Could not resolve ") + getPathString(path)); return {nullptr}; } // if we have more than one result, log an error. if (resolved.size() > 1) { logger.error(getPathString(path) + " was ambigous: "); for (auto &r : resolved) { logger.error(getPathString(r.node->path())); } } // Return the resulting node. return resolved[0].node.cast(); } /** * This builds the root StructuredEntity for the given document. It * automatically appends the newly build entity to the given document. * * @param document is the document this entity shall be build for. The * resulting entity will automatically be appended to that * document. Also the manager of that document will be * used to register the new node. * @param logger is the current logger. * @param path is the name of the StructuredClass or a path specifying it * uniquely. * @param attributes are the attributes of the new node in terms of a Struct * variant (empty per default). * @param name is the name of this StructuredEntity (empty per * default). * @return the newly created StructuredEntity or a nullptr if some * input handle was empty or the given domains did not * contain a StructuredClass with the given name. */ Rooted buildRootStructuredEntity(Handle document, Logger &logger, const Path &path, Variant attributes = {}, std::string name = "") { // If the parent is not set, we can not build the entity. if (document == nullptr) { logger.error("The input document handle was null!"); return {nullptr}; } // If we can not find the correct descriptor, we can not build the entity // either. Rooted descriptor = resolveDescriptor(document, logger, path, RttiTypes::StructuredClass); if (descriptor == nullptr) { return {nullptr}; } // Then construct the StructuredEntity itself. Rooted root{new StructuredEntity( document->getManager(), document, descriptor.cast(), attributes, std::move(name))}; // and return it. return root; } /** * This builds a StructuredEntity as child of the given DocumentEntity. It * automatically appends the newly build entity to its parent. * * @param document is the document this entity shall be build for. The domains * referenced here are the basis to resolve the given path. * @param logger is the current logger. * @param parent is the parent DocumentEntity. The newly constructed * StructuredEntity will automatically be appended to it. * @param path is the name of the StructuredClass or a path specifying it * uniquely. * @param fieldName is the name of the field where the newly constructed * StructuredEntity shall be appended. * @param attributes are the attributes of the new node in terms of a Struct * variant (empty per default). * @param name is the name of this StructuredEntity (empty per * default). * @return the newly created StructuredEntity or a nullptr if some * input handle was empty or the given domains did not * contain a StructuredClass with the given name. */ Rooted buildStructuredEntity( Handle document, Logger &logger, Handle parent, Path path, const std::string &fieldName = "", Variant attributes = {}, std::string name = "") { // If the input handles are not set, we can not build the entity. if (parent == nullptr) { logger.error("The input parent handle was null!"); return {nullptr}; } if (document == nullptr) { logger.error("The input document handle was null!"); return {nullptr}; } // If we can not find the correct descriptor, we can not build the entity // either. Rooted descriptor = resolveDescriptor(document, logger, path, RttiTypes::StructuredClass); if (descriptor == nullptr) { return {nullptr}; } if(!descriptor->isa(RttiTypes::StructuredClass)){ return {nullptr}; logger.error("The descriptor was not an AnnotationClass!"); } // Then construct the StructuredEntity itself. Rooted entity{new StructuredEntity( parent->getManager(), parent, descriptor.cast(), attributes, fieldName, std::move(name))}; // and return it. return entity; } /** * This builds an AnnotationEntity as child of the given Document. It * automatically appends the newly build entity to its parent. * * @param document is the document this entity shall be build for. The domains * referenced here are the basis to resolve the given path. * @param logger is the current logger. * @param path is the name of the AnnotationClass or a path specifying it * uniquely. * @param start is the start Anchor for this AnnotationEntity. * @param end is the end Anchor for this AnnotationEntity. * @param attributes are the attributes of the new node in terms of a Struct * variant (empty per default). * @param name is the name of this AnnotationEntity (empty per * default). * @return the newly created AnnotationEntity or a nullptr if some * input handle was empty or the given domains did not * contain a AnnotationClass with the given name. */ Rooted buildAnnotationEntity( Handle document, Logger &logger, const Path &path, Handle start, Handle end, Variant attributes = {}, std::string name = "") { // If the input handles are not set, we can not build the entity. if (document == nullptr) { logger.error("The input document handle was null!"); return {nullptr}; } // If we can not find the correct descriptor, we can not build the // entity either. Rooted descriptor = resolveDescriptor(document, logger, path, RttiTypes::AnnotationClass); if (descriptor == nullptr) { return {nullptr}; } if(!descriptor->isa(RttiTypes::AnnotationClass)){ return {nullptr}; logger.error("The descriptor was not an AnnotationClass!"); } // Then construct the AnnotationEntity itself Rooted anno{new AnnotationEntity( document->getManager(), document, descriptor.cast(), start, end, attributes, name)}; // and return it. return anno; } } #endif