From eba5513f82f0e1458543e8646db0317d7211cf96 Mon Sep 17 00:00:00 2001 From: Adrian Kummerländer Date: Sat, 26 Apr 2014 20:06:17 +0200 Subject: Converted external read-file function output into a node set * A call to _read-file_ now returns a _content_ and _status_ node ** this enables XSL transformations to easily react to io related errors * fixed bug in path resolution ** boost::filesystem _canonical_ method is throwing and exception when the given path does not exist, this pulled down the whole stack ** replaced call to _canonical_ with call to _absolute_ which does not have this requirement --- src/function/read_file.cc | 89 ++++++++++++++++++++++++++++++++++++++++------- src/function/read_file.h | 2 ++ 2 files changed, 79 insertions(+), 12 deletions(-) (limited to 'src/function') diff --git a/src/function/read_file.cc b/src/function/read_file.cc index ac6225a..6f02702 100644 --- a/src/function/read_file.cc +++ b/src/function/read_file.cc @@ -1,13 +1,23 @@ #include "read_file.h" +#include +#include +#include +#include +#include + #include "boost/filesystem/fstream.hpp" #include +#include "support/xerces_string_guard.h" +#include "support/utility.h" + namespace InputXSLT { FunctionReadFile::FunctionReadFile(const FilesystemContext& context): - fs_context_(context) { } + fs_context_(context), + document_cache_(std::make_shared()) { } xalan::XObjectPtr FunctionReadFile::execute( xalan::XPathExecutionContext& executionContext, @@ -19,22 +29,77 @@ xalan::XObjectPtr FunctionReadFile::execute( this->fs_context_.resolve(argument->str()) ); - if ( boost::filesystem::is_regular_file(filePath) ) { - boost::filesystem::ifstream file(filePath); + DomDocumentCache::item* const cachedDocument( + this->document_cache_->get(xalanToString(argument->str())) + ); - const std::string fileContent( - (std::istreambuf_iterator(file)), - (std::istreambuf_iterator()) + if ( !cachedDocument->isFinalized() ) { + xercesc::DOMDocument* const domDocument( + cachedDocument->getXercesDocument() ); - return executionContext.getXObjectFactory().createString( - xalan::XalanDOMString(fileContent.data()) - ); - } else { - return executionContext.getXObjectFactory().createString( - xalan::XalanDOMString("io error") + xercesc::DOMNode* const rootNode( + domDocument->getDocumentElement() ); + + if ( boost::filesystem::is_regular_file(filePath) ) { + boost::filesystem::ifstream file(filePath); + + const std::string fileContent( + (std::istreambuf_iterator(file)), + (std::istreambuf_iterator()) + ); + + xercesc::DOMElement* const contentNode( + domDocument->createElement(*XercesStringGuard("content")) + ); + + xercesc::DOMText* const contentTextNode( + domDocument->createTextNode( + *XercesStringGuard(fileContent) + ) + ); + + xercesc::DOMElement* const resultNode( + domDocument->createElement(*XercesStringGuard("status")) + ); + + xercesc::DOMText* const resultTextNode( + domDocument->createTextNode( + *XercesStringGuard("successful") + ) + ); + + contentNode->appendChild(contentTextNode); + resultNode->appendChild(resultTextNode); + + rootNode->appendChild(contentNode); + rootNode->appendChild(resultNode); + } else { + xercesc::DOMElement* const resultNode( + domDocument->createElement(*XercesStringGuard("status")) + ); + + xercesc::DOMText* const resultTextNode( + domDocument->createTextNode( + *XercesStringGuard("error") + ) + ); + + resultNode->appendChild(resultTextNode); + rootNode->appendChild(resultNode); + } } + + xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( + executionContext + ); + + nodeList->addNodes( + *cachedDocument->getXalanDocument()->getDocumentElement()->getChildNodes() + ); + + return executionContext.getXObjectFactory().createNodeSet(nodeList); } FunctionReadFile* FunctionReadFile::clone( diff --git a/src/function/read_file.h b/src/function/read_file.h index 2d1dedf..6f38e95 100644 --- a/src/function/read_file.h +++ b/src/function/read_file.h @@ -10,6 +10,7 @@ #include "common.h" #include "support/filesystem_context.h" +#include "support/dom/document_cache.h" namespace InputXSLT { @@ -31,6 +32,7 @@ class FunctionReadFile : public xalan::Function { private: const FilesystemContext& fs_context_; + std::shared_ptr document_cache_; const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; -- cgit v1.2.3