aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerländer2014-06-05 20:44:26 +0200
committerAdrian Kummerländer2014-06-05 20:44:26 +0200
commit78bb3387b15d15d766fb5d17a99612f0480f2bee (patch)
treec87a2516f56d7f6317a704b91b340bc14cabfd28
parent11355181c0b5f8377774daefcc17bb5e6bc20f61 (diff)
downloadInputXSLT-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.txt3
-rw-r--r--ixslt.cc7
-rw-r--r--src/function/transform.cc1
-rw-r--r--src/support/error/error_capacitor.cc37
-rw-r--r--src/support/error/error_capacitor.h46
-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.cc9
-rw-r--r--src/transformation_facade.h3
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
diff --git a/ixslt.cc b/ixslt.cc
index 76c35d3..d65e5aa 100644
--- a/ixslt.cc
+++ b/ixslt.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&);