From e5ed418907f09bf8905463f42a44593d51159bc9 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Fri, 2 May 2014 22:06:37 +0200 Subject: Changed external functions to enable global installation * up until now all external functions were locally installed to a specific XalanTransformer instance contained within a TransformationGuard instance ** this had to change as I planned to add a "execute-transformation" function based on TransformationGuard which would have led to recursive self-instantiation ** global external functions have to be thread-safe * as global external function can not be provided with a reference to a transformation-specific FilesystemFacade instance, the working path is now determined using xalan::Locator ** currently using pointer arithmetics on XMLCh* to remove the "file://" prefix of the URI returned by locator->getSystemId(), may be unsafe * added compilation unit for PlattformGuard as it now contains function installation in addition to plattform lifetime management --- CMakeLists.txt | 1 + src/function/read_directory.cc | 16 ++++++++++----- src/function/read_directory.h | 4 +--- src/function/read_file.cc | 14 +++++++++---- src/function/read_file.h | 4 +--- src/function/read_xml_file.cc | 14 +++++++++---- src/function/read_xml_file.h | 4 +--- src/plattform_guard.cc | 46 ++++++++++++++++++++++++++++++++++++++++++ src/plattform_guard.h | 17 ++-------------- src/transformation_facade.cc | 27 ------------------------- src/transformation_facade.h | 2 -- 11 files changed, 83 insertions(+), 66 deletions(-) create mode 100644 src/plattform_guard.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 02a9b79..fd14740 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories( add_executable( test test.cc + src/plattform_guard.cc src/transformation_facade.cc src/function/read_file.cc src/function/read_xml_file.cc diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc index f155029..b13be2b 100644 --- a/src/function/read_directory.cc +++ b/src/function/read_directory.cc @@ -6,21 +6,27 @@ #include #include "support/xerces_string_guard.h" +#include "support/filesystem_context.h" namespace InputXSLT { -FunctionReadDirectory::FunctionReadDirectory(const FilesystemContext& context): - fs_context_(context), +FunctionReadDirectory::FunctionReadDirectory(): document_cache_(std::make_shared()) { } xalan::XObjectPtr FunctionReadDirectory::execute( xalan::XPathExecutionContext& executionContext, xalan::XalanNode*, const xalan::XObjectPtr argument, - const xalan::Locator* + const xalan::Locator* locator ) const { + const FilesystemContext fs_context( + boost::filesystem::path( + xercesc::XMLString::transcode(locator->getSystemId() + 7) + ).parent_path().string() + ); + const boost::filesystem::path directoryPath( - this->fs_context_.resolve(argument->str()) + fs_context.resolve(argument->str()) ); DomDocumentCache::item* const cachedDocument( @@ -37,7 +43,7 @@ xalan::XObjectPtr FunctionReadDirectory::execute( ); if ( boost::filesystem::is_directory(directoryPath) ) { - this->fs_context_.iterate( + fs_context.iterate( argument->str(), [&domDocument, &rootNode](const boost::filesystem::path& p) { xercesc::DOMElement* const itemNode( diff --git a/src/function/read_directory.h b/src/function/read_directory.h index f4f7ec8..02a0305 100644 --- a/src/function/read_directory.h +++ b/src/function/read_directory.h @@ -9,14 +9,13 @@ #include #include "common.h" -#include "support/filesystem_context.h" #include "support/dom/document_cache.h" namespace InputXSLT { class FunctionReadDirectory : public xalan::Function { public: - FunctionReadDirectory(const FilesystemContext&); + FunctionReadDirectory(); virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext&, @@ -31,7 +30,6 @@ class FunctionReadDirectory : public xalan::Function { bool operator==(const FunctionReadDirectory&) const = delete; private: - const FilesystemContext& fs_context_; std::shared_ptr document_cache_; const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; diff --git a/src/function/read_file.cc b/src/function/read_file.cc index f531191..7634d54 100644 --- a/src/function/read_file.cc +++ b/src/function/read_file.cc @@ -8,6 +8,7 @@ #include "boost/filesystem/fstream.hpp" #include "support/xerces_string_guard.h" +#include "support/filesystem_context.h" namespace { @@ -24,18 +25,23 @@ inline std::string readFile(const boost::filesystem::path& filePath) { namespace InputXSLT { -FunctionReadFile::FunctionReadFile(const FilesystemContext& context): - fs_context_(context), +FunctionReadFile::FunctionReadFile(): document_cache_(std::make_shared()) { } xalan::XObjectPtr FunctionReadFile::execute( xalan::XPathExecutionContext& executionContext, xalan::XalanNode*, const xalan::XObjectPtr argument, - const xalan::Locator* + const xalan::Locator* locator ) const { + const FilesystemContext fs_context( + boost::filesystem::path( + xercesc::XMLString::transcode(locator->getSystemId() + 7) + ).parent_path().string() + ); + const boost::filesystem::path filePath( - this->fs_context_.resolve(argument->str()) + fs_context.resolve(argument->str()) ); DomDocumentCache::item* const cachedDocument( diff --git a/src/function/read_file.h b/src/function/read_file.h index 6f38e95..65746a5 100644 --- a/src/function/read_file.h +++ b/src/function/read_file.h @@ -9,14 +9,13 @@ #include #include "common.h" -#include "support/filesystem_context.h" #include "support/dom/document_cache.h" namespace InputXSLT { class FunctionReadFile : public xalan::Function { public: - FunctionReadFile(const FilesystemContext&); + FunctionReadFile(); virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext&, @@ -31,7 +30,6 @@ class FunctionReadFile : public xalan::Function { bool operator==(const FunctionReadFile&) const = delete; private: - const FilesystemContext& fs_context_; std::shared_ptr document_cache_; const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; diff --git a/src/function/read_xml_file.cc b/src/function/read_xml_file.cc index bf9ec2e..608e71a 100644 --- a/src/function/read_xml_file.cc +++ b/src/function/read_xml_file.cc @@ -9,6 +9,7 @@ #include "boost/filesystem/fstream.hpp" #include "support/xerces_string_guard.h" +#include "support/filesystem_context.h" namespace { @@ -30,18 +31,23 @@ inline xercesc::DOMNode* importDocumentElement( namespace InputXSLT { -FunctionReadXmlFile::FunctionReadXmlFile(const FilesystemContext& context): - fs_context_(context), +FunctionReadXmlFile::FunctionReadXmlFile(): document_cache_(std::make_shared()) { } xalan::XObjectPtr FunctionReadXmlFile::execute( xalan::XPathExecutionContext& executionContext, xalan::XalanNode*, const xalan::XObjectPtr argument, - const xalan::Locator* + const xalan::Locator* locator ) const { + const FilesystemContext fs_context( + boost::filesystem::path( + xercesc::XMLString::transcode(locator->getSystemId() + 7) + ).parent_path().string() + ); + const boost::filesystem::path filePath( - this->fs_context_.resolve(argument->str()) + fs_context.resolve(argument->str()) ); DomDocumentCache::item* const cachedDocument( diff --git a/src/function/read_xml_file.h b/src/function/read_xml_file.h index 1df48fb..d7ef440 100644 --- a/src/function/read_xml_file.h +++ b/src/function/read_xml_file.h @@ -10,14 +10,13 @@ #include #include "common.h" -#include "support/filesystem_context.h" #include "support/dom/document_cache.h" namespace InputXSLT { class FunctionReadXmlFile : public xalan::Function { public: - FunctionReadXmlFile(const FilesystemContext&); + FunctionReadXmlFile(); virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext&, @@ -32,7 +31,6 @@ class FunctionReadXmlFile : public xalan::Function { bool operator==(const FunctionReadXmlFile&) const = delete; private: - const FilesystemContext& fs_context_; std::shared_ptr document_cache_; const xalan::XalanDOMString& getError(xalan::XalanDOMString& result) const; diff --git a/src/plattform_guard.cc b/src/plattform_guard.cc new file mode 100644 index 0000000..2c3cee4 --- /dev/null +++ b/src/plattform_guard.cc @@ -0,0 +1,46 @@ +#include "plattform_guard.h" + +#include +#include + +#include + +#include "common.h" +#include "function/read_file.h" +#include "function/read_xml_file.h" +#include "function/read_directory.h" + +namespace InputXSLT { + +PlattformGuard::PlattformGuard() { + xercesc::XMLPlatformUtils::Initialize(); + xalan::XalanTransformer::initialize(); + + const xalan::XalanDOMString customNamespace( + "function.inputxslt.application" + ); + + xalan::XalanTransformer::installExternalFunctionGlobal( + customNamespace, + xalan::XalanDOMString("read-file"), + InputXSLT::FunctionReadFile() + ); + + xalan::XalanTransformer::installExternalFunctionGlobal( + customNamespace, + xalan::XalanDOMString("read-xml-file"), + InputXSLT::FunctionReadXmlFile() + ); + + xalan::XalanTransformer::installExternalFunctionGlobal( + customNamespace, + xalan::XalanDOMString("read-directory"), + InputXSLT::FunctionReadDirectory() + ); +} + +PlattformGuard::~PlattformGuard() { + xalan::XalanTransformer::terminate(); +} + +} diff --git a/src/plattform_guard.h b/src/plattform_guard.h index fe8b954..12b19f0 100644 --- a/src/plattform_guard.h +++ b/src/plattform_guard.h @@ -1,24 +1,11 @@ #ifndef INPUTXSLT_SRC_PLATTFORM_GUARD_H_ #define INPUTXSLT_SRC_PLATTFORM_GUARD_H_ -#include -#include - -#include - -#include "common.h" - namespace InputXSLT { struct PlattformGuard { - PlattformGuard() { - xercesc::XMLPlatformUtils::Initialize(); - xalan::XalanTransformer::initialize(); - } - - ~PlattformGuard() { - xalan::XalanTransformer::terminate(); - } + PlattformGuard(); + ~PlattformGuard(); }; } diff --git a/src/transformation_facade.cc b/src/transformation_facade.cc index 3fee24f..91d761d 100644 --- a/src/transformation_facade.cc +++ b/src/transformation_facade.cc @@ -6,38 +6,11 @@ #include #include -#include "function/read_file.h" -#include "function/read_xml_file.h" -#include "function/read_directory.h" - namespace InputXSLT { TransformationFacade::TransformationFacade(const std::string& transformation): - fs_context_(boost::filesystem::path(transformation).parent_path().string()), transformation_{}, transformer_() { - const xalan::XalanDOMString customNamespace( - "function.inputxslt.application" - ); - - this->transformer_.installExternalFunction( - customNamespace, - xalan::XalanDOMString("read-file"), - InputXSLT::FunctionReadFile(this->fs_context_) - ); - - this->transformer_.installExternalFunction( - customNamespace, - xalan::XalanDOMString("read-xml-file"), - InputXSLT::FunctionReadXmlFile(this->fs_context_) - ); - - this->transformer_.installExternalFunction( - customNamespace, - xalan::XalanDOMString("read-directory"), - InputXSLT::FunctionReadDirectory(this->fs_context_) - ); - this->transformer_.compileStylesheet( xalan::XSLTInputSource(transformation.data()), this->transformation_ diff --git a/src/transformation_facade.h b/src/transformation_facade.h index 880335f..833016d 100644 --- a/src/transformation_facade.h +++ b/src/transformation_facade.h @@ -7,7 +7,6 @@ #include #include "common.h" -#include "support/filesystem_context.h" namespace InputXSLT { @@ -22,7 +21,6 @@ class TransformationFacade { int generate(const std::string&, const parameter_map&); private: - const FilesystemContext fs_context_; const xalan::XalanCompiledStylesheet* transformation_; xalan::XalanTransformer transformer_; -- cgit v1.2.3