diff options
author | Adrian Kummerländer | 2014-05-30 22:19:32 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-05-30 22:19:32 +0200 |
commit | 79d3e2bdfd441d6eba2f22af78d5bea5e488daf1 (patch) | |
tree | b28b0603958140777ee46d98f2fc4359c9f72c4d | |
parent | 484143667bd6885236b679a8f54dad3c512ea2dd (diff) | |
download | InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.tar InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.tar.gz InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.tar.bz2 InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.tar.lz InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.tar.xz InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.tar.zst InputXSLT-79d3e2bdfd441d6eba2f22af78d5bea5e488daf1.zip |
Rewrote error handling based on exceptions
* ErrorHandler is replaced by ErrorCapacitor
** temporarily registers itself as both the ProblemListener and ErrorHandler of a given XalanTransformer instance
** deregisters itself on destruction
** collects all problems and errors during its lifetime inside a internal std::vector<std::string> instance
** if this instance is not empty it is thrown contained within a ErrorCapacitor::exception by the member method ErrorCapacitor::discharge
* this enables using the same code for handling transformation compilation and generation errors and problems
* updated test frontend accordingly
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/function/transform.cc | 19 | ||||
-rw-r--r-- | src/support/error_capacitor.cc (renamed from src/support/error_handler.cc) | 58 | ||||
-rw-r--r-- | src/support/error_capacitor.h (renamed from src/support/error_handler.h) | 30 | ||||
-rw-r--r-- | src/transformation_facade.cc | 49 | ||||
-rw-r--r-- | src/transformation_facade.h | 33 | ||||
-rw-r--r-- | test.cc | 33 |
7 files changed, 119 insertions, 105 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d83c0a..2ca7990 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ set( src/support/stylesheet_parameter_guard.cc src/support/xalan_string.cc src/support/include_entity_resolver.cc - src/support/error_handler.cc + src/support/error_capacitor.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/transform.cc b/src/function/transform.cc index 7e8a844..e952018 100644 --- a/src/function/transform.cc +++ b/src/function/transform.cc @@ -41,17 +41,16 @@ xercesc::DOMDocument* FunctionTransform::constructDocument( ResultNodeFacade result(domDocument, rootNode, "result"); result.setAttribute("name", targetPath); - InputXSLT::TransformationFacade transformation( - transformationPath, - this->include_resolver_ - ); - - InputXSLT::TransformationFacade::return_type errors( - transformation.generate(targetPath, parameterObject) - ); + try { + InputXSLT::TransformationFacade transformation( + transformationPath, + this->include_resolver_ + ); - if ( errors ) { - for ( auto&& error : *errors ) { + transformation.generate(targetPath, parameterObject); + } + catch (const ErrorCapacitor::exception& exception) { + for ( auto&& error : *(exception.getCachedErrors()) ) { result.setValueNode("error", error); } } diff --git a/src/support/error_handler.cc b/src/support/error_capacitor.cc index 2ca721d..e83ba9a 100644 --- a/src/support/error_handler.cc +++ b/src/support/error_capacitor.cc @@ -1,4 +1,4 @@ -#include "error_handler.h" +#include "error_capacitor.h" #include <xercesc/sax/SAXParseException.hpp> @@ -19,50 +19,57 @@ inline std::string getMessage(const xercesc::SAXParseException& exception) { namespace InputXSLT { -ErrorHandler::ErrorHandler(): - error_cache_{} { } +ErrorCapacitor::ErrorCapacitor(xalan::XalanTransformer* transformer): + transformer_(transformer), + error_cache_(new error_cache()) { + this->transformer_->setErrorHandler(this); + this->transformer_->setProblemListener(this); +} + +ErrorCapacitor::~ErrorCapacitor() { + this->transformer_->setErrorHandler(nullptr); + this->transformer_->setProblemListener(nullptr); +} -void ErrorHandler::warning(const xercesc::SAXParseException& exception) { - this->constructErrorCache(); +void ErrorCapacitor::discharge() { + if ( !this->error_cache_->empty() ) { + throw exception(std::move(this->error_cache_)); + } +} +void ErrorCapacitor::warning(const xercesc::SAXParseException& exception) { this->error_cache_->emplace_back( "Warning: " + getMessage(exception) ); } -void ErrorHandler::error(const xercesc::SAXParseException& exception) { - this->constructErrorCache(); - +void ErrorCapacitor::error(const xercesc::SAXParseException& exception) { this->error_cache_->emplace_back( "Error: " + getMessage(exception) ); } -void ErrorHandler::fatalError(const xercesc::SAXParseException& exception) { - this->constructErrorCache(); - +void ErrorCapacitor::fatalError(const xercesc::SAXParseException& exception) { this->error_cache_->emplace_back( "Fatal error: " + getMessage(exception) ); } -void ErrorHandler::resetErrors() { } +void ErrorCapacitor::resetErrors() { } -void ErrorHandler::problem( +void ErrorCapacitor::problem( xalan::ProblemListenerBase::eSource, xalan::ProblemListenerBase::eClassification, const xalan::XalanDOMString& message, const xalan::Locator*, const xalan::XalanNode* ) { - this->constructErrorCache(); - this->error_cache_->emplace_back( "XSLT problem: " + toString(message) ); } -void ErrorHandler::problem( +void ErrorCapacitor::problem( xalan::ProblemListenerBase::eSource, xalan::ProblemListenerBase::eClassification, const xalan::XalanNode*, @@ -72,36 +79,29 @@ void ErrorHandler::problem( xalan::XalanFileLoc, xalan::XalanFileLoc ) { - this->constructErrorCache(); - this->error_cache_->emplace_back( "XSLT problem: " + toString(message) ); } -void ErrorHandler::problem( +void ErrorCapacitor::problem( xalan::ProblemListenerBase::eSource, xalan::ProblemListenerBase::eClassification, const xalan::XalanDOMString& message, const xalan::XalanNode* ) { - this->constructErrorCache(); - this->error_cache_->emplace_back( "XSLT problem: " + toString(message) ); } -void ErrorHandler::setPrintWriter(xalan::PrintWriter*) { } +void ErrorCapacitor::setPrintWriter(xalan::PrintWriter*) { } -auto ErrorHandler::getCachedErrors() -> error_cache_ptr { - return error_cache_ptr(this->error_cache_.release()); -} +ErrorCapacitor::exception::exception(error_cache_ptr ptr): + error_cache_(std::move(ptr)) { } -void ErrorHandler::constructErrorCache() { - if ( !this->error_cache_ ) { - this->error_cache_.reset(new error_cache()); - } +auto ErrorCapacitor::exception::getCachedErrors() const -> const error_cache* { + return this->error_cache_.get(); } } diff --git a/src/support/error_handler.h b/src/support/error_capacitor.h index 02d741e..d89b5ae 100644 --- a/src/support/error_handler.h +++ b/src/support/error_capacitor.h @@ -1,8 +1,9 @@ -#ifndef INPUTXSLT_SRC_SUPPORT_ERROR_HANDLER_H_ -#define INPUTXSLT_SRC_SUPPORT_ERROR_HANDLER_H_ +#ifndef INPUTXSLT_SRC_SUPPORT_ERROR_CAPACITOR_H_ +#define INPUTXSLT_SRC_SUPPORT_ERROR_CAPACITOR_H_ #include <xercesc/sax/ErrorHandler.hpp> #include <xalanc/XSLT/ProblemListener.hpp> +#include <xalanc/XalanTransformer/XalanTransformer.hpp> #include <memory> #include <vector> @@ -12,13 +13,18 @@ namespace InputXSLT { -class ErrorHandler : public xercesc::ErrorHandler, +class ErrorCapacitor : public xercesc::ErrorHandler, public xalan::ProblemListener { public: + class exception; + typedef std::vector<std::string> error_cache; typedef std::unique_ptr<error_cache> error_cache_ptr; - ErrorHandler(); + ErrorCapacitor(xalan::XalanTransformer*); + ~ErrorCapacitor(); + + void discharge(); virtual void warning(const xercesc::SAXParseException&); virtual void error(const xercesc::SAXParseException&); @@ -53,15 +59,23 @@ class ErrorHandler : public xercesc::ErrorHandler, virtual void setPrintWriter(xalan::PrintWriter*); - error_cache_ptr getCachedErrors(); - private: + xalan::XalanTransformer* const transformer_; error_cache_ptr error_cache_; - void constructErrorCache(); +}; + +class ErrorCapacitor::exception { + public: + exception(error_cache_ptr); + + const error_cache* getCachedErrors() const; + + private: + error_cache_ptr error_cache_; }; } -#endif // INPUTXSLT_SRC_SUPPORT_ERROR_HANDLER_H_ +#endif // INPUTXSLT_SRC_SUPPORT_ERROR_CAPACITOR_H_ diff --git a/src/transformation_facade.cc b/src/transformation_facade.cc index 8b9e1a2..f415cd8 100644 --- a/src/transformation_facade.cc +++ b/src/transformation_facade.cc @@ -14,16 +14,17 @@ TransformationFacade::TransformationFacade( IncludeEntityResolver* resolver ): transformation_{}, - transformer_(), - error_handler_() { + transformer_() { this->transformer_.setEntityResolver(resolver); - this->transformer_.setErrorHandler(&this->error_handler_); - this->transformer_.setProblemListener(&this->error_handler_); + + ErrorCapacitor errorCapacitor(&this->transformer_); this->transformer_.compileStylesheet( xalan::XSLTInputSource(transformation.data()), this->transformation_ ); + + errorCapacitor.discharge(); } TransformationFacade::~TransformationFacade() { @@ -32,10 +33,10 @@ TransformationFacade::~TransformationFacade() { ); } -auto TransformationFacade::generate( +void TransformationFacade::generate( const std::string& targetPath, StylesheetParameterGuard& parameters -) -> return_type { +) { const boost::filesystem::path targetPathHelper( boost::filesystem::absolute(targetPath) ); @@ -47,38 +48,38 @@ auto TransformationFacade::generate( "parent-directory", targetPathHelper.parent_path().filename().string() ); - return this->generate( + this->generate( xalan::XSLTResultTarget(targetPath.data()), parameters ); } -auto TransformationFacade::generate( +void TransformationFacade::generate( std::basic_ostream<char>& targetStream, StylesheetParameterGuard& parameters -) -> return_type { - return this->generate( +) { + this->generate( xalan::XSLTResultTarget(targetStream), parameters ); } -auto TransformationFacade::generate( +void TransformationFacade::generate( xalan::XSLTResultTarget&& outputTarget, StylesheetParameterGuard& -) -> return_type { - if ( this->transformation_ != nullptr ) { - std::stringstream emptyStream("<dummy/>"); - xalan::XSLTInputSource inputSource(emptyStream); - - this->transformer_.transform( - inputSource, - this->transformation_, - outputTarget - ); - } - - return this->error_handler_.getCachedErrors(); +) { + ErrorCapacitor errorCapacitor(&this->transformer_); + + std::stringstream emptyStream("<dummy/>"); + xalan::XSLTInputSource inputSource(emptyStream); + + this->transformer_.transform( + inputSource, + this->transformation_, + outputTarget + ); + + errorCapacitor.discharge(); } } diff --git a/src/transformation_facade.h b/src/transformation_facade.h index 28d1895..4fb997b 100644 --- a/src/transformation_facade.h +++ b/src/transformation_facade.h @@ -6,7 +6,7 @@ #include <string> #include "common.h" -#include "support/error_handler.h" +#include "support/error_capacitor.h" #include "support/include_entity_resolver.h" #include "support/stylesheet_parameter_guard.h" @@ -14,58 +14,55 @@ namespace InputXSLT { class TransformationFacade { public: - typedef ErrorHandler::error_cache_ptr return_type; - TransformationFacade(const std::string&, IncludeEntityResolver*); ~TransformationFacade(); template <typename Target> - return_type generate(Target&); + void generate(Target&); template <typename Target> - return_type generate(Target&, const StylesheetParameterGuard::map&); + void generate(Target&, const StylesheetParameterGuard::map&); template <typename Target> - return_type generate(Target&, const xalan::XObjectPtr&); + void generate(Target&, const xalan::XObjectPtr&); private: const xalan::XalanCompiledStylesheet* transformation_; xalan::XalanTransformer transformer_; - ErrorHandler error_handler_; - return_type generate(const std::string&, StylesheetParameterGuard&); - return_type generate(std::basic_ostream<char>&, StylesheetParameterGuard&); - return_type generate(xalan::XSLTResultTarget&&, StylesheetParameterGuard&); + void generate(const std::string&, StylesheetParameterGuard&); + void generate(std::basic_ostream<char>&, StylesheetParameterGuard&); + void generate(xalan::XSLTResultTarget&&, StylesheetParameterGuard&); }; template <typename Target> -auto TransformationFacade::generate(Target& target) -> return_type { +void TransformationFacade::generate(Target& target) { StylesheetParameterGuard guard(this->transformer_); - return this->generate(target, guard); + this->generate(target, guard); } template <typename Target> -auto TransformationFacade::generate( +void TransformationFacade::generate( Target& target, const StylesheetParameterGuard::map& parameters -) -> return_type { +) { StylesheetParameterGuard guard(this->transformer_, parameters); - return this->generate(target, guard); + this->generate(target, guard); } template <typename Target> -auto TransformationFacade::generate( +void TransformationFacade::generate( Target& target, const xalan::XObjectPtr& parameter -) -> return_type { +) { StylesheetParameterGuard guard(this->transformer_); guard.set("parameters", parameter); - return this->generate(target, guard); + this->generate(target, guard); } } @@ -43,25 +43,28 @@ int main(int ac, char** av) { InputXSLT::PlattformGuard plattform(includePath); - InputXSLT::TransformationFacade transformation( - variables["transformation"].as<std::string>(), - plattform.getEntityResolver() - ); - - InputXSLT::TransformationFacade::return_type errors{}; - - if ( variables.count("target") ) { - errors = transformation.generate( - variables["target"].as<std::string>() + try { + InputXSLT::TransformationFacade transformation( + variables["transformation"].as<std::string>(), + plattform.getEntityResolver() ); - } else { - errors = transformation.generate(std::cout); - } - if ( errors ) { - for ( auto&& error : *errors ) { + if ( variables.count("target") ) { + transformation.generate( + variables["target"].as<std::string>() + ); + } else { + transformation.generate(std::cout); + } + + return 0; + } + catch (const InputXSLT::ErrorCapacitor::exception& exception) { + for ( auto&& error : *(exception.getCachedErrors()) ) { std::cerr << error << std::endl; } + + return 1; } } else { std::cout << optionDescription << std::endl; |