diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/Registry.cpp | 47 | ||||
| -rw-r--r-- | src/core/Registry.hpp | 21 | ||||
| -rw-r--r-- | src/core/resource/Resource.cpp | 46 | ||||
| -rw-r--r-- | src/core/resource/Resource.hpp | 144 | ||||
| -rw-r--r-- | src/core/resource/ResourceLocator.cpp | 103 | ||||
| -rw-r--r-- | src/core/resource/ResourceLocator.hpp | 194 | 
6 files changed, 464 insertions, 91 deletions
| diff --git a/src/core/Registry.cpp b/src/core/Registry.cpp index 74d1cf8..b714241 100644 --- a/src/core/Registry.cpp +++ b/src/core/Registry.cpp @@ -16,8 +16,11 @@      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ -#include <core/common/Logger.hpp>  #include <core/parser/Parser.hpp> +#include <core/resource/Resource.hpp> +#include <core/resource/ResourceLocator.hpp> + +#include "Registry.hpp"  namespace ousia { @@ -25,9 +28,9 @@ using namespace parser;  /* Class Registry */ -void Registry::registerParser(parser::Parser *parser) +void Registry::registerParser(parser::Parser &parser)  { -	parsers.push_back(parser); +	parsers.push_back(&parser);  	for (const auto &mime : parser->mimetypes()) {  		//TODO: This does not allow for multiple parsers with the same mimetype.  		// Is that how its supposed to be? @@ -44,24 +47,40 @@ Parser *Registry::getParserForMimetype(const std::string &mimetype) const  	return nullptr;  } -void Registry::registerResourceLocator(ResourceLocator *locator) +void Registry::registerResourceLocator(ResourceLocator &locator)  { -	locators.push_back(locator); +	locators.push_back(&locator);  } -ResourceLocator::Location Registry::locateResource( -    const std::string &path, const std::string &relativeTo, -    ResourceLocator::Type type) const +bool Registry::locateResource(Resource &resource, const std::string &path, +                              ResourceType type, +                              const Resource &relativeTo) const  { -	ResourceLocator::Location *last; +	// Try the locator of the given "relativeTo" resource first +	if (relativeTo.isValid()) { +		if (relativeTo.getLocator().locate(resource, path, type, relativeTo)) { +			return true; +		} +	} + +	// Iterate over all registered locators and try to resolve the given path  	for (auto &locator : locators) { -		ResourceLocator::Location loc = locator->locate(path, relativeTo, type); -		if (loc.found) { -			return loc; +		if (locator->locate(resource, path, type, relativeTo)) { +			return true;  		} -		last = &loc;  	} -	return *last; + +	// If this did not work out, retry but use the UNKNOWN type. +	if (type != ResourceType::UNKNOWN) { +		for (auto &locator : locators) { +			if (locator->locate(resource, path, ResourceType::UNKNOWN, +			                    relativeTo)) { +				return true; +			} +		} +	} + +	return false;  }  } diff --git a/src/core/Registry.hpp b/src/core/Registry.hpp index 01d57e8..40eede1 100644 --- a/src/core/Registry.hpp +++ b/src/core/Registry.hpp @@ -22,37 +22,34 @@  #include <map>  #include <vector> -#include "ResourceLocator.hpp" +#include <core/resource/Resource.hpp>  namespace ousia {  // TODO: Add support for ScriptEngine type -class Logger; -  namespace parser {  class Parser;  } +class ResourceLocator;  class Registry {  private: -	Logger &logger;  	std::vector<parser::Parser *> parsers;  	std::map<std::string, parser::Parser *> parserMimetypes; +  	std::vector<ResourceLocator *> locators;  public: -	Registry(Logger &logger) : logger(logger) {} - -	void registerParser(parser::Parser *parser); +	void registerParser(parser::Parser &parser); -	parser::Parser *getParserForMimetype(const std::string& mimetype) const; +	parser::Parser *getParserForMimetype(const std::string &mimetype) const; -	void registerResourceLocator(ResourceLocator *locator); +	void registerResourceLocator(ResourceLocator &locator); -	ResourceLocator::Location locateResource(const std::string &path, -	                                         const std::string &relativeTo, -	                                         ResourceLocator::Type type) const; +	bool locateResource(Resource &resource, const std::string &path, +	                    ResourceType type = ResourceType::UNKNOWN, +	                    const Resource &relativeTo = NullResource) const;  };  } diff --git a/src/core/resource/Resource.cpp b/src/core/resource/Resource.cpp index e69de29..349c82a 100644 --- a/src/core/resource/Resource.cpp +++ b/src/core/resource/Resource.cpp @@ -0,0 +1,46 @@ +/* +    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 "Resource.hpp" +#include "ResourceLocator.hpp" + +namespace ousia { + +/* Class Resource */ + +Resource::Resource() +    : Resource(false, NullResourceLocator, ResourceType::UNKNOWN, "") +{ +} + +Resource::Resource(bool valid, const ResourceLocator &locator, +                   ResourceType type, const std::string &location) +    : valid(valid), locator(&locator), type(type), location(location) +{ +} + +std::unique_ptr<std::istream> Resource::stream() const +{ +	return locator->stream(location); +} + +/* NullResource instance */ + +const Resource NullResource{}; +} + diff --git a/src/core/resource/Resource.hpp b/src/core/resource/Resource.hpp index 9df851d..1934029 100644 --- a/src/core/resource/Resource.hpp +++ b/src/core/resource/Resource.hpp @@ -22,15 +22,159 @@   * Contains the Resource class, representing an external resource as well as   * further types used for describing resources.   * + * @author Benjamin Paaßen (bpassen@techfak.uni-bielefeld.de)   */  #ifndef _OUSIA_RESOURCE_HPP_  #define _OUSIA_RESOURCE_HPP_ +#include <map> +#include <memory> +#include <string> +  namespace ousia { +// Forward declaration +class ResourceLocator; + +/** + * This enum contains all possible types of includable resources in Ousía. + */ +enum class ResourceType { +	/** +     * Unknown type. +     */ +	UNKNOWN, + +	/** +     * The resource contains a domain description. +     */ +	DOMAIN_DESC, + +	/** +     * The resource contains a typesystem description. +     */ +	TYPESYSTEM, + +	/** +     * The resource contains a simple document. +     */ +	DOCUMENT, +	/** +     * The resource contains style attributes. +     */ +	ATTRIBUTES, + +	/** +     * The resource is a stylesheet. +     */ +	STYLESHEET, + +	/** +     * The resource contains script (note that the actual scripting language is +     * not specified by the resource type). +     */ +	SCRIPT, + +	/** +     * Generic data, such as e.g. images. +     */ +	DATA +}; + +/** + * A Location contains the location of a Resource, e.g. a file path + * on a hard drive. Note that the 'found' flag might be set to false + * indicating that a resource was not found. + */ +class Resource { +private: +	/** +	 * Specifies whether the resource points at a valid location or not. +	 */ +	bool valid; +	/** +	 * Reference pointing at the location +	 */ +	ResourceLocator const *locator; + +	/** +	 * Requested type of the resource. +	 */ +	ResourceType type; + +	/** +	 * This is a fully qualified/canonical path to the resource found or +	 * in an undefined state (possibly empty) if the 'valid' flag is set +	 * to 'false'. +	 */ +	std::string location; + +public: +	/** +	 * Default constructor of the Resource class, represents an invalid +	 * resource. +	 */ +	Resource(); + +	/** +	 * Constructor of the Resource class. +	 * +	 * @param valid specifies whether the Resource is valid or not. +	 * @param locator specifies the resource locator that was used to locate the +	 * resource. +	 */ +	Resource(bool valid, const ResourceLocator &locator, +	         ResourceType type, const std::string &location); + +	/** +	 * This calls the 'stream' method of the underlying ResourceLocator that +	 * found this location and returns a stream containing the data of the +	 * Resource at this location. +	 * +	 * @return a stream containing the data of the Resource at this +	 *         location. This has to be a unique_pointer because the current +	 *         C++11 compiler does not yet support move semantics for +	 *         streams. +	 */ +	std::unique_ptr<std::istream> stream() const; + +	/** +	 * Returns whether this resource is valid or not. +	 * +	 * @return true if the resource is valid, false otherwise. +	 */ +	bool isValid() const { return valid; } + +	/** +	 * Returns a reference pointing at the locator that was used to locate this +	 * resource. +	 * +	 * @return the locator used for locating this resource. +	 */ +	const ResourceLocator &getLocator() const { return *locator; } + +	/** +	 * Returns the type of the resource that was requested when the resource was +	 * located. +	 * +	 * @return the type of the resource. +	 */ +	ResourceType getType() const { return type; } + +	/** +	 * Returns a canonical location that can be used in a hash map to identify +	 * a resource. +	 */ +	const std::string &getLocation() const { return location; } +}; + +/** + * Invalid resource instance. + */ +extern const Resource NullResource;  }  #endif /* _OUSIA_RESOURCE_HPP_ */ diff --git a/src/core/resource/ResourceLocator.cpp b/src/core/resource/ResourceLocator.cpp index e69de29..1b8490d 100644 --- a/src/core/resource/ResourceLocator.cpp +++ b/src/core/resource/ResourceLocator.cpp @@ -0,0 +1,103 @@ +/* +    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 <sstream> + +#include "Resource.hpp" +#include "ResourceLocator.hpp" + +namespace ousia { + +/* Class ResourceLocator */ + +bool ResourceLocator::locate(Resource &resource, const std::string &path, +                             const ResourceType type, +                             const Resource &relativeTo) const +{ +	if (&relativeTo.getLocator() == this) { +		return doLocate(resource, path, type, relativeTo.getLocation()); +	} +	return doLocate(resource, path, type, ""); +} + +bool ResourceLocator::locate(Resource &resource, const std::string &path, +                             const ResourceType type, +                             const std::string &relativeTo) const +{ +	return doLocate(resource, path, type, relativeTo); +} + +std::unique_ptr<std::istream> ResourceLocator::stream( +    const std::string &location) const +{ +	return doStream(location); +} + +/* Class StaticResourceLocator */ + +bool StaticResourceLocator::doLocate( +    Resource &resource, const std::string &path, const ResourceType type, +    const std::string &relativeTo) const +{ +	auto it = resources.find(path); +	if (it != resources.end()) { +		resource = Resource(true, *this, type, path); +		return true; +	} +	return false; +} + +std::unique_ptr<std::istream> StaticResourceLocator::doStream( +    const std::string &location) const +{ +	auto it = resources.find(location); +	if (it != resources.end()) { +		return std::unique_ptr<std::istream>{new std::stringstream{it->second}}; +	} +	return std::unique_ptr<std::istream>{new std::stringstream{""}}; +} + +void StaticResourceLocator::store(const std::string &path, +                                  const std::string &data) +{ +	auto it = resources.find(path); +	if (it != resources.end()) { +		it->second = data; +	} else { +		resources.emplace(path, data); +	} +} + +/* Class NullResourceLocatorImpl */ + +bool NullResourceLocatorImpl::doLocate(Resource &resource, +                                       const std::string &path, +                                       const ResourceType type, +                                       const std::string &relativeTo) const +{ +	return false; +} +std::unique_ptr<std::istream> NullResourceLocatorImpl::doStream( +    const std::string &location) const +{ +	return std::unique_ptr<std::istream>{new std::stringstream{""}}; +} + +const NullResourceLocatorImpl NullResourceLocator; +} + diff --git a/src/core/resource/ResourceLocator.hpp b/src/core/resource/ResourceLocator.hpp index 39c7b30..c1d0807 100644 --- a/src/core/resource/ResourceLocator.hpp +++ b/src/core/resource/ResourceLocator.hpp @@ -22,8 +22,13 @@  #include <istream>  #include <memory> +#include "Resource.hpp" +  namespace ousia { +// Forward declaration +class ResourceLocator; +  /**   * A ResourceLocator is a class able to locate resources in some way, usually   * on the hard drive. @@ -33,84 +38,82 @@ namespace ousia {   * locations (e.g. online resources, .zip files, etc.).   */  class ResourceLocator { -public: +protected:  	/** -	 * This enum contains all possible types of includable resources in Ousía. +	 * The locate function uses this ResourceLocator to search for a given +	 * Resource name (path parameter). It returns a Location with the +	 * 'valid' flag set accordingly. +	 * +	 * @param resource reference to a Resource the will be set the the found +	 * location. The content of the variable will be only valid if the return +	 * value of this function is set to true. +	 * @param path is the resource name. +	 * @param relativeTo is an already resolved fully qualified name/canonical +	 * path that is to be used as base directory for this search. It is +	 * guaranteed that the path was produced by this locator instance. Otherwise +	 * this argument is set to an empty string. +	 * @param type is the type of this resource. +	 * @return true if a resource could be found, false otherwise. +	 */ +	virtual bool doLocate(Resource &resource, const std::string &path, +	                      const ResourceType type, +	                      const std::string &relativeTo) const = 0; + +	/** +	 * This method returns a stream containing the data of the resource at the +	 * given location. +	 * +	 * @param location is a found location, most likely from a Location. +	 * +	 * @return a stream containing the data of the Resource at this +	 *         location. This has to be a unique_pointer because the current +	 *         C++11 compiler does not yet support move semantics for +	 *         streams.  	 */ -	enum class Type { -		// A Domain description -		DOMAIN_DESC, -		// An ECMA/JavaScript -		SCRIPT, -		// A Type System -		TYPESYS, -		DOCUMENT, -		ATTRIBUTES, -		// TODO: Aren't documents and attribute descriptors missing? -		// TODO: What is the purpose of these two? -		GENERIC_MODULE, -		GENERIC_INCLUDE -	}; +	virtual std::unique_ptr<std::istream> doStream( +	    const std::string &location) const = 0; +public:  	/** -	 * A Location contains the location of a Resource, e.g. a file path -	 * on a hard drive. Note that the 'found' flag might be set to false -	 * indicating that a resource was not found. +	 * Virtual destructor of the ResourceLocator interface.  	 */ -	struct Location { -		const bool found; -		const ResourceLocator &locator; -		const Type type; -		/** -		 * This is a fully qualified/canonical path to the resource found or -		 * in an undefined state (possibly empty) if the 'found' flag is set -		 * to 'false'. -		 */ -		const std::string location; - -		Location(const bool found, const ResourceLocator &locator, -		         const Type type, const std::string location) -		    : found(found), locator(locator), type(type), location(location) -		{ -		} - -		/** -		 * This calls the 'stream' method of the underlying ResourceLocator that -		 * found this location and returns a stream containing the data of the -		 * Resource at this location. -		 * -		 * @return a stream containing the data of the Resource at this -		 *         location. This has to be a unique_pointer because the current -		 *         C++11 compiler does not yet support move semantics for -		 *         streams. -		 */ -		std::unique_ptr<std::istream> stream() const -		{ -			return std::move(locator.stream(location)); -		} -	}; +	virtual ~ResourceLocator() {}  	/**  	 * The locate function uses this ResourceLocator to search for a given -	 * Resource name (path parameter). It returns a Location with the -	 * 'found' flag set accordingly. +	 * Resource name (path parameter).  	 * +	 * @param resource reference to a Resource the will be set the the found +	 * location. The content of the variable will be only valid if the return +	 * value of this function is set to true.  	 * @param path is the resource name. -	 * @param relativeTo is an already resolved fully qualified name/canonical -	 *                   path that is to be used as base directory for this -	 *                   search. +	 * @param relativeTo is an already resolved Resource.  	 * @param type is the type of this resource. +	 * @return true if a resource could be found, false otherwise. +	 */ +	bool locate(Resource &resource, const std::string &path, +	            const ResourceType type = ResourceType::UNKNOWN, +	            const Resource &relativeTo = NullResource) const; + +	/** +	 * The locate function uses this ResourceLocator to search for a given +	 * Resource name (path parameter).  	 * -	 * @return A Location containing either the found location of the -	 *         Resource and the found flag set to 'true' or an empty location -	 *         and the found flag set to 'false'. +	 * @param resource reference to a Resource the will be set the the found +	 * location. The content of the variable will be only valid if the return +	 * value of this function is set to true. +	 * @param path is the resource name. +	 * @param type is the type of this resource. +	 * @param relativeTo is the location of an already resolved resource +	 * relative to which this resource should be located. +	 * @return true if a resource could be found, false otherwise.  	 */ -	virtual Location locate(const std::string &path, -	                        const std::string &relativeTo, -	                        const Type type) const = 0; +	bool locate(Resource &resource, const std::string &path, +	            const ResourceType type, +	            const std::string &relativeTo) const;  	/** -	 * This method returns a strem containing the data of the resource at the +	 * This method returns a stream containing the data of the resource at the  	 * given location.  	 *  	 * @param location is a found location, most likely from a Location. @@ -120,9 +123,70 @@ public:  	 *         C++11 compiler does not yet support move semantics for  	 *         streams.  	 */ -	virtual std::unique_ptr<std::istream> stream( -	    const std::string &location) const = 0; +	std::unique_ptr<std::istream> stream(const std::string &location) const;	 +}; + +/** + * The StaticResourceLocator class stores a set of predefined resources in + * memory and allows to return these. + */ +class StaticResourceLocator : public ResourceLocator { +private: +	/** +	 * Map containing the paths and the corresponding stored data. +	 */ +	std::map<std::string, std::string> resources; + +protected: +	/** +	 * Always returns false. +	 */ +	bool doLocate(Resource &resource, const std::string &path, +	              const ResourceType type, +	              const std::string &relativeTo) const override; + +	/** +	 * Returns an input stream containing an empty string. +	 */ +	std::unique_ptr<std::istream> doStream( +	    const std::string &location) const override; + +public: +	/** +	 * Stores static (string) data for the given path. +	 * +	 * @param path is the path the resource should be stored with. +	 * @param data is the data that should be stored for that path. +	 */ +	void store(const std::string &path, const std::string &data);  }; + +/** + * Implementation of the NullResourceLocator - contains a default implementation + * of the ResourceLocator class that does nothing. This class is e.g. used in + * the default constructor of the resource class. A instance of the class is + * provided as "NullResourceLocator". + */ +class NullResourceLocatorImpl : public ResourceLocator { +protected: +	/** +	 * Always returns false. +	 */ +	bool doLocate(Resource &resource, const std::string &path, +	              const ResourceType type, +	              const std::string &relativeTo) const override; + +	/** +	 * Returns an input stream containing an empty string. +	 */ +	std::unique_ptr<std::istream> doStream( +	    const std::string &location) const override; +}; + +/** + * The NullResourceLocator is used as a fallback for invalid Resources. + */ +extern const NullResourceLocatorImpl NullResourceLocator;  }  #endif /* _RESOURCE_LOCATOR_HPP_ */ | 
