ruboto 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/COPYING +19 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +21 -0
  4. data/README.md +293 -0
  5. data/Rakefile +114 -0
  6. data/assets/Rakefile +386 -0
  7. data/assets/res/drawable-hdpi/icon.png +0 -0
  8. data/assets/res/drawable-ldpi/icon.png +0 -0
  9. data/assets/res/drawable-mdpi/icon.png +0 -0
  10. data/assets/res/layout/get_ruboto_core.xml +25 -0
  11. data/assets/samples/sample_activity.rb +21 -0
  12. data/assets/samples/sample_activity_test.rb +21 -0
  13. data/assets/samples/sample_broadcast_receiver.rb +6 -0
  14. data/assets/samples/sample_broadcast_receiver_test.rb +1 -0
  15. data/assets/samples/sample_service.rb +14 -0
  16. data/assets/samples/sample_service_test.rb +1 -0
  17. data/assets/src/InheritingActivity.java +195 -0
  18. data/assets/src/InheritingBroadcastReceiver.java +27 -0
  19. data/assets/src/InheritingClass.java +19 -0
  20. data/assets/src/InheritingService.java +9 -0
  21. data/assets/src/RubotoActivity.java +111 -0
  22. data/assets/src/RubotoBroadcastReceiver.java +51 -0
  23. data/assets/src/RubotoService.java +61 -0
  24. data/assets/src/org/ruboto/RubotoDialog.java +11 -0
  25. data/assets/src/org/ruboto/Script.java +545 -0
  26. data/assets/src/org/ruboto/test/ActivityTest.java +63 -0
  27. data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +124 -0
  28. data/assets/src/ruboto.rb +621 -0
  29. data/assets/test/assets/scripts/test_helper.rb +13 -0
  30. data/bin/ruboto +5 -0
  31. data/lib/java_class_gen/InheritingClass.java.erb +10 -0
  32. data/lib/java_class_gen/android_api.xml +1 -0
  33. data/lib/ruboto.rb +16 -0
  34. data/lib/ruboto/api.rb +21 -0
  35. data/lib/ruboto/commands/base.rb +392 -0
  36. data/lib/ruboto/core_ext/array.rb +6 -0
  37. data/lib/ruboto/core_ext/object.rb +10 -0
  38. data/lib/ruboto/util/asset_copier.rb +27 -0
  39. data/lib/ruboto/util/build.rb +201 -0
  40. data/lib/ruboto/util/code_formatting.rb +22 -0
  41. data/lib/ruboto/util/log_action.rb +20 -0
  42. data/lib/ruboto/util/main_fix.rb +13 -0
  43. data/lib/ruboto/util/objectspace.rb +8 -0
  44. data/lib/ruboto/util/scan_in_api.rb +40 -0
  45. data/lib/ruboto/util/update.rb +420 -0
  46. data/lib/ruboto/util/verify.rb +87 -0
  47. data/lib/ruboto/util/xml_element.rb +200 -0
  48. data/lib/ruboto/version.rb +3 -0
  49. data/test/activity/image_button_activity.rb +21 -0
  50. data/test/activity/image_button_activity_test.rb +21 -0
  51. data/test/activity/image_button_and_button_activity.rb +24 -0
  52. data/test/activity/image_button_and_button_activity_test.rb +27 -0
  53. data/test/activity/option_menu_activity.rb +21 -0
  54. data/test/activity/option_menu_activity_test.rb +20 -0
  55. data/test/activity/stack_activity.rb +21 -0
  56. data/test/activity/stack_activity_test.rb +23 -0
  57. data/test/app_test_methods.rb +41 -0
  58. data/test/minimal_app_test.rb +23 -0
  59. data/test/rake_test.rb +40 -0
  60. data/test/ruboto_gen_test.rb +32 -0
  61. data/test/ruboto_gen_with_psych_test.rb +16 -0
  62. data/test/ruboto_update_test.rb +5 -0
  63. data/test/ruboto_update_with_psych_test.rb +18 -0
  64. data/test/service_test.rb +49 -0
  65. data/test/test_helper.rb +177 -0
  66. data/test/update_test_methods.rb +33 -0
  67. metadata +157 -0
@@ -0,0 +1,61 @@
1
+ package THE_PACKAGE;
2
+
3
+ import org.ruboto.Script;
4
+ import java.io.IOException;
5
+ import android.app.ProgressDialog;
6
+
7
+ public abstract class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
8
+ private String scriptName;
9
+ private String remoteVariable = "";
10
+ public Object[] args;
11
+
12
+ THE_CONSTANTS
13
+
14
+ private Object[] callbackProcs = new Object[CONSTANTS_COUNT];
15
+
16
+ public void setCallbackProc(int id, Object obj) {
17
+ callbackProcs[id] = obj;
18
+ }
19
+
20
+ public THE_RUBOTO_CLASS setRemoteVariable(String var) {
21
+ remoteVariable = ((var == null) ? "" : (var + "."));
22
+ return this;
23
+ }
24
+
25
+ public void setScriptName(String name){
26
+ scriptName = name;
27
+ }
28
+
29
+ /****************************************************************************************
30
+ *
31
+ * Activity Lifecycle: onCreate
32
+ */
33
+
34
+ @Override
35
+ public void onCreate() {
36
+ args = new Object[0];
37
+
38
+ super.onCreate();
39
+
40
+ if (Script.setUpJRuby(this)) {
41
+ Script.defineGlobalVariable("$service", this);
42
+ try {
43
+ new Script(scriptName).execute();
44
+ } catch(IOException e) {
45
+ e.printStackTrace();
46
+ }
47
+ } else {
48
+ // FIXME(uwe): What to do if the Ruboto Core plarform cannot be found?
49
+ }
50
+ }
51
+
52
+ /****************************************************************************************
53
+ *
54
+ * Generated Methods
55
+ */
56
+
57
+ THE_METHODS
58
+
59
+ }
60
+
61
+
@@ -0,0 +1,11 @@
1
+ package org.ruboto;
2
+
3
+ /***********************************************************
4
+ *
5
+ * Extends RubotoActivity to specify Theme.Dialog in
6
+ * the AndroidManifest.xml file.
7
+ *
8
+ */
9
+
10
+ public class RubotoDialog extends RubotoActivity {
11
+ }
@@ -0,0 +1,545 @@
1
+ package org.ruboto;
2
+
3
+ import android.content.Context;
4
+ import android.content.Intent;
5
+ import android.content.pm.ApplicationInfo;
6
+ import android.content.pm.PackageInfo;
7
+ import android.content.pm.PackageManager;
8
+ import android.content.pm.PackageManager.NameNotFoundException;
9
+ import android.content.res.AssetManager;
10
+ import android.net.Uri;
11
+ import android.os.Environment;
12
+ import android.util.Log;
13
+
14
+ import java.io.BufferedOutputStream;
15
+ import java.io.BufferedReader;
16
+ import java.io.File;
17
+ import java.io.FileOutputStream;
18
+ import java.io.FileReader;
19
+ import java.io.FilenameFilter;
20
+ import java.io.IOException;
21
+ import java.io.InputStream;
22
+ import java.io.OutputStream;
23
+ import java.io.PrintStream;
24
+ import java.lang.reflect.InvocationTargetException;
25
+ import java.lang.reflect.Method;
26
+ import java.util.List;
27
+
28
+ import dalvik.system.PathClassLoader;
29
+
30
+ public class Script {
31
+ private static String scriptsDir = "scripts";
32
+ private static File scriptsDirFile = null;
33
+
34
+ private String name = null;
35
+ private static Object ruby;
36
+ private static boolean initialized = false;
37
+
38
+ private static String localContextScope = "SINGLETON";
39
+ private static String localVariableBehavior = "TRANSIENT";
40
+
41
+ public static final String TAG = "RUBOTO"; // for logging
42
+ private static String JRUBY_VERSION;
43
+
44
+ /*************************************************************************************************
45
+ *
46
+ * Static Methods: ScriptingContainer config
47
+ */
48
+
49
+ public static void setLocalContextScope(String val) {
50
+ localContextScope = val;
51
+ }
52
+
53
+ public static void setLocalVariableBehavior(String val) {
54
+ localVariableBehavior = val;
55
+ }
56
+
57
+ /*************************************************************************************************
58
+ *
59
+ * Static Methods: JRuby Execution
60
+ */
61
+
62
+ public static final FilenameFilter RUBY_FILES = new FilenameFilter() {
63
+ public boolean accept(File dir, String fname) {
64
+ return fname.endsWith(".rb");
65
+ }
66
+ };
67
+
68
+ public static synchronized boolean isInitialized() {
69
+ return initialized;
70
+ }
71
+
72
+ public static synchronized boolean setUpJRuby(Context appContext) {
73
+ return setUpJRuby(appContext, System.out);
74
+ }
75
+
76
+ public static synchronized boolean setUpJRuby(Context appContext, PrintStream out) {
77
+ if (!initialized) {
78
+ Log.d(TAG, "Setting up JRuby runtime");
79
+ System.setProperty("jruby.bytecode.version", "1.5");
80
+ System.setProperty("jruby.interfaces.useProxy", "true");
81
+ System.setProperty("jruby.management.enabled", "false");
82
+ System.setProperty("jruby.objectspace.enabled", "false");
83
+ System.setProperty("jruby.thread.pooling", "true");
84
+ System.setProperty("jruby.native.enabled", "false");
85
+
86
+ // Uncomment these to debug Ruby source loading
87
+ // System.setProperty("jruby.debug.loadService", "true");
88
+ // System.setProperty("jruby.debug.loadService.timing", "true");
89
+
90
+
91
+ ClassLoader classLoader;
92
+ Class<?> scriptingContainerClass;
93
+ String apkName = null;
94
+
95
+ try {
96
+ scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer");
97
+ System.out.println("Found JRuby in this APK");
98
+ classLoader = Script.class.getClassLoader();
99
+ try {
100
+ apkName = appContext.getPackageManager().getApplicationInfo(appContext.getPackageName(), 0).sourceDir;
101
+ } catch (NameNotFoundException e) {}
102
+ } catch (ClassNotFoundException e1) {
103
+ String packageName = "org.ruboto.core";
104
+ try {
105
+ apkName = appContext.getPackageManager().getApplicationInfo(packageName, 0).sourceDir;
106
+ } catch (PackageManager.NameNotFoundException e) {
107
+ System.out.println("JRuby not found");
108
+ return false;
109
+ }
110
+
111
+ System.out.println("Found JRuby in platform APK");
112
+ if (true) {
113
+ classLoader = new PathClassLoader(apkName, Script.class.getClassLoader());
114
+ } else {
115
+ // Alternative way to get the class loader. The other way is rumoured to have memory leaks.
116
+ try {
117
+ Context platformAppContext = appContext.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE + Context.CONTEXT_IGNORE_SECURITY);
118
+ classLoader = platformAppContext.getClassLoader();
119
+ } catch (PackageManager.NameNotFoundException e) {
120
+ System.out.println("Could not create package context even if application info could be found. Should never happen.");
121
+ return false;
122
+ }
123
+ }
124
+
125
+ try {
126
+ scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer", true, classLoader);
127
+ } catch (ClassNotFoundException e) {
128
+ // FIXME(uwe): ScriptingContainer not found in the platform APK...
129
+ e.printStackTrace();
130
+ return false;
131
+ }
132
+ }
133
+
134
+ try {
135
+ try {
136
+ JRUBY_VERSION = (String) Class.forName("org.jruby.runtime.Constants", true, classLoader).getDeclaredField("VERSION").get(String.class);
137
+ } catch (java.lang.NoSuchFieldException nsfex) {
138
+ nsfex.printStackTrace();
139
+ JRUBY_VERSION = "ERROR";
140
+ }
141
+
142
+ Class scopeClass = Class.forName("org.jruby.embed.LocalContextScope", true, scriptingContainerClass.getClassLoader());
143
+ Class behaviorClass = Class.forName("org.jruby.embed.LocalVariableBehavior", true, scriptingContainerClass.getClassLoader());
144
+
145
+ ruby = scriptingContainerClass
146
+ .getConstructor(scopeClass, behaviorClass)
147
+ .newInstance(Enum.valueOf(scopeClass, localContextScope),
148
+ Enum.valueOf(behaviorClass, localVariableBehavior));
149
+
150
+ Class compileModeClass = Class.forName("org.jruby.RubyInstanceConfig$CompileMode", true, classLoader);
151
+ callScriptingContainerMethod(Void.class, "setCompileMode", Enum.valueOf(compileModeClass, "OFF"));
152
+
153
+ // Class traceTypeClass = Class.forName("org.jruby.runtime.backtrace.TraceType", true, classLoader);
154
+ // Method traceTypeForMethod = traceTypeClass.getMethod("traceTypeFor", String.class);
155
+ // Object traceTypeRaw = traceTypeForMethod.invoke(null, "raw");
156
+ // callScriptingContainerMethod(Void.class, "setTraceType", traceTypeRaw);
157
+
158
+ // FIXME(uwe): Write tutorial on profiling.
159
+ // container.getProvider().getRubyInstanceConfig().setProfilingMode(mode);
160
+
161
+ // callScriptingContainerMethod(Void.class, "setClassLoader", classLoader);
162
+ Method setClassLoaderMethod = ruby.getClass().getMethod("setClassLoader", ClassLoader.class);
163
+ setClassLoaderMethod.invoke(ruby, classLoader);
164
+
165
+ Thread.currentThread().setContextClassLoader(classLoader);
166
+
167
+ String defaultCurrentDir = appContext.getFilesDir().getPath();
168
+ Log.d(TAG, "Setting JRuby current directory to " + defaultCurrentDir);
169
+ callScriptingContainerMethod(Void.class, "setCurrentDirectory", defaultCurrentDir);
170
+
171
+ if (out != null) {
172
+ // callScriptingContainerMethod(Void.class, "setOutput", out);
173
+ Method setOutputMethod = ruby.getClass().getMethod("setOutput", PrintStream.class);
174
+ setOutputMethod.invoke(ruby, out);
175
+
176
+ // callScriptingContainerMethod(Void.class, "setError", out);
177
+ Method setErrorMethod = ruby.getClass().getMethod("setError", PrintStream.class);
178
+ setErrorMethod.invoke(ruby, out);
179
+ }
180
+
181
+ String jrubyHome = "file:" + apkName + "!";
182
+ Log.i(TAG, "Setting JRUBY_HOME: " + jrubyHome);
183
+ System.setProperty("jruby.home", jrubyHome);
184
+
185
+ String extraScriptsDir = scriptsDirName(appContext);
186
+ Log.i(TAG, "Checking scripts in " + extraScriptsDir);
187
+ if (configDir(extraScriptsDir)) {
188
+ Log.i(TAG, "Added extra scripts path: " + extraScriptsDir);
189
+ }
190
+ initialized = true;
191
+ } catch (ClassNotFoundException e) {
192
+ handleInitException(e);
193
+ } catch (IllegalArgumentException e) {
194
+ handleInitException(e);
195
+ } catch (SecurityException e) {
196
+ handleInitException(e);
197
+ } catch (InstantiationException e) {
198
+ handleInitException(e);
199
+ } catch (IllegalAccessException e) {
200
+ handleInitException(e);
201
+ } catch (InvocationTargetException e) {
202
+ handleInitException(e);
203
+ } catch (NoSuchMethodException e) {
204
+ handleInitException(e);
205
+ }
206
+ }
207
+ return initialized;
208
+ }
209
+
210
+ private static void handleInitException(Exception e) {
211
+ Log.e(TAG, "Exception starting JRuby");
212
+ Log.e(TAG, e.getMessage() != null ? e.getMessage() : e.getClass().getName());
213
+ e.printStackTrace();
214
+ ruby = null;
215
+ }
216
+
217
+ @SuppressWarnings("unchecked")
218
+ public static <T> T callScriptingContainerMethod(Class<T> returnType, String methodName, Object... args) {
219
+ Class<?>[] argClasses = new Class[args.length];
220
+ for (int i = 0; i < argClasses.length; i++) {
221
+ argClasses[i] = args[i].getClass();
222
+ }
223
+ try {
224
+ Method method = ruby.getClass().getMethod(methodName, argClasses);
225
+ System.out.println("callScriptingContainerMethod: method: " + method);
226
+ T result = (T) method.invoke(ruby, args);
227
+ System.out.println("callScriptingContainerMethod: result: " + result);
228
+ return result;
229
+ } catch (RuntimeException re) {
230
+ re.printStackTrace();
231
+ } catch (IllegalAccessException e) {
232
+ // TODO Auto-generated catch block
233
+ e.printStackTrace();
234
+ } catch (InvocationTargetException e) {
235
+ try {
236
+ e.printStackTrace();
237
+ } catch (NullPointerException npe) {
238
+ }
239
+ } catch (NoSuchMethodException e) {
240
+ // TODO Auto-generated catch block
241
+ e.printStackTrace();
242
+ }
243
+ return null;
244
+ }
245
+
246
+ public static String execute(String code) {
247
+ Object result = exec(code);
248
+ return result != null ? result.toString() : "nil";
249
+ // TODO: Why is callMethod returning "main"?
250
+ // return result != null ? callMethod(result, "inspect", String.class) : "null";
251
+ }
252
+
253
+ public static Object exec(String code) {
254
+ // return callScriptingContainerMethod(Object.class, "runScriptlet", code);
255
+ try {
256
+ Method runScriptletMethod = ruby.getClass().getMethod("runScriptlet", String.class);
257
+ return runScriptletMethod.invoke(ruby, code);
258
+ } catch (NoSuchMethodException nsme) {
259
+ throw new RuntimeException(nsme);
260
+ } catch (IllegalAccessException iae) {
261
+ throw new RuntimeException(iae);
262
+ } catch (java.lang.reflect.InvocationTargetException ite) {
263
+ throw ((RuntimeException) ite.getCause());
264
+ }
265
+ }
266
+
267
+ public static void defineGlobalConstant(String name, Object object) {
268
+ put(name, object);
269
+ }
270
+
271
+ public static void put(String name, Object object) {
272
+ // callScriptingContainerMethod(Void.class, "put", name, object);
273
+ try {
274
+ Method putMethod = ruby.getClass().getMethod("put", String.class, Object.class);
275
+ putMethod.invoke(ruby, name, object);
276
+ } catch (NoSuchMethodException nsme) {
277
+ throw new RuntimeException(nsme);
278
+ } catch (IllegalAccessException iae) {
279
+ throw new RuntimeException(iae);
280
+ } catch (java.lang.reflect.InvocationTargetException ite) {
281
+ throw new RuntimeException(ite);
282
+ }
283
+ }
284
+
285
+ public static void defineGlobalVariable(String name, Object object) {
286
+ defineGlobalConstant(name, object);
287
+ }
288
+
289
+ /*************************************************************************************************
290
+ *
291
+ * Static Methods: Scripts Directory
292
+ */
293
+
294
+ public static void setDir(String dir) {
295
+ scriptsDir = dir;
296
+ scriptsDirFile = new File(dir);
297
+ if (ruby != null) {
298
+ Log.d(TAG, "Changing JRuby current directory to " + scriptsDir);
299
+ callScriptingContainerMethod(Void.class, "setCurrentDirectory", scriptsDir);
300
+ }
301
+ }
302
+
303
+ public static String getDir() {
304
+ return scriptsDir;
305
+ }
306
+
307
+ public static File getDirFile() {
308
+ return scriptsDirFile;
309
+ }
310
+
311
+ private static void setLoadPath(List<String> loadPath) {
312
+ // callScriptingContainerMethod(Void.class, "setLoadPaths", loadPath);
313
+ try {
314
+ Method setLoadPathsMethod = ruby.getClass().getMethod("setLoadPaths", List.class);
315
+ setLoadPathsMethod.invoke(ruby, loadPath);
316
+ } catch (NoSuchMethodException nsme) {
317
+ throw new RuntimeException(nsme);
318
+ } catch (IllegalAccessException iae) {
319
+ throw new RuntimeException(iae);
320
+ } catch (java.lang.reflect.InvocationTargetException ite) {
321
+ throw new RuntimeException(ite);
322
+ }
323
+ }
324
+
325
+ private static List<String> getLoadPath() {
326
+ return callScriptingContainerMethod(List.class, "getLoadPaths");
327
+ }
328
+
329
+ public static Boolean configDir(String scriptsDir) {
330
+ if (new File(scriptsDir).exists()) {
331
+ Log.i(TAG, "Found extra scripts dir: " + scriptsDir);
332
+ setDir(scriptsDir);
333
+ exec("$:.unshift '" + scriptsDir + "' ; $:.uniq! ; p $:");
334
+ return true;
335
+ } else {
336
+ Log.i(TAG, "Extra scripts dir not present: " + scriptsDir);
337
+ return false;
338
+ }
339
+ }
340
+
341
+ private static void copyScripts(String from, File to, AssetManager assets) {
342
+ try {
343
+ byte[] buffer = new byte[8192];
344
+ for (String f : assets.list(from)) {
345
+ File dest = new File(to, f);
346
+
347
+ if (dest.exists()) {
348
+ continue;
349
+ }
350
+
351
+ Log.d(TAG, "copying file from " + from + "/" + f + " to " + dest);
352
+
353
+ if (assets.list(from + "/" + f).length == 0) {
354
+ InputStream is = assets.open(from + "/" + f);
355
+ OutputStream fos = new BufferedOutputStream(new FileOutputStream(dest), 8192);
356
+
357
+ int n;
358
+ while ((n = is.read(buffer, 0, buffer.length)) != -1) {
359
+ fos.write(buffer, 0, n);
360
+ }
361
+ is.close();
362
+ fos.close();
363
+ } else {
364
+ dest.mkdir();
365
+ copyScripts(from + "/" + f, dest, assets);
366
+ }
367
+ }
368
+ } catch (IOException iox) {
369
+ Log.e(TAG, "error copying scripts", iox);
370
+ }
371
+ }
372
+
373
+ public static void copyAssets(Context context, String directory) {
374
+ File dest = new File(scriptsDirFile.getParentFile(), directory);
375
+ if (dest.exists() || dest.mkdir()) {
376
+ copyScripts(directory, dest, context.getAssets());
377
+ } else {
378
+ throw new RuntimeException("Unable to create scripts directory: " + dest);
379
+ }
380
+ }
381
+
382
+ private static boolean isDebugBuild(Context context) {
383
+ PackageManager pm = context.getPackageManager();
384
+ PackageInfo pi;
385
+ try {
386
+ pi = pm.getPackageInfo(context.getPackageName(), 0);
387
+ return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
388
+ } catch (NameNotFoundException e) {
389
+ return false;
390
+ }
391
+
392
+ }
393
+
394
+ private static String scriptsDirName(Context context) {
395
+ File storageDir = null;
396
+ if (isDebugBuild(context)) {
397
+
398
+ // FIXME(uwe): Simplify this as soon as we drop support for android-7 or JRuby 1.5.6 or JRuby 1.6.2
399
+ Log.i(TAG, "JRuby VERSION: " + JRUBY_VERSION);
400
+ if (!JRUBY_VERSION.equals("1.5.6") && !JRUBY_VERSION.equals("1.6.2") && android.os.Build.VERSION.SDK_INT >= 8) {
401
+ put("script_context", context);
402
+ storageDir = (File) exec("script_context.getExternalFilesDir(nil)");
403
+ } else {
404
+ storageDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/files");
405
+ Log.e(TAG, "Calculated path to sdcard the old way: " + storageDir);
406
+ }
407
+ // FIXME end
408
+
409
+ if (storageDir == null || (!storageDir.exists() && !storageDir.mkdirs())) {
410
+ Log.e(TAG,
411
+ "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.");
412
+ storageDir = context.getFilesDir();
413
+ }
414
+ } else {
415
+ storageDir = context.getFilesDir();
416
+ }
417
+ return storageDir.getAbsolutePath() + "/scripts";
418
+ }
419
+
420
+ private static void copyScriptsIfNeeded(Context context) {
421
+ String to = scriptsDirName(context);
422
+ Log.i(TAG, "Checking scripts in " + to);
423
+
424
+ /* the if makes sure we only do this the first time */
425
+ if (configDir(to)) {
426
+ Log.i(TAG, "Copying scripts to " + to);
427
+ copyAssets(context, "scripts");
428
+ }
429
+ }
430
+
431
+
432
+ /*************************************************************************************************
433
+ *
434
+ * Constructors
435
+ */
436
+
437
+ public Script(String name) {
438
+ this.name = name;
439
+ }
440
+
441
+ /*************************************************************************************************
442
+ *
443
+ * Attribute Access
444
+ */
445
+
446
+ public String getName() {
447
+ return name;
448
+ }
449
+
450
+ public File getFile() {
451
+ return new File(getDir(), name);
452
+ }
453
+
454
+ public Script setName(String name) {
455
+ this.name = name;
456
+ return this;
457
+ }
458
+
459
+ public String getContents() throws IOException {
460
+ InputStream is;
461
+ if (new File(scriptsDir + "/" + name).exists()) {
462
+ is = new java.io.FileInputStream(scriptsDir + "/" + name);
463
+ } else {
464
+ is = getClass().getClassLoader().getResourceAsStream(name);
465
+ }
466
+ BufferedReader buffer = new BufferedReader(new java.io.InputStreamReader(is), 8192);
467
+ StringBuilder source = new StringBuilder();
468
+ while (true) {
469
+ String line = buffer.readLine();
470
+ if (line == null) {
471
+ break;
472
+ }
473
+ source.append(line).append("\n");
474
+ }
475
+ buffer.close();
476
+ return source.toString();
477
+ }
478
+
479
+ /*************************************************************************************************
480
+ *
481
+ * Script Actions
482
+ */
483
+
484
+ public static String getScriptFilename() {
485
+ return callScriptingContainerMethod(String.class, "getScriptFilename");
486
+ }
487
+
488
+ public static void setScriptFilename(String name) {
489
+ callScriptingContainerMethod(Void.class, "setScriptFilename", name);
490
+ }
491
+
492
+ public String execute() throws IOException {
493
+ Script.setScriptFilename(getClass().getClassLoader().getResource(name).getPath());
494
+ return Script.execute(getContents());
495
+ }
496
+
497
+ public static void callMethod(Object receiver, String methodName, Object[] args) {
498
+ // callScriptingContainerMethod(Void.class, "callMethod", receiver, methodName, args);
499
+ try {
500
+ Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object[].class);
501
+ callMethodMethod.invoke(ruby, receiver, methodName, args);
502
+ } catch (NoSuchMethodException nsme) {
503
+ throw new RuntimeException(nsme);
504
+ } catch (IllegalAccessException iae) {
505
+ throw new RuntimeException(iae);
506
+ } catch (java.lang.reflect.InvocationTargetException ite) {
507
+ throw (RuntimeException)(ite.getCause());
508
+ }
509
+ }
510
+
511
+ public static void callMethod(Object object, String methodName, Object arg) {
512
+ callMethod(object, methodName, new Object[] { arg });
513
+ }
514
+
515
+ public static void callMethod(Object object, String methodName) {
516
+ callMethod(object, methodName, new Object[] {});
517
+ }
518
+
519
+ @SuppressWarnings("unchecked")
520
+ public static <T> T callMethod(Object receiver, String methodName, Object[] args, Class<T> returnType) {
521
+ // return callScriptingContainerMethod(returnType, "callMethod", receiver, methodName, args, returnType);
522
+ try {
523
+ Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Object[].class, Class.class);
524
+ return (T) callMethodMethod.invoke(ruby, receiver, methodName, args, returnType);
525
+ } catch (NoSuchMethodException nsme) {
526
+ throw new RuntimeException(nsme);
527
+ } catch (IllegalAccessException iae) {
528
+ throw new RuntimeException(iae);
529
+ } catch (java.lang.reflect.InvocationTargetException ite) {
530
+ throw (RuntimeException) ite.getCause();
531
+ }
532
+ }
533
+
534
+ public static <T> T callMethod(Object receiver, String methodName,
535
+ Object arg, Class<T> returnType) {
536
+ return callMethod(receiver, methodName, new Object[]{arg}, returnType);
537
+ }
538
+
539
+ public static <T> T callMethod(Object receiver, String methodName,
540
+ Class<T> returnType) {
541
+ return callMethod(receiver, methodName, new Object[]{}, returnType);
542
+ }
543
+
544
+ }
545
+