From 35334241ce4b76b1b1a66219ce938f27fdf39031 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Tue, 20 May 2014 21:17:10 +0200 Subject: Replaced FunctionResolveInclude with IncludeEntityResolver * xalan / xerces offers the possibility of implementing custom entity resolvers which are called upon by "" had to be implemented --- CMakeLists.txt | 1 + src/function/resolve_include.cc | 62 ------------------------------ src/function/resolve_include.h | 44 --------------------- src/function/transform.cc | 9 ++++- src/function/transform.h | 7 +++- src/plattform_guard.cc | 16 ++++---- src/plattform_guard.h | 15 ++++++-- src/support/include_entity_resolver.cc | 70 ++++++++++++++++++++++++++++++++++ src/support/include_entity_resolver.h | 30 +++++++++++++++ src/transformation_facade.cc | 7 +++- src/transformation_facade.h | 3 +- test.cc | 3 +- 12 files changed, 144 insertions(+), 123 deletions(-) delete mode 100644 src/function/resolve_include.cc delete mode 100644 src/function/resolve_include.h create mode 100644 src/support/include_entity_resolver.cc create mode 100644 src/support/include_entity_resolver.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c5aa8ea..7722264 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ set( src/support/filesystem_context.cc src/support/stylesheet_parameter_guard.cc src/support/xalan_string.cc + src/support/include_entity_resolver.cc src/support/tuple/xobject_value.cc src/support/dom/document_cache.cc src/support/dom/document_cache_item.cc diff --git a/src/function/resolve_include.cc b/src/function/resolve_include.cc deleted file mode 100644 index ac4adf5..0000000 --- a/src/function/resolve_include.cc +++ /dev/null @@ -1,62 +0,0 @@ -#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 deleted file mode 100644 index 2d6e62f..0000000 --- a/src/function/resolve_include.h +++ /dev/null @@ -1,44 +0,0 @@ -#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/function/transform.cc b/src/function/transform.cc index 6a2b7ad..8823745 100644 --- a/src/function/transform.cc +++ b/src/function/transform.cc @@ -9,6 +9,10 @@ namespace InputXSLT { +FunctionTransform::FunctionTransform(IncludeEntityResolver* resolver): + FunctionBase::FunctionBase(), + include_resolver_(resolver) { } + xercesc::DOMDocument* FunctionTransform::constructDocument( const InputXSLT::FilesystemContext& fsContext, const FunctionBase::parameter_tuple& parameters @@ -37,7 +41,10 @@ xercesc::DOMDocument* FunctionTransform::constructDocument( domDocument->getDocumentElement() ); - InputXSLT::TransformationFacade transformation(transformationPath); + InputXSLT::TransformationFacade transformation( + transformationPath, + this->include_resolver_ + ); if ( transformation.generate(targetPath, parameterObject) == 0 ) { xercesc::DOMElement* const resultNode( diff --git a/src/function/transform.h b/src/function/transform.h index 810738e..94fae53 100644 --- a/src/function/transform.h +++ b/src/function/transform.h @@ -3,6 +3,8 @@ #include "base.h" +#include "support/include_entity_resolver.h" + namespace InputXSLT { class FunctionTransform : public FunctionBase< @@ -12,7 +14,7 @@ class FunctionTransform : public FunctionBase< xalan::XObjectPtr > { public: - using FunctionBase::FunctionBase; + FunctionTransform(IncludeEntityResolver*); protected: friend FunctionBase; @@ -22,6 +24,9 @@ class FunctionTransform : public FunctionBase< const FunctionBase::parameter_tuple& ); + private: + IncludeEntityResolver* const include_resolver_; + }; } diff --git a/src/plattform_guard.cc b/src/plattform_guard.cc index 820346e..8ffbbb9 100644 --- a/src/plattform_guard.cc +++ b/src/plattform_guard.cc @@ -10,11 +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(const std::vector& path) { +PlattformGuard::PlattformGuard(const std::vector& path): + include_resolver_(path) { xercesc::XMLPlatformUtils::Initialize(); xalan::XalanTransformer::initialize(); @@ -43,13 +43,7 @@ PlattformGuard::PlattformGuard(const std::vector& path) { xalan::XalanTransformer::installExternalFunctionGlobal( customNamespace, xalan::XalanDOMString("transform"), - InputXSLT::FunctionTransform() - ); - - xalan::XalanTransformer::installExternalFunctionGlobal( - customNamespace, - xalan::XalanDOMString("resolve-include"), - InputXSLT::FunctionResolveInclude(path) + InputXSLT::FunctionTransform(&this->include_resolver_) ); } @@ -57,4 +51,8 @@ PlattformGuard::~PlattformGuard() { xalan::XalanTransformer::terminate(); } +IncludeEntityResolver* PlattformGuard::getEntityResolver() { + return &this->include_resolver_; +} + } diff --git a/src/plattform_guard.h b/src/plattform_guard.h index f6abcba..ccc9449 100644 --- a/src/plattform_guard.h +++ b/src/plattform_guard.h @@ -4,11 +4,20 @@ #include #include +#include "support/include_entity_resolver.h" + namespace InputXSLT { -struct PlattformGuard { - PlattformGuard(const std::vector&); - ~PlattformGuard(); +class PlattformGuard { + public: + PlattformGuard(const std::vector&); + ~PlattformGuard(); + + IncludeEntityResolver* getEntityResolver(); + + private: + IncludeEntityResolver include_resolver_; + }; } diff --git a/src/support/include_entity_resolver.cc b/src/support/include_entity_resolver.cc new file mode 100644 index 0000000..79631a5 --- /dev/null +++ b/src/support/include_entity_resolver.cc @@ -0,0 +1,70 @@ +#include "include_entity_resolver.h" + +#include + +#include "boost/filesystem.hpp" + +#include "support/xerces_string_guard.h" + +namespace InputXSLT { + +IncludeEntityResolver::IncludeEntityResolver( + const std::vector& path): + path_() { + this->path_.reserve(path.size()); + + std::transform( + path.begin(), + path.end(), + std::back_inserter(this->path_), + [](const std::string& path) -> FilesystemContext { + return FilesystemContext(path); + } + ); +} + +xercesc::InputSource* IncludeEntityResolver::resolveEntity( + const XMLCh* const, + const XMLCh* const systemId +) { + if ( systemId != nullptr ) { + const std::string rawPath( + *XercesStringGuard(systemId) + ); + + 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 ) { + const std::string filePath( + rawPath.substr( + leadingDelimiter + 1, + closingDelimiter - leadingDelimiter - 1 + ) + ); + + 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 new xercesc::LocalFileInputSource( + *XercesStringGuard(resolvedPath.string()) + ); + } + } + + return nullptr; + } else { + return nullptr; + } + } else { + return nullptr; + } +} + +} diff --git a/src/support/include_entity_resolver.h b/src/support/include_entity_resolver.h new file mode 100644 index 0000000..390cfe1 --- /dev/null +++ b/src/support/include_entity_resolver.h @@ -0,0 +1,30 @@ +#ifndef INPUTXSLT_SRC_SUPPORT_INCLUDE_ENTITY_RESOLVER_H_ +#define INPUTXSLT_SRC_SUPPORT_INCLUDE_ENTITY_RESOLVER_H_ + +#include +#include + +#include +#include + +#include "filesystem_context.h" + +namespace InputXSLT { + +class IncludeEntityResolver : public xercesc::EntityResolver { + public: + IncludeEntityResolver(const std::vector&); + + xercesc::InputSource* resolveEntity( + const XMLCh* const, + const XMLCh* const + ); + + private: + std::vector path_; + +}; + +} + +#endif // INPUTXSLT_SRC_SUPPORT_INCLUDE_ENTITY_RESOLVER_H_ diff --git a/src/transformation_facade.cc b/src/transformation_facade.cc index 07483c1..3bf1532 100644 --- a/src/transformation_facade.cc +++ b/src/transformation_facade.cc @@ -10,9 +10,14 @@ namespace InputXSLT { -TransformationFacade::TransformationFacade(const std::string& transformation): +TransformationFacade::TransformationFacade( + const std::string& transformation, + IncludeEntityResolver* resolver +): transformation_{}, transformer_() { + this->transformer_.setEntityResolver(resolver); + this->transformer_.compileStylesheet( xalan::XSLTInputSource(transformation.data()), this->transformation_ diff --git a/src/transformation_facade.h b/src/transformation_facade.h index 7fb0926..1e09248 100644 --- a/src/transformation_facade.h +++ b/src/transformation_facade.h @@ -6,13 +6,14 @@ #include #include "common.h" +#include "support/include_entity_resolver.h" #include "support/stylesheet_parameter_guard.h" namespace InputXSLT { class TransformationFacade { public: - explicit TransformationFacade(const std::string&); + TransformationFacade(const std::string&, IncludeEntityResolver*); ~TransformationFacade(); template diff --git a/test.cc b/test.cc index a21f25a..9d1dd3a 100644 --- a/test.cc +++ b/test.cc @@ -44,7 +44,8 @@ int main(int ac, char** av) { InputXSLT::PlattformGuard plattform(includePath); InputXSLT::TransformationFacade transformation( - variables["transformation"].as() + variables["transformation"].as(), + plattform.getEntityResolver() ); if ( variables.count("target") ) { -- cgit v1.2.3