From 426265b91d4533b7aa16d53124ad9b5d0a6862d6 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Mon, 19 May 2014 22:14:31 +0200 Subject: Implemented external "resolve-include" function * resolves paths provided as strings against include paths provided through the newly created "--include" argument of the test executable * this was implemented to enable central collections of XSLT libraries simmilar to how there are C headers in "/usr/include" --- CMakeLists.txt | 1 + src/function/resolve_include.cc | 62 +++++++++++++++++++++++++++++++++++++++++ src/function/resolve_include.h | 44 +++++++++++++++++++++++++++++ src/plattform_guard.cc | 9 +++++- src/plattform_guard.h | 5 +++- test.cc | 15 ++++++++-- 6 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 src/function/resolve_include.cc create mode 100644 src/function/resolve_include.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ffcb49..c5aa8ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set( src/function/read_xml_file.cc src/function/read_directory.cc src/function/transform.cc + src/function/resolve_include.cc src/support/filesystem_context.cc src/support/stylesheet_parameter_guard.cc src/support/xalan_string.cc diff --git a/src/function/resolve_include.cc b/src/function/resolve_include.cc new file mode 100644 index 0000000..ac4adf5 --- /dev/null +++ b/src/function/resolve_include.cc @@ -0,0 +1,62 @@ +#include "resolve_include.h" + +#include + +#include "support/xalan_string.h" + +namespace InputXSLT { + +FunctionResolveInclude::FunctionResolveInclude( + const std::vector& path): + path_(new std::vector()) { + this->path_->reserve(path.size()); + + std::transform( + path.begin(), + path.end(), + std::back_inserter(*this->path_), + [](const std::string& path) -> FilesystemContext { + return FilesystemContext(path); + } + ); +} + +xalan::XObjectPtr FunctionResolveInclude::execute( + xalan::XPathExecutionContext& executionContext, + xalan::XalanNode*, + const xalan::XObjectPtr parameter, + const xalan::Locator* +) const { + const std::string filePath(toString(parameter->str())); + + for ( auto&& context : *this->path_ ) { + const boost::filesystem::path resolvedPath( + context.resolve(filePath) + ); + + if ( boost::filesystem::exists(resolvedPath) && + boost::filesystem::is_regular_file(resolvedPath) ) { + return executionContext.getXObjectFactory().createString( + toString(resolvedPath.string()) + ); + } + } + + return executionContext.getXObjectFactory().createString( + toString("error") + ); +} + +FunctionResolveInclude* FunctionResolveInclude::clone( + xalan::MemoryManager& manager) const { + return xalan::XalanCopyConstruct(manager, *this); +} + +const xalan::XalanDOMString& FunctionResolveInclude::getError( + xalan::XalanDOMString& result) const { + result.assign("The function expects one parameter of type string."); + + return result; +} + +} diff --git a/src/function/resolve_include.h b/src/function/resolve_include.h new file mode 100644 index 0000000..2d6e62f --- /dev/null +++ b/src/function/resolve_include.h @@ -0,0 +1,44 @@ +#ifndef INPUTXSLT_SRC_FUNCTION_RESOLVE_INCLUDE_H_ +#define INPUTXSLT_SRC_FUNCTION_RESOLVE_INCLUDE_H_ + +#include +#include +#include + +#include "boost/filesystem.hpp" + +#include +#include +#include + +#include "common.h" +#include "support/filesystem_context.h" + +namespace InputXSLT { + +class FunctionResolveInclude : public xalan::Function { + public: + FunctionResolveInclude(const std::vector&); + + virtual xalan::XObjectPtr execute( + xalan::XPathExecutionContext&, + xalan::XalanNode*, + const xalan::XObjectPtr, + const xalan::Locator* + ) const; + + virtual FunctionResolveInclude* clone(xalan::MemoryManager&) const; + + FunctionResolveInclude& operator=(const FunctionResolveInclude&) = delete; + bool operator==(const FunctionResolveInclude&) const = delete; + + private: + const std::shared_ptr> path_; + + const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; + +}; + +} + +#endif // INPUTXSLT_SRC_FUNCTION_RESOLVE_INCLUDE_H_ diff --git a/src/plattform_guard.cc b/src/plattform_guard.cc index da3b6d7..820346e 100644 --- a/src/plattform_guard.cc +++ b/src/plattform_guard.cc @@ -10,10 +10,11 @@ #include "function/read_xml_file.h" #include "function/read_directory.h" #include "function/transform.h" +#include "function/resolve_include.h" namespace InputXSLT { -PlattformGuard::PlattformGuard() { +PlattformGuard::PlattformGuard(const std::vector& path) { xercesc::XMLPlatformUtils::Initialize(); xalan::XalanTransformer::initialize(); @@ -44,6 +45,12 @@ PlattformGuard::PlattformGuard() { xalan::XalanDOMString("transform"), InputXSLT::FunctionTransform() ); + + xalan::XalanTransformer::installExternalFunctionGlobal( + customNamespace, + xalan::XalanDOMString("resolve-include"), + InputXSLT::FunctionResolveInclude(path) + ); } PlattformGuard::~PlattformGuard() { diff --git a/src/plattform_guard.h b/src/plattform_guard.h index 12b19f0..f6abcba 100644 --- a/src/plattform_guard.h +++ b/src/plattform_guard.h @@ -1,10 +1,13 @@ #ifndef INPUTXSLT_SRC_PLATTFORM_GUARD_H_ #define INPUTXSLT_SRC_PLATTFORM_GUARD_H_ +#include +#include + namespace InputXSLT { struct PlattformGuard { - PlattformGuard(); + PlattformGuard(const std::vector&); ~PlattformGuard(); }; diff --git a/test.cc b/test.cc index 1262520..a21f25a 100644 --- a/test.cc +++ b/test.cc @@ -3,6 +3,8 @@ #include "boost/program_options.hpp" +#include +#include #include int main(int ac, char** av) { @@ -11,8 +13,9 @@ int main(int ac, char** av) { ); optionDescription.add_options() - ("transformation", boost::program_options::value()->required(), "transformation file") - ("target", boost::program_options::value(), "target file") + ("transformation", boost::program_options::value()->required(), "transformation file") + ("target", boost::program_options::value(), "target file") + ("include", boost::program_options::value>(), "include paths") ; boost::program_options::variables_map variables; @@ -32,7 +35,13 @@ int main(int ac, char** av) { } if ( variables.count("transformation") ) { - InputXSLT::PlattformGuard plattform; + std::vector includePath; + + if ( variables.count("include") ) { + includePath = variables["include"].as>(); + }; + + InputXSLT::PlattformGuard plattform(includePath); InputXSLT::TransformationFacade transformation( variables["transformation"].as() -- cgit v1.2.3