summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/Registry.cpp47
-rw-r--r--src/core/Registry.hpp21
-rw-r--r--src/core/resource/Resource.cpp46
-rw-r--r--src/core/resource/Resource.hpp144
-rw-r--r--src/core/resource/ResourceLocator.cpp103
-rw-r--r--src/core/resource/ResourceLocator.hpp194
-rw-r--r--src/plugins/boost/FileLocator.cpp49
-rw-r--r--src/plugins/boost/FileLocator.hpp50
-rw-r--r--test/core/RegistryTest.cpp48
-rw-r--r--test/core/parser/StandaloneParserContext.hpp6
-rw-r--r--test/core/resource/ResourceLocatorTest.cpp53
-rw-r--r--test/plugins/boost/FileLocatorTest.cpp89
12 files changed, 607 insertions, 243 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_ */
diff --git a/src/plugins/boost/FileLocator.cpp b/src/plugins/boost/FileLocator.cpp
index 3db214f..9ab398e 100644
--- a/src/plugins/boost/FileLocator.cpp
+++ b/src/plugins/boost/FileLocator.cpp
@@ -18,46 +18,55 @@
#include "FileLocator.hpp"
+#include <boost/filesystem.hpp>
+
#include <fstream>
namespace ousia {
-void FileLocator::addSearchPath(const boost::filesystem::path &path,
- std::set<ResourceLocator::Type> types)
+void FileLocator::addSearchPath(const std::string &path,
+ std::set<ResourceType> types)
{
+ // Canonicalize the given path
+ std::string canonicalPath =
+ boost::filesystem::canonical(path).generic_string();
+
+ // Insert the path for all given types.
for (auto &type : types) {
- // retrieve the path vector for the given type.
auto it = searchPaths.find(type);
if (it != searchPaths.end()) {
- it->second.push_back(path);
+ it->second.push_back(canonicalPath);
} else {
- std::vector<boost::filesystem::path> v{path};
- searchPaths.insert({type, v});
+ searchPaths.insert({type, {canonicalPath}});
}
}
}
-ResourceLocator::Location FileLocator::locate(const std::string &path,
- const std::string &relativeTo,
- const Type type) const
+bool FileLocator::doLocate(Resource &resource, const std::string &path,
+ const ResourceType type,
+ const std::string &relativeTo) const
{
boost::filesystem::path base(relativeTo);
if (boost::filesystem::exists(base)) {
- // look if 'relativeTo' is a directory already.
+ // Look if 'relativeTo' is a directory already.
if (!boost::filesystem::is_directory(base)) {
- // if not we use the parent directory.
+ // If not we use the parent directory.
base = base.parent_path();
}
- // use the / operator to append the path.
+
+ // Use the / operator to append the path.
base /= path;
- // if we already found a fitting resource there, use that.
+
+ // If we already found a fitting resource there, use that.
if (boost::filesystem::exists(base)) {
std::string location =
boost::filesystem::canonical(base).generic_string();
- return ResourceLocator::Location(true, *this, type, location);
+ resource = Resource(true, *this, type, location);
+ return true;
}
}
- // otherwise look in the search paths.
+
+ // Otherwise look in the search paths.
auto it = searchPaths.find(type);
if (it != searchPaths.end()) {
for (boost::filesystem::path p : it->second) {
@@ -65,17 +74,15 @@ ResourceLocator::Location FileLocator::locate(const std::string &path,
if (boost::filesystem::exists(p)) {
std::string location =
boost::filesystem::canonical(p).generic_string();
- return ResourceLocator::Location(true, *this, type, location);
+ resource = Resource(true, *this, type, location);
+ return true;
}
}
}
- // if we find the resource in none of the search paths we return a location.
- // with the found flag set to false.
- ResourceLocator::Location l(false, *this, type, "");
- return l;
+ return false;
}
-std::unique_ptr<std::istream> FileLocator::stream(
+std::unique_ptr<std::istream> FileLocator::doStream(
const std::string &location) const
{
std::unique_ptr<std::istream> ifs{new std::ifstream(location)};
diff --git a/src/plugins/boost/FileLocator.hpp b/src/plugins/boost/FileLocator.hpp
index 9cb705c..ffe5c8f 100644
--- a/src/plugins/boost/FileLocator.hpp
+++ b/src/plugins/boost/FileLocator.hpp
@@ -19,15 +19,13 @@
#ifndef _OUSIA_FILE_LOCATOR_HPP_
#define _OUSIA_FILE_LOCATOR_HPP_
-#include <core/ResourceLocator.hpp>
+#include <core/resource/Resource.hpp>
+#include <core/resource/ResourceLocator.hpp>
#include <map>
#include <set>
#include <vector>
-#include <boost/filesystem.hpp>
-
-
namespace ousia {
/**
@@ -39,8 +37,25 @@ namespace ousia {
* locations (e.g. online resources, .zip files, etc.).
*/
class FileLocator : public ResourceLocator {
+public:
+ /**
+ * Type alias representing a Res
+ */
+ using SearchPaths = std::map<ResourceType, std::vector<std::string>>;
+
private:
- std::map<ResourceLocator::Type, std::vector<boost::filesystem::path>> searchPaths;
+ /**
+ * Internal variable containing all stored search paths.
+ */
+ SearchPaths searchPaths;
+
+protected:
+ bool doLocate(Resource &resource, const std::string &path,
+ const ResourceType type,
+ const std::string &relativeTo) const override;
+
+ std::unique_ptr<std::istream> doStream(
+ const std::string &location) const override;
public:
FileLocator() : searchPaths() {}
@@ -53,24 +68,23 @@ public:
* resources of the specified types at the given path in the
* future.
*/
- void addSearchPath(const boost::filesystem::path &path,
- std::set<ResourceLocator::Type> types);
+ void addSearchPath(const std::string &path, std::set<ResourceType> types);
+
+ /**
+ * Adds a search path. Implicitly adds the search path for the "unknown"
+ *
+ * @param path is a fully qualified/canonical path to a directory.
+ * @param types is a set of Resource Types. The FileLocator will look for
+ * resources of the specified types at the given path in the
+ * future.
+ */
+ void addSearchPath(const std::string &path);
/**
* Returns the backing map containing all search paths for a given type.
* This is read-only.
*/
- const std::map<ResourceLocator::Type, std::vector<boost::filesystem::path>> &
- getSearchPaths() const
- {
- return searchPaths;
- }
-
- Location locate(const std::string &path, const std::string &relativeTo,
- const Type type) const override;
-
- std::unique_ptr<std::istream> stream(
- const std::string &location) const override;
+ const SearchPaths &getSearchPaths() const { return searchPaths; }
};
}
diff --git a/test/core/RegistryTest.cpp b/test/core/RegistryTest.cpp
index 8280188..45e09d3 100644
--- a/test/core/RegistryTest.cpp
+++ b/test/core/RegistryTest.cpp
@@ -18,46 +18,26 @@
#include <gtest/gtest.h>
-#include <core/Registry.hpp>
-
#include <sstream>
-#include <core/common/Logger.hpp>
+#include <core/resource/ResourceLocator.hpp>
+#include <core/Registry.hpp>
namespace ousia {
-class TestResourceLocator : public ResourceLocator {
-public:
- ResourceLocator::Location locate(
- const std::string &path, const std::string &relativeTo,
- const ResourceLocator::Type type) const override
- {
- // trivial test implementation.
- return ResourceLocator::Location(true, *this, type, path);
- }
-
- std::unique_ptr<std::istream> stream(
- const std::string &location) const override
- {
- // trivial test implementation.
- std::unique_ptr<std::stringstream> ss(new std::stringstream());
- (*ss) << "test";
- return std::move(ss);
- }
-};
-
TEST(Registry, locateResource)
{
- TestResourceLocator locator;
- Logger logger;
- Registry instance {logger};
- instance.registerResourceLocator(&locator);
-
- ResourceLocator::Location location =
- instance.locateResource("path", "", ResourceLocator::Type::DOMAIN_DESC);
- ASSERT_TRUE(location.found);
- ASSERT_EQ(ResourceLocator::Type::DOMAIN_DESC, location.type);
- ASSERT_EQ("path", location.location);
+ StaticResourceLocator locator;
+ locator.store("path", "test");
+
+ Registry registry;
+ registry.registerResourceLocator(locator);
+
+ Resource res;
+ ASSERT_TRUE(
+ registry.locateResource(res, "path", ResourceType::DOMAIN_DESC));
+ ASSERT_TRUE(res.isValid());
+ ASSERT_EQ(ResourceType::DOMAIN_DESC, res.getType());
+ ASSERT_EQ("path", res.getLocation());
}
-
}
diff --git a/test/core/parser/StandaloneParserContext.hpp b/test/core/parser/StandaloneParserContext.hpp
index aca056e..347d34f 100644
--- a/test/core/parser/StandaloneParserContext.hpp
+++ b/test/core/parser/StandaloneParserContext.hpp
@@ -37,15 +37,13 @@ public:
ParserContext context;
StandaloneParserContext()
- : registry(logger),
- project(new model::Project(manager)),
+ : project(new model::Project(manager)),
context(scope, registry, logger, manager, project)
{
}
StandaloneParserContext(Logger &externalLogger)
- : registry(externalLogger),
- project(new model::Project(manager)),
+ : project(new model::Project(manager)),
context(scope, registry, externalLogger, manager, project){};
};
}
diff --git a/test/core/resource/ResourceLocatorTest.cpp b/test/core/resource/ResourceLocatorTest.cpp
index ebb164d..d009883 100644
--- a/test/core/resource/ResourceLocatorTest.cpp
+++ b/test/core/resource/ResourceLocatorTest.cpp
@@ -18,48 +18,31 @@
#include <gtest/gtest.h>
-#include <core/ResourceLocator.hpp>
-
-#include <sstream>
+#include <core/resource/ResourceLocator.hpp>
namespace ousia {
-class TestResourceLocator : public ResourceLocator {
-public:
- ResourceLocator::Location locate(
- const std::string &path, const std::string &relativeTo,
- const ResourceLocator::Type type) const override
- {
- // trivial test implementation.
- return ResourceLocator::Location(true, *this, type, path);
- }
-
- std::unique_ptr<std::istream> stream(
- const std::string &location) const override
- {
- // trivial test implementation.
- std::unique_ptr<std::stringstream> ss(new std::stringstream());
- (*ss) << "test";
- return std::move(ss);
- }
-};
-
-TEST(ResourceLocator, locate)
+TEST(StaticResourceLocator, locate)
{
- TestResourceLocator instance;
- ResourceLocator::Location location =
- instance.locate("path", "", ResourceLocator::Type::DOMAIN_DESC);
- ASSERT_TRUE(location.found);
- ASSERT_EQ(ResourceLocator::Type::DOMAIN_DESC, location.type);
- ASSERT_EQ("path", location.location);
+ StaticResourceLocator locator;
+ locator.store("path", "test");
+
+ Resource res;
+ ASSERT_TRUE(locator.locate(res, "path"));
+ ASSERT_TRUE(res.isValid());
+ ASSERT_EQ(ResourceType::UNKNOWN, res.getType());
+ ASSERT_EQ("path", res.getLocation());
}
-TEST(ResourceLocator, stream)
+TEST(StaticResourceLocator, stream)
{
- TestResourceLocator instance;
- ResourceLocator::Location location =
- instance.locate("path", "", ResourceLocator::Type::DOMAIN_DESC);
- std::unique_ptr<std::istream> is = location.stream();
+ StaticResourceLocator locator;
+ locator.store("path", "test");
+
+ Resource res;
+ ASSERT_TRUE(locator.locate(res, "path"));
+
+ auto is = res.stream();
std::string str;
*is >> str;
diff --git a/test/plugins/boost/FileLocatorTest.cpp b/test/plugins/boost/FileLocatorTest.cpp
index 2057a9f..473b15e 100644
--- a/test/plugins/boost/FileLocatorTest.cpp
+++ b/test/plugins/boost/FileLocatorTest.cpp
@@ -20,67 +20,75 @@
#include <plugins/boost/FileLocator.hpp>
+#include <boost/filesystem.hpp>
+
namespace ousia {
TEST(FileLocator, testAddSearchPath)
{
FileLocator instance;
- ASSERT_EQ(0, instance.getSearchPaths().size());
+ ASSERT_EQ(0U, instance.getSearchPaths().size());
+
+ // Read the canonical path of "."
+ std::string canonicalPath =
+ boost::filesystem::canonical(".").generic_string();
// Add one path for three types.
- instance.addSearchPath(
- ".", {ResourceLocator::Type::DOMAIN_DESC, ResourceLocator::Type::SCRIPT,
- ResourceLocator::Type::TYPESYS});
+ instance.addSearchPath(".",
+ {ResourceType::DOMAIN_DESC, ResourceType::SCRIPT,
+ ResourceType::TYPESYSTEM});
- ASSERT_EQ(3, instance.getSearchPaths().size());
+ ASSERT_EQ(3U, instance.getSearchPaths().size());
- auto it =
- instance.getSearchPaths().find(ResourceLocator::Type::DOMAIN_DESC);
+ auto it = instance.getSearchPaths().find(ResourceType::DOMAIN_DESC);
- ASSERT_EQ(1, it->second.size());
- ASSERT_EQ(".", it->second[0].generic_string());
+ ASSERT_EQ(1U, it->second.size());
+ ASSERT_EQ(canonicalPath, it->second[0]);
- it = instance.getSearchPaths().find(ResourceLocator::Type::SCRIPT);
+ it = instance.getSearchPaths().find(ResourceType::SCRIPT);
- ASSERT_EQ(1, it->second.size());
- ASSERT_EQ(".", it->second[0].generic_string());
+ ASSERT_EQ(1U, it->second.size());
+ ASSERT_EQ(canonicalPath, it->second[0]);
- it = instance.getSearchPaths().find(ResourceLocator::Type::TYPESYS);
+ it = instance.getSearchPaths().find(ResourceType::TYPESYSTEM);
- ASSERT_EQ(1, it->second.size());
- ASSERT_EQ(".", it->second[0].generic_string());
+ ASSERT_EQ(1U, it->second.size());
+ ASSERT_EQ(canonicalPath, it->second[0]);
// Add another path for only one of those types.
- instance.addSearchPath("..", {ResourceLocator::Type::DOMAIN_DESC});
+ std::string canonicalPath2 =
+ boost::filesystem::canonical("..").generic_string();
+
+ instance.addSearchPath("..", {ResourceType::DOMAIN_DESC});
- ASSERT_EQ(3, instance.getSearchPaths().size());
+ ASSERT_EQ(3U, instance.getSearchPaths().size());
- it = instance.getSearchPaths().find(ResourceLocator::Type::DOMAIN_DESC);
+ it = instance.getSearchPaths().find(ResourceType::DOMAIN_DESC);
- ASSERT_EQ(2, it->second.size());
- ASSERT_EQ(".", it->second[0].generic_string());
- ASSERT_EQ("..", it->second[1].generic_string());
+ ASSERT_EQ(2U, it->second.size());
+ ASSERT_EQ(canonicalPath, it->second[0]);
+ ASSERT_EQ(canonicalPath2, it->second[1]);
}
-void assert_located(
- const FileLocator &instance, const std::string &path,
- const std::string &relativeTo,
- ResourceLocator::Type type = ResourceLocator::Type::DOMAIN_DESC)
+void assert_located(const FileLocator &instance, const std::string &path,
+ const std::string &relativeTo,
+ ResourceType type = ResourceType::DOMAIN_DESC)
{
- ResourceLocator::Location loc = instance.locate(path, relativeTo, type);
- ASSERT_TRUE(loc.found);
- boost::filesystem::path p(loc.location);
+ Resource res;
+ ASSERT_TRUE(instance.locate(res, path, type, relativeTo));
+ ASSERT_TRUE(res.isValid());
+ boost::filesystem::path p(res.getLocation());
ASSERT_TRUE(boost::filesystem::exists(p));
ASSERT_EQ(path, p.filename());
}
-void assert_not_located(
- const FileLocator &instance, const std::string &path,
- const std::string &relativeTo,
- ResourceLocator::Type type = ResourceLocator::Type::DOMAIN_DESC)
+void assert_not_located(const FileLocator &instance, const std::string &path,
+ const std::string &relativeTo,
+ ResourceType type = ResourceType::DOMAIN_DESC)
{
- ResourceLocator::Location loc = instance.locate(path, relativeTo, type);
- ASSERT_FALSE(loc.found);
+ Resource res;
+ ASSERT_FALSE(instance.locate(res, path, type, relativeTo));
+ ASSERT_FALSE(res.isValid());
}
TEST(FileLocator, testLocate)
@@ -106,14 +114,14 @@ TEST(FileLocator, testLocate)
assert_not_located(instance, "FileLocator.hpp", relativeTo);
// Add the respective search path.
- instance.addSearchPath(start / "src/plugins/boost",
- {ResourceLocator::Type::DOMAIN_DESC});
+ instance.addSearchPath((start / "src/plugins/boost").generic_string(),
+ {ResourceType::DOMAIN_DESC});
// Now we should be able to find both.
assert_located(instance, "CMakeLists.txt", relativeTo);
assert_located(instance, "FileLocator.hpp", relativeTo);
// but only with the correct type.
assert_not_located(instance, "FileLocator.hpp", relativeTo,
- ResourceLocator::Type::SCRIPT);
+ ResourceType::SCRIPT);
}
TEST(FileLocator, testStream)
@@ -133,10 +141,11 @@ TEST(FileLocator, testStream)
}
FileLocator instance;
// Locate the CMakeLists.txt
- ResourceLocator::Location loc = instance.locate(
- "CMakeLists.txt", relativeTo, ResourceLocator::Type::DOMAIN_DESC);
+ Resource res;
+ instance.locate(res, "CMakeLists.txt", ResourceType::DOMAIN_DESC,
+ relativeTo);
// Stream the content.
- auto is_ptr = loc.stream();
+ auto is_ptr = res.stream();
// get the beginning.
char buf[256];
is_ptr->getline(buf, 256);