summaryrefslogtreecommitdiffstats
path: root/src/bind
diff options
context:
space:
mode:
authorBob Jamison <ishmalius@gmail.com>2008-03-11 21:13:53 +0000
committerishmal <ishmal@users.sourceforge.net>2008-03-11 21:13:53 +0000
commitc12eeb6315500334d0a244d87f8a88936ee04959 (patch)
treef8ffc37515b41260d18e4ddf4012b9a7fa9107fe /src/bind
parentAdd more javac stuff. Add target="" attribute to javac (diff)
downloadinkscape-c12eeb6315500334d0a244d87f8a88936ee04959.tar.gz
inkscape-c12eeb6315500334d0a244d87f8a88936ee04959.zip
Got initial JS execution working
(bzr r5057)
Diffstat (limited to 'src/bind')
-rw-r--r--src/bind/java/org/inkscape/cmn/ScriptRunner.java211
-rw-r--r--src/bind/javabind-private.h2
-rw-r--r--src/bind/javabind.cpp179
-rw-r--r--src/bind/javabind.h29
4 files changed, 348 insertions, 73 deletions
diff --git a/src/bind/java/org/inkscape/cmn/ScriptRunner.java b/src/bind/java/org/inkscape/cmn/ScriptRunner.java
index a128af734..d05afd2e3 100644
--- a/src/bind/java/org/inkscape/cmn/ScriptRunner.java
+++ b/src/bind/java/org/inkscape/cmn/ScriptRunner.java
@@ -25,6 +25,7 @@
package org.inkscape.cmn;
import javax.script.*;
+import java.util.List;
import java.io.FileReader;
import java.io.PrintStream;
import java.io.OutputStream;
@@ -37,9 +38,40 @@ import javax.swing.JOptionPane;
*/
public class ScriptRunner
{
+/**
+ * Pointer back to the BinderyImpl C++ object that launched me
+ */
long backPtr;
+/**
+ * The script engine manager that we want to use
+ */
+ScriptEngineManager scriptEngineManager;
+
+
+//########################################################################
+//# MESSSAGES
+//########################################################################
+static void err(String message)
+{
+ System.err.println("ScriptRunner err:" + message);
+}
+
+static void msg(String message)
+{
+ System.out.println("ScriptRunner:" + message);
+}
+static void trace(String message)
+{
+ log.println("ScriptRunner:" + message);
+}
+
+
+
+//########################################################################
+//# REDIRECT STDERR / STDOUT
+//########################################################################
/**
* Redirect stdout
*/
@@ -55,7 +87,6 @@ public void write(int b)
}
-
/**
* Redirect stderr
*/
@@ -71,14 +102,27 @@ public void write(int b)
}
+/**
+ * A logging stream
+ */
+static PrintStream log;
+public native void logWrite(long ptr, int b);
+class LogStream extends OutputStream
+{
-static void err(String message)
+public void write(int b)
{
- JOptionPane.showMessageDialog(null, message,
- "Script Error", JOptionPane.ERROR_MESSAGE);
+ logWrite(backPtr, b);
}
+}
+
+
+//########################################################################
+//# RUN
+//########################################################################
+
/**
* Run a script buffer
@@ -87,12 +131,16 @@ static void err(String message)
* @param str the script buffer to execute
* @return true if successful, else false
*/
-public boolean run(String lang, String str)
+public boolean doRun(String lang, String str)
{
- ScriptEngineManager factory = new ScriptEngineManager();
// create JavaScript engine
- ScriptEngine engine = factory.getEngineByName(lang);
- // evaluate JavaScript code from given file - specified by first argument
+ ScriptEngine engine = scriptEngineManager.getEngineByName(lang);
+ if (engine == null)
+ {
+ err("doRun: cannot find script engine '" + lang + "'");
+ return false;
+ }
+ //execute script from buffer
try
{
engine.eval(str);
@@ -100,10 +148,41 @@ public boolean run(String lang, String str)
catch (javax.script.ScriptException e)
{
err("Executing script: " + e);
+ e.printStackTrace();
}
return true;
}
+/**
+ * Run a script buffer
+ *
+ * @param backPtr pointer back to the C context that called this
+ * @param lang the scripting language to run
+ * @param str the script buffer to execute
+ * @return true if successful, else false
+ */
+public static boolean run(String lang, String str)
+{
+ //wrap whole thing in try/catch, since this will
+ //likely be called from C
+ try
+ {
+ ScriptRunner runner = getInstance();
+ if (runner == null)
+ {
+ err("ScriptRunner not initialized");
+ return false;
+ }
+ return runner.doRun(lang, str);
+ }
+ catch (Exception e)
+ {
+ err("run :" + e);
+ e.printStackTrace();
+ return false;
+ }
+}
+
/**
* Run a script file
@@ -112,12 +191,16 @@ public boolean run(String lang, String str)
* @param fname the script file to execute
* @return true if successful, else false
*/
-public boolean runFile(String lang, String fname)
+public boolean doRunFile(String lang, String fname)
{
- ScriptEngineManager factory = new ScriptEngineManager();
// create JavaScript engine
- ScriptEngine engine = factory.getEngineByName(lang);
- // evaluate JavaScript code from given file - specified by first argument
+ ScriptEngine engine = scriptEngineManager.getEngineByName(lang);
+ if (engine == null)
+ {
+ err("doRunFile: cannot find script engine '" + lang + "'");
+ return false;
+ }
+ //try opening file and feeding into engine
FileReader in = null;
boolean ret = true;
try
@@ -152,58 +235,104 @@ public boolean runFile(String lang, String fname)
/**
- * Constructor
+ * Run a script file
+ *
* @param backPtr pointer back to the C context that called this
+ * @param lang the scripting language to run
+ * @param fname the script file to execute
+ * @return true if successful, else false
*/
-public ScriptRunner(long backPtr)
+public static boolean runFile(String lang, String fname)
{
- this.backPtr = backPtr;
- System.setOut(new PrintStream(new StdOutStream()));
- System.setErr(new PrintStream(new StdErrStream()));
+ //wrap whole thing in try/catch, since this will
+ //likely be called from C
+ try
+ {
+ ScriptRunner runner = getInstance();
+ if (runner == null)
+ {
+ err("ScriptRunner not initialized");
+ return false;
+ }
+ return runner.doRunFile(lang, fname);
+ }
+ catch (Exception e)
+ {
+ err("run :" + e);
+ return false;
+ }
}
-private static ScriptRunner _instance = null;
+//########################################################################
+//# CONSTRUCTOR
+//########################################################################
+
-public static ScriptRunner getInstance(long backPtr)
+private static ScriptRunner _instance = null;
+public static ScriptRunner getInstance()
{
- if (_instance == null)
- _instance = new ScriptRunner(backPtr);
return _instance;
}
-
-/**
- * Run a script buffer
- *
- * @param backPtr pointer back to the C context that called this
- * @param lang the scripting language to run
- * @param str the script buffer to execute
- * @return true if successful, else false
- */
-public static boolean run(long ptr, String lang, String str)
+private void listFactories()
{
- ScriptRunner runner = getInstance(ptr);
- return runner.run(lang, str);
+ List<ScriptEngineFactory> factories =
+ scriptEngineManager.getEngineFactories();
+ for (ScriptEngineFactory factory: factories)
+ {
+ log.println("ScriptEngineFactory Info");
+ String engName = factory.getEngineName();
+ String engVersion = factory.getEngineVersion();
+ String langName = factory.getLanguageName();
+ String langVersion = factory.getLanguageVersion();
+ log.printf("\tScript Engine: %s (%s)\n",
+ engName, engVersion);
+ List<String> engNames = factory.getNames();
+ for(String name: engNames)
+ {
+ log.printf("\tEngine Alias: %s\n", name);
+ }
+ log.printf("\tLanguage: %s (%s)\n",
+ langName, langVersion);
+ }
}
+
/**
- * Run a script file
- *
+ * Constructor
* @param backPtr pointer back to the C context that called this
- * @param lang the scripting language to run
- * @param fname the script file to execute
- * @return true if successful, else false
*/
-public static boolean runFile(long ptr, String lang, String fname)
+public ScriptRunner(long backPtr)
{
- ScriptRunner runner = getInstance(ptr);
- return runner.runFile(lang, fname);
+ /**
+ * Set up the output, error, and logging stream
+ */
+ System.setOut(new PrintStream(new StdOutStream()));
+ System.setErr(new PrintStream(new StdErrStream()));
+ log = new PrintStream(new LogStream());
+
+ //Point back to C++ object
+ this.backPtr = backPtr;
+
+ //Start up the factory
+ scriptEngineManager = new ScriptEngineManager();
+ listFactories();
+ _instance = this;
}
+static
+{
+
+}
}
+//########################################################################
+//# E N D O F F I L E
+//########################################################################
+
+
diff --git a/src/bind/javabind-private.h b/src/bind/javabind-private.h
index ce595fa85..f76118c28 100644
--- a/src/bind/javabind-private.h
+++ b/src/bind/javabind-private.h
@@ -63,6 +63,8 @@ public:
virtual bool doBinding();
+ virtual bool setupScriptRunner();
+
static JavaBinderyImpl *getInstance();
diff --git a/src/bind/javabind.cpp b/src/bind/javabind.cpp
index 3d68bdc15..5a8700633 100644
--- a/src/bind/javabind.cpp
+++ b/src/bind/javabind.cpp
@@ -285,40 +285,115 @@ static bool getRegistryString(HKEY root, const char *keyName,
}
+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
+};
+
static CreateVMFunc getCreateVMFunc()
{
- 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)
+ bool found = false;
+ String libname;
+
+ /**
+ * First, look for JAVA_HOME. This will allow the user
+ * to override what's in the registry
+ */
+ const char *envStr = getenv("JAVA_HOME");
+ if (envStr)
{
- err("JVM CurrentVersion not found in registry\n");
- return NULL;
+ String javaHome = cleanPath(envStr);
+ msg("JAVA_HOME='%s'", javaHome.c_str());
+ for (const char **path = commonJavaPaths ; *path ; path++)
+ {
+ String jpath = javaHome;
+ jpath.append(*path);
+ //msg("trying '%s'", jpath.c_str());
+ struct stat finfo;
+ if (stat(jpath.c_str(), &finfo)>=0)
+ {
+ //msg("found");
+ libname = jpath;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ //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);
+ }
+ }
}
- strcat(regpath, "\\");
- strcat(regpath, verbuf);
- //msg("reg path: %s\n", regpath);
- char libname[80];
- ret = getRegistryString(HKEY_LOCAL_MACHINE,
- regpath, "RuntimeLib", libname, 79);
- if (!ret)
+
+ if (!found)
{
- err("Current JVM RuntimeLib not found in registry\n");
+ err("JVM not found at JAVA_HOME or in registry");
return NULL;
}
- //msg("jvm path: %s\n", libname);
- HMODULE lib = LoadLibrary(libname);
+
+ /**
+ * 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);
+ 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");
+ err("Could not find 'JNI_CreateJavaVM' in shared library '%s'",
+ libname.c_str());
return NULL;
}
return createVM;
@@ -451,6 +526,7 @@ static CreateVMFunc getCreateVMFunc()
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)
{
@@ -547,7 +623,7 @@ static void populateClassPath(const String &javaroot,
//========================================================================
-// Native methods
+// SCRIPT RUNNER
//========================================================================
/**
* These methods are used to allow the ScriptRunner class to
@@ -569,14 +645,57 @@ void JNICALL stdErrWrite(JNIEnv */*env*/, jobject /*obj*/, jlong ptr, jint ch)
}
+void JNICALL logWrite(JNIEnv */*env*/, jobject /*obj*/, jlong ptr, jint ch)
+{
+ JavaBinderyImpl *bind = (JavaBinderyImpl *)ptr;
+ bind->log(ch);
+}
+
+
static JNINativeMethod scriptRunnerMethods[] =
{
{ (char *)"stdOutWrite", (char *)"(JI)V", (void *)stdOutWrite },
{ (char *)"stdErrWrite", (char *)"(JI)V", (void *)stdErrWrite },
+{ (char *)"logWrite", (char *)"(JI)V", (void *)logWrite },
{ NULL, NULL, NULL }
};
+
+/**
+ * This sets up the 'ScriptRunner' java class for execution of
+ * scripts
+ */
+bool JavaBinderyImpl::setupScriptRunner()
+{
+ String className = "org/inkscape/cmn/ScriptRunner";
+ if (!registerNatives(className, scriptRunnerMethods))
+ {
+ return false;
+ }
+ jclass cls = env->FindClass(className.c_str());
+ if (!cls)
+ {
+ err("setupScriptRunner: cannot find class '%s'", className.c_str());
+ return false;
+ }
+ jmethodID mid = env->GetMethodID(cls, "<init>", "(J)V");
+ if (!mid)
+ {
+ err("setupScriptRunner: cannot find constructor for '%s'", className.c_str());
+ return false;
+ }
+ jobject obj = env->NewObject(cls, mid, ((jlong)this));
+ if (!obj)
+ {
+ err("setupScriptRunner: cannot construct '%s'", className.c_str());
+ return false;
+ }
+ msg("ScriptRunner ready");
+ return true;
+}
+
+
//========================================================================
-// End native methods
+// End SCRIPT RUNNER
//========================================================================
@@ -647,16 +766,14 @@ bool JavaBinderyImpl::loadJVM()
int versionMinor = (vers ) & 0xffff;
msg("Loaded JVM version %d.%d", versionMajor, versionMinor);
- if (!registerNatives("org/inkscape/cmn/ScriptRunner",
- scriptRunnerMethods))
- {
+ if (!setupScriptRunner())
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
@@ -763,6 +880,12 @@ bool JavaBinderyImpl::callStatic(int type,
}
}
delete jvals;
+ String errStr = getException(env);
+ if (errStr.size()>0)
+ {
+ err("callStatic: %s", errStr.c_str());
+ return false;
+ }
return true;
}
@@ -800,7 +923,7 @@ bool JavaBinderyImpl::registerNatives(const String &className,
err("Could not find class '%s'", className.c_str());
return false;
}
- msg("registerNatives: class '%s' found", className.c_str());
+ //msg("registerNatives: class '%s' found", className.c_str());
/**
* hack for JDK bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6493522
diff --git a/src/bind/javabind.h b/src/bind/javabind.h
index 164110ea6..b20132d03 100644
--- a/src/bind/javabind.h
+++ b/src/bind/javabind.h
@@ -272,6 +272,11 @@ public:
stdOutBuf.clear();
}
+ virtual void stdOut(int ch)
+ {
+ stdOutBuf.push_back((char)ch);
+ }
+
virtual String stdErrGet()
{
return stdErrBuf;
@@ -282,14 +287,29 @@ public:
stdErrBuf.clear();
}
- virtual void stdOut(int ch)
+ virtual void stdErr(int ch)
{
- stdOutBuf.push_back((char)ch);
+ stdErrBuf.push_back((char)ch);
}
- virtual void stdErr(int ch)
+ virtual String logGet()
{
- stdErrBuf.push_back((char)ch);
+ return logBuf;
+ }
+
+ virtual void logClear()
+ {
+ logBuf.clear();
+ }
+
+ virtual void log(int ch)
+ {
+ logBuf.push_back((char)ch);
+ if (ch == '\n' || ch == '\r')
+ {
+ g_message(logBuf.c_str());
+ logBuf.clear();
+ }
}
@@ -303,6 +323,7 @@ protected:
String stdOutBuf;
String stdErrBuf;
+ String logBuf;
};