Merge branch 'java-director-exceptions'
* java-director-exceptions: Add recent Java director enhancements to the changes file Replace DirectorException::raiseJavaException with DirectorException::throwException Improve Java director exception customization documentation Add Swig::DirectorException directorthrows typemap for Java Cosmetic whitespace improvement in generated code from throws typemaps. Tidy up director_exception testcase Changes to use common DirectorException class Improved Java director exceptions documentation Java director exception handling improvements
This commit is contained in:
commit
069ce1f6e9
21 changed files with 709 additions and 224 deletions
15
Lib/go/director.swg
Normal file
15
Lib/go/director.swg
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* director.swg
|
||||
*
|
||||
* This file contains support for director classes so that Go proxy
|
||||
* methods can be called from C++.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace Swig {
|
||||
|
||||
class DirectorException : public std::exception {
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -259,8 +259,10 @@ namespace Swig {
|
|||
JavaExceptionMessage(JNIEnv *jenv, jthrowable throwable) : message_(jenv, exceptionMessageFromThrowable(jenv, throwable)) {
|
||||
}
|
||||
|
||||
const char *message() const {
|
||||
return message_.c_str("Could not get exception message in JavaExceptionMessage");
|
||||
// Return a C string of the exception message in the jthrowable passed in the constructor
|
||||
// If no message is available, null_string is return instead
|
||||
const char *message(const char *null_string = "Could not get exception message in JavaExceptionMessage") const {
|
||||
return message_.c_str(null_string);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -294,10 +296,11 @@ namespace Swig {
|
|||
public:
|
||||
|
||||
// Construct exception from a Java throwable
|
||||
DirectorException(JNIEnv *jenv, jthrowable throwable) : classname_(0), msg_(0) {
|
||||
DirectorException(JNIEnv *jenv, jthrowable throwable) : jenv_(jenv), throwable_(throwable), classname_(0), msg_(0) {
|
||||
|
||||
// Call Java method Object.getClass().getName() to obtain the throwable's class name (delimited by '/')
|
||||
if (throwable) {
|
||||
if (jenv && throwable) {
|
||||
jenv->ExceptionClear(); // Cannot invoke methods with any pending exceptions
|
||||
jclass throwclz = jenv->GetObjectClass(throwable);
|
||||
if (throwclz) {
|
||||
jclass clzclz = jenv->GetObjectClass(throwclz);
|
||||
|
|
@ -318,11 +321,11 @@ namespace Swig {
|
|||
}
|
||||
|
||||
JavaExceptionMessage exceptionmsg(jenv, throwable);
|
||||
msg_ = copystr(exceptionmsg.message());
|
||||
msg_ = copystr(exceptionmsg.message(0));
|
||||
}
|
||||
|
||||
// More general constructor for handling as a java.lang.RuntimeException
|
||||
DirectorException(const char *msg) : classname_(0), msg_(copystr(msg ? msg : "Unspecified DirectorException message")) {
|
||||
DirectorException(const char *msg) : jenv_(0), throwable_(0), classname_(0), msg_(msg ? copystr(msg) : 0) {
|
||||
}
|
||||
|
||||
~DirectorException() throw() {
|
||||
|
|
@ -331,31 +334,49 @@ namespace Swig {
|
|||
}
|
||||
|
||||
const char *what() const throw() {
|
||||
return msg_;
|
||||
return msg_ ? msg_ : "Unspecified DirectorException message";
|
||||
}
|
||||
|
||||
// Reconstruct and raise/throw the Java Exception that caused the DirectorException
|
||||
// Note that any error in the JNI exception handling results in a Java RuntimeException
|
||||
void raiseJavaException(JNIEnv *jenv) const {
|
||||
void throwException(JNIEnv *jenv) const {
|
||||
if (jenv) {
|
||||
jenv->ExceptionClear();
|
||||
if (jenv == jenv_ && throwable_) {
|
||||
// Throw original exception if not already pending
|
||||
jthrowable throwable = jenv->ExceptionOccurred();
|
||||
if (throwable && jenv->IsSameObject(throwable, throwable_) == JNI_FALSE) {
|
||||
jenv->ExceptionClear();
|
||||
throwable = 0;
|
||||
}
|
||||
if (!throwable)
|
||||
jenv->Throw(throwable_);
|
||||
} else {
|
||||
// Try and reconstruct original exception, but original stacktrace is not reconstructed
|
||||
jenv->ExceptionClear();
|
||||
|
||||
jmethodID ctorMethodID = 0;
|
||||
jclass throwableclass = 0;
|
||||
if (classname_) {
|
||||
throwableclass = jenv->FindClass(classname_);
|
||||
if (throwableclass)
|
||||
ctorMethodID = jenv->GetMethodID(throwableclass, "<init>", "(Ljava/lang/String;)V");
|
||||
}
|
||||
jmethodID ctorMethodID = 0;
|
||||
jclass throwableclass = 0;
|
||||
if (classname_) {
|
||||
throwableclass = jenv->FindClass(classname_);
|
||||
if (throwableclass)
|
||||
ctorMethodID = jenv->GetMethodID(throwableclass, "<init>", "(Ljava/lang/String;)V");
|
||||
}
|
||||
|
||||
if (ctorMethodID) {
|
||||
jenv->ThrowNew(throwableclass, what());
|
||||
} else {
|
||||
SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, what());
|
||||
}
|
||||
if (ctorMethodID) {
|
||||
jenv->ThrowNew(throwableclass, what());
|
||||
} else {
|
||||
SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated - use throwException
|
||||
void raiseJavaException(JNIEnv *jenv) const {
|
||||
throwException(jenv);
|
||||
}
|
||||
|
||||
// Create and throw the DirectorException
|
||||
static void raise(JNIEnv *jenv, jthrowable throwable) {
|
||||
throw DirectorException(jenv, throwable);
|
||||
}
|
||||
|
|
@ -380,11 +401,14 @@ namespace Swig {
|
|||
return target;
|
||||
}
|
||||
|
||||
JNIEnv *jenv_;
|
||||
jthrowable throwable_;
|
||||
const char *classname_;
|
||||
const char *msg_;
|
||||
};
|
||||
|
||||
// Helper method to determine if a Java throwable matches a particular Java class type
|
||||
// Note side effect of clearing any pending exceptions
|
||||
SWIGINTERN bool ExceptionMatches(JNIEnv *jenv, jthrowable throwable, const char *classname) {
|
||||
bool matches = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -1051,6 +1051,14 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
|
|||
%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1);
|
||||
return $null; %}
|
||||
|
||||
/* For methods to raise/throw the original Java exception thrown in a director method */
|
||||
%typemap(throws) Swig::DirectorException
|
||||
%{ $1.throwException(jenv);
|
||||
return $null; %}
|
||||
|
||||
/* Java to C++ DirectorException should already be handled. Suppress warning and do nothing in the
|
||||
event a user specifies a global: %catches(Swig::DirectorException); */
|
||||
%typemap(directorthrows) Swig::DirectorException ""
|
||||
|
||||
/* Typemaps for code generation in proxy classes and Java type wrapper classes */
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,22 @@ namespace Swig {
|
|||
}
|
||||
};
|
||||
|
||||
struct DirectorTypeMismatchException {
|
||||
// Base class for director exceptions.
|
||||
class DirectorException : public std::exception {
|
||||
public:
|
||||
static void raise(const char *msg) {
|
||||
// ... todo
|
||||
throw(DirectorException());
|
||||
}
|
||||
|
||||
static void raise(const octave_value &ov, const char *msg) {
|
||||
// ... todo
|
||||
raise(msg);
|
||||
}
|
||||
};
|
||||
|
||||
class DirectorTypeMismatchException : public DirectorException {
|
||||
public:
|
||||
static void raise(const char *msg) {
|
||||
// ... todo
|
||||
throw(DirectorTypeMismatchException());
|
||||
|
|
@ -58,7 +73,8 @@ namespace Swig {
|
|||
}
|
||||
};
|
||||
|
||||
struct DirectorPureVirtualException {
|
||||
class DirectorPureVirtualException : public DirectorException {
|
||||
public:
|
||||
static void raise(const char *msg) {
|
||||
// ... todo
|
||||
throw(DirectorPureVirtualException());
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@
|
|||
/* raise exception */
|
||||
%define %raise(obj, type, desc) sv_setsv(get_sv("@", GV_ADD), obj); SWIG_fail %enddef
|
||||
|
||||
/* For directors to raise/throw the original exception */
|
||||
%typemap(throws) Swig::DirectorException
|
||||
%{ sv_setsv(ERRSV, $1.getNative()); SWIG_fail; %}
|
||||
|
||||
/* Include the unified typemap library */
|
||||
%include <typemaps/swigtypemaps.swg>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue