Skip to content
Browse files

Merge pull request #200 from ruboto/jruby_adapter_and_script_rewrite

* Issue #103 Split Script responsibilities into JRubyAdapter and Script.
  • Loading branch information...
2 parents ada55bb + bf6b172 commit 49e7ae67793bbd1e2b57b54f99f44d6ce43703d3 @donv donv committed
View
6 assets/src/InheritingBroadcastReceiver.java
@@ -1,20 +1,20 @@
package THE_PACKAGE;
-import org.ruboto.Script;
+import org.ruboto.JRubyAdapter;
public class InheritingBroadcastReceiver extends org.ruboto.RubotoBroadcastReceiver {
private boolean scriptLoaded = false;
public InheritingBroadcastReceiver() {
super("sample_broadcast_receiver.rb");
- if (Script.isInitialized()) {
+ if (JRubyAdapter.isInitialized()) {
scriptLoaded = true;
}
}
public void onReceive(android.content.Context context, android.content.Intent intent) {
if (!scriptLoaded) {
- if (Script.setUpJRuby(context)) {
+ if (JRubyAdapter.setUpJRuby(context)) {
loadScript();
scriptLoaded = true;
} else {
View
2 assets/src/InheritingClass.java
@@ -1,6 +1,6 @@
package THE_PACKAGE;
-import org.ruboto.Script;
+import org.ruboto.JRubyAdapter;
public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
View
34 assets/src/RubotoActivity.java
@@ -62,7 +62,7 @@ public void onCreate(Bundle bundle) {
super.onCreate(bundle);
- if (Script.isInitialized()) {
+ if (JRubyAdapter.isInitialized()) {
prepareJRuby();
loadScript();
}
@@ -70,32 +70,36 @@ public void onCreate(Bundle bundle) {
// This causes JRuby to initialize and takes a while.
protected void prepareJRuby() {
- Script.put("$context", this);
- Script.put("$activity", this);
- Script.put("$bundle", args[0]);
+ JRubyAdapter.put("$context", this);
+ JRubyAdapter.put("$activity", this);
+ JRubyAdapter.put("$bundle", args[0]);
}
protected void loadScript() {
try {
if (scriptName != null) {
- new Script(scriptName).execute();
String rubyClassName = Script.toCamelCase(scriptName);
System.out.println("Looking for Ruby class: " + rubyClassName);
- Object rubyClass = Script.get(rubyClassName);
+ Object rubyClass = JRubyAdapter.get(rubyClassName);
+ if (rubyClass == null) {
+ System.out.println("Loading script: " + scriptName);
+ JRubyAdapter.exec(new Script(scriptName).getContents());
+ }
+ rubyClass = JRubyAdapter.get(rubyClassName);
if (rubyClass != null) {
System.out.println("Instanciating Ruby class: " + rubyClassName);
- Script.put("$java_activity", this);
- Script.exec("$ruby_activity = " + rubyClassName + ".new($java_activity)");
- rubyInstance = Script.get("$ruby_activity");
- Script.exec("$ruby_activity.on_create($bundle)");
+ JRubyAdapter.put("$java_activity", this);
+ JRubyAdapter.exec("$ruby_activity = " + rubyClassName + ".new($java_activity)");
+ rubyInstance = JRubyAdapter.get("$ruby_activity");
+ JRubyAdapter.exec("$ruby_activity.on_create($bundle)");
}
} else if (configBundle != null) {
- // TODO: Why doesn't this work?
- // Script.callMethod(this, "initialize_ruboto");
- Script.execute("$activity.initialize_ruboto");
// TODO: Why doesn't this work?
- // Script.callMethod(this, "on_create", args[0]);
- Script.execute("$activity.on_create($bundle)");
+ // JRubyAdapter.callMethod(this, "initialize_ruboto");
+ JRubyAdapter.execute("$activity.initialize_ruboto");
+ // TODO: Why doesn't this work?
+ // JRubyAdapter.callMethod(this, "on_create", args[0]);
+ JRubyAdapter.execute("$activity.on_create($bundle)");
}
} catch(IOException e){
e.printStackTrace();
View
26 assets/src/RubotoBroadcastReceiver.java
@@ -25,25 +25,25 @@ public THE_RUBOTO_CLASS(String name) {
if (name != null) {
setScriptName(name);
- if (Script.isInitialized()) {
+ if (JRubyAdapter.isInitialized()) {
loadScript();
}
}
}
protected void loadScript() {
- Script.put("$broadcast_receiver", this);
+ JRubyAdapter.put("$broadcast_receiver", this);
if (scriptName != null) {
try {
- new Script(scriptName).execute();
+ JRubyAdapter.exec(new Script(scriptName).getContents());
String rubyClassName = Script.toCamelCase(scriptName);
System.out.println("Looking for Ruby class: " + rubyClassName);
- Object rubyClass = Script.get(rubyClassName);
+ Object rubyClass = JRubyAdapter.get(rubyClassName);
if (rubyClass != null) {
System.out.println("Instanciating Ruby class: " + rubyClassName);
- Script.put("$java_broadcast_receiver", this);
- Script.exec("$ruby_broadcast_receiver = " + rubyClassName + ".new($java_broadcast_receiver)");
- rubyInstance = Script.get("$ruby_broadcast_receiver");
+ JRubyAdapter.put("$java_broadcast_receiver", this);
+ JRubyAdapter.exec("$ruby_broadcast_receiver = " + rubyClassName + ".new($java_broadcast_receiver)");
+ rubyInstance = JRubyAdapter.get("$ruby_broadcast_receiver");
}
} catch(IOException e) {
throw new RuntimeException("IOException loading broadcast receiver script", e);
@@ -54,18 +54,16 @@ protected void loadScript() {
public void onReceive(android.content.Context context, android.content.Intent intent) {
try {
System.out.println("onReceive: " + rubyInstance);
- Script.put("$context", context);
- Script.put("$broadcast_receiver", this);
- Script.put("$intent", intent);
+ JRubyAdapter.put("$context", context);
+ JRubyAdapter.put("$broadcast_receiver", this);
+ JRubyAdapter.put("$intent", intent);
if (rubyInstance != null) {
- Script.exec("$ruby_broadcast_receiver.on_receive($context, $intent)");
+ JRubyAdapter.exec("$ruby_broadcast_receiver.on_receive($context, $intent)");
} else {
- Script.execute("$broadcast_receiver.on_receive($context, $intent)");
+ JRubyAdapter.execute("$broadcast_receiver.on_receive($context, $intent)");
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
-
-
View
22 assets/src/RubotoService.java
@@ -32,27 +32,27 @@ public void onCreate() {
super.onCreate();
- if (Script.setUpJRuby(this)) {
- Script.defineGlobalVariable("$context", this);
- Script.defineGlobalVariable("$service", this);
+ if (JRubyAdapter.setUpJRuby(this)) {
+ JRubyAdapter.defineGlobalVariable("$context", this);
+ JRubyAdapter.defineGlobalVariable("$service", this);
try {
if (scriptName != null) {
System.out.println("Loading service script: " + scriptName);
- new Script(scriptName).execute();
+ JRubyAdapter.exec(new Script(scriptName).getContents());
String rubyClassName = Script.toCamelCase(scriptName);
System.out.println("Looking for Ruby class: " + rubyClassName);
- Object rubyClass = Script.get(rubyClassName);
+ Object rubyClass = JRubyAdapter.get(rubyClassName);
if (rubyClass != null) {
System.out.println("Instanciating Ruby class: " + rubyClassName);
- Script.put("$java_service", this);
- Script.exec("$ruby_service = " + rubyClassName + ".new($java_service)");
- rubyInstance = Script.get("$ruby_service");
- Script.exec("$ruby_service.on_create");
+ JRubyAdapter.put("$java_service", this);
+ JRubyAdapter.exec("$ruby_service = " + rubyClassName + ".new($java_service)");
+ rubyInstance = JRubyAdapter.get("$ruby_service");
+ JRubyAdapter.exec("$ruby_service.on_create");
}
} else {
- Script.execute("$service.initialize_ruboto");
- Script.execute("$service.on_create");
+ JRubyAdapter.execute("$service.initialize_ruboto");
+ JRubyAdapter.execute("$service.on_create");
}
} catch(IOException e) {
e.printStackTrace();
View
8 assets/src/org/ruboto/EntryPointActivity.java
@@ -1,7 +1,5 @@
package org.ruboto;
-import org.ruboto.Script;
-
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -32,7 +30,7 @@ public void onCreate(Bundle bundle) {
splash = -1;
}
- if (Script.isInitialized()) {
+ if (JRubyAdapter.isInitialized()) {
appStarted = true;
}
super.onCreate(bundle);
@@ -48,7 +46,7 @@ public void onResume() {
}
Log.d("RUBOTO", "onResume: Checking JRuby");
- if (Script.isInitialized()) {
+ if (JRubyAdapter.isInitialized()) {
Log.d("RUBOTO", "Already initialized");
fireRubotoActivity();
} else {
@@ -100,7 +98,7 @@ public void onDestroy() {
private void initJRuby(final boolean firstTime) {
new Thread(new Runnable() {
public void run() {
- final boolean jrubyOk = Script.setUpJRuby(EntryPointActivity.this);
+ final boolean jrubyOk = JRubyAdapter.setUpJRuby(EntryPointActivity.this);
if (jrubyOk) {
Log.d("RUBOTO", "onResume: JRuby OK");
prepareJRuby();
View
476 assets/src/org/ruboto/JRubyAdapter.java
@@ -0,0 +1,476 @@
+package org.ruboto;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Environment;
+import dalvik.system.PathClassLoader;
+
+public class JRubyAdapter {
+ private static Object ruby;
+ private static boolean isDebugBuild = false;
+ private static PrintStream output = null;
+ private static boolean initialized = false;
+
+ private static String localContextScope = "SINGLETON";
+ private static String localVariableBehavior = "TRANSIENT";
+
+ private static String RUBOTO_CORE_VERSION_NAME;
+
+ /*************************************************************************************************
+ *
+ * Static Methods: ScriptingContainer config
+ */
+
+ public static void setLocalContextScope(String val) {
+ localContextScope = val;
+ }
+
+ public static void setLocalVariableBehavior(String val) {
+ localVariableBehavior = val;
+ }
+
+ /*************************************************************************************************
+ *
+ * Static Methods: JRuby Execution
+ */
+
+ public static final FilenameFilter RUBY_FILES = new FilenameFilter() {
+ public boolean accept(File dir, String fname) {
+ return fname.endsWith(".rb");
+ }
+ };
+
+ public static synchronized boolean isInitialized() {
+ return initialized;
+ }
+
+ public static boolean usesPlatformApk() {
+ return RUBOTO_CORE_VERSION_NAME != null;
+ }
+
+ public static String getPlatformVersionName() {
+ return RUBOTO_CORE_VERSION_NAME;
+ }
+
+ public static synchronized boolean setUpJRuby(Context appContext) {
+ return setUpJRuby(appContext, output == null ? System.out : output);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static synchronized boolean setUpJRuby(Context appContext, PrintStream out) {
+ if (!initialized) {
+ // BEGIN Ruboto HeapAlloc
+ @SuppressWarnings("unused")
+ byte[] arrayForHeapAllocation = new byte[13 * 1024 * 1024];
+ arrayForHeapAllocation = null;
+ // END Ruboto HeapAlloc
+ setDebugBuild(appContext);
+ Log.d("Setting up JRuby runtime (" + (isDebugBuild ? "DEBUG" : "RELEASE") + ")");
+ System.setProperty("jruby.bytecode.version", "1.6");
+ System.setProperty("jruby.interfaces.useProxy", "true");
+ System.setProperty("jruby.management.enabled", "false");
+ System.setProperty("jruby.objectspace.enabled", "false");
+ System.setProperty("jruby.thread.pooling", "true");
+ System.setProperty("jruby.native.enabled", "false");
+ // System.setProperty("jruby.compat.version", "RUBY1_8"); // RUBY1_9 is the default
+
+ // Uncomment these to debug Ruby source loading
+ // System.setProperty("jruby.debug.loadService", "true");
+ // System.setProperty("jruby.debug.loadService.timing", "true");
+
+
+ ClassLoader classLoader;
+ Class<?> scriptingContainerClass;
+ String apkName = null;
+
+ try {
+ scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer");
+ System.out.println("Found JRuby in this APK");
+ classLoader = JRubyAdapter.class.getClassLoader();
+ try {
+ apkName = appContext.getPackageManager().getApplicationInfo(appContext.getPackageName(), 0).sourceDir;
+ } catch (NameNotFoundException e) {}
+ } catch (ClassNotFoundException e1) {
+ String packageName = "org.ruboto.core";
+ try {
+ PackageInfo pkgInfo = appContext.getPackageManager().getPackageInfo(packageName, 0);
+ apkName = pkgInfo.applicationInfo.sourceDir;
+ RUBOTO_CORE_VERSION_NAME = pkgInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e2) {
+ out.println("JRuby not found in local APK:");
+ e1.printStackTrace(out);
+ out.println("JRuby not found in platform APK:");
+ e2.printStackTrace(out);
+ return false;
+ }
+
+ System.out.println("Found JRuby in platform APK");
+ classLoader = new PathClassLoader(apkName, JRubyAdapter.class.getClassLoader());
+
+ try {
+ scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer", true, classLoader);
+ } catch (ClassNotFoundException e) {
+ // FIXME(uwe): ScriptingContainer not found in the platform APK...
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ try {
+ Class scopeClass = Class.forName("org.jruby.embed.LocalContextScope", true, scriptingContainerClass.getClassLoader());
+ Class behaviorClass = Class.forName("org.jruby.embed.LocalVariableBehavior", true, scriptingContainerClass.getClassLoader());
+
+ ruby = scriptingContainerClass
+ .getConstructor(scopeClass, behaviorClass)
+ .newInstance(Enum.valueOf(scopeClass, localContextScope),
+ Enum.valueOf(behaviorClass, localVariableBehavior));
+
+ Class compileModeClass = Class.forName("org.jruby.RubyInstanceConfig$CompileMode", true, classLoader);
+ callScriptingContainerMethod(Void.class, "setCompileMode", Enum.valueOf(compileModeClass, "OFF"));
+
+ // Class traceTypeClass = Class.forName("org.jruby.runtime.backtrace.TraceType", true, classLoader);
+ // Method traceTypeForMethod = traceTypeClass.getMethod("traceTypeFor", String.class);
+ // Object traceTypeRaw = traceTypeForMethod.invoke(null, "raw");
+ // callScriptingContainerMethod(Void.class, "setTraceType", traceTypeRaw);
+
+ // FIXME(uwe): Write tutorial on profiling.
+ // container.getProvider().getRubyInstanceConfig().setProfilingMode(mode);
+
+ // callScriptingContainerMethod(Void.class, "setClassLoader", classLoader);
+ Method setClassLoaderMethod = ruby.getClass().getMethod("setClassLoader", ClassLoader.class);
+ setClassLoaderMethod.invoke(ruby, classLoader);
+
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ String defaultCurrentDir = appContext.getFilesDir().getPath();
+ Log.d("Setting JRuby current directory to " + defaultCurrentDir);
+ callScriptingContainerMethod(Void.class, "setCurrentDirectory", defaultCurrentDir);
+
+ if (out != null) {
+ output = out;
+ setOutputStream(out);
+ } else if (output != null) {
+ setOutputStream(output);
+ }
+
+ String jrubyHome = "file:" + apkName + "!";
+ Log.i("Setting JRUBY_HOME: " + jrubyHome);
+ System.setProperty("jruby.home", jrubyHome);
+
+ String extraScriptsDir = scriptsDirName(appContext);
+ Log.i("Checking scripts in " + extraScriptsDir);
+ if (configDir(extraScriptsDir)) {
+ Log.i("Added extra scripts path: " + extraScriptsDir);
+ }
+ initialized = true;
+ } catch (ClassNotFoundException e) {
+ handleInitException(e);
+ } catch (IllegalArgumentException e) {
+ handleInitException(e);
+ } catch (SecurityException e) {
+ handleInitException(e);
+ } catch (InstantiationException e) {
+ handleInitException(e);
+ } catch (IllegalAccessException e) {
+ handleInitException(e);
+ } catch (InvocationTargetException e) {
+ handleInitException(e);
+ } catch (NoSuchMethodException e) {
+ handleInitException(e);
+ }
+ }
+ return initialized;
+ }
+
+ private static String scriptsDirName(Context context) {
+ File storageDir = null;
+ if (JRubyAdapter.isDebugBuild()) {
+
+ // FIXME(uwe): Simplify this as soon as we drop support for android-7
+ if (android.os.Build.VERSION.SDK_INT >= 8) {
+ try {
+ Method method = context.getClass().getMethod("getExternalFilesDir", String.class);
+ storageDir = (File) method.invoke(context, (Object) null);
+ } catch (SecurityException e) {
+ printStackTrace(e);
+ } catch (NoSuchMethodException e) {
+ printStackTrace(e);
+ } catch (IllegalArgumentException e) {
+ printStackTrace(e);
+ } catch (IllegalAccessException e) {
+ printStackTrace(e);
+ } catch (InvocationTargetException e) {
+ printStackTrace(e);
+ }
+ } else {
+ storageDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/files");
+ Log.e("Calculated path to sdcard the old way: " + storageDir);
+ }
+ // FIXME end
+
+ if (storageDir == null || (!storageDir.exists() && !storageDir.mkdirs())) {
+ Log.e("Development mode active, but sdcard is not available. Make sure you have added\n<uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' />\nto your AndroidManifest.xml file.");
+ storageDir = context.getFilesDir();
+ }
+ } else {
+ storageDir = context.getFilesDir();
+ }
+ return storageDir.getAbsolutePath() + "/scripts";
+ }
+
+ public static Boolean configDir(String scriptsDir) {
+ if (new File(scriptsDir).exists()) {
+ Log.i("Found extra scripts dir: " + scriptsDir);
+ Script.setDir(scriptsDir);
+ JRubyAdapter.exec("$:.unshift '" + scriptsDir + "' ; $:.uniq!");
+ return true;
+ } else {
+ Log.i("Extra scripts dir not present: " + scriptsDir);
+ return false;
+ }
+ }
+
+ public static void setOutputStream(PrintStream out) {
+ if (ruby == null) {
+ output = out;
+ } else {
+ try {
+ Method setOutputMethod = ruby.getClass().getMethod("setOutput", PrintStream.class);
+ setOutputMethod.invoke(ruby, out);
+ Method setErrorMethod = ruby.getClass().getMethod("setError", PrintStream.class);
+ setErrorMethod.invoke(ruby, out);
+ } catch (IllegalArgumentException e) {
+ handleInitException(e);
+ } catch (SecurityException e) {
+ handleInitException(e);
+ } catch (IllegalAccessException e) {
+ handleInitException(e);
+ } catch (InvocationTargetException e) {
+ handleInitException(e);
+ } catch (NoSuchMethodException e) {
+ handleInitException(e);
+ }
+ }
+ }
+
+ private static void handleInitException(Exception e) {
+ Log.e("Exception starting JRuby");
+ Log.e(e.getMessage() != null ? e.getMessage() : e.getClass().getName());
+ e.printStackTrace();
+ ruby = null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T callScriptingContainerMethod(Class<T> returnType, String methodName, Object... args) {
+ Class<?>[] argClasses = new Class[args.length];
+ for (int i = 0; i < argClasses.length; i++) {
+ argClasses[i] = args[i].getClass();
+ }
+ try {
+ Method method = ruby.getClass().getMethod(methodName, argClasses);
+ System.out.println("callScriptingContainerMethod: method: " + method);
+ T result = (T) method.invoke(ruby, args);
+ System.out.println("callScriptingContainerMethod: result: " + result);
+ return result;
+ } catch (RuntimeException re) {
+ re.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ printStackTrace(e);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String execute(String code) {
+ Object result = exec(code);
+ return result != null ? result.toString() : "nil";
+// TODO: Why is callMethod returning "main"?
+// return result != null ? callMethod(result, "inspect", String.class) : "null";
+ }
+
+ public static Object exec(String code) {
+ // return callScriptingContainerMethod(Object.class, "runScriptlet", code);
+ try {
+ Method runScriptletMethod = ruby.getClass().getMethod("runScriptlet", String.class);
+ return runScriptletMethod.invoke(ruby, code);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ if (isDebugBuild) {
+ throw ((RuntimeException) ite.getCause());
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public static void defineGlobalConstant(String name, Object object) {
+ put(name, object);
+ }
+
+ public static void put(String name, Object object) {
+ try {
+ Method putMethod = ruby.getClass().getMethod("put", String.class, Object.class);
+ putMethod.invoke(ruby, name, object);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ throw new RuntimeException(ite);
+ }
+ }
+
+ public static Object get(String name) {
+ try {
+ Method getMethod = ruby.getClass().getMethod("get", String.class);
+ return getMethod.invoke(ruby, name);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ throw new RuntimeException(ite);
+ }
+ }
+
+ public static void defineGlobalVariable(String name, Object object) {
+ defineGlobalConstant(name, object);
+ }
+
+ public static boolean isDebugBuild() {
+ return isDebugBuild;
+ }
+
+ private static void setDebugBuild(Context context) {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo pi;
+ try {
+ pi = pm.getPackageInfo(context.getPackageName(), 0);
+ isDebugBuild = ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
+ } catch (NameNotFoundException e) {
+ isDebugBuild = false;
+ }
+ }
+
+ /*************************************************************************************************
+ *
+ * Script Actions
+ */
+
+ public static String getScriptFilename() {
+ return callScriptingContainerMethod(String.class, "getScriptFilename");
+ }
+
+ public static void setScriptFilename(String name) {
+ callScriptingContainerMethod(Void.class, "setScriptFilename", name);
+ }
+
+ public static void callMethod(Object receiver, String methodName, Object[] args) {
+ try {
+ Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object[].class);
+ callMethodMethod.invoke(ruby, receiver, methodName, args);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ printStackTrace(ite);
+ if (isDebugBuild) {
+ throw new RuntimeException(ite);
+ }
+ }
+ }
+
+ public static void callMethod(Object object, String methodName, Object arg) {
+ callMethod(object, methodName, new Object[] { arg });
+ }
+
+ public static void callMethod(Object object, String methodName) {
+ callMethod(object, methodName, new Object[] {});
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T callMethod(Object receiver, String methodName, Object[] args, Class<T> returnType) {
+ try {
+ Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object[].class, Class.class);
+ return (T) callMethodMethod.invoke(ruby, receiver, methodName, args, returnType);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ printStackTrace(ite);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T callMethod(Object receiver, String methodName, Object arg, Class<T> returnType) {
+ try {
+ Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object.class, Class.class);
+ return (T) callMethodMethod.invoke(ruby, receiver, methodName, arg, returnType);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ printStackTrace(ite);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T callMethod(Object receiver, String methodName, Class<T> returnType) {
+ try {
+ Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Class.class);
+ return (T) callMethodMethod.invoke(ruby, receiver, methodName, returnType);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ printStackTrace(ite);
+ }
+ return null;
+ }
+
+ private static void printStackTrace(Throwable t) {
+ PrintStream out;
+ try {
+ Method getOutputMethod = ruby.getClass().getMethod("getOutput");
+ out = (PrintStream) getOutputMethod.invoke(ruby);
+ } catch (java.lang.NoSuchMethodException nsme) {
+ throw new RuntimeException("ScriptingContainer#getOutput method not found.", nsme);
+ } catch (java.lang.IllegalAccessException iae) {
+ throw new RuntimeException("ScriptingContainer#getOutput method not accessable.", iae);
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ throw new RuntimeException("ScriptingContainer#getOutput failed.", ite);
+ }
+
+ // TODO(uwe): Simplify this when Issue #144 is resolved
+ try {
+ t.printStackTrace(out);
+ } catch (NullPointerException npe) {
+ // TODO(uwe): printStackTrace should not fail
+ for (java.lang.StackTraceElement ste : t.getStackTrace()) {
+ out.append(ste.toString() + "\n");
+ }
+ }
+ }
+
+}
View
22 assets/src/org/ruboto/Log.java
@@ -0,0 +1,22 @@
+package org.ruboto;
+
+public class Log {
+ public static final String TAG = "RUBOTO";
+
+ public static void d(String message) {
+ android.util.Log.d(TAG, message);
+ }
+
+ public static void i(String message) {
+ android.util.Log.i(TAG, message);
+ }
+
+ public static void e(String message) {
+ android.util.Log.e(TAG, message);
+ }
+
+ public static void e(String message, Throwable t) {
+ android.util.Log.e(TAG, message, t);
+ }
+
+}
View
558 assets/src/org/ruboto/Script.java
@@ -1,352 +1,32 @@
package org.ruboto;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.AssetManager;
-import android.os.Environment;
-import android.util.Log;
-
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import dalvik.system.PathClassLoader;
+import android.content.Context;
+import android.content.res.AssetManager;
public class Script {
private static String scriptsDir = "scripts";
private static File scriptsDirFile = null;
private String name = null;
- private static Object ruby;
- private static boolean isDebugBuild = false;
- private static PrintStream output = null;
- private static boolean initialized = false;
-
- private static String localContextScope = "SINGLETON";
- private static String localVariableBehavior = "TRANSIENT";
-
- public static final String TAG = "RUBOTO"; // for logging
- private static String JRUBY_VERSION;
- private static String RUBOTO_CORE_VERSION_NAME;
-
- /*************************************************************************************************
- *
- * Static Methods: ScriptingContainer config
- */
-
- public static void setLocalContextScope(String val) {
- localContextScope = val;
- }
-
- public static void setLocalVariableBehavior(String val) {
- localVariableBehavior = val;
- }
-
- /*************************************************************************************************
- *
- * Static Methods: JRuby Execution
- */
-
- public static final FilenameFilter RUBY_FILES = new FilenameFilter() {
- public boolean accept(File dir, String fname) {
- return fname.endsWith(".rb");
- }
- };
-
- public static synchronized boolean isInitialized() {
- return initialized;
- }
-
- public static boolean usesPlatformApk() {
- return RUBOTO_CORE_VERSION_NAME != null;
- }
-
- public static String getPlatformVersionName() {
- return RUBOTO_CORE_VERSION_NAME;
- }
-
- public static synchronized boolean setUpJRuby(Context appContext) {
- return setUpJRuby(appContext, output == null ? System.out : output);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static synchronized boolean setUpJRuby(Context appContext, PrintStream out) {
- if (!initialized) {
- // BEGIN Ruboto HeapAlloc
- byte[] arrayForHeapAllocation = new byte[13 * 1024 * 1024];
- arrayForHeapAllocation = null;
- // END Ruboto HeapAlloc
- setDebugBuild(appContext);
- Log.d(TAG, "Setting up JRuby runtime (" + (isDebugBuild ? "DEBUG" : "RELEASE") + ")");
- System.setProperty("jruby.bytecode.version", "1.6");
- System.setProperty("jruby.interfaces.useProxy", "true");
- System.setProperty("jruby.management.enabled", "false");
- System.setProperty("jruby.objectspace.enabled", "false");
- System.setProperty("jruby.thread.pooling", "true");
- System.setProperty("jruby.native.enabled", "false");
- // System.setProperty("jruby.compat.version", "RUBY1_8"); // RUBY1_9 is the default
-
- // Uncomment these to debug Ruby source loading
- // System.setProperty("jruby.debug.loadService", "true");
- // System.setProperty("jruby.debug.loadService.timing", "true");
-
-
- ClassLoader classLoader;
- Class<?> scriptingContainerClass;
- String apkName = null;
-
- try {
- scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer");
- System.out.println("Found JRuby in this APK");
- classLoader = Script.class.getClassLoader();
- try {
- apkName = appContext.getPackageManager().getApplicationInfo(appContext.getPackageName(), 0).sourceDir;
- } catch (NameNotFoundException e) {}
- } catch (ClassNotFoundException e1) {
- String packageName = "org.ruboto.core";
- try {
- PackageInfo pkgInfo = appContext.getPackageManager().getPackageInfo(packageName, 0);
- apkName = pkgInfo.applicationInfo.sourceDir;
- RUBOTO_CORE_VERSION_NAME = pkgInfo.versionName;
- } catch (PackageManager.NameNotFoundException e2) {
- out.println("JRuby not found in local APK:");
- e1.printStackTrace(out);
- out.println("JRuby not found in platform APK:");
- e2.printStackTrace(out);
- return false;
- }
-
- System.out.println("Found JRuby in platform APK");
- if (true) {
- classLoader = new PathClassLoader(apkName, Script.class.getClassLoader());
- } else {
- // Alternative way to get the class loader. The other way is rumoured to have memory leaks.
- try {
- Context platformAppContext = appContext.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE + Context.CONTEXT_IGNORE_SECURITY);
- classLoader = platformAppContext.getClassLoader();
- } catch (PackageManager.NameNotFoundException e) {
- System.out.println("Could not create package context even if application info could be found. Should never happen.");
- return false;
- }
- }
-
- try {
- scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer", true, classLoader);
- } catch (ClassNotFoundException e) {
- // FIXME(uwe): ScriptingContainer not found in the platform APK...
- e.printStackTrace();
- return false;
- }
- }
-
- try {
- try {
- JRUBY_VERSION = (String) Class.forName("org.jruby.runtime.Constants", true, classLoader).getDeclaredField("VERSION").get(String.class);
- } catch (java.lang.NoSuchFieldException nsfex) {
- nsfex.printStackTrace();
- JRUBY_VERSION = "ERROR";
- }
-
- Class scopeClass = Class.forName("org.jruby.embed.LocalContextScope", true, scriptingContainerClass.getClassLoader());
- Class behaviorClass = Class.forName("org.jruby.embed.LocalVariableBehavior", true, scriptingContainerClass.getClassLoader());
-
- ruby = scriptingContainerClass
- .getConstructor(scopeClass, behaviorClass)
- .newInstance(Enum.valueOf(scopeClass, localContextScope),
- Enum.valueOf(behaviorClass, localVariableBehavior));
-
- Class compileModeClass = Class.forName("org.jruby.RubyInstanceConfig$CompileMode", true, classLoader);
- callScriptingContainerMethod(Void.class, "setCompileMode", Enum.valueOf(compileModeClass, "OFF"));
-
- // Class traceTypeClass = Class.forName("org.jruby.runtime.backtrace.TraceType", true, classLoader);
- // Method traceTypeForMethod = traceTypeClass.getMethod("traceTypeFor", String.class);
- // Object traceTypeRaw = traceTypeForMethod.invoke(null, "raw");
- // callScriptingContainerMethod(Void.class, "setTraceType", traceTypeRaw);
-
- // FIXME(uwe): Write tutorial on profiling.
- // container.getProvider().getRubyInstanceConfig().setProfilingMode(mode);
-
- // callScriptingContainerMethod(Void.class, "setClassLoader", classLoader);
- Method setClassLoaderMethod = ruby.getClass().getMethod("setClassLoader", ClassLoader.class);
- setClassLoaderMethod.invoke(ruby, classLoader);
-
- Thread.currentThread().setContextClassLoader(classLoader);
-
- String defaultCurrentDir = appContext.getFilesDir().getPath();
- Log.d(TAG, "Setting JRuby current directory to " + defaultCurrentDir);
- callScriptingContainerMethod(Void.class, "setCurrentDirectory", defaultCurrentDir);
-
- if (out != null) {
- output = out;
- setOutputStream(out);
- } else if (output != null) {
- setOutputStream(output);
- }
-
- String jrubyHome = "file:" + apkName + "!";
- Log.i(TAG, "Setting JRUBY_HOME: " + jrubyHome);
- System.setProperty("jruby.home", jrubyHome);
-
- String extraScriptsDir = scriptsDirName(appContext);
- Log.i(TAG, "Checking scripts in " + extraScriptsDir);
- if (configDir(extraScriptsDir)) {
- Log.i(TAG, "Added extra scripts path: " + extraScriptsDir);
- }
- initialized = true;
- } catch (ClassNotFoundException e) {
- handleInitException(e);
- } catch (IllegalArgumentException e) {
- handleInitException(e);
- } catch (SecurityException e) {
- handleInitException(e);
- } catch (InstantiationException e) {
- handleInitException(e);
- } catch (IllegalAccessException e) {
- handleInitException(e);
- } catch (InvocationTargetException e) {
- handleInitException(e);
- } catch (NoSuchMethodException e) {
- handleInitException(e);
- }
- }
- return initialized;
- }
-
- public static void setOutputStream(PrintStream out) {
- if (ruby == null) {
- output = out;
- } else {
- try {
- Method setOutputMethod = ruby.getClass().getMethod("setOutput", PrintStream.class);
- setOutputMethod.invoke(ruby, out);
- Method setErrorMethod = ruby.getClass().getMethod("setError", PrintStream.class);
- setErrorMethod.invoke(ruby, out);
- } catch (IllegalArgumentException e) {
- handleInitException(e);
- } catch (SecurityException e) {
- handleInitException(e);
- } catch (IllegalAccessException e) {
- handleInitException(e);
- } catch (InvocationTargetException e) {
- handleInitException(e);
- } catch (NoSuchMethodException e) {
- handleInitException(e);
- }
- }
- }
-
- private static void handleInitException(Exception e) {
- Log.e(TAG, "Exception starting JRuby");
- Log.e(TAG, e.getMessage() != null ? e.getMessage() : e.getClass().getName());
- e.printStackTrace();
- ruby = null;
- }
-
- @SuppressWarnings("unchecked")
- public static <T> T callScriptingContainerMethod(Class<T> returnType, String methodName, Object... args) {
- Class<?>[] argClasses = new Class[args.length];
- for (int i = 0; i < argClasses.length; i++) {
- argClasses[i] = args[i].getClass();
- }
- try {
- Method method = ruby.getClass().getMethod(methodName, argClasses);
- System.out.println("callScriptingContainerMethod: method: " + method);
- T result = (T) method.invoke(ruby, args);
- System.out.println("callScriptingContainerMethod: result: " + result);
- return result;
- } catch (RuntimeException re) {
- re.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- printStackTrace(e);
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public static String execute(String code) {
- Object result = exec(code);
- return result != null ? result.toString() : "nil";
-// TODO: Why is callMethod returning "main"?
-// return result != null ? callMethod(result, "inspect", String.class) : "null";
- }
-
- public static Object exec(String code) {
- // return callScriptingContainerMethod(Object.class, "runScriptlet", code);
- try {
- Method runScriptletMethod = ruby.getClass().getMethod("runScriptlet", String.class);
- return runScriptletMethod.invoke(ruby, code);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- if (isDebugBuild) {
- throw ((RuntimeException) ite.getCause());
- } else {
- return null;
- }
- }
- }
-
- public static void defineGlobalConstant(String name, Object object) {
- put(name, object);
- }
-
- public static void put(String name, Object object) {
- try {
- Method putMethod = ruby.getClass().getMethod("put", String.class, Object.class);
- putMethod.invoke(ruby, name, object);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- throw new RuntimeException(ite);
- }
- }
-
- public static Object get(String name) {
- try {
- Method getMethod = ruby.getClass().getMethod("get", String.class);
- return getMethod.invoke(ruby, name);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- throw new RuntimeException(ite);
- }
- }
-
- public static void defineGlobalVariable(String name, Object object) {
- defineGlobalConstant(name, object);
- }
/*************************************************************************************************
*
* Static Methods: Scripts Directory
*/
-
public static void setDir(String dir) {
scriptsDir = dir;
scriptsDirFile = new File(dir);
- if (ruby != null) {
- Log.d(TAG, "Changing JRuby current directory to " + scriptsDir);
- callScriptingContainerMethod(Void.class, "setCurrentDirectory", scriptsDir);
+ if (JRubyAdapter.isInitialized()) {
+ Log.d("Changing JRuby current directory to " + scriptsDir);
+ JRubyAdapter.callScriptingContainerMethod(Void.class, "setCurrentDirectory", scriptsDir);
}
}
@@ -358,18 +38,6 @@ public static File getDirFile() {
return scriptsDirFile;
}
- public static Boolean configDir(String scriptsDir) {
- if (new File(scriptsDir).exists()) {
- Log.i(TAG, "Found extra scripts dir: " + scriptsDir);
- setDir(scriptsDir);
- exec("$:.unshift '" + scriptsDir + "' ; $:.uniq!");
- return true;
- } else {
- Log.i(TAG, "Extra scripts dir not present: " + scriptsDir);
- return false;
- }
- }
-
private static void copyScripts(String from, File to, AssetManager assets) {
try {
byte[] buffer = new byte[8192];
@@ -380,7 +48,7 @@ private static void copyScripts(String from, File to, AssetManager assets) {
continue;
}
- Log.d(TAG, "copying file from " + from + "/" + f + " to " + dest);
+ Log.d("copying file from " + from + "/" + f + " to " + dest);
if (assets.list(from + "/" + f).length == 0) {
InputStream is = assets.open(from + "/" + f);
@@ -398,7 +66,7 @@ private static void copyScripts(String from, File to, AssetManager assets) {
}
}
} catch (IOException iox) {
- Log.e(TAG, "error copying scripts", iox);
+ Log.e("error copying scripts", iox);
}
}
@@ -411,54 +79,6 @@ public static void copyAssets(Context context, String directory) {
}
}
- private static void setDebugBuild(Context context) {
- PackageManager pm = context.getPackageManager();
- PackageInfo pi;
- try {
- pi = pm.getPackageInfo(context.getPackageName(), 0);
- isDebugBuild = ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
- } catch (NameNotFoundException e) {
- isDebugBuild = false;
- }
- }
-
- private static String scriptsDirName(Context context) {
- File storageDir = null;
- if (isDebugBuild) {
-
- // FIXME(uwe): Simplify this as soon as we drop support for android-7
- if (android.os.Build.VERSION.SDK_INT >= 8) {
- try {
- Method method = context.getClass().getMethod("getExternalFilesDir", String.class);
- storageDir = (File) method.invoke(context, (Object) null);
- } catch (SecurityException e) {
- printStackTrace(e);
- } catch (NoSuchMethodException e) {
- printStackTrace(e);
- } catch (IllegalArgumentException e) {
- printStackTrace(e);
- } catch (IllegalAccessException e) {
- printStackTrace(e);
- } catch (InvocationTargetException e) {
- printStackTrace(e);
- }
- } else {
- storageDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/files");
- Log.e(TAG, "Calculated path to sdcard the old way: " + storageDir);
- }
- // FIXME end
-
- if (storageDir == null || (!storageDir.exists() && !storageDir.mkdirs())) {
- Log.e(TAG,
- "Development mode active, but sdcard is not available. Make sure you have added\n<uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' />\nto your AndroidManifest.xml file.");
- storageDir = context.getFilesDir();
- }
- } else {
- storageDir = context.getFilesDir();
- }
- return storageDir.getAbsolutePath() + "/scripts";
- }
-
/*************************************************************************************************
*
* Constructors
@@ -487,38 +107,39 @@ public Script setName(String name) {
}
public String getContents() throws IOException {
- InputStream is;
- if (new File(scriptsDir + "/" + name).exists()) {
- is = new java.io.FileInputStream(scriptsDir + "/" + name);
- } else {
- is = getClass().getClassLoader().getResourceAsStream(name);
- }
- BufferedReader buffer = new BufferedReader(new java.io.InputStreamReader(is), 8192);
- StringBuilder source = new StringBuilder();
- while (true) {
- String line = buffer.readLine();
- if (line == null) {
- break;
+ InputStream is = null;
+ BufferedReader buffer = null;
+ try {
+ if (new File(scriptsDir + "/" + name).exists()) {
+ is = new java.io.FileInputStream(scriptsDir + "/" + name);
+ } else {
+ is = getClass().getClassLoader().getResourceAsStream(name);
+ }
+ buffer = new BufferedReader(new java.io.InputStreamReader(is), 8192);
+ StringBuilder source = new StringBuilder();
+ while (true) {
+ String line = buffer.readLine();
+ if (line == null) {
+ break;
+ }
+ source.append(line).append("\n");
+ }
+ return source.toString();
+ } finally {
+ if (is != null) {
+ is.close();
}
- source.append(line).append("\n");
- }
- buffer.close();
- return source.toString();
- }
+ if (is != null) {
+ buffer.close();
+ }
+ }
+ }
/*************************************************************************************************
*
* Script Actions
*/
- public static String getScriptFilename() {
- return callScriptingContainerMethod(String.class, "getScriptFilename");
- }
-
- public static void setScriptFilename(String name) {
- callScriptingContainerMethod(Void.class, "setScriptFilename", name);
- }
-
public static String toSnakeCase(String s) {
return s.replaceAll(
String.format("%s|%s|%s",
@@ -539,118 +160,7 @@ public static String toCamelCase(String s) {
}
public String execute() throws IOException {
- Object result;
- Script.setScriptFilename(getClass().getClassLoader().getResource(name).getPath());
- try {
- Method runScriptletMethod = ruby.getClass().getMethod("runScriptlet", String.class);
- result = runScriptletMethod.invoke(ruby, getContents());
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- if (isDebugBuild) {
- throw ((RuntimeException) ite.getCause());
- } else {
- return null;
- }
- }
- return result != null ? result.toString() : "nil";
- // TODO: Why is callMethod returning "main"?
- // return result != null ? callMethod(result, "inspect", String.class) : "null";
- }
-
- public static void callMethod(Object receiver, String methodName, Object[] args) {
- try {
- Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object[].class);
- callMethodMethod.invoke(ruby, receiver, methodName, args);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- printStackTrace(ite);
- if (isDebugBuild) {
- throw new RuntimeException(ite);
- }
- }
- }
-
- public static void callMethod(Object object, String methodName, Object arg) {
- callMethod(object, methodName, new Object[] { arg });
- }
-
- public static void callMethod(Object object, String methodName) {
- callMethod(object, methodName, new Object[] {});
- }
-
- @SuppressWarnings("unchecked")
- public static <T> T callMethod(Object receiver, String methodName, Object[] args, Class<T> returnType) {
- try {
- Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object[].class, Class.class);
- return (T) callMethodMethod.invoke(ruby, receiver, methodName, args, returnType);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- printStackTrace(ite);
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public static <T> T callMethod(Object receiver, String methodName, Object arg, Class<T> returnType) {
- try {
- Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object.class, Class.class);
- return (T) callMethodMethod.invoke(ruby, receiver, methodName, arg, returnType);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- printStackTrace(ite);
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public static <T> T callMethod(Object receiver, String methodName, Class<T> returnType) {
- try {
- Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Class.class);
- return (T) callMethodMethod.invoke(ruby, receiver, methodName, returnType);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException(nsme);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- printStackTrace(ite);
+ return JRubyAdapter.execute(getContents());
}
- return null;
- }
-
- private static void printStackTrace(Throwable t) {
- PrintStream out;
- try {
- Method getOutputMethod = ruby.getClass().getMethod("getOutput");
- out = (PrintStream) getOutputMethod.invoke(ruby);
- } catch (java.lang.NoSuchMethodException nsme) {
- throw new RuntimeException("ScriptingContainer#getOutput method not found.", nsme);
- } catch (java.lang.IllegalAccessException iae) {
- throw new RuntimeException("ScriptingContainer#getOutput method not accessable.", iae);
- } catch (java.lang.reflect.InvocationTargetException ite) {
- throw new RuntimeException("ScriptingContainer#getOutput failed.", ite);
- }
-
- // TODO(uwe): Simplify this when Issue #144 is resolved
- try {
- t.printStackTrace(out);
- } catch (NullPointerException npe) {
- // TODO(uwe): printStackTrace should not fail
- for (java.lang.StackTraceElement ste : t.getStackTrace()) {
- out.append(ste.toString() + "\n");
- }
- }
- }
}
View
14 assets/src/org/ruboto/test/ActivityTest.java
@@ -13,7 +13,7 @@
import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
-import org.ruboto.Script;
+import org.ruboto.JRubyAdapter;
public class ActivityTest extends ActivityInstrumentationTestCase2 {
private final Object setup;
@@ -38,16 +38,16 @@ public void runTest() throws Exception {
Log.i(getClass().getName(), "Activity OK");
Runnable testRunnable = new Runnable() {
public void run() {
- String oldFile = Script.getScriptFilename();
+ String oldFile = JRubyAdapter.getScriptFilename();
Log.i(getClass().getName(), "calling setup");
- Script.setScriptFilename(filename);
- Script.callMethod(setup, "call", activity);
+ JRubyAdapter.setScriptFilename(filename);
+ JRubyAdapter.callMethod(setup, "call", activity);
Log.i(getClass().getName(), "setup ok");
- Script.setScriptFilename(filename);
- Script.callMethod(block, "call", activity);
- Script.setScriptFilename(oldFile);
+ JRubyAdapter.setScriptFilename(filename);
+ JRubyAdapter.callMethod(block, "call", activity);
+ JRubyAdapter.setScriptFilename(oldFile);
}
};
if (onUiThread) {
View
24 assets/src/org/ruboto/test/InstrumentationTestRunner.java
@@ -24,7 +24,7 @@
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.ruboto.Script;
+import org.ruboto.JRubyAdapter;
import java.util.Set;
import java.util.HashSet;
@@ -45,7 +45,7 @@ public TestSuite getAllTests() {
// TODO(uwe): Simplify when we stop support for JRuby 1.7.0 or android-10
Thread t = new Thread(null, new Runnable() {
public void run() {
- JRubyLoadedOk.set(Script.setUpJRuby(getTargetContext()));
+ JRubyLoadedOk.set(JRubyAdapter.setUpJRuby(getTargetContext()));
}
}, "Setup JRuby from instrumentation test runner", 64 * 1024);
try {
@@ -64,9 +64,9 @@ public void run() {
// TODO(uwe): Simplify when we stop support for JRuby 1.7.0 or android-10
Thread t2 = new Thread(null, new Runnable() {
public void run() {
- Script.put("$runner", InstrumentationTestRunner.this);
- Script.put("$test", InstrumentationTestRunner.this);
- Script.put("$suite", suite);
+ JRubyAdapter.put("$runner", InstrumentationTestRunner.this);
+ JRubyAdapter.put("$test", InstrumentationTestRunner.this);
+ JRubyAdapter.put("$suite", suite);
}
}, "Setup JRuby from instrumentation test runner", 64 * 1024);
try {
@@ -129,7 +129,7 @@ public void test(String name, Map options, Object block) {
boolean runOnUiThread = options == null || options.get("ui") == "true";
- Test test = new ActivityTest(activityClass, Script.getScriptFilename(), setup, name, runOnUiThread, block);
+ Test test = new ActivityTest(activityClass, JRubyAdapter.getScriptFilename(), setup, name, runOnUiThread, block);
suite.addTest(test);
Log.d(getClass().getName(), "Made test instance: " + test);
}
@@ -162,12 +162,12 @@ private void loadScript(String f) throws IOException {
}
buffer.close();
- String oldFilename = Script.getScriptFilename();
- Script.setScriptFilename(f);
- Script.put("$script_code", source.toString());
- Script.setScriptFilename(f);
- Script.execute("$test.instance_eval($script_code)");
- Script.setScriptFilename(oldFilename);
+ String oldFilename = JRubyAdapter.getScriptFilename();
+ JRubyAdapter.setScriptFilename(f);
+ JRubyAdapter.put("$script_code", source.toString());
+ JRubyAdapter.setScriptFilename(f);
+ JRubyAdapter.execute("$test.instance_eval($script_code)");
+ JRubyAdapter.setScriptFilename(oldFilename);
Log.d(getClass().getName(), "Test script " + f + " loaded");
}
View
8 lib/ruboto/util/xml_element.rb
@@ -175,9 +175,9 @@ def ruby_call(on_ruby_instance = false, camelize = false)
end
if on_ruby_instance
- ["#{return_cast}Script.callMethod(rubyInstance, \"#{camelize ? attribute("name") : snake_case_attribute}\" #{args}#{convert_return});"]
+ ["#{return_cast}JRubyAdapter.callMethod(rubyInstance, \"#{camelize ? attribute("name") : snake_case_attribute}\" #{args}#{convert_return});"]
else
- ["#{return_cast}Script.callMethod(callbackProcs[#{constant_string}], \"call\" #{args}#{convert_return});"]
+ ["#{return_cast}JRubyAdapter.callMethod(callbackProcs[#{constant_string}], \"call\" #{args}#{convert_return});"]
end
end
@@ -190,10 +190,10 @@ def method_definition
(attribute("return") ? attribute("return") : "void"),
attribute("name"), parameters,
if_else(
- "rubyInstance != null && Script.callMethod(rubyInstance, \"respond_to?\" , new Object[]{\""+ snake_case_attribute + "\"}, Boolean.class)",
+ "rubyInstance != null && JRubyAdapter.callMethod(rubyInstance, \"respond_to?\" , new Object[]{\""+ snake_case_attribute + "\"}, Boolean.class)",
[super_string] + ruby_call(true),
if_else(
- "rubyInstance != null && Script.callMethod(rubyInstance, \"respond_to?\" , new Object[]{\""+ attribute("name") +"\"}, Boolean.class)",
+ "rubyInstance != null && JRubyAdapter.callMethod(rubyInstance, \"respond_to?\" , new Object[]{\""+ attribute("name") +"\"}, Boolean.class)",
[super_string] + ruby_call(true, true),
if_else(
"callbackProcs != null && callbackProcs[#{constant_string}] != null",
View
6 test/activity/stack_activity_test.rb
@@ -12,11 +12,11 @@
test('stack depth') do |activity|
os_offset = {13 => 1, 15 => 1, 16 => 1}[android.os.Build::VERSION::SDK_INT].to_i
- if org.ruboto.Script.uses_platform_apk?
+ if org.ruboto.JRubyAdapter.uses_platform_apk?
jruby_offset = {
'0.4.7' => [0, 0, 0, 0],
'0.4.8.dev' => [0, 0, 0, 0],
- }[org.ruboto.Script.platform_version_name] || [0, 0, 0, 0]
+ }[org.ruboto.JRubyAdapter.platform_version_name] || [0, 0, 0, 0]
else # STANDALONE
jruby_offset = {
'1.7.0.dev' => [1, 1, 1, 1],
@@ -24,7 +24,7 @@
'1.7.0.preview2.dev' => [0, 0, 0, 0],
}[org.jruby.runtime.Constants::VERSION] || [0, 0, 0, 0]
end
- version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.Script.uses_platform_apk ? org.ruboto.Script.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
+ version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.JRubyAdapter.uses_platform_apk ? org.ruboto.JRubyAdapter.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
assert_equal 43 + os_offset + jruby_offset[0], activity.find_view_by_id(42).text.to_i, version_message
assert_equal 48 + os_offset + jruby_offset[1], activity.find_view_by_id(43).text.to_i, version_message
assert_equal 49 + os_offset + jruby_offset[2], activity.find_view_by_id(44).text.to_i, version_message
View
6 test/block_def_activity/stack_activity_test.rb
@@ -12,18 +12,18 @@
test('stack depth') do |activity|
os_offset = {13 => 1, 15 => 1, 16 => 1}[android.os.Build::VERSION::SDK_INT].to_i
- if org.ruboto.Script.uses_platform_apk?
+ if org.ruboto.JRubyAdapter.uses_platform_apk?
jruby_offset = {
'0.4.7' => [0, 0, 0, 0],
'0.4.8.dev' => [0, -1, 0, 0],
- }[org.ruboto.Script.platform_version_name] || [0, 0, 0, 0]
+ }[org.ruboto.JRubyAdapter.platform_version_name] || [0, 0, 0, 0]
else # STANDALONE
jruby_offset = {
'1.7.0.preview1' => [0, -1, -1, -1],
'1.7.0.preview2.dev' => [0, -1, 0, 0],
}[org.jruby.runtime.Constants::VERSION] || [0, 0, 0, 0]
end
- version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.Script.uses_platform_apk ? org.ruboto.Script.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
+ version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.JRubyAdapter.uses_platform_apk ? org.ruboto.JRubyAdapter.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
assert_equal 43 + os_offset + jruby_offset[0], activity.find_view_by_id(42).text.to_i, version_message
assert_equal 78 + os_offset + jruby_offset[1], activity.find_view_by_id(43).text.to_i, version_message
assert_equal 61 + os_offset + jruby_offset[2], activity.find_view_by_id(44).text.to_i, version_message
View
6 test/handle_activity/stack_activity_test.rb
@@ -12,11 +12,11 @@
test('stack depth') do |activity|
os_offset = {13 => 1, 15 => 1, 16 => 1}[android.os.Build::VERSION::SDK_INT].to_i
- if org.ruboto.Script.uses_platform_apk?
+ if org.ruboto.JRubyAdapter.uses_platform_apk?
jruby_offset = {
'0.4.7' => [0, 0, 0, 0],
'0.4.8.dev' => [0, -1, -1, -1],
- }[org.ruboto.Script.platform_version_name] || [0, 0, 0, 0]
+ }[org.ruboto.JRubyAdapter.platform_version_name] || [0, 0, 0, 0]
else
jruby_offset = {
'1.7.0.dev' => [1, 1, 1, 1],
@@ -24,7 +24,7 @@
'1.7.0.preview2.dev' => [0, -1, -1, -1],
}[org.jruby.runtime.Constants::VERSION] || [0, 0, 0, 0]
end
- version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.Script.uses_platform_apk ? org.ruboto.Script.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
+ version_message ="ANDROID: #{android.os.Build::VERSION::SDK_INT}, PLATFORM: #{org.ruboto.JRubyAdapter.uses_platform_apk ? org.ruboto.JRubyAdapter.platform_version_name : 'STANDALONE'}, JRuby: #{org.jruby.runtime.Constants::VERSION}"
assert_equal 43 + os_offset + jruby_offset[0], activity.find_view_by_id(42).text.to_i, version_message
assert_equal 67 + os_offset + jruby_offset[1], activity.find_view_by_id(43).text.to_i, version_message
assert_equal 76 + os_offset + jruby_offset[2], activity.find_view_by_id(44).text.to_i, version_message

0 comments on commit 49e7ae6

Please sign in to comment.
Something went wrong with that request. Please try again.