aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2014-06-25 20:23:35 +0200
committerAdrian Kummerlaender2014-06-25 20:23:35 +0200
commit7b872121000d4db4026d0c90fcb95a10f1e43694 (patch)
treed1cea19c4556b3574978f51bdf2bed2d36fbb73f
parent0d670478b51c55e44f57995fe3ca8a4585723a6c (diff)
downloadInputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.tar
InputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.tar.gz
InputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.tar.bz2
InputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.tar.lz
InputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.tar.xz
InputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.tar.zst
InputXSLT-7b872121000d4db4026d0c90fcb95a10f1e43694.zip
Added support for resolving non-existing paths
* previous logic for resolving boost::filesystem::path parameters in the XObjectValue class actively tried to resolve existing files ** this contradicts the planned introduction of e.g. a external "write-file" function * callers of external functions with path arguments now have to enclose them in square brackets if include path resolution is required ** analog to the usage of the "xsl:import" tag * moved "getPathFromSystemId" from compilation local method into static method of IncludeEntityResolver * changed test cases accordingly
-rw-r--r--src/function/base.h2
-rw-r--r--src/support/include_entity_resolver.cc66
-rw-r--r--src/support/include_entity_resolver.h10
-rw-r--r--src/support/type/xobject_value.cc19
-rw-r--r--test/external_text_formatter/transformation.xsl2
-rw-r--r--test/read_file/transformation.xsl2
-rw-r--r--test/read_xml_file/transformation.xsl2
7 files changed, 54 insertions, 49 deletions
diff --git a/src/function/base.h b/src/function/base.h
index 5aada0e..7c2043e 100644
--- a/src/function/base.h
+++ b/src/function/base.h
@@ -97,7 +97,7 @@ class FunctionBase : public xalan::Function {
Sequence<Index...>
) const {
XObjectValue valueGetter(
- this->include_resolver_->resolve(
+ IncludeEntityResolver::getPathFromSystemId(
locator->getSystemId()
),
this->include_resolver_
diff --git a/src/support/include_entity_resolver.cc b/src/support/include_entity_resolver.cc
index e1c9f96..07577c1 100644
--- a/src/support/include_entity_resolver.cc
+++ b/src/support/include_entity_resolver.cc
@@ -4,35 +4,29 @@
#include "boost/filesystem.hpp"
+#include "support/xalan_string.h"
#include "support/xerces_string_guard.h"
namespace {
-using InputXSLT::XercesStringGuard;
-
-inline boost::filesystem::path getPathFromSystemId(
- const XMLCh* const systemId) {
- return boost::filesystem::path(
- *XercesStringGuard<char>(systemId) + 7
- );
-}
-
-boost::optional<std::string> extractFilePath(const XMLCh* const rawPath) {
- const std::string filePath = *XercesStringGuard<char>(rawPath);
- const std::size_t leadingDelimiter = filePath.find_first_of('[');
- const std::size_t closingDelimiter = filePath.find_last_of(']');
+boost::optional<boost::filesystem::path> extractFilePath(
+ const std::string& rawPath) {
+ const std::size_t leadingDelimiter = rawPath.find_first_of('[');
+ const std::size_t closingDelimiter = rawPath.find_last_of(']');
if ( leadingDelimiter != std::string::npos &&
closingDelimiter != std::string::npos &&
leadingDelimiter < closingDelimiter ) {
return boost::make_optional(
- filePath.substr(
- leadingDelimiter + 1,
- closingDelimiter - leadingDelimiter - 1
+ boost::filesystem::path(
+ rawPath.substr(
+ leadingDelimiter + 1,
+ closingDelimiter - leadingDelimiter - 1
+ )
)
);
} else {
- return boost::optional<std::string>();
+ return boost::optional<boost::filesystem::path>();
}
}
@@ -40,6 +34,13 @@ boost::optional<std::string> extractFilePath(const XMLCh* const rawPath) {
namespace InputXSLT {
+boost::filesystem::path IncludeEntityResolver::getPathFromSystemId(
+ const XMLCh* const systemId) {
+ return boost::filesystem::path(
+ *XercesStringGuard<char>(systemId) + 7
+ );
+}
+
IncludeEntityResolver::IncludeEntityResolver(
const std::vector<std::string>& path):
path_(path.begin(), path.end()) { }
@@ -49,36 +50,45 @@ xercesc::InputSource* IncludeEntityResolver::resolveEntity(
const XMLCh* const systemId
) {
if ( systemId != nullptr ) {
- return new xercesc::LocalFileInputSource(
- *XercesStringGuard<XMLCh>(this->resolve(systemId).string())
+ const std::string systemIdString(
+ *XercesStringGuard<char>(systemId)
);
+
+ if ( auto resolvedPath = this->resolve(systemIdString) ) {
+ return new xercesc::LocalFileInputSource(
+ *XercesStringGuard<XMLCh>((*resolvedPath).string())
+ );
+ } else {
+ return new xercesc::LocalFileInputSource(
+ *XercesStringGuard<XMLCh>(systemIdString)
+ );
+ }
} else {
return nullptr;
}
}
-boost::filesystem::path IncludeEntityResolver::resolve(
- const XMLCh* const rawPath) const {
+boost::optional<boost::filesystem::path> IncludeEntityResolver::resolve(
+ const std::string& rawPath) const {
if ( auto filePath = extractFilePath(rawPath) ) {
- if ( auto resolvedPath = this->resolve(*filePath) ) {
- return *resolvedPath;
+ if ( auto resolvedPath = this->tryIncludePaths(*filePath) ) {
+ return boost::make_optional(*resolvedPath);
} else {
- return *filePath;
+ return boost::make_optional(*filePath);
}
} else {
- return getPathFromSystemId(rawPath);
+ return boost::optional<boost::filesystem::path>();
}
}
-boost::optional<boost::filesystem::path> IncludeEntityResolver::resolve(
+boost::optional<boost::filesystem::path> IncludeEntityResolver::tryIncludePaths(
const boost::filesystem::path& filePath) const {
for ( auto&& context : this->path_ ) {
const boost::filesystem::path resolvedPath(
context.resolve(filePath)
);
- if ( boost::filesystem::exists(resolvedPath) &&
- boost::filesystem::is_regular_file(resolvedPath) ) {
+ if ( boost::filesystem::exists(resolvedPath) ) {
return boost::make_optional(resolvedPath);
}
}
diff --git a/src/support/include_entity_resolver.h b/src/support/include_entity_resolver.h
index 32d9001..ea5fb7a 100644
--- a/src/support/include_entity_resolver.h
+++ b/src/support/include_entity_resolver.h
@@ -15,6 +15,8 @@ namespace InputXSLT {
class IncludeEntityResolver : public xercesc::EntityResolver {
public:
+ static boost::filesystem::path getPathFromSystemId(const XMLCh* const);
+
IncludeEntityResolver(const std::vector<std::string>&);
xercesc::InputSource* resolveEntity(
@@ -22,14 +24,16 @@ class IncludeEntityResolver : public xercesc::EntityResolver {
const XMLCh* const
);
- boost::filesystem::path resolve(
- const XMLCh* const) const;
boost::optional<boost::filesystem::path> resolve(
- const boost::filesystem::path&) const;
+ const std::string&) const;
private:
const std::vector<FilesystemContext> path_;
+ boost::optional<boost::filesystem::path> tryIncludePaths(
+ const boost::filesystem::path&) const;
+
+
};
}
diff --git a/src/support/type/xobject_value.cc b/src/support/type/xobject_value.cc
index 0236597..46ce53c 100644
--- a/src/support/type/xobject_value.cc
+++ b/src/support/type/xobject_value.cc
@@ -28,23 +28,14 @@ std::string XObjectValue::get<std::string>(
template <>
boost::filesystem::path XObjectValue::get<boost::filesystem::path>(
const xalan::XObjectPtr& ptr) const {
- const boost::filesystem::path rawPath(
- toString(ptr->str())
+ const std::string rawPath(
+ this->get<std::string>(ptr)
);
- const boost::filesystem::path filePath(
- this->filesystem_context_.resolve(rawPath)
- );
-
- if ( !(boost::filesystem::exists(filePath) &&
- boost::filesystem::is_regular_file(filePath)) ) {
- if ( auto resolvedPath = this->include_resolver_->resolve(rawPath) ) {
- return *resolvedPath;
- } else {
- return filePath;
- }
+ if ( auto resolvedPath = this->include_resolver_->resolve(rawPath) ) {
+ return *resolvedPath;
} else {
- return filePath;
+ return this->filesystem_context_.resolve(rawPath);
}
}
diff --git a/test/external_text_formatter/transformation.xsl b/test/external_text_formatter/transformation.xsl
index 7be4866..2026302 100644
--- a/test/external_text_formatter/transformation.xsl
+++ b/test/external_text_formatter/transformation.xsl
@@ -26,7 +26,7 @@
<xsl:template name="implementation">
<xsl:variable name="result">
<xsl:call-template name="formatter">
- <xsl:with-param name="source" select="InputXSLT:read-file('test.md')"/>
+ <xsl:with-param name="source" select="InputXSLT:read-file('[test.md]')"/>
</xsl:call-template>
</xsl:variable>
diff --git a/test/read_file/transformation.xsl b/test/read_file/transformation.xsl
index 53a815c..c5ba24e 100644
--- a/test/read_file/transformation.xsl
+++ b/test/read_file/transformation.xsl
@@ -10,7 +10,7 @@
<xsl:import href="[testcase.xsl]"/>
<xsl:template name="implementation">
- <xsl:variable name="result" select="InputXSLT:read-file('test.md')"/>
+ <xsl:variable name="result" select="InputXSLT:read-file('[test.md]')"/>
<xsl:choose>
<xsl:when test="$result/self::file/@result = 'success'">
diff --git a/test/read_xml_file/transformation.xsl b/test/read_xml_file/transformation.xsl
index 98ae358..cd06c46 100644
--- a/test/read_xml_file/transformation.xsl
+++ b/test/read_xml_file/transformation.xsl
@@ -10,7 +10,7 @@
<xsl:import href="[testcase.xsl]"/>
<xsl:template name="implementation">
- <xsl:variable name="result" select="InputXSLT:read-file('test.xml')"/>
+ <xsl:variable name="result" select="InputXSLT:read-file('[test.xml]')"/>
<xsl:choose>
<xsl:when test="$result/self::file/@result = 'success'">