summaryrefslogtreecommitdiff
path: root/libdb_java/java_except.i
diff options
context:
space:
mode:
Diffstat (limited to 'libdb_java/java_except.i')
-rw-r--r--libdb_java/java_except.i180
1 files changed, 180 insertions, 0 deletions
diff --git a/libdb_java/java_except.i b/libdb_java/java_except.i
new file mode 100644
index 0000000..2ea416b
--- /dev/null
+++ b/libdb_java/java_except.i
@@ -0,0 +1,180 @@
+%{
+/*
+ * Macros to find the Java DbEnv object for methods in various classes.
+ * Note that "arg1" is from the code SWIG generates for the "this"/"self".
+ */
+#define JDBENV (arg1 ? (jobject)DB_ENV_INTERNAL(arg1) : NULL)
+#define DB2JDBENV ((jobject)DB_ENV_INTERNAL(arg1->dbenv))
+#define DBC2JDBENV ((jobject)DB_ENV_INTERNAL(arg1->dbp->dbenv))
+#define TXN2JDBENV ((jobject)DB_ENV_INTERNAL(arg1->mgrp->env->dbenv))
+%}
+
+/* Common case exception handling */
+%typemap(check) SWIGTYPE *self %{
+ if ($input == 0) {
+ __dbj_throw(jenv, EINVAL, "call on closed handle", NULL, NULL);
+ return $null;
+ }%}
+
+%define JAVA_EXCEPT_NONE
+%exception %{ $action %}
+%enddef
+
+/* Most methods return an error code. */
+%define JAVA_EXCEPT(_retcheck, _jdbenv)
+%exception %{
+ $action
+ if (!_retcheck(result)) {
+ __dbj_throw(jenv, result, NULL, NULL, _jdbenv);
+ }
+%}
+%enddef
+
+/* For everything else, errno is set in db.i. */
+%define JAVA_EXCEPT_ERRNO(_retcheck, _jdbenv)
+%exception %{
+ errno = 0;
+ $action
+ if (!_retcheck(errno)) {
+ __dbj_throw(jenv, errno, NULL, NULL, _jdbenv);
+ }
+%}
+%enddef
+
+/* And then there are these (extra) special cases. */
+%exception __db_env::lock_get %{
+ errno = 0;
+ $action
+ if (errno == DB_LOCK_NOTGRANTED) {
+ (*jenv)->Throw(jenv,
+ (*jenv)->NewObject(jenv, lockex_class, lockex_construct,
+ (*jenv)->NewStringUTF(jenv, "DbEnv.lock_get not granted"),
+ DB_LOCK_GET, arg5, jarg4, NULL, -1, JDBENV));
+ } else if (!DB_RETOK_STD(errno)) {
+ __dbj_throw(jenv, errno, NULL, NULL, JDBENV);
+ }
+%}
+
+%{
+static jthrowable __dbj_get_except(JNIEnv *jenv,
+ int err, const char *msg, jobject obj, jobject jdbenv) {
+ jobject jmsg;
+
+ if (msg == NULL)
+ msg = db_strerror(err);
+
+ jmsg = (*jenv)->NewStringUTF(jenv, msg);
+
+ /* Retrieve error message logged by DB */
+ if (jdbenv != NULL) {
+ jmsg = (jstring) (*jenv)->CallNonvirtualObjectMethod(jenv,
+ jdbenv, dbenv_class, get_err_msg_method, jmsg);
+ }
+
+ switch (err) {
+ case EINVAL:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ illegalargex_class, illegalargex_construct, jmsg);
+
+ case ENOENT:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ filenotfoundex_class, filenotfoundex_construct, jmsg);
+
+ case ENOMEM:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ outofmemerr_class, outofmemerr_construct, jmsg);
+
+ case DB_BUFFER_SMALL:
+ return (jthrowable)(*jenv)->NewObject(jenv, memex_class,
+ memex_construct, jmsg, obj, err, jdbenv);
+
+ case DB_REP_DUPMASTER:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ repdupmasterex_class, repdupmasterex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_HANDLE_DEAD:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ rephandledeadex_class, rephandledeadex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_HOLDELECTION:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ repholdelectionex_class, repholdelectionex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_JOIN_FAILURE:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ repjoinfailex_class, repjoinfailex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_LEASE_EXPIRED:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ repleaseexpiredex_class, repleaseexpiredex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_LEASE_TIMEOUT:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ repleasetimeoutex_class, repleasetimeoutex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_LOCKOUT:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ replockoutex_class, replockoutex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_REP_UNAVAIL:
+ return (jthrowable)(*jenv)->NewObject(jenv,
+ repunavailex_class, repunavailex_construct,
+ jmsg, err, jdbenv);
+
+ case DB_RUNRECOVERY:
+ return (jthrowable)(*jenv)->NewObject(jenv, runrecex_class,
+ runrecex_construct, jmsg, err, jdbenv);
+
+ case DB_LOCK_DEADLOCK:
+ return (jthrowable)(*jenv)->NewObject(jenv, deadex_class,
+ deadex_construct, jmsg, err, jdbenv);
+
+ case DB_LOCK_NOTGRANTED:
+ return (jthrowable)(*jenv)->NewObject(jenv, lockex_class,
+ lockex_construct, jmsg, err, 0, NULL, NULL, 0, jdbenv);
+
+ case DB_VERSION_MISMATCH:
+ return (jthrowable)(*jenv)->NewObject(jenv, versionex_class,
+ versionex_construct, jmsg, err, jdbenv);
+
+ default:
+ return (jthrowable)(*jenv)->NewObject(jenv, dbex_class,
+ dbex_construct, jmsg, err, jdbenv);
+ }
+}
+
+static int __dbj_throw(JNIEnv *jenv,
+ int err, const char *msg, jobject obj, jobject jdbenv)
+{
+ jthrowable t;
+
+ /* If an exception is pending, ignore requests to throw a new one. */
+ if ((*jenv)->ExceptionOccurred(jenv) == NULL) {
+ t = __dbj_get_except(jenv, err, msg, obj, jdbenv);
+ if (t == NULL) {
+ /*
+ * This is a problem - something went wrong creating an
+ * exception. We have to assume there is an exception
+ * created by the JVM that is pending as a result
+ * (e.g., OutOfMemoryError), but we don't want to lose
+ * this error, so we just call __db_errx here.
+ */
+ if (msg == NULL)
+ msg = db_strerror(err);
+
+ __db_errx(NULL, "Couldn't create exception for: '%s'",
+ msg);
+ } else
+ (*jenv)->Throw(jenv, t);
+ }
+
+ return (err);
+}
+%}