From 9b9c7439b6cb1b711901ad49cd4855e1b0964652 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Thu, 22 Jan 2015 02:49:09 +0100 Subject: Backup --- src/core/resource/ResourceManager.cpp | 252 ++++++++++++++++++++++++++++++++++ src/core/resource/ResourceManager.hpp | 152 ++++++++++++++++++++ 2 files changed, 404 insertions(+) create mode 100644 src/core/resource/ResourceManager.cpp create mode 100644 src/core/resource/ResourceManager.hpp (limited to 'src/core/resource') diff --git a/src/core/resource/ResourceManager.cpp b/src/core/resource/ResourceManager.cpp new file mode 100644 index 0000000..563fc12 --- /dev/null +++ b/src/core/resource/ResourceManager.cpp @@ -0,0 +1,252 @@ +/* + 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 "Resource.hpp" +#include "ResourceManager.hpp" + +namespace ousia { + +/* Deduction of the ResourceType */ + +namespace RttiTypes { +extern const Rtti Document; +extern const Rtti Domain; +extern const Rtti Node; +extern const Rtti Typesystem; +} + +/** + * Map mapping from relations (the "rel" attribute in includes) to the + * corresponding ResourceType. + */ +static const std::unordered_map RelResourceTypeMap{ + {"document", ResourceType::DOCUMENT}, + {"domain", ResourceType::DOMAIN_DESC}, + {"typesystem", ResourceType::TYPESYSTEM}}; + +/** + * Map mapping from Rtti pointers to the corresponding ResourceType. + */ +static const std::unordered_map RttiResourceTypeMap{ + {&RttiTypes::Document, ResourceType::DOCUMENT}, + {&RttiTypes::Domain, ResourceType::DOMAIN_DESC}, + {&RttiTypes::Typesystem, ResourceType::TYPESYSTEM}}; + +static ResourceType relToResourceType(const std::string &rel, Logger &logger) +{ + std::string s = Utils::toLowercase(rel); + if (!s.empty()) { + auto it = RelResourceTypeMap.find(s); + if (it != RelResourceTypeMap.end()) { + return it->second; + } else { + logger.error(std::string("Unknown relation \"") + rel + + std::string("\"")); + } + } + return ResourceType::UNKNOWN; +} + +static ResourceType supportedTypesToResourceType(const RttiSet &supportedTypes) +{ + if (supportedTypes.size() == 1U) { + auto it = RttiResourceTypeMap.find(supportedTypes[0]); + if (it != RelResourceTypeMap.end()) { + return it->second; + } + } + return ResourceType::UNKNOWN; +} + +static ResourceType deduceResourceType(const std::string &rel, + const RttiSet &supportedTypes, + Logger &logger) +{ + ResourceType res; + + // Try to deduce the ResourceType from the "rel" attribute + res = relToResourceType(rel, logger); + + // If this did not work, try to deduce the ResourceType from the + // supportedTypes supplied by the Parser instance. + if (res == ResourceType::UNKNOWN) { + res = supportedTypesToResourceType(supportedTypes); + } + if (res == ResourceType::UNKNOWN) { + logger.note( + "Ambigous resource type, consider specifying the \"rel\" " + "attribute"); + } + return res; +} + +/* Functions for reducing the set of supported types */ + +/** + * Map mapping from relations (the "rel" attribute in includes) to the + * corresponding RttiType + */ +static const std::unordered_map RelRttiTypeMap{ + {"document", &RttiTypes::DOCUMENT}, + {"domain", &RttiTypes::DOMAIN}, + {"typesystem", &RttiTypes::TYPESYSTEM}}; + +static Rtti *relToRttiType(const std::string &rel) +{ + std::string s = Utils::toLowercase(rel); + if (!s.empty()) { + auto it = RelRttiTypeMap.find(s); + if (it != RelRttiTypeMap.end()) { + return it->second; + } + } + return &ResourceType::Node; +} + +static RttiType shrinkSupportedTypes(const RttiSet &supportedTypes, + const std::string &rel) +{ + RttiSet types; + RttiType *type = relToRttiType(rel); + for (RttiType *supportedType : supportedTypes) { + if (supportedType->isa(type)) { + types.insert(supportedType); + } + } + return types; +} + +/* Class ResourceManager */ + +Rooted ResourceManager::link(ParserContext &ctx, Resource &resource, + const std::string &mimetype, + const RttiSet &supportedTypes) +{ + +} + +Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, + const std::string &mimetype, + const std::string &rel, + const RttiSet &supportedTypes, + const Resource &relativeTo) +{ + // Try to deduce the ResourceType + ResourceType resourceType = + deduceResourceType(rel, supportedTypes, ctx.logger); + + // Lookup the resource for given path and resource type + Resource resource; + if (!ctx.registry.locateResource(resource, path, resourceType, + relativeTo)) { + ctx.logger.error("File \"" + path + "\" not found."); + return nullptr; + } + + // Try to shrink the set of supportedTypes + RttiSet types = shrinkSupportedTypes(supportedTypes, rel); + + // Check whether the resource has already been parsed + Rooted node = nullptr; + auto it = locations.find(res.getLocation()); + if (it != locations.end()) { + node = + } + = link(ctx, resource, mimetype, types); + + // Try to deduce the mimetype + std::string mime = mimetype; + if (mime.empty()) { + // Fetch the file extension + std::string ext = Utils::extractFileExtension(path); + if (ext.empty()) { + ctx.logger.error( + std::string("Specified filename \"") + path + + std::string( + "\" has no extension and no mimetype (\"type\" " + "attribute) was given instead.")); + return nullptr; + } + + // Fetch the mimetype for the extension + mime = ctx.registry.getMimetypeForExtension(ext); + if (mime.empty()) { + ctx.logger.error(std::string("Unknown file extension \"") + ext + + std::string("\"")); + return nullptr; + } + } + + // Fetch a parser for the mimetype + const std::pair parser = + ctx.registry.getParserForMimetype(mime); + + // Make sure a parser was found + if (!parser->first) { + ctx.logger.error(std::string("Cannot parse files of type \"") + mime + + std::string("\"")); + } + + // Make sure the parser returns one of the supported types +} + +Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, + const std::string &mimetype, + const std::string &rel, + const RttiSet &supportedTypes, + SourceId relativeTo) +{ + // Fetch the resource corresponding to the source id, make sure it is valid + const Resource &relativeResource = getResource(relativeTo); + if (!relativeResource.isValid()) { + ctx.logger.fatalError("Internal error: Invalid SourceId supplied."); + return nullptr; + } + + // Continue with the usual include routine + return include(ctx, path, mimetype, rel, supportedTypes, relativeResource); +} + +const Resource &getResource(SourceId sourceId) const +{ + if (sourceId < resources.size()) { + return resources[sourceId]; + } + return NullResource; +} + +SourceContext ResourceManager::buildContext(const SourceLocation &location) +{ + SourceContext res; + + // TODO + + return res; +} +}; +} + +#endif /* _OUSIA_RESOURCE_MANAGER_HPP_ */ + diff --git a/src/core/resource/ResourceManager.hpp b/src/core/resource/ResourceManager.hpp new file mode 100644 index 0000000..809fd55 --- /dev/null +++ b/src/core/resource/ResourceManager.hpp @@ -0,0 +1,152 @@ +/* + 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 . +*/ + +/** + * @file ResourceManager.hpp + * + * Defines the ResourceManager class which is responsible for keeping track of + * already included resources and to retrieve CharReader instance for not-yet + * parsed resources. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_RESOURCE_MANAGER_HPP_ +#define _OUSIA_RESOURCE_MANAGER_HPP_ + +#include +#include + +#include +#include + +namespace ousia { + +// Forward declarations +class Node; +class ParserContext; +class Resource; +class RttiSet; +extern const Resource NullResource; + +/** + * The ResourceManager class is responsible for keepking track of all included + * resources. It retrieves CharReader instances for not-yet parsed resources + * and returns references for those resources that already have been parsed. + */ +class ResourceManager { +private: + /** + * Vector used for mapping SourceId instances to the underlying resource. + */ + std::vector resources; + + /** + * Index pointing at the next free entry in the resources list. + */ + SourceId nextFreeSourceId = 0; + + /** + * Map between Resource locations and the corresponding SourceId. + */ + std::unordered_map locations; + + /** + * Map between a SourceId and the corresponding (if available) parsed node + * uid (this resembles weak references to the Node instance). + */ + std::unordered_map nodes; + + /** + * Cache used for translating byte offsets to line numbers. Maps from a + * SourceId onto a list of (sorted) SourceOffsets. The index in the list + * corresponds to the line number. + */ + std::unordered_map> lineNumberCache; + + + Rooted getCachedNode(SourceId id); + + Rooted getCachedNode(const std::string &location); + + SourceId getSourceId(const std::string &location); + + /** + * Used internally to either parse a resource or retrieve it from the + * internal cache of already parsed resources. + */ + Rooted link(ParserContext &ctx, Resource &resource, const std::string &mimetype, + const RttiSet &supportedTypes); + + +public: + /** + * Resolves the reference to the file specified by the given path and -- if + * this has not already happened -- parses the file. Logs any problem in + * the logger instance of the given ParserContext. + * + * @param ctx is the context from the Registry and the Logger instance will + * be looked up. + * @param path is the path to the file that should be included. + * @param mimetype is the mimetype the file was included with. If no + * mimetype is given, the path must have an extension that is known by + */ + Rooted link(ParserContext &ctx, const std::string &path, + const std::string &mimetype = "", + const std::string &rel = "", + const RttiSet &supportedTypes = RttiSet{}, + const Resource &relativeTo = NullResource); + + /** + * Resolves the reference to the file specified by the given path and -- if + * this has not already happened -- parses the file. Logs any problem in + * the logger instance of the given ParserContext. + */ + Rooted link(ParserContext &ctx, const std::string &path, + const std::string &mimetype, const std::string &rel, + const RttiSet &supportedTypes, SourceId relativeTo); + + /** + * Returns a Resource instance for the given SourceId. + * + * @param sourceId is the id of the Resource instance that should be + * returned. + * @return the Resource instance corresponding to the given sourceId. If the + * sourceId is invalid, the returned Resource will be invalid (a reference + * at NullResource). + */ + const Resource &getResource(SourceId sourceId) const; + + /** + * Creates and returns a SourceContext structure containing information + * about the given SourceLocation (such as line and column number). Throws + * a LoggableException if an irrecoverable error occurs while looking up the + * context (such as a no longer existing resource). + * + * @param location is the SourceLocation for which context information + * should be retrieved. This method is used by the Logger class to print + * pretty messages. + * @return a valid SourceContext if a valid SourceLocation was given or an + * invalid SourceContext if the location is invalid. + */ + SourceContext buildContext(const SourceLocation &location); +}; +} + +#endif /* _OUSIA_RESOURCE_MANAGER_HPP_ */ + -- cgit v1.2.3