From 938ed7622656c3494ae8fdb83bc2ad4b1f31d901 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Fri, 25 Apr 2014 17:44:32 +0200 Subject: Improved argument resolution and error handling * execute member method internal argument count checks are not needed when using between one and two arguments ** xalan automatically generates the appropriate message containing the getError message when only offered fixed argument execute member overloads * improved FunctionReadDirectory attribute element generation * added additional validations to FunctionReadFile and FunctionReadXMLFile * I plan to return errors inside a DOM tree alongside the function return values in the future --- src/function/read_directory.cc | 48 ++++++++++++++++++++++-------------------- src/function/read_directory.h | 6 ++++-- src/function/read_file.cc | 44 +++++++++++++++++++------------------- src/function/read_file.h | 2 +- src/function/read_xml_file.cc | 40 +++++++++++++++++------------------ src/function/read_xml_file.h | 8 +++---- src/transformation_facade.cc | 9 +++++++- 7 files changed, 84 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc index 245f311..9711239 100644 --- a/src/function/read_directory.cc +++ b/src/function/read_directory.cc @@ -15,41 +15,43 @@ FunctionReadDirectory::FunctionReadDirectory(const FilesystemContext& context): documents_(std::make_shared>()) { } xalan::XObjectPtr FunctionReadDirectory::execute( - xalan::XPathExecutionContext& executionContext, - xalan::XalanNode* context, - const xalan::Function::XObjectArgVectorType& arguments, - const xalan::Locator* locator + xalan::XPathExecutionContext& executionContext, + xalan::XalanNode*, + const xalan::XObjectPtr argument, + const xalan::Locator* ) const { - if ( arguments.size() != 1 ) { - xalan::XPathExecutionContext::GetAndReleaseCachedString guard( - executionContext - ); - - this->generalError(executionContext, context, locator); - } - this->documents_->emplace("content"); DomDocumentGuard& domDocument = this->documents_->top(); xercesc::DOMNode* const rootNode = domDocument->getDocumentElement(); this->fs_context_.iterate( - arguments[0]->str(), + argument->str(), [&domDocument, &rootNode](const boost::filesystem::path& p) { xercesc::DOMElement* const itemNode( domDocument->createElement(*XercesStringGuard("item")) ); - if ( boost::filesystem::is_regular_file(p) ) { - itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("file") - ); - } else if ( boost::filesystem::is_directory(p) ) { - itemNode->setAttribute( - *XercesStringGuard("type"), - *XercesStringGuard("directory") - ); + switch ( boost::filesystem::status(p).type() ) { + case boost::filesystem::regular_file: { + itemNode->setAttribute( + *XercesStringGuard("type"), + *XercesStringGuard("file") + ); + + break; + }; + case boost::filesystem::directory_file: { + itemNode->setAttribute( + *XercesStringGuard("type"), + *XercesStringGuard("directory") + ); + + break; + }; + default: { + break; + }; } xercesc::DOMText* const textNode( diff --git a/src/function/read_directory.h b/src/function/read_directory.h index 3c55591..782ebed 100644 --- a/src/function/read_directory.h +++ b/src/function/read_directory.h @@ -22,7 +22,7 @@ class FunctionReadDirectory : public xalan::Function { virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext&, xalan::XalanNode*, - const xalan::Function::XObjectArgVectorType&, + const xalan::XObjectPtr, const xalan::Locator* ) const; @@ -34,7 +34,9 @@ class FunctionReadDirectory : public xalan::Function { private: const FilesystemContext& fs_context_; - std::shared_ptr> documents_; + std::shared_ptr< + std::stack + > documents_; const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; diff --git a/src/function/read_file.cc b/src/function/read_file.cc index 9e32f04..ac6225a 100644 --- a/src/function/read_file.cc +++ b/src/function/read_file.cc @@ -10,31 +10,31 @@ FunctionReadFile::FunctionReadFile(const FilesystemContext& context): fs_context_(context) { } xalan::XObjectPtr FunctionReadFile::execute( - xalan::XPathExecutionContext& executionContext, - xalan::XalanNode* context, - const xalan::Function::XObjectArgVectorType& arguments, - const xalan::Locator* locator + xalan::XPathExecutionContext& executionContext, + xalan::XalanNode*, + const xalan::XObjectPtr argument, + const xalan::Locator* ) const { - if ( arguments.size() != 1 ) { - xalan::XPathExecutionContext::GetAndReleaseCachedString guard( - executionContext - ); - - this->generalError(executionContext, context, locator); - } - - boost::filesystem::ifstream file( - this->fs_context_.resolve(arguments[0]->str()) + const boost::filesystem::path filePath( + this->fs_context_.resolve(argument->str()) ); - const std::string fileContent( - (std::istreambuf_iterator(file)), - (std::istreambuf_iterator()) - ); + if ( boost::filesystem::is_regular_file(filePath) ) { + boost::filesystem::ifstream file(filePath); - return executionContext.getXObjectFactory().createString( - xalan::XalanDOMString(fileContent.data()) - ); + const std::string fileContent( + (std::istreambuf_iterator(file)), + (std::istreambuf_iterator()) + ); + + return executionContext.getXObjectFactory().createString( + xalan::XalanDOMString(fileContent.data()) + ); + } else { + return executionContext.getXObjectFactory().createString( + xalan::XalanDOMString("io error") + ); + } } FunctionReadFile* FunctionReadFile::clone( @@ -44,7 +44,7 @@ FunctionReadFile* FunctionReadFile::clone( const xalan::XalanDOMString& FunctionReadFile::getError( xalan::XalanDOMString& result) const { - result.assign("The read-file() function expects one argument."); + result.assign("The read-file() function expects one argument of type string."); return result; } diff --git a/src/function/read_file.h b/src/function/read_file.h index b88336a..2d1dedf 100644 --- a/src/function/read_file.h +++ b/src/function/read_file.h @@ -20,7 +20,7 @@ class FunctionReadFile : public xalan::Function { virtual xalan::XObjectPtr execute( xalan::XPathExecutionContext&, xalan::XalanNode*, - const xalan::Function::XObjectArgVectorType&, + const xalan::XObjectPtr, const xalan::Locator* ) const; diff --git a/src/function/read_xml_file.cc b/src/function/read_xml_file.cc index ac42288..d429f34 100644 --- a/src/function/read_xml_file.cc +++ b/src/function/read_xml_file.cc @@ -13,28 +13,28 @@ FunctionReadXmlFile::FunctionReadXmlFile(const FunctionReadXmlFile& src): parser_() { } xalan::XObjectPtr FunctionReadXmlFile::execute( - xalan::XPathExecutionContext& executionContext, - xalan::XalanNode* context, - const xalan::Function::XObjectArgVectorType& arguments, - const xalan::Locator* locator + xalan::XPathExecutionContext& executionContext, + xalan::XalanNode*, + const xalan::XObjectPtr argument, + const xalan::Locator* ) const { - if ( arguments.size() != 1 ) { - xalan::XPathExecutionContext::GetAndReleaseCachedString guard( - executionContext - ); - - this->generalError(executionContext, context, locator); - } - - boost::filesystem::ifstream file( - this->fs_context_.resolve(arguments[0]->str()) + const boost::filesystem::path filePath( + this->fs_context_.resolve(argument->str()) ); - return executionContext.getXObjectFactory().createNodeSet( - this->parser_.parseXMLStream( - xalan::XSLTInputSource(file) - ) - ); + if ( boost::filesystem::is_regular_file(filePath) ) { + boost::filesystem::ifstream file(filePath); + + return executionContext.getXObjectFactory().createNodeSet( + this->parser_.parseXMLStream( + xalan::XSLTInputSource(file) + ) + ); + } else { + return executionContext.getXObjectFactory().createString( + xalan::XalanDOMString("io error") + ); + } } FunctionReadXmlFile* FunctionReadXmlFile::clone( @@ -44,7 +44,7 @@ FunctionReadXmlFile* FunctionReadXmlFile::clone( const xalan::XalanDOMString& FunctionReadXmlFile::getError( xalan::XalanDOMString& result) const { - result.assign("The read-xml-file() function expects one argument."); + result.assign("The read-xml-file() function expects one argument of type string."); return result; } diff --git a/src/function/read_xml_file.h b/src/function/read_xml_file.h index aa8590a..775ec96 100644 --- a/src/function/read_xml_file.h +++ b/src/function/read_xml_file.h @@ -20,10 +20,10 @@ class FunctionReadXmlFile : public xalan::Function { FunctionReadXmlFile(const FunctionReadXmlFile&); virtual xalan::XObjectPtr execute( - xalan::XPathExecutionContext& executionContext, - xalan::XalanNode* context, - const xalan::Function::XObjectArgVectorType& arguments, - const xalan::Locator* locator + xalan::XPathExecutionContext&, + xalan::XalanNode*, + const xalan::XObjectPtr, + const xalan::Locator* ) const; virtual FunctionReadXmlFile* clone(xalan::MemoryManager&) const; diff --git a/src/transformation_facade.cc b/src/transformation_facade.cc index 19f7772..38dfe93 100644 --- a/src/transformation_facade.cc +++ b/src/transformation_facade.cc @@ -4,6 +4,7 @@ #include #include +#include #include "function/read_file.h" #include "function/read_xml_file.h" @@ -54,11 +55,17 @@ int TransformationFacade::generate(const std::string& target) { xalan::XSLTInputSource inputSource(emptyStream); xalan::XSLTResultTarget outputTarget(target.data()); - return this->transformer_.transform( + const int resultCode = this->transformer_.transform( inputSource, this->transformation_, outputTarget ); + + if ( resultCode != 0 ) { + std::cerr << this->transformer_.getLastError() << std::endl; + } + + return resultCode; } } -- cgit v1.2.3