diff options
author | Adrian Kummerländer | 2014-06-05 20:44:26 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-06-05 20:44:26 +0200 |
commit | 78bb3387b15d15d766fb5d17a99612f0480f2bee (patch) | |
tree | c87a2516f56d7f6317a704b91b340bc14cabfd28 | |
parent | 11355181c0b5f8377774daefcc17bb5e6bc20f61 (diff) | |
download | InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.tar InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.tar.gz InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.tar.bz2 InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.tar.lz InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.tar.xz InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.tar.zst InputXSLT-78bb3387b15d15d766fb5d17a99612f0480f2bee.zip |
Implemented ErrorMultiplexer as primary error handler
* ErrorMultiplexer is derived from both xercesc::ErrorHandler and xalan::ProblemListener
* registers itself as XalanTransformer's ErrorHandler and ProblemListener
* distributes captured errors and warnings to all registered ErrorMultiplexer::Receiver instances
** ErrorCapacitor implements the ErrorMultiplexer::Receiver interface and as such registers itself in a given ErrorMultiplexer instance
** ErrorMultiplexer reduces the different xalan and xercesc internal error classifications into either warnings or errors
* this was implemented to make it possible to easily differentiate between warnings and errors
** previously warnings were treated as errors
** ErrorCapacitor ignores warnings and only captures errors
** WarningCapacitor will be implemented to handle warnings during XSLT processing
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | ixslt.cc | 7 | ||||
-rw-r--r-- | src/function/transform.cc | 1 | ||||
-rw-r--r-- | src/support/error/error_capacitor.cc | 37 | ||||
-rw-r--r-- | src/support/error/error_capacitor.h | 46 | ||||
-rw-r--r-- | src/support/error/error_multiplexer.cc (renamed from src/support/error_capacitor.cc) | 91 | ||||
-rw-r--r-- | src/support/error/error_multiplexer.h (renamed from src/support/error_capacitor.h) | 44 | ||||
-rw-r--r-- | src/transformation_facade.cc | 9 | ||||
-rw-r--r-- | src/transformation_facade.h | 3 |
9 files changed, 185 insertions, 56 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b9e2771..ea46ab6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,8 @@ set( src/support/stylesheet_parameter_guard.cc src/support/xalan_string.cc src/support/include_entity_resolver.cc - src/support/error_capacitor.cc + src/support/error/error_multiplexer.cc + src/support/error/error_capacitor.cc src/support/tuple/xobject_value.cc src/support/dom/document_cache.cc src/support/dom/document_cache_item.cc @@ -1,6 +1,3 @@ -#include "plattform_guard.h" -#include "transformation_facade.h" - #include "boost/optional.hpp" #include "boost/program_options.hpp" @@ -8,6 +5,10 @@ #include <vector> #include <iostream> +#include "plattform_guard.h" +#include "transformation_facade.h" +#include "support/error/error_capacitor.h" + boost::optional<boost::program_options::variables_map> input( int argc, char** argv diff --git a/src/function/transform.cc b/src/function/transform.cc index ab8c51c..86bc91c 100644 --- a/src/function/transform.cc +++ b/src/function/transform.cc @@ -7,6 +7,7 @@ #include "transformation_facade.h" #include "support/xerces_string_guard.h" #include "support/dom/result_node_facade.h" +#include "support/error/error_capacitor.h" namespace InputXSLT { diff --git a/src/support/error/error_capacitor.cc b/src/support/error/error_capacitor.cc new file mode 100644 index 0000000..58cfb81 --- /dev/null +++ b/src/support/error/error_capacitor.cc @@ -0,0 +1,37 @@ +#include "error_capacitor.h" + +namespace InputXSLT { + +ErrorCapacitor::ErrorCapacitor(ErrorMultiplexer* multiplexer): + multiplexer_(multiplexer), + error_cache_(new error_cache()) { + this->multiplexer_->connectReceiver(this); +} + +ErrorCapacitor::~ErrorCapacitor() { + this->multiplexer_->disconnectReceiver(this); +} + +void ErrorCapacitor::discharge() { + if ( !this->error_cache_->empty() ) { + throw exception(std::move(this->error_cache_)); + } +} + +void ErrorCapacitor::receive( + const ErrorMultiplexer::ErrorType type, + const std::string& message +) { + if ( type == ErrorMultiplexer::ErrorType::Error ) { + this->error_cache_->emplace_back(message); + } +} + +ErrorCapacitor::exception::exception(error_cache_ptr ptr): + error_cache_(std::move(ptr)) { } + +auto ErrorCapacitor::exception::getCachedErrors() const -> const error_cache* { + return this->error_cache_.get(); +} + +} diff --git a/src/support/error/error_capacitor.h b/src/support/error/error_capacitor.h new file mode 100644 index 0000000..6017cb4 --- /dev/null +++ b/src/support/error/error_capacitor.h @@ -0,0 +1,46 @@ +#ifndef INPUTXSLT_SRC_SUPPORT_ERROR_ERROR_CAPACITOR_H_ +#define INPUTXSLT_SRC_SUPPORT_ERROR_ERROR_CAPACITOR_H_ + +#include <memory> + +#include "error_multiplexer.h" + +namespace InputXSLT { + +class ErrorCapacitor : public ErrorMultiplexer::Receiver { + public: + class exception; + + typedef std::vector<std::string> error_cache; + typedef std::unique_ptr<error_cache> error_cache_ptr; + + ErrorCapacitor(ErrorMultiplexer*); + ~ErrorCapacitor(); + + void discharge(); + + virtual void receive( + const ErrorMultiplexer::ErrorType, + const std::string& + ); + + private: + ErrorMultiplexer* const multiplexer_; + error_cache_ptr error_cache_; + +}; + +class ErrorCapacitor::exception { + public: + exception(error_cache_ptr); + + const error_cache* getCachedErrors() const; + + private: + error_cache_ptr error_cache_; + +}; + +} + +#endif // INPUTXSLT_SRC_SUPPORT_ERROR_ERROR_CAPACITOR_H_ diff --git a/src/support/error_capacitor.cc b/src/support/error/error_multiplexer.cc index e624cd1..f5d4e0f 100644 --- a/src/support/error_capacitor.cc +++ b/src/support/error/error_multiplexer.cc @@ -1,10 +1,10 @@ -#include "error_capacitor.h" +#include "error_multiplexer.h" #include <xercesc/sax/SAXParseException.hpp> #include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp> -#include <iostream> +#include <algorithm> #include "support/xalan_string.h" #include "support/xerces_string_guard.h" @@ -12,6 +12,7 @@ namespace { using InputXSLT::XercesStringGuard; +using InputXSLT::ErrorMultiplexer; inline std::string getMessage(const xercesc::SAXParseException& exception) { return ( @@ -26,49 +27,73 @@ inline std::string getMessage(const xercesc::SAXParseException& exception) { ); } +inline ErrorMultiplexer::ErrorType toErrorType( + const xalan::ProblemListenerBase::eClassification classification) { + switch ( classification ) { + case xalan::ProblemListenerBase::eClassification::eMessage || + xalan::ProblemListenerBase::eClassification::eWarning: { + return ErrorMultiplexer::ErrorType::Warning; + } + default: { + return ErrorMultiplexer::ErrorType::Error; + } + } +} + } namespace InputXSLT { -ErrorCapacitor::ErrorCapacitor(xalan::XalanTransformer* transformer): +ErrorMultiplexer::ErrorMultiplexer(xalan::XalanTransformer* transformer): transformer_(transformer), - error_cache_(new error_cache()) { + receivers_() { this->transformer_->setErrorHandler(this); this->transformer_->setProblemListener(this); } -ErrorCapacitor::~ErrorCapacitor() { +ErrorMultiplexer::~ErrorMultiplexer() { this->transformer_->setErrorHandler(nullptr); this->transformer_->setProblemListener(nullptr); } -void ErrorCapacitor::discharge() { - if ( !this->error_cache_->empty() ) { - throw exception(std::move(this->error_cache_)); - } +void ErrorMultiplexer::connectReceiver(Receiver* receiver) { + this->receivers_.push_back(receiver); +} + +void ErrorMultiplexer::disconnectReceiver(Receiver* receiver) { + this->receivers_.erase( + std::remove( + this->receivers_.begin(), + this->receivers_.end(), + receiver + ) + ); } -void ErrorCapacitor::warning(const xercesc::SAXParseException& exception) { - this->error_cache_->emplace_back( +void ErrorMultiplexer::warning(const xercesc::SAXParseException& exception) { + this->multiplex( + ErrorType::Warning, "Warning: " + getMessage(exception) ); } -void ErrorCapacitor::error(const xercesc::SAXParseException& exception) { - this->error_cache_->emplace_back( +void ErrorMultiplexer::error(const xercesc::SAXParseException& exception) { + this->multiplex( + ErrorType::Error, "Error: " + getMessage(exception) ); } -void ErrorCapacitor::fatalError(const xercesc::SAXParseException& exception) { - this->error_cache_->emplace_back( +void ErrorMultiplexer::fatalError(const xercesc::SAXParseException& exception) { + this->multiplex( + ErrorType::Error, "Fatal error: " + getMessage(exception) ); } -void ErrorCapacitor::resetErrors() { } +void ErrorMultiplexer::resetErrors() { } -void ErrorCapacitor::problem( +void ErrorMultiplexer::problem( xalan::ProblemListenerBase::eSource source, xalan::ProblemListenerBase::eClassification classification, const xalan::XalanDOMString& message, @@ -87,10 +112,13 @@ void ErrorCapacitor::problem( node ); - this->error_cache_->emplace_back(toString(problemSummary)); + this->multiplex( + toErrorType(classification), + toString(problemSummary) + ); } -void ErrorCapacitor::problem( +void ErrorMultiplexer::problem( xalan::ProblemListenerBase::eSource source, xalan::ProblemListenerBase::eClassification classification, const xalan::XalanDOMString& message, @@ -107,10 +135,13 @@ void ErrorCapacitor::problem( node ); - this->error_cache_->emplace_back(toString(problemSummary)); + this->multiplex( + toErrorType(classification), + toString(problemSummary) + ); } -void ErrorCapacitor::problem( +void ErrorMultiplexer::problem( xalan::ProblemListenerBase::eSource, xalan::ProblemListenerBase::eClassification, const xalan::XalanNode*, @@ -121,13 +152,19 @@ void ErrorCapacitor::problem( xalan::XalanFileLoc ) { } -void ErrorCapacitor::setPrintWriter(xalan::PrintWriter*) { } +void ErrorMultiplexer::setPrintWriter(xalan::PrintWriter*) { } -ErrorCapacitor::exception::exception(error_cache_ptr ptr): - error_cache_(std::move(ptr)) { } - -auto ErrorCapacitor::exception::getCachedErrors() const -> const error_cache* { - return this->error_cache_.get(); +void ErrorMultiplexer::multiplex( + const ErrorType type, + const std::string& message +) { + std::for_each( + this->receivers_.begin(), + this->receivers_.end(), + [&type, &message](Receiver* const receiver) -> void { + receiver->receive(type, message); + } + ); } } diff --git a/src/support/error_capacitor.h b/src/support/error/error_multiplexer.h index b94d5f8..02cfaf8 100644 --- a/src/support/error_capacitor.h +++ b/src/support/error/error_multiplexer.h @@ -1,12 +1,11 @@ -#ifndef INPUTXSLT_SRC_SUPPORT_ERROR_CAPACITOR_H_ -#define INPUTXSLT_SRC_SUPPORT_ERROR_CAPACITOR_H_ +#ifndef INPUTXSLT_SRC_SUPPORT_ERROR_ERROR_MULTIPLEXER_H_ +#define INPUTXSLT_SRC_SUPPORT_ERROR_ERROR_MULTIPLEXER_H_ #include <xercesc/sax/ErrorHandler.hpp> #include <xalanc/XSLT/ProblemListener.hpp> #include <xalanc/XalanTransformer/XalanTransformer.hpp> -#include <memory> #include <vector> #include <string> @@ -14,18 +13,17 @@ namespace InputXSLT { -class ErrorCapacitor : public xercesc::ErrorHandler, - public xalan::ProblemListener { +class ErrorMultiplexer : public xercesc::ErrorHandler, + public xalan::ProblemListener { public: - class exception; + enum class ErrorType; + struct Receiver; - typedef std::vector<std::string> error_cache; - typedef std::unique_ptr<error_cache> error_cache_ptr; + ErrorMultiplexer(xalan::XalanTransformer*); + ~ErrorMultiplexer(); - ErrorCapacitor(xalan::XalanTransformer*); - ~ErrorCapacitor(); - - void discharge(); + void connectReceiver(Receiver*); + void disconnectReceiver(Receiver*); virtual void warning(const xercesc::SAXParseException&); virtual void error(const xercesc::SAXParseException&); @@ -62,21 +60,25 @@ class ErrorCapacitor : public xercesc::ErrorHandler, private: xalan::XalanTransformer* const transformer_; - error_cache_ptr error_cache_; -}; + std::vector<Receiver*> receivers_; -class ErrorCapacitor::exception { - public: - exception(error_cache_ptr); + void multiplex(const ErrorType, const std::string&); - const error_cache* getCachedErrors() const; +}; - private: - error_cache_ptr error_cache_; +enum class ErrorMultiplexer::ErrorType { + Warning, + Error +}; +struct ErrorMultiplexer::Receiver { + virtual void receive( + const ErrorMultiplexer::ErrorType, + const std::string& + ) = 0; }; } -#endif // INPUTXSLT_SRC_SUPPORT_ERROR_CAPACITOR_H_ +#endif // INPUTXSLT_SRC_SUPPORT_ERROR_ERROR_MULTIPLEXER_H_ diff --git a/src/transformation_facade.cc b/src/transformation_facade.cc index f415cd8..6d7b7a3 100644 --- a/src/transformation_facade.cc +++ b/src/transformation_facade.cc @@ -7,6 +7,8 @@ #include <sstream> +#include "support/error/error_capacitor.h" + namespace InputXSLT { TransformationFacade::TransformationFacade( @@ -14,10 +16,11 @@ TransformationFacade::TransformationFacade( IncludeEntityResolver* resolver ): transformation_{}, - transformer_() { + transformer_(), + error_multiplexer_(&transformer_) { this->transformer_.setEntityResolver(resolver); - ErrorCapacitor errorCapacitor(&this->transformer_); + ErrorCapacitor errorCapacitor(&this->error_multiplexer_); this->transformer_.compileStylesheet( xalan::XSLTInputSource(transformation.data()), @@ -68,7 +71,7 @@ void TransformationFacade::generate( xalan::XSLTResultTarget&& outputTarget, StylesheetParameterGuard& ) { - ErrorCapacitor errorCapacitor(&this->transformer_); + ErrorCapacitor errorCapacitor(&this->error_multiplexer_); std::stringstream emptyStream("<dummy/>"); xalan::XSLTInputSource inputSource(emptyStream); diff --git a/src/transformation_facade.h b/src/transformation_facade.h index 4fb997b..53f1bbd 100644 --- a/src/transformation_facade.h +++ b/src/transformation_facade.h @@ -6,9 +6,9 @@ #include <string> #include "common.h" -#include "support/error_capacitor.h" #include "support/include_entity_resolver.h" #include "support/stylesheet_parameter_guard.h" +#include "support/error/error_multiplexer.h" namespace InputXSLT { @@ -30,6 +30,7 @@ class TransformationFacade { const xalan::XalanCompiledStylesheet* transformation_; xalan::XalanTransformer transformer_; + ErrorMultiplexer error_multiplexer_; void generate(const std::string&, StylesheetParameterGuard&); void generate(std::basic_ostream<char>&, StylesheetParameterGuard&); |