diff options
| author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-23 15:47:59 +0100 | 
|---|---|---|
| committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-23 15:47:59 +0100 | 
| commit | 18d3637ca02ab69f1ee744fa94c43c243de0f571 (patch) | |
| tree | 42c859f014ab7dbb7d31a747e0ef3839c77c60fa /src/core/resource | |
| parent | 85d72823ef18711fe7a29f5b23cc37b318766332 (diff) | |
| parent | aa817d3bfd90aa39b6fd8a915bc78a8bb210cd3d (diff) | |
Merge branch 'master' of somweyr.de:ousia
Diffstat (limited to 'src/core/resource')
| -rw-r--r-- | src/core/resource/ResourceManager.cpp | 275 | ||||
| -rw-r--r-- | src/core/resource/ResourceManager.hpp | 236 | ||||
| -rw-r--r-- | src/core/resource/ResourceUtils.cpp | 138 | ||||
| -rw-r--r-- | src/core/resource/ResourceUtils.hpp | 128 | 
4 files changed, 777 insertions, 0 deletions
| diff --git a/src/core/resource/ResourceManager.cpp b/src/core/resource/ResourceManager.cpp new file mode 100644 index 0000000..f154c9c --- /dev/null +++ b/src/core/resource/ResourceManager.cpp @@ -0,0 +1,275 @@ +/* +    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 <vector> + +#include <core/common/CharReader.hpp> +#include <core/common/Exceptions.hpp> +#include <core/common/Logger.hpp> +#include <core/common/Rtti.hpp> +#include <core/common/Utils.hpp> +#include <core/model/Node.hpp> +#include <core/parser/ParserContext.hpp> +#include <core/parser/Parser.hpp> +#include <core/Registry.hpp> + +#include "ResourceManager.hpp" +#include "ResourceUtils.hpp" + +namespace ousia { + +/* Static helper functions */ + +static void logUnsopportedType(Logger &logger, Resource &resource, const RttiSet &supportedTypes) +{ +	// Build a list containing the expected type names +	std::vector<std::string> expected; +	for (const Rtti *supportedType : supportedTypes) { +		expected.push_back(supportedType->name); +	} + +	// Log the actual error message +	logger.error( +	    std::string("Expected the file \"") + resource.getLocation() + +	    std::string("\" to define one of the following internal types ") + +	    Utils::join(expected, ", ", "{", "}")); +} + +/* Class ResourceManager */ + +SourceId ResourceManager::allocateSourceId(const Resource &resource) +{ +	// Increment the source id and make sure the values don't overflow +	SourceId sourceId = nextSourceId++; +	if (sourceId == InvalidSourceId) { +		nextSourceId = InvalidSourceId; +		throw OusiaException{"Internal resource handles depleted!"}; +	} + +	// Register the node and the resource with this id +	locations[resource.getLocation()] = sourceId; +	resources[sourceId] = resource; + +	return sourceId; +} + +void ResourceManager::storeNode(SourceId sourceId, Handle<Node> node) +{ +	nodes[sourceId] = node->getUid(); +} + +void ResourceManager::purgeResource(SourceId sourceId) +{ +	Resource res = getResource(sourceId); +	if (res.isValid()) { +		locations.erase(res.getLocation()); +	} +	resources.erase(sourceId); +	nodes.erase(sourceId); +	lineNumberCache.erase(sourceId); +} + +Rooted<Node> ResourceManager::parse(ParserContext &ctx, Resource &resource, +                                    const std::string &mimetype, +                                    const RttiSet &supportedTypes) +{ +	// Try to deduce the mimetype of no mimetype was given +	std::string mime = mimetype; +	if (mime.empty()) { +		mime = ctx.registry.getMimetypeForFilename(resource.getLocation()); +		if (mime.empty()) { +			ctx.logger.error(std::string("Filename \"") + resource.getLocation() + +			                 std::string( +			                     "\" has an unknown file extension. Explicitly " +			                     "specify a mimetype.")); +			return nullptr; +		} +	} + +	// Fetch a parser for the mimetype +	const std::pair<Parser *, RttiSet> &parserDescr = +	    ctx.registry.getParserForMimetype(mime); +	Parser *parser = parserDescr.first; + +	// Make sure a parser was found +	if (!parser) { +		ctx.logger.error(std::string("Cannot parse files of type \"") + mime + +		                 std::string("\"")); +		return nullptr; +	} + +	// Make sure the parser returns at least one of the supported types +	if (!Rtti::setIsOneOf(parserDescr.second, supportedTypes)) { +		logUnsopportedType(ctx.logger, resource, supportedTypes); +		return nullptr; +	} + +	// Allocate a new SourceId handle for this Resource +	SourceId sourceId = allocateSourceId(resource); + +	// We can now try to parse the given file +	Rooted<Node> node; +	try { +		// Set the current source id in the logger instance +		ScopedLogger logger(ctx.logger, SourceLocation{sourceId}); + +		// Fetch the input stream and create a char reader +		std::unique_ptr<std::istream> is = resource.stream(); +		CharReader reader(*is, sourceId); + +		// Actually parse the input stream +		node = parser->parse(reader, ctx); +		if (node == nullptr) { +			throw LoggableException{"Internal error: Parser returned null."}; +		} +	} catch (LoggableException ex) { +		// Remove all data associated with the allocated source id +		purgeResource(sourceId); + +		// Log the exception and return nullptr +		ctx.logger.log(ex); +		return nullptr; +	} + +	// Store the parsed node along with the sourceId +	storeNode(sourceId, node); + +	// Return the parsed node +	return node; +} + +SourceId ResourceManager::getSourceId(const std::string &location) +{ +	auto it = locations.find(location); +	if (it != locations.end()) { +		return it->second; +	} +	return InvalidSourceId; +} + +SourceId ResourceManager::getSourceId(const Resource &resource) +{ +	if (resource.isValid()) { +		return getSourceId(resource.getLocation()); +	} +	return InvalidSourceId; +} + +const Resource &ResourceManager::getResource(SourceId sourceId) const +{ +	auto it = resources.find(sourceId); +	if (it != resources.end()) { +		return it->second; +	} +	return NullResource; +} + +Rooted<Node> ResourceManager::getNode(Manager &mgr, SourceId sourceId) +{ +	auto it = nodes.find(sourceId); +	if (it != nodes.end()) { +		Managed *managed = mgr.getManaged(sourceId); +		if (managed != nullptr) { +			return dynamic_cast<Node *>(managed); +		} else { +			purgeResource(sourceId); +		} +	} +	return nullptr; +} + +Rooted<Node> ResourceManager::getNode(Manager &mgr, const std::string &location) +{ +	return getNode(mgr, getSourceId(location)); +} + +Rooted<Node> ResourceManager::getNode(Manager &mgr, const Resource &resource) +{ +	return getNode(mgr, getSourceId(resource)); +} + +Rooted<Node> 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 = +	    ResourceUtils::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 = ResourceUtils::limitRttiTypes(supportedTypes, rel); + +	// Check whether the resource has already been parsed +	Rooted<Node> node = getNode(ctx.manager, resource); +	if (node == nullptr) { +		// Node has not already been parsed, parse it now +		node = parse(ctx, resource, mimetype, supportedTypes); + +		// Abort if parsing failed +		if (node == nullptr) { +			return nullptr; +		} +	} + +	// Make sure the node has one of the supported types +	if (!node->type().isOneOf(supportedTypes)) { +		logUnsopportedType(ctx.logger, resource, supportedTypes); +		return nullptr; +	} + +	return node; +} + +Rooted<Node> 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 link(ctx, path, mimetype, rel, supportedTypes, relativeResource); +} + +SourceContext ResourceManager::buildContext(const SourceLocation &location) +{ +	SourceContext res; + +	// TODO + +	return res; +} + +} + diff --git a/src/core/resource/ResourceManager.hpp b/src/core/resource/ResourceManager.hpp new file mode 100644 index 0000000..51c00e3 --- /dev/null +++ b/src/core/resource/ResourceManager.hpp @@ -0,0 +1,236 @@ +/* +    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/>. +*/ + +/** + * @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 <string> +#include <unordered_map> + +#include <core/common/Location.hpp> +#include <core/common/Rtti.hpp> +#include <core/managed/Managed.hpp> + +#include "Resource.hpp" + +namespace ousia { + +// Forward declarations +class Node; +class ParserContext; +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: +	/** +	 * Next SourceId to be used. +	 */ +	SourceId nextSourceId = 0; + +	/** +	 * Map between Resource locations and the corresponding SourceId. +	 */ +	std::unordered_map<std::string, SourceId> locations; + +	/** +	 * Map used for mapping SourceId instances to the underlying resource. +	 */ +	std::unordered_map<SourceId, Resource> resources; + +	/** +	 * Map between a SourceId and the corresponding (if available) parsed node +	 * uid (this resembles weak references to the Node instance). +	 */ +	std::unordered_map<SourceId, ManagedUid> 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<SourceId, std::vector<SourceOffset>> lineNumberCache; + +	/** +	 * Allocates a new SourceId for the given resource. +	 * +	 * @param resource is the Resource that should be associated with the newly +	 * allocated SourceId. +	 * @return a new SourceId describing the given resource. +	 */ +	SourceId allocateSourceId(const Resource &resource); + +	/** +	 * Registers the parsed node for this node id. +	 * +	 * @param sourceId is SourceId instance of the resource. +	 * @param node is the node that was parsed from that resource. +	 */ +	void storeNode(SourceId sourceId, Handle<Node> node); + +	/** +	 * Removes a resource from the internal stores. +	 * +	 * @param sourceId is the id of the file that should be removed. +	 */ +	void purgeResource(SourceId sourceId); + +	/** +	 * Used internally to parse the given resource. +	 * +	 * @param ctx is the context from the Registry and the Logger instance will +	 * be looked up. +	 * @param resource is the resource from which the input stream should be +	 * obtained. +	 * @param mimetype is the mimetype of the resource that should be parsed +	 * (may be empty, in which case the mimetype is deduced from the file +	 * extension) +	 * @param supportedTypes contains the types of the returned Node the caller +	 * can deal with. Note that only the types the parser claims to return are +	 * checked, not the actual result. +	 * @return the parsed node or nullptr if something goes wrong. +	 */ +	Rooted<Node> parse(ParserContext &ctx, Resource &resource, +	                   const std::string &mimetype, +	                   const RttiSet &supportedTypes); + +public: +	/** +	 * Returns the sourceId for the given location string. +	 * +	 * @param location is the location string for which the resource id should +	 * be returned. +	 * @return the SourceId that can be used to identify the Resource, or +	 * InvalidSourceId if the specified location is not loaded. +	 */ +	SourceId getSourceId(const std::string &location); + +	/** +	 * Returns the sourceId for the given Resource. +	 * +	 * @param resource is the Resource for which the sourceId should be +	 * returned. +	 * @return the SourceId that can be used to identify the Resource, or +	 * InvalidSourceId if the specified resource is not loaded or invalid. +	 */ +	SourceId getSourceId(const Resource &resource); + +	/** +	 * 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; + +	/** +	 * Returns the node that is associated with the given SourceId or nullptr if +	 * the Node no longer exists or the supplied SourceId is invalid. +	 * +	 * @param mgr is the Manager instance that should be used to resolve the +	 * internal weak reference to the Node instance. +	 * @param sourceId is the id of the resource for which the parsed Node +	 * instance should be returned. +	 * @return the Node instance corresponding to the given sourceId. +	 */ +	Rooted<Node> getNode(Manager &mgr, SourceId sourceId); + +	/** +	 * Returns the node that is associated with the given location or nullptr if +	 * the Node no longer exists or the supplied location was never parsed. +	 * +	 * @param mgr is the Manager instance that should be used to resolve the +	 * internal weak reference to the Node instance. +	 * @param location is the location from which the node was parsed. +	 * @return the Node instance corresponding to the given location. +	 */ +	Rooted<Node> getNode(Manager &mgr, const std::string &location); + +	/** +	 * Returns the node that is associated with the given resource or nullptr if +	 * the Node no longer exists or the supplied resource was never parsed. +	 * +	 * @param mgr is the Manager instance that should be used to resolve the +	 * internal weak reference to the Node instance. +	 * @param resource is the resource from which the node was parsed. +	 * @return the Node instance corresponding to the given resource. +	 */ +	Rooted<Node> getNode(Manager &mgr, const Resource &resource); + +	/** +	 * 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<Node> 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<Node> link(ParserContext &ctx, const std::string &path, +	                  const std::string &mimetype, const std::string &rel, +	                  const RttiSet &supportedTypes, SourceId relativeTo); + +	/** +	 * 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_ */ + diff --git a/src/core/resource/ResourceUtils.cpp b/src/core/resource/ResourceUtils.cpp new file mode 100644 index 0000000..7c42716 --- /dev/null +++ b/src/core/resource/ResourceUtils.cpp @@ -0,0 +1,138 @@ +/* +    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/Logger.hpp> +#include <core/common/Rtti.hpp> +#include <core/common/Utils.hpp> + +#include "ResourceUtils.hpp" + +namespace ousia { + +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<std::string, ResourceType> RelResourceTypeMap{ +    {"document", ResourceType::DOCUMENT}, +    {"domain", ResourceType::DOMAIN_DESC}, +    {"typesystem", ResourceType::TYPESYSTEM}}; + +/** + * Map mapping from relations to the corresponding Rtti descriptor. + */ +static const std::unordered_map<std::string, const Rtti *> RelRttiTypeMap{ +    {"document", &RttiTypes::Document}, +    {"domain", &RttiTypes::Domain}, +    {"typesystem", &RttiTypes::Typesystem}}; + +/** + * Map mapping from Rtti pointers to the corresponding ResourceType. + */ +static const std::unordered_map<const Rtti *, ResourceType> RttiResourceTypeMap{ +    {&RttiTypes::Document, ResourceType::DOCUMENT}, +    {&RttiTypes::Domain, ResourceType::DOMAIN_DESC}, +    {&RttiTypes::Typesystem, ResourceType::TYPESYSTEM}}; + +ResourceType ResourceUtils::deduceResourceType(const std::string &rel, +                                               const RttiSet &supportedTypes, +                                               Logger &logger) +{ +	ResourceType res; + +	// Try to deduce the ResourceType from the "rel" attribute +	res = deduceResourceType(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 = deduceResourceType(supportedTypes, logger); +	} +	if (res == ResourceType::UNKNOWN) { +		logger.note( +		    "Ambigous resource type, consider specifying the \"rel\" " +		    "attribute"); +	} +	return res; +} + +ResourceType ResourceUtils::deduceResourceType(const std::string &rel, +                                               Logger &logger) +{ +	std::string s = Utils::toLower(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; +} + +ResourceType ResourceUtils::deduceResourceType(const RttiSet &supportedTypes, +                                               Logger &logger) +{ +	if (supportedTypes.size() == 1U) { +		auto it = RttiResourceTypeMap.find(*supportedTypes.begin()); +		if (it != RttiResourceTypeMap.end()) { +			return it->second; +		} +	} +	return ResourceType::UNKNOWN; +} + +const Rtti *ResourceUtils::deduceRttiType(const std::string &rel) +{ +	std::string s = Utils::toLower(rel); +	if (!s.empty()) { +		auto it = RelRttiTypeMap.find(s); +		if (it != RelRttiTypeMap.end()) { +			return it->second; +		} +	} +	return &RttiTypes::Node; +} + +RttiSet ResourceUtils::limitRttiTypes(const RttiSet &supportedTypes, +                                      const std::string &rel) +{ +	return limitRttiTypes(supportedTypes, deduceRttiType(rel)); +} + +RttiSet ResourceUtils::limitRttiTypes(const RttiSet &supportedTypes, +                                      const Rtti *type) +{ +	RttiSet res; +	for (const Rtti *supportedType : supportedTypes) { +		if (supportedType->isa(*type)) { +			res.insert(supportedType); +		} +	} +	return res; +} +} diff --git a/src/core/resource/ResourceUtils.hpp b/src/core/resource/ResourceUtils.hpp new file mode 100644 index 0000000..13f9251 --- /dev/null +++ b/src/core/resource/ResourceUtils.hpp @@ -0,0 +1,128 @@ +/* +    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/>. +*/ + +/** + * @file ResourceUtils.hpp + * + * Contains the ResourceUtils class which defines a set of static utility + * functions for dealing with Resources and ResourceTypes. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_RESOURCE_UTILS_HPP_ +#define _OUSIA_RESOURCE_UTILS_HPP_ + +#include <string> + +#include <core/common/Rtti.hpp> + +#include "Resource.hpp" + +namespace ousia { + +/** + * Class containing static utility functions for dealing with Resources and + * ResourceTypes. + */ +class ResourceUtils { +public: +	/** +	 * Function used to deduce the resource type from a given "relation" string +	 * and a set of RTTI types into which the resource should be converted by a +	 * parser. +	 * +	 * @param rel is a relation string which specifies the type of the resource. +	 * May be empty. +	 * @param supportedTypes is a set of RTTI types into which the resource +	 * should be converted by a parser. Set may be empty. +	 * @param logger is the Logger instance to which errors should be logged. +	 * @return a ResourceType specifier. +	 */ +	static ResourceType deduceResourceType(const std::string &rel, +	                                       const RttiSet &supportedTypes, +	                                       Logger &logger); + +	/** +	 * Function used to deduce the resource type from a given "relation" string. +	 * +	 * @param rel is a relation string which specifies the type of the resource. +	 * May be empty. +	 * @param logger is the Logger instance to which errors should be logged +	 * (e.g. if the relation string is invalid). +	 * @return a ResourceType specifier. +	 */ +	static ResourceType deduceResourceType(const std::string &rel, +	                                       Logger &logger); + +	/** +	 * Function used to deduce the resource type from a set of RTTI types into +	 * which the resource should be converted by a parser. +	 * +	 * @param supportedTypes is a set of RTTI types into which the resource +	 * should be converted by a parser. Set may be empty. +	 * @param logger is the Logger instance to which errors should be logged. +	 * @return a ResourceType specifier. +	 */ +	static ResourceType deduceResourceType(const RttiSet &supportedTypes, +	                                       Logger &logger); + +	/** +	 * Transforms the given relation string to the corresponding RttiType. +	 * +	 * @param rel is a relation string which specifies the type of the resource. +	 * May be empty. +	 * @return a pointer at the corresponding Rtti instance or a pointer at the +	 * Rtti descriptor of the Node class (the most general Node type) if the +	 * given relation type is unknown. +	 */ +	static const Rtti *deduceRttiType(const std::string &rel); + +	/** +	 * Reduces the number of types supported by a parser as the type of a +	 * resource to the intersection of the given supported types and the RTTI +	 * type associated with the given relation string. +	 * +	 * @param supportedTypes is a set of RTTI types into which the resource +	 * should be converted by a parser. Set may be empty. +	 * @param rel is a relation string which specifies the type of the resource. +	 * @return the supported type set limited to those types that can actually +	 * be returned according to the given relation string. +	 */ +	static RttiSet limitRttiTypes(const RttiSet &supportedTypes, +	                              const std::string &rel); + +	/** +	 * Reduces the number of types supported by a parser as the type of a +	 * resource to the intersection of the given supported types and the RTTI +	 * type associated with the given relation string. +	 * +	 * @param supportedTypes is a set of RTTI types into which the resource +	 * should be converted by a parser. Set may be empty. +	 * @param type is the type that is to be expected from the parser. +	 * @return the supported type set limited to those types that can actually +	 * be returned according to the given relation string (form an isa +	 * relationship with the given type). +	 */ +	static RttiSet limitRttiTypes(const RttiSet &supportedTypes, +	                              const Rtti *type); +}; +} + +#endif /* _OUSIA_RESOURCE_UTILS_HPP_ */ + | 
