aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerländer2014-05-30 22:19:32 +0200
committerAdrian Kummerländer2014-05-30 22:19:32 +0200
commit79d3e2bdfd441d6eba2f22af78d5bea5e488daf1 (patch)
treeb28b0603958140777ee46d98f2fc4359c9f72c4d
parent484143667bd6885236b679a8f54dad3c512ea2dd (diff)
downloadInputXSLT-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.txt2
-rw-r--r--src/function/transform.cc19
-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.cc49
-rw-r--r--src/transformation_facade.h33
-rw-r--r--test.cc33
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);
}
}
diff --git a/test.cc b/test.cc
index 0c5e4b2..6874fd5 100644
--- a/test.cc
+++ b/test.cc
@@ -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;