From 943768ad437011756395b86958399992e6822604 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Wed, 14 May 2014 16:41:58 +0200 Subject: Added ArgumentCount parameter to FunctionBase template * constructDocument member method is provided with a FunctionBase::argument_array instance * improved argument validation in FunctionBase * this parameter was added to support FunctionBase as a base class for FunctionTransform --- src/function/base.h | 66 ++++++++++++++++++++++++++++++++++++++---- src/function/read_directory.cc | 4 ++- src/function/read_directory.h | 4 +-- src/function/read_file.cc | 4 ++- src/function/read_file.h | 4 +-- src/function/read_xml_file.cc | 4 ++- src/function/read_xml_file.h | 4 +-- src/function/transform.cc | 64 ++++------------------------------------ src/function/transform.h | 37 ++++++----------------- 9 files changed, 90 insertions(+), 101 deletions(-) diff --git a/src/function/base.h b/src/function/base.h index fe9f6ff..5604186 100644 --- a/src/function/base.h +++ b/src/function/base.h @@ -7,6 +7,8 @@ #include #include +#include +#include #include "common.h" #include "support/dom/document_cache.h" @@ -14,19 +16,44 @@ namespace InputXSLT { -template +template < + class Implementation, + std::size_t ArgumentCount +> class FunctionBase : public xalan::Function { public: + typedef std::array< + boost::filesystem::path, + ArgumentCount + > argument_array; + FunctionBase(): document_cache_(std::make_shared()) { } virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext& executionContext, - xalan::XalanNode*, - const xalan::XObjectPtr argument, + xalan::XalanNode* context, + const XObjectArgVectorType& rawArguments, const xalan::Locator* locator ) const { + this->validateArguments( + rawArguments, + executionContext, + context, + locator + ); + const FilesystemContext fsContext(locator); + argument_array pathArguments; + + std::transform( + rawArguments.begin(), + rawArguments.end(), + pathArguments.begin(), + [&fsContext](const xalan::XObjectPtr& ptr) -> boost::filesystem::path { + return fsContext.resolve(ptr->str()); + } + ); xalan::XalanDocument* const domDocument( this->document_cache_->create( @@ -34,7 +61,7 @@ class FunctionBase : public xalan::Function { const_cast(this) )->constructDocument( fsContext, - fsContext.resolve(argument->str()) + pathArguments ) ) ); @@ -61,16 +88,43 @@ class FunctionBase : public xalan::Function { FunctionBase& operator=(const FunctionBase&) = delete; bool operator==(const FunctionBase&) const = delete; - protected: + private: std::shared_ptr document_cache_; const xalan::XalanDOMString& getError( xalan::XalanDOMString& result) const { - result.assign("The function expects one argument of type string."); + result.assign(std::string( + "The function expects " + + std::to_string(ArgumentCount) + + " argument(s) of type string." + ).data()); return result; } + inline void validateArguments( + const XObjectArgVectorType& rawArguments, + xalan::XPathExecutionContext& executionContext, + xalan::XalanNode* context, + const xalan::Locator* locator + ) const { + const bool notNull = std::none_of( + rawArguments.begin(), + rawArguments.end(), + [](const xalan::XObjectPtr& ptr) -> bool { + return ptr.null(); + } + ); + + if ( rawArguments.size() != ArgumentCount && notNull ) { + xalan::XPathExecutionContext::GetAndReleaseCachedString guard( + executionContext + ); + + this->generalError(executionContext, context, locator); + } + } + }; } diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc index 8b41dae..e030e33 100644 --- a/src/function/read_directory.cc +++ b/src/function/read_directory.cc @@ -11,8 +11,10 @@ namespace InputXSLT { xercesc::DOMDocument* FunctionReadDirectory::constructDocument( const InputXSLT::FilesystemContext& fsContext, - const boost::filesystem::path& directoryPath + const FunctionBase::argument_array& arguments ) { + const boost::filesystem::path& directoryPath = arguments[0]; + xercesc::DOMDocument* const domDocument( xercesc::DOMImplementation::getImplementation()->createDocument( nullptr, diff --git a/src/function/read_directory.h b/src/function/read_directory.h index b050ff8..9dc3869 100644 --- a/src/function/read_directory.h +++ b/src/function/read_directory.h @@ -5,7 +5,7 @@ namespace InputXSLT { -class FunctionReadDirectory : public FunctionBase { +class FunctionReadDirectory : public FunctionBase { public: using FunctionBase::FunctionBase; @@ -14,7 +14,7 @@ class FunctionReadDirectory : public FunctionBase { xercesc::DOMDocument* constructDocument( const FilesystemContext&, - const boost::filesystem::path& + const FunctionBase::argument_array& ); }; diff --git a/src/function/read_file.cc b/src/function/read_file.cc index 439d905..da0e988 100644 --- a/src/function/read_file.cc +++ b/src/function/read_file.cc @@ -26,8 +26,10 @@ namespace InputXSLT { xercesc::DOMDocument* FunctionReadFile::constructDocument( const FilesystemContext&, - const boost::filesystem::path& filePath + const FunctionBase::argument_array& arguments ) { + const boost::filesystem::path& filePath = arguments[0]; + xercesc::DOMDocument* const domDocument( xercesc::DOMImplementation::getImplementation()->createDocument( nullptr, diff --git a/src/function/read_file.h b/src/function/read_file.h index 90139f4..e7b746c 100644 --- a/src/function/read_file.h +++ b/src/function/read_file.h @@ -5,7 +5,7 @@ namespace InputXSLT { -class FunctionReadFile : public FunctionBase { +class FunctionReadFile : public FunctionBase { public: using FunctionBase::FunctionBase; @@ -14,7 +14,7 @@ class FunctionReadFile : public FunctionBase { xercesc::DOMDocument* constructDocument( const FilesystemContext&, - const boost::filesystem::path& + const FunctionBase::argument_array& ); }; diff --git a/src/function/read_xml_file.cc b/src/function/read_xml_file.cc index 71ba819..b3bf3de 100644 --- a/src/function/read_xml_file.cc +++ b/src/function/read_xml_file.cc @@ -34,8 +34,10 @@ namespace InputXSLT { xercesc::DOMDocument* FunctionReadXmlFile::constructDocument( const FilesystemContext&, - const boost::filesystem::path& filePath + const FunctionBase::argument_array& arguments ) { + const boost::filesystem::path& filePath = arguments[0]; + xercesc::DOMDocument* const domDocument( xercesc::DOMImplementation::getImplementation()->createDocument( nullptr, diff --git a/src/function/read_xml_file.h b/src/function/read_xml_file.h index 3636d18..423f0a2 100644 --- a/src/function/read_xml_file.h +++ b/src/function/read_xml_file.h @@ -5,7 +5,7 @@ namespace InputXSLT { -class FunctionReadXmlFile : public FunctionBase { +class FunctionReadXmlFile : public FunctionBase { public: using FunctionBase::FunctionBase; @@ -14,7 +14,7 @@ class FunctionReadXmlFile : public FunctionBase { xercesc::DOMDocument* constructDocument( const FilesystemContext&, - const boost::filesystem::path& + const FunctionBase::argument_array& ); }; diff --git a/src/function/transform.cc b/src/function/transform.cc index 9b600d9..360b61d 100644 --- a/src/function/transform.cc +++ b/src/function/transform.cc @@ -7,15 +7,15 @@ #include "transformation_facade.h" #include "support/xerces_string_guard.h" -namespace { - -using InputXSLT::XercesStringGuard; +namespace InputXSLT { -xercesc::DOMDocument* constructDocument( +xercesc::DOMDocument* FunctionTransform::constructDocument( const InputXSLT::FilesystemContext&, - const boost::filesystem::path& transformationPath, - const boost::filesystem::path& targetPath + const FunctionBase::argument_array& arguments ) { + const boost::filesystem::path& transformationPath = arguments[0]; + const boost::filesystem::path& targetPath = arguments[1]; + xercesc::DOMDocument* const domDocument( xercesc::DOMImplementation::getImplementation()->createDocument( nullptr, @@ -59,55 +59,3 @@ xercesc::DOMDocument* constructDocument( } } - -namespace InputXSLT { - -FunctionTransform::FunctionTransform(): - document_cache_(std::make_shared()) { } - -xalan::XObjectPtr FunctionTransform::execute( - xalan::XPathExecutionContext& executionContext, - xalan::XalanNode*, - const xalan::XObjectPtr argument1, - const xalan::XObjectPtr argument2, - const xalan::Locator* locator -) const { - const FilesystemContext fsContext(locator); - - xalan::XalanDocument* const domDocument( - this->document_cache_->create( - constructDocument( - fsContext, - fsContext.resolve(argument1->str()), - fsContext.resolve(argument2->str()) - ) - ) - ); - - xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( - executionContext - ); - - nodeList->addNodes( - *domDocument->getDocumentElement()->getChildNodes() - ); - - return executionContext.getXObjectFactory().createNodeSet(nodeList); -} - -FunctionTransform* FunctionTransform::clone( - xalan::MemoryManager& manager) const { - return xalan::XalanCopyConstruct( - manager, - *this - ); -} - -const xalan::XalanDOMString& FunctionTransform::getError( - xalan::XalanDOMString& result) const { - result.assign("The function expects two arguments of type string."); - - return result; -} - -} diff --git a/src/function/transform.h b/src/function/transform.h index 41bba05..fc735f0 100644 --- a/src/function/transform.h +++ b/src/function/transform.h @@ -1,40 +1,21 @@ #ifndef INPUTXSLT_SRC_FUNCTION_TRANSFORM_H_ #define INPUTXSLT_SRC_FUNCTION_TRANSFORM_H_ -#include -#include -#include -#include - -#include - -#include "common.h" -#include "support/dom/document_cache.h" -#include "support/filesystem_context.h" +#include "base.h" namespace InputXSLT { -class FunctionTransform : public xalan::Function { +class FunctionTransform : public FunctionBase { public: - FunctionTransform(); - - virtual xalan::XObjectPtr execute( - xalan::XPathExecutionContext&, - xalan::XalanNode*, - const xalan::XObjectPtr, - const xalan::XObjectPtr, - const xalan::Locator* - ) const; - - virtual FunctionTransform* clone(xalan::MemoryManager&) const; - - FunctionTransform& operator=(const FunctionTransform&) = delete; - bool operator==(const FunctionTransform&) const = delete; + using FunctionBase::FunctionBase; - private: - std::shared_ptr document_cache_; + protected: + friend FunctionBase; - const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; + xercesc::DOMDocument* constructDocument( + const FilesystemContext&, + const FunctionBase::argument_array& + ); }; -- cgit v1.2.3