diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2013-07-23 10:54:01 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2013-07-23 10:54:01 +0000 |
| commit | eb7b26af09df66f30ba50058e9e4a583028cd81a (patch) | |
| tree | 384f5487c22c5ff04379dae851289d6ebd3167fc /src/bind/javabind.cpp | |
| parent | German translation update (diff) | |
| download | inkscape-eb7b26af09df66f30ba50058e9e4a583028cd81a.tar.gz inkscape-eb7b26af09df66f30ba50058e9e4a583028cd81a.zip | |
Remove the disabled script dialog and the nonfunctional Java binding
(bzr r12428)
Diffstat (limited to 'src/bind/javabind.cpp')
| -rw-r--r-- | src/bind/javabind.cpp | 1209 |
1 files changed, 0 insertions, 1209 deletions
diff --git a/src/bind/javabind.cpp b/src/bind/javabind.cpp deleted file mode 100644 index 8a66bac59..000000000 --- a/src/bind/javabind.cpp +++ /dev/null @@ -1,1209 +0,0 @@ -/** - * @file - * This is a simple mechanism to bind Inkscape to Java, and thence - * to all of the nice things that can be layered upon that. - * - * Note: We must limit Java or JVM-specific code to this file - * and to dobinding.cpp. It should be hidden from javabind.h - * - * This file is mostly about getting things up and running, and - * providing the basic C-to-Java hooks. - * - * dobinding.cpp will have the rote and repetitious - * class-by-class binding - */ -/* - * Authors: - * Bob Jamison - * - * Copyright (C) 2007-2008 Bob Jamison - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <jni.h> - -#include <sys/types.h> -#include <dirent.h> - - -#ifdef __WIN32__ -#include <windows.h> -#else -#include <dlfcn.h> -#include <errno.h> -#endif - -#if HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#include "javabind.h" -#include "javabind-private.h" -#include <path-prefix.h> -#include <prefix.h> -#include <glib.h> - -//For repr and document -#include <document.h> -#include <inkscape.h> -#include <xml/repr.h> - - - -namespace Inkscape -{ - -namespace Bind -{ - - -//######################################################################## -//# DEFINITIONS -//######################################################################## - -typedef jint (*CreateVMFunc)(JavaVM **, JNIEnv **, void *); - - - -//######################################################################## -//# UTILITY -//######################################################################## - -/** - * Normalize path. Java wants '/', even on Windows - */ -String normalizePath(const String &str) -{ - String buf; - for (unsigned int i=0 ; i<str.size() ; i++) - { - char ch = str[i]; - if (ch == '\\') - buf.push_back('/'); - else - buf.push_back(ch); - } - return buf; -} - - -/** - * Convert a java string to a C++ string - */ -static String getString(JNIEnv *env, jstring jstr) -{ - const char *chars = env->GetStringUTFChars(jstr, JNI_FALSE); - String str = chars; - env->ReleaseStringUTFChars(jstr, chars); - return str; -} - - -/** - * Check if the VM has encountered an Exception. If so, get the String for it - * and clear the exception - */ -String getExceptionString(JNIEnv *env) -{ - String buf; - jthrowable exc = env->ExceptionOccurred(); - if (!exc) - return buf; - jclass cls = env->GetObjectClass(exc); - jmethodID mid = env->GetMethodID(cls, "toString", "()Ljava/lang/String;"); - jstring jstr = (jstring) env->CallObjectMethod(exc, mid); - buf.append(getString(env, jstr)); - env->ExceptionClear(); - return buf; -} - -//######################################################################## -//# CONSTRUCTOR/DESTRUCTOR -//######################################################################## - -static JavaBinderyImpl *_instance = NULL; - -JavaBindery *JavaBindery::getInstance() -{ - return JavaBinderyImpl::getInstance(); -} - -JavaBinderyImpl *JavaBinderyImpl::getInstance() -{ - if (!_instance) - { - _instance = new JavaBinderyImpl(); - } - return _instance; -} - -JavaBinderyImpl::JavaBinderyImpl() -{ - jvm = NULL; - env = NULL; - gatewayObj = NULL; -} - -JavaBinderyImpl::~JavaBinderyImpl() -{ -} - - -//######################################################################## -//# MESSAGES -//######################################################################## - -void err(const char *fmt, ...) -{ - va_list args; - g_warning("JavaBinderyImpl err:"); - va_start(args, fmt); - g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, fmt, args); - va_end(args); - g_warning("\n"); -} - -void msg(const char *fmt, ...) -{ - va_list args; - g_message("JavaBinderyImpl:"); - va_start(args, fmt); - g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, args); - va_end(args); - g_message("\n"); -} - - - -//######################################################################## -//# W I N 3 2 S T Y L E -//######################################################################## -#ifdef __WIN32__ - - -#define DIR_SEPARATOR "\\" -#define PATH_SEPARATOR ";" - - - -static bool getRegistryString(HKEY /*root*/, const char *keyName, - const char *valName, char *buf, int buflen) -{ - HKEY key; - DWORD bufsiz = buflen; - RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key); - int ret = RegQueryValueEx(key, TEXT(valName), - NULL, NULL, (BYTE *)buf, &bufsiz); - if (ret != ERROR_SUCCESS) - { - err("Key '%s\\%s not found\n", keyName, valName); - return false; - } - RegCloseKey(key); - return true; -} - - -static String cleanPath(const String &s) -{ - String buf; - for (unsigned int i=0 ; i<s.size() ; i++) - { - char ch = s[i]; - if (ch != '"') - buf.push_back(ch); - } - return buf; -} - - -/** - * Common places to find jvm.dll under JAVA_HOME - */ -static const char *commonJavaPaths[] = -{ - "\\jre\\bin\\client\\jvm.dll", - "\\bin\\client\\jvm.dll", - "\\jvm.dll", - NULL -}; - - -/** - * Return the directory of the .exe that is currently running - */ -static String getExePath() -{ - char exeName[MAX_PATH+1]; - GetModuleFileName(NULL, exeName, MAX_PATH); - char *slashPos = strrchr(exeName, '\\'); - if (slashPos) - *slashPos = '\0'; - String s = exeName; - return s; -} - - -/** - * Check a directory for several possibilities of sub-locations - * under it, where a jvm might exist. - */ -static String checkPathUnderRoot(const String &root) -{ - for (const char **path = commonJavaPaths ; *path ; path++) - { - String jpath = root; - jpath.append(*path); - //msg("trying '%s'", jpath.c_str()); - struct stat finfo; - if (stat(jpath.c_str(), &finfo)>=0) - { - //msg("found"); - return jpath; - } - } - return ""; -} - - - -/** - * Attempt to find and load a jvm.dll file. Find the createVM() - * function's address and return it - */ -static CreateVMFunc getCreateVMFunc() -{ - bool found = false; - String libname; - - /** - * First, look for an embedded jre in the .exe's dir. - * This allows us to package our own JRE if we want to. - */ - String inkscapeHome = getExePath(); - inkscapeHome.append("\\jre"); - msg("INKSCAPE_HOME='%s'", inkscapeHome.c_str()); - String path = checkPathUnderRoot(inkscapeHome); - if (path.size() > 0) - { - libname = path; - found = true; - } - - /** - * Next, look for JAVA_HOME. This will allow the user - * to override what's in the registry - */ - if (!found) - { - const char *envStr = getenv("JAVA_HOME"); - if (envStr) - { - String javaHome = cleanPath(envStr); - msg("JAVA_HOME='%s'", javaHome.c_str()); - path = checkPathUnderRoot(javaHome); - if (path.size() > 0) - { - libname = path; - found = true; - } - } - } - - //not at JAVA_HOME. check the registry - if (!found) - { - char verbuf[16]; - char regpath[80]; - strcpy(regpath, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); - bool ret = getRegistryString(HKEY_LOCAL_MACHINE, - regpath, "CurrentVersion", verbuf, 15); - if (!ret) - { - msg("JVM CurrentVersion not found in registry at '%s'", regpath); - } - else - { - strcat(regpath, "\\"); - strcat(regpath, verbuf); - //msg("reg path: %s\n", regpath); - char valbuf[80]; - ret = getRegistryString(HKEY_LOCAL_MACHINE, - regpath, "RuntimeLib", valbuf, 79); - if (ret) - { - found = true; - libname = valbuf; - } - else - { - msg("JVM RuntimeLib not found in registry at '%s'", - regpath); - } - } - } - - if (!found) - { - err("JVM not found at JAVA_HOME or in registry"); - return NULL; - } - - /** - * If we are here, then we seem to have a valid path for jvm.dll - * Give it a try - */ - msg("getCreateVMFunc: Loading JVM: %s", libname.c_str()); - HMODULE lib = LoadLibrary(libname.c_str()); - if (!lib) - { - err("Java VM not found at '%s'", libname.c_str()); - return NULL; - } - CreateVMFunc createVM = (CreateVMFunc)GetProcAddress(lib, "JNI_CreateJavaVM"); - if (!createVM) - { - err("Could not find 'JNI_CreateJavaVM' in shared library '%s'", - libname.c_str()); - return NULL; - } - return createVM; -} - -/** - * Return the directory where the Java classes/libs/resources are - * located - */ -static void getJavaRoot(String &javaroot) -{ - /* - javaroot = getExePath(); - javaroot.append("\\"); - javaroot.append(INKSCAPE_BINDDIR); - javaroot.append("\\java"); - */ - javaroot = INKSCAPE_BINDDIR; - javaroot.append("\\java"); -} - - - - -//######################################################################## -//# U N I X S T Y L E -//######################################################################## -#else /* !__WIN32__ */ - - -#define DIR_SEPARATOR "/" -#define PATH_SEPARATOR ":" - - -/** - * Recursively descend into a directory looking for libjvm.so - */ -static bool findJVMRecursive(const String &dirpath, - std::vector<String> &results) -{ - DIR *dir = opendir(dirpath.c_str()); - if (!dir) - return false; - bool ret = false; - while (true) - { - struct dirent *de = readdir(dir); - if (!de) - break; - String fname = de->d_name; - if (fname == "." || fname == "..") - continue; - String path = dirpath; - path.push_back('/'); - path.append(fname); - if (fname == "libjvm.so") - { - ret = true; - results.push_back(path); - continue; - } - struct stat finfo; - if (lstat(path.c_str(), &finfo)<0) - { - break; - } - if (finfo.st_mode & S_IFDIR) - { - ret |= findJVMRecursive(path, results); - } - } - closedir(dir); - return ret; -} - - -/** - * Some common places on a Unix filesystem where JVMs are - * often found. - */ -static const char *commonJavaPaths[] = -{ - "/usr/lib/jvm/jre", - "/usr/lib/jvm", - "/usr/local/lib/jvm/jre", - "/usr/local/lib/jvm", - "/usr/java", - "/usr/local/java", - NULL -}; - - - -/** - * Look for a Java VM (libjvm.so) in several Unix places - */ -static bool findJVM(String &result) -{ - std::vector<String> results; - bool found = false; - - /* Is there one specified by the user? */ - const char *javaHome = getenv("JAVA_HOME"); - if (javaHome && findJVMRecursive(javaHome, results)) - found = true; - else for (const char **path = commonJavaPaths ; *path ; path++) - { - if (findJVMRecursive(*path, results)) - { - found = true; - break; - } - } - if (!found) - { - return false; - } - if (results.empty()) - return false; - //Look first for a Client VM - for (unsigned int i=0 ; i<results.size() ; i++) - { - String s = results[i]; - if (s.find("client") != s.npos) - { - result = s; - return true; - } - } - //else default to the first - result = results[0]; - return true; -} - - - -/** - * Attempt to find and load a jvm.dll file. Find the createVM() - * function's address and return it - */ -static CreateVMFunc getCreateVMFunc() -{ - String libname; - if (!findJVM(libname)) - { - err("No Java VM found. Is JAVA_HOME defined? Need to find 'libjvm.so'"); - return NULL; - } - msg("getCreateVMFunc: Loading JVM: %s", libname.c_str()); - void *lib = dlopen(libname.c_str(), RTLD_NOW); - if (!lib) - { - err("Java VM not found at '%s' : %s", libname.c_str(), strerror(errno)); - return NULL; - } - CreateVMFunc createVM = (CreateVMFunc)dlsym(lib, "JNI_CreateJavaVM"); - if (!createVM) - { - err("Could not find 'JNI_CreateJavaVM' in shared library"); - return NULL; - } - return createVM; -} - - -/** - * Return the directory where the Java classes/libs/resources are - * located - */ -static void getJavaRoot(String &javaroot) -{ - javaroot = INKSCAPE_BINDDIR; - javaroot.append("/java"); -} - -#endif /* !__WIN32__ */ - - -//######################################################################## -//# COMMON -//######################################################################## - - -bool JavaBinderyImpl::isLoaded() -{ - return (jvm != (void *)0); -} - - - -/** - * This will set up the classpath for the launched VM. - * We will add two things: - * 1. INKSCAPE_JAVADIR/classes -- path to loose classes - * 2. A concatenation of all jar files in INKSCAPE_JAVADIR/lib - * - * This will allow people to add classes and jars to the JVM without - * needing to state them explicitly. - * - * @param javaroot. Should be INKSCAPE_JAVADIR - * @param result a string buffer to hold the result of this method - */ -static void populateClassPath(const String &javaroot, - String &result) -{ - String classdir = javaroot; - classdir.append(DIR_SEPARATOR); - classdir.append("classes"); - - String cp = classdir; - - String libdir = javaroot; - libdir.append(DIR_SEPARATOR); - libdir.append("lib"); - - DIR *dir = opendir(libdir.c_str()); - if (!dir) - { - result = cp; - return; - } - - while (true) - { - struct dirent *de = readdir(dir); - if (!de) - break; - String fname = de->d_name; - if (fname == "." || fname == "..") - continue; - if (fname.size()<5) //x.jar - continue; - if (fname.compare(fname.size()-4, 4, ".jar") != 0) - continue; - - String path = libdir; - path.append(DIR_SEPARATOR); - path.append(fname); - - cp.append(PATH_SEPARATOR); - cp.append(path); - } - closedir(dir); - - result = cp; -} - - - -//======================================================================== -// Gateway -//======================================================================== -/** - * This is provided to scripts can grab the current copy or the - * repr tree. If anyone has a smarter way of doing this, please implement. - */ -static jstring JNICALL documentGet(JNIEnv *env, jobject /*obj*/, jlong /*ptr*/) -{ - //JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr; - String buf = sp_repr_save_buf((SP_ACTIVE_DOCUMENT)->rdoc); - jstring jstr = env->NewStringUTF(buf.c_str()); - return jstr; -} - -/** - * This is provided to scripts can load an XML tree into Inkscape. - * If anyone has a smarter way of doing this, please implement. - */ -static jboolean JNICALL documentSet(JNIEnv */*env*/, jobject /*obj*/, jlong /*ptr*/, jstring /*jstr*/) -{ - /* - JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr; - String s = getString(env, jstr); - SPDocument *doc = sp_document_new_from_mem(s.c_str(), s.size(), true); - */ - return JNI_TRUE; -} - -/** - * This method is used to allow the gateway class to - * redirect its logging stream here. - * For the main C++/Java bindings, see dobinding.cpp - */ -static void JNICALL logWrite(JNIEnv */*env*/, jobject /*obj*/, jlong ptr, jint ch) -{ - JavaBinderyImpl *bind = reinterpret_cast<JavaBinderyImpl *>(ptr); - bind->log(ch); -} - - -static JNINativeMethod gatewayMethods[] = -{ -{ (char *)"documentGet", (char *)"(J)Ljava/lang/String;", (void *)documentGet }, -{ (char *)"documentSet", (char *)"(JLjava/lang/String;)Z", (void *)documentSet }, -{ (char *)"logWrite", (char *)"(JI)V", (void *)logWrite }, -{ NULL, NULL, NULL } -}; - - -/** - * This sets up the 'Gateway' java class for execution of - * scripts. The class's constructor takes a jlong. This java long - * is used to store the pointer to 'this'. When ScriptRunner makes - * native calls, it passes that jlong back, so that it can call the - * methods of this C++ class. - */ -bool JavaBinderyImpl::setupGateway() -{ - String className = "org/inkscape/cmn/Gateway"; - if (!registerNatives(className, gatewayMethods)) - { - return false; - } - jclass cls = env->FindClass(className.c_str()); - if (!cls) - { - err("setupGateway: cannot find class '%s' : %s", - className.c_str(), getException().c_str()); - return false; - } - jmethodID mid = env->GetMethodID(cls, "<init>", "(J)V"); - if (!mid) - { - err("setupGateway: cannot find constructor for '%s' : %s", - className.c_str(), getException().c_str()); - return false; - } - gatewayObj = env->NewObject(cls, mid, ((jlong)this)); - if (!gatewayObj) - { - err("setupGateway: cannot construct '%s' : %s", - className.c_str(), getException().c_str()); - return false; - } - - msg("Gateway ready"); - return true; -} - -bool JavaBinderyImpl::scriptRun(const String &lang, const String &script) -{ - if (!loadJVM()) - return false; - - std::vector<Value> params; - Value langParm(lang); - params.push_back(langParm); - Value scriptParm(script); - params.push_back(scriptParm); - Value retval; - callInstance(Value::BIND_VOID, gatewayObj, "scriptRun", - "(Ljava/lang/String;Ljava/lang/String;)Z", params, retval); - return retval.getBoolean(); -} - -bool JavaBinderyImpl::scriptRunFile(const String &lang, const String &fname) -{ - if (!loadJVM()) - return false; - - std::vector<Value> params; - Value langParm(lang); - params.push_back(langParm); - Value fnameParm(fname); - params.push_back(fnameParm); - Value retval; - callInstance(Value::BIND_VOID, gatewayObj, "scriptRunFile", - "(Ljava/lang/String;Ljava/lang/String;)Z", params, retval); - return retval.getBoolean(); -} - -bool JavaBinderyImpl::showConsole() -{ - if (!loadJVM()) - return false; - - std::vector<Value> params; - Value retval; - callInstance(Value::BIND_VOID, gatewayObj, "showConsole", - "()Z", params, retval); - return retval.getBoolean(); -} - - -//======================================================================== -// End Gateway -//======================================================================== - - -/** - * This is used to grab output from the VM itself. See 'options' below. - */ -static int JNICALL vfprintfHook(FILE* /*f*/, const char *fmt, va_list args) -{ - g_logv(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, args); - return JNI_TRUE; -} - - -/** - * This is the most important part of this class. Here we - * attempt to find, load, and initialize a java (or mlvm?) virtual - * machine. - * - * @return true if successful, else false - */ -bool JavaBinderyImpl::loadJVM() -{ - if (jvm) - return true; - - CreateVMFunc createVM = getCreateVMFunc(); - if (!createVM) - { - err("Could not find 'JNI_CreateJavaVM' in shared library"); - return false; - } - - String javaroot; - getJavaRoot(javaroot); - String cp; - populateClassPath(javaroot, cp); - String classpath = "-Djava.class.path="; - classpath.append(normalizePath(cp)); - msg("Class path is: '%s'", classpath.c_str()); - - String libpath = "-Djava.library.path="; - libpath.append(javaroot); - libpath.append(DIR_SEPARATOR); - libpath.append("libm"); - libpath = normalizePath(libpath); - msg("Lib path is: '%s'", libpath.c_str()); - - JavaVMInitArgs vm_args; - JavaVMOption options[10];//should be enough - int nOptions = 0; - options[nOptions++].optionString = (char *)classpath.c_str(); - options[nOptions++].optionString = (char *)libpath.c_str(); - //options[nOptions++].optionString = (char *)"-verbose:jni"; - options[nOptions ].optionString = (char *)"vfprintf"; - options[nOptions++].extraInfo = (void *)vfprintfHook; - vm_args.version = JNI_VERSION_1_4; - vm_args.options = options; - vm_args.nOptions = nOptions; - vm_args.ignoreUnrecognized = true; - - if (createVM(&jvm, &env, &vm_args) < 0) - { - err("JNI_CreateJavaVM() failed"); - return false; - } - - //get jvm version - jint vers = env->GetVersion(); - int versionMajor = (vers>>16) & 0xffff; - int versionMinor = (vers ) & 0xffff; - msg("Loaded JVM version %d.%d", versionMajor, versionMinor); - - if (!setupGateway()) { - // set jvm = NULL, otherwise, this method will return true when called for the second time while the gateway might not have been created! - jvm->DestroyJavaVM(); - jvm = NULL; - env = NULL; - err("Java bindings: setupGateway() failed"); - return false; - } - - return true; -} - - -/** - * This is a difficult method. What we are doing is trying to - * call a static method with a list of arguments. Similar to - * a varargs call, we need to marshal the Values into their - * Java equivalents and make the proper call. - * - * @param type the return type of the method - * @param className the full (package / name) name of the java class - * @param methodName the name of the method being invoked - * @param signature the method signature (ex: "(Ljava/lang/String;I)V" ) - * that describes the param and return types of the method. - * @param retval the return value of the java method - * @return true if the call was successful, else false. This is not - * the return value of the method. - */ -bool JavaBinderyImpl::callStatic(int type, - const String &className, - const String &methodName, - const String &signature, - const std::vector<Value> ¶ms, - Value &retval) -{ - jclass cls = env->FindClass(className.c_str()); - if (!cls) - { - err("Could not find class '%s' : %s", - className.c_str(), getException().c_str()); - return false; - } - jmethodID mid = env->GetStaticMethodID(cls, - methodName.c_str(), signature.c_str()); - if (!mid) - { - err("Could not find method '%s:%s/%s' : %s", - className.c_str(), methodName.c_str(), - signature.c_str(), getException().c_str()); - return false; - } - /** - * Assemble your parameters into a form usable by JNI - */ - jvalue *jvals = new jvalue[params.size()]; - for (unsigned int i=0 ; i<params.size() ; i++) - { - Value v = params[i]; - switch (v.getType()) - { - case Value::BIND_BOOLEAN: - { - jvals[i].z = (jboolean)v.getBoolean(); - break; - } - case Value::BIND_INT: - { - jvals[i].i = (jint)v.getInt(); - break; - } - case Value::BIND_DOUBLE: - { - jvals[i].d = (jdouble)v.getDouble(); - break; - } - case Value::BIND_STRING: - { - jvals[i].l = (jobject) env->NewStringUTF(v.getString().c_str()); - break; - } - default: - { - err("Unknown value type: %d", v.getType()); - delete [] jvals; - return false; - } - } - } - switch (type) - { - case Value::BIND_VOID: - { - env->CallStaticVoidMethodA(cls, mid, jvals); - break; - } - case Value::BIND_BOOLEAN: - { - jboolean ret = env->CallStaticBooleanMethodA(cls, mid, jvals); - if (ret == JNI_TRUE) //remember, don't truncate - retval.setBoolean(true); - else - retval.setBoolean(false); - break; - } - case Value::BIND_INT: - { - jint ret = env->CallStaticIntMethodA(cls, mid, jvals); - retval.setInt(ret); - break; - } - case Value::BIND_DOUBLE: - { - jdouble ret = env->CallStaticDoubleMethodA(cls, mid, jvals); - retval.setDouble(ret); - break; - } - case Value::BIND_STRING: - { - jobject ret = env->CallStaticObjectMethodA(cls, mid, jvals); - jstring jstr = (jstring) ret; - const char *str = env->GetStringUTFChars(jstr, JNI_FALSE); - retval.setString(str); - env->ReleaseStringUTFChars(jstr, str); - break; - } - default: - { - err("Unknown return type: %d", type); - return false; - } - } - delete [] jvals; - String errStr = getException(); - if (errStr.size()>0) - { - err("callStatic: %s", errStr.c_str()); - return false; - } - return true; -} - - - -/** - * Another difficult method. However, this time we are operating - * on an existing instance jobject. - * - * @param type the return type of the method - * @param obj the instance upon which to make the call - * @param methodName the name of the method being invoked - * @param signature the method signature (ex: "(Ljava/lang/String;I)V" ) - * that describes the param and return types of the method. - * @param retval the return value of the java method - * @return true if the call was successful, else false. This is not - * the return value of the method. - */ -bool JavaBinderyImpl::callInstance( - int type, - const jobject obj, - const String &methodName, - const String &signature, - const std::vector<Value> ¶ms, - Value &retval) -{ - jmethodID mid = env->GetMethodID(env->GetObjectClass(obj), - methodName.c_str(), signature.c_str()); - if (!mid) - { - err("Could not find method '%s/%s' : %s", - methodName.c_str(), - signature.c_str(), getException().c_str()); - return false; - } - /** - * Assemble your parameters into a form usable by JNI - */ - jvalue *jvals = new jvalue[params.size()]; - for (unsigned int i=0 ; i<params.size() ; i++) - { - Value v = params[i]; - switch (v.getType()) - { - case Value::BIND_BOOLEAN: - { - jvals[i].z = (jboolean)v.getBoolean(); - break; - } - case Value::BIND_INT: - { - jvals[i].i = (jint)v.getInt(); - break; - } - case Value::BIND_DOUBLE: - { - jvals[i].d = (jdouble)v.getDouble(); - break; - } - case Value::BIND_STRING: - { - jvals[i].l = (jobject) env->NewStringUTF(v.getString().c_str()); - break; - } - default: - { - err("Unknown value type: %d", v.getType()); - delete [] jvals; - return false; - } - } - } - switch (type) - { - case Value::BIND_VOID: - { - env->CallVoidMethodA(obj, mid, jvals); - break; - } - case Value::BIND_BOOLEAN: - { - jboolean ret = env->CallBooleanMethodA(obj, mid, jvals); - if (ret == JNI_TRUE) //remember, don't truncate - retval.setBoolean(true); - else - retval.setBoolean(false); - break; - } - case Value::BIND_INT: - { - jint ret = env->CallIntMethodA(obj, mid, jvals); - retval.setInt(ret); - break; - } - case Value::BIND_DOUBLE: - { - jdouble ret = env->CallDoubleMethodA(obj, mid, jvals); - retval.setDouble(ret); - break; - } - case Value::BIND_STRING: - { - jobject ret = env->CallObjectMethodA(obj, mid, jvals); - jstring jstr = (jstring) ret; - const char *str = env->GetStringUTFChars(jstr, JNI_FALSE); - retval.setString(str); - env->ReleaseStringUTFChars(jstr, str); - break; - } - default: - { - err("Unknown return type: %d", type); - return false; - } - } - delete [] jvals; - String errStr = getException(); - if (errStr.size()>0) - { - err("callStatic: %s", errStr.c_str()); - return false; - } - return true; -} - - - - -/** - * Fetch the last exception from the JVM, if any. Clear it to - * continue processing - * - * @return the exception's descriptio,if any. Else "" - */ -String JavaBinderyImpl::getException() -{ - return getExceptionString(env); -} - - - -/** - * Convenience method to call the static void main(String argv[]) - * method of a given class - * - * @param className full name of the java class - * @args the argument strings to the method - * @return true if successful, else false - */ -bool JavaBinderyImpl::callMain(const String &className, - const std::vector<String> &args) -{ - std::vector<Value> parms; - for (unsigned int i=0 ; i<args.size() ; i++) - { - Value v; - v.setString(args[i]); - parms.push_back(v); - } - Value retval; - return callStatic(Value::BIND_VOID, className, "main", - "([Ljava/lang/String;)V", parms, retval); -} - - -/** - * Used to register an array of native methods for a named class - * - * @param className the full name of the java class - * @param the method array - * @return true if successful, else false - */ -bool JavaBinderyImpl::registerNatives(const String &className, - const JNINativeMethod *methods) -{ - jclass cls = env->FindClass(className.c_str()); - if (!cls) - { - err("Could not find class '%s'", className.c_str()); - return false; - } - //msg("registerNatives: class '%s' found", className.c_str()); - - /** - * hack for JDK bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6493522 - */ - jmethodID mid = env->GetMethodID(env->GetObjectClass(cls), "getConstructors", - "()[Ljava/lang/reflect/Constructor;"); - if (!mid) - { - err("Could not get reflect mid for 'getConstructors' : %s", - getException().c_str()); - return false; - } - jobject res = env->CallObjectMethod(cls, mid); - if (!res) - { - err("Could not get constructors : %s", getException().c_str()); - return false; - } - /** - * end hack - */ - jint nrMethods = 0; - for (const JNINativeMethod *m = methods ; m->name ; m++) - nrMethods++; - jint ret = env->RegisterNatives(cls, methods, nrMethods); - if (ret < 0) - { - err("Could not register %d native methods for '%s' : %s", - nrMethods, className.c_str(), getException().c_str()); - return false; - } - return true; -} - - - - -} // namespace Bind -} // namespace Inkscape - -//######################################################################## -//# E N D O F F I L E -//######################################################################## |
