Android Open Source - ISBN-Reporter J Ruby Adapter






From Project

Back to project page ISBN-Reporter.

License

The source code is released under:

MIT License

If you think the Android project ISBN-Reporter listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.ruboto;
//w  w  w  .j a  v a  2  s .c  o  m
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"; // FIXME(uwe):  Why not CONCURRENT ?  Help needed!
    private static String localVariableBehavior = "TRANSIENT";
    private static String RUBOTO_CORE_VERSION_NAME;

    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 String getPlatformVersionName() {
        return RUBOTO_CORE_VERSION_NAME;
    }

    public static String getScriptFilename() {
        return (String) callScriptingContainerMethod(String.class, "getScriptFilename");
    }

    public static Object runRubyMethod(Object receiver, String methodName, Object... args) {
        try {
            Method m = ruby.getClass().getMethod("runRubyMethod", Class.class, Object.class, String.class, Object[].class);
            return m.invoke(ruby, Object.class, 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);
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static <T> T runRubyMethod(Class<T> returnType, Object receiver, String methodName, Object... args) {
        try {
            Method m = ruby.getClass().getMethod("runRubyMethod", Class.class, Object.class, String.class, Object[].class);
            return (T) m.invoke(ruby, returnType, 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);
        }
        return null;
    }

    public static boolean isDebugBuild() {
        return isDebugBuild;
    }

    public static boolean isInitialized() {
        return initialized;
    }

    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 runScriptlet(String 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) {
                if (ite.getCause() instanceof RuntimeException) {
                    throw ((RuntimeException) ite.getCause());
                } else {
                    throw ((Error) ite.getCause());
                }
            } else {
                return null;
            }
        }
    }

    public static 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.backtrace.style", "normal"); // normal raw full mri
            System.setProperty("jruby.bytecode.version", "1.6");
            // BEGIN Ruboto RubyVersion
            System.setProperty("jruby.compat.version", "RUBY1_9"); // RUBY1_9 is the default in JRuby 1.7
            // END Ruboto RubyVersion
            // System.setProperty("jruby.compile.backend", "DALVIK");
            System.setProperty("jruby.compile.mode", "OFF"); // OFF OFFIR JITIR? FORCE FORCEIR
            System.setProperty("jruby.interfaces.useProxy", "true");
            System.setProperty("jruby.ir.passes", "LocalOptimizationPass,DeadCodeElimination");
            System.setProperty("jruby.management.enabled", "false");
            System.setProperty("jruby.native.enabled", "false");
            System.setProperty("jruby.objectspace.enabled", "false");
            System.setProperty("jruby.rewrite.java.trace", "true");
            System.setProperty("jruby.thread.pooling", "true");

            // Uncomment these to debug/profile Ruby source loading
            // Analyse the output: grep "LoadService:   <-" | cut -f5 -d- | cut -c2- | cut -f1 -dm | awk '{total = total + $1}END{print total}'
            // System.setProperty("jruby.debug.loadService", "true");
            // System.setProperty("jruby.debug.loadService.timing", "true");

            // Used to enable JRuby to generate proxy classes
            System.setProperty("jruby.ji.proxyClassFactory", "org.ruboto.DalvikProxyClassFactory");
            System.setProperty("jruby.ji.upper.case.package.name.allowed", "true");
            System.setProperty("jruby.class.cache.path", appContext.getDir("dex", 0).getAbsolutePath());

            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) {
                    System.out.println("JRuby not found in local APK:");
                    e1.printStackTrace();
                    System.out.println("JRuby not found in platform APK:");
                    e2.printStackTrace();
                    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 {
                //////////////////////////////////
                //
                // Set jruby.home
                //

                String jrubyHome = "file:" + apkName + "!/jruby.home";

                // FIXME(uwe): Remove when we stop supporting RubotoCore 0.4.7
                Log.i("RUBOTO_CORE_VERSION_NAME: " + RUBOTO_CORE_VERSION_NAME);
                if (RUBOTO_CORE_VERSION_NAME != null &&
                        (RUBOTO_CORE_VERSION_NAME.equals("0.4.7") || RUBOTO_CORE_VERSION_NAME.equals("0.4.8"))) {
                    jrubyHome = "file:" + apkName + "!";
                }
                // EMXIF

                Log.i("Setting JRUBY_HOME: " + jrubyHome);
                // This needs to be set before the ScriptingContainer is initialized
                System.setProperty("jruby.home", jrubyHome);

                //////////////////////////////////
                //
                // Determine Output
                //

                if (out != null) {
                  output = out;
                }

                //////////////////////////////////
                //
                // Disable rubygems
                //

                Class rubyClass = Class.forName("org.jruby.Ruby", true, scriptingContainerClass.getClassLoader());
                Class rubyInstanceConfigClass = Class.forName("org.jruby.RubyInstanceConfig", true, scriptingContainerClass.getClassLoader());

                Object config = rubyInstanceConfigClass.getConstructor().newInstance();
                rubyInstanceConfigClass.getMethod("setDisableGems", boolean.class).invoke(config, true);
                rubyInstanceConfigClass.getMethod("setLoader", ClassLoader.class).invoke(config, classLoader);

                if (output != null) {
                    rubyInstanceConfigClass.getMethod("setOutput", PrintStream.class).invoke(config, output);
                    rubyInstanceConfigClass.getMethod("setError", PrintStream.class).invoke(config, output);
                }

                // This will become the global runtime and be used by our ScriptingContainer
                rubyClass.getMethod("newInstance", rubyInstanceConfigClass).invoke(null, config);

                //////////////////////////////////
                //
                // Create the ScriptingContainer
                //

                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));

                // 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);

                if (appContext.getFilesDir() != null) {
                    String defaultCurrentDir = appContext.getFilesDir().getPath();
                    Log.d("Setting JRuby current directory to " + defaultCurrentDir);
                    callScriptingContainerMethod(Void.class, "setCurrentDirectory", defaultCurrentDir);
                } else {
                    Log.e("Unable to find app files dir!");
                }

                addLoadPath(scriptsDirName(appContext));
                put("$package_name", appContext.getPackageName());

                runScriptlet("::RUBOTO_JAVA_PROXIES = {}");

                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 setScriptFilename(String name) {
        callScriptingContainerMethod(Void.class, "setScriptFilename", name);
    }

    public static boolean usesPlatformApk() {
        return RUBOTO_CORE_VERSION_NAME != null;
    }

    public static Boolean addLoadPath(String scriptsDir) {
        if (new File(scriptsDir).exists()) {
            Log.i("Added directory to load path: " + scriptsDir);
            Script.addDir(scriptsDir);
            runScriptlet("$:.unshift '" + scriptsDir + "' ; $:.uniq!");
            // Log.d("Changing JRuby current directory to " + scriptsDir);
            // callScriptingContainerMethod(Void.class, "setCurrentDirectory", scriptsDir);
            return true;
        } else {
            Log.i("Extra scripts dir not present: " + scriptsDir);
            return false;
        }
    }

    // Private methods

    @SuppressWarnings("unchecked")
    private 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);
            T result = (T) method.invoke(ruby, args);
            return result;
        } catch (RuntimeException re) {
            re.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            printStackTrace(e);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

    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;
    }

    // FIXME(uwe):  Remove when we stop supporting Ruby 1.8
    @Deprecated public static boolean isRubyOneEight() {
        return ((String)get("RUBY_VERSION")).startsWith("1.8.");
    }

    // FIXME(uwe):  Remove when we stop supporting Ruby 1.8
    @Deprecated public static boolean isRubyOneNine() {
    String rv = ((String)get("RUBY_VERSION"));
        return rv.startsWith("2.1.") || rv.startsWith("2.0.") || rv.startsWith("1.9.");
    }

    static void printStackTrace(Throwable t) {
        // TODO(uwe):  Simplify this when Issue #144 is resolved
        // TODO(scott):  printStackTrace is causing too many problems
        //try {
        //    t.printStackTrace(output);
        //} catch (NullPointerException npe) {
            // TODO(uwe): printStackTrace should not fail
            for (java.lang.StackTraceElement ste : t.getStackTrace()) {
                output.append(ste.toString() + "\n");
            }
        //}
    }

    private static String scriptsDirName(Context context) {
        File storageDir = null;
        if (isDebugBuild()) {
            storageDir = context.getExternalFilesDir(null);
            if (storageDir == null) {
                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();
        }
        File scriptsDir = new File(storageDir, "scripts");
        if ((!scriptsDir.exists() && !scriptsDir.mkdirs())) {
            Log.e("Unable to create the scripts dir.");
            scriptsDir = new File(context.getFilesDir(), "scripts");
        }
        return scriptsDir.getAbsolutePath();
    }

    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;
        }
    }

    public static void setLocalContextScope(String val) {
        localContextScope = val;
    }

    public static void setLocalVariableBehavior(String val) {
        localVariableBehavior = val;
    }

    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);
        }
      }
    }

}




Java Source Code List

org.ruboto.EntryPointActivity.java
org.ruboto.JRubyAdapter.java
org.ruboto.Log.java
org.ruboto.RubotoActivity.java
org.ruboto.RubotoBroadcastReceiver.java
org.ruboto.RubotoComponent.java
org.ruboto.RubotoDialog.java
org.ruboto.RubotoService.java
org.ruboto.ScriptInfo.java
org.ruboto.ScriptLoader.java
org.ruboto.Script.java
org.ruboto.SplashActivity.java
org.ruboto.example.isbn_reporter.IsbnReporterActivity.java