ruboto 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +13 -49
- data/Rakefile +26 -26
- data/assets/rakelib/ruboto.rake +29 -9
- data/assets/res/drawable-hdpi/{icon.png → ic_launcher.png} +0 -0
- data/assets/res/drawable-ldpi/{icon.png → ic_launcher.png} +0 -0
- data/assets/res/drawable-mdpi/{icon.png → ic_launcher.png} +0 -0
- data/assets/samples/sample_activity.rb +19 -9
- data/assets/samples/sample_broadcast_receiver.rb +3 -1
- data/assets/samples/sample_service.rb +9 -9
- data/assets/src/InheritingActivity.java +1 -1
- data/assets/src/InheritingBroadcastReceiver.java +4 -4
- data/assets/src/InheritingClass.java +1 -1
- data/assets/src/InheritingService.java +2 -1
- data/assets/src/RubotoActivity.java +26 -17
- data/assets/src/RubotoBroadcastReceiver.java +32 -11
- data/assets/src/RubotoService.java +23 -13
- data/assets/src/org/ruboto/EntryPointActivity.java +18 -26
- data/assets/src/org/ruboto/JRubyAdapter.java +468 -0
- data/assets/src/org/ruboto/Log.java +22 -0
- data/assets/src/org/ruboto/Script.java +113 -587
- data/assets/src/org/ruboto/test/ActivityTest.java +7 -7
- data/assets/src/org/ruboto/test/InstrumentationTestRunner.java +27 -12
- data/assets/src/ruboto.rb +1 -1
- data/assets/src/ruboto/activity.rb +10 -1
- data/assets/src/ruboto/base.rb +0 -12
- data/assets/src/ruboto/broadcast_receiver.rb +12 -0
- data/assets/src/ruboto/menu.rb +0 -1
- data/assets/src/ruboto/package.rb +11 -0
- data/assets/src/ruboto/service.rb +9 -0
- data/lib/ruboto/commands/base.rb +1 -1
- data/lib/ruboto/util/build.rb +1 -1
- data/lib/ruboto/util/update.rb +35 -27
- data/lib/ruboto/util/xml_element.rb +25 -12
- data/lib/ruboto/version.rb +2 -2
- data/test/activity/image_button_activity.rb +14 -11
- data/test/activity/image_button_activity_test.rb +2 -6
- data/test/activity/image_button_and_button_activity.rb +15 -17
- data/test/activity/image_button_and_button_activity_test.rb +4 -8
- data/test/activity/option_menu_activity.rb +17 -12
- data/test/activity/option_menu_activity_test.rb +1 -4
- data/test/activity/psych_activity.rb +20 -13
- data/test/activity/psych_activity_test.rb +3 -1
- data/test/activity/stack_activity.rb +17 -14
- data/test/activity/stack_activity_test.rb +13 -12
- data/test/app_test_methods.rb +25 -19
- data/test/block_def_activity/image_button_activity.rb +23 -0
- data/test/block_def_activity/image_button_activity_test.rb +21 -0
- data/test/block_def_activity/image_button_and_button_activity.rb +20 -0
- data/test/block_def_activity/image_button_and_button_activity_test.rb +27 -0
- data/test/block_def_activity/option_menu_activity.rb +26 -0
- data/test/block_def_activity/option_menu_activity_test.rb +18 -0
- data/test/block_def_activity/psych_activity.rb +35 -0
- data/test/block_def_activity/psych_activity_test.rb +16 -0
- data/test/block_def_activity/stack_activity.rb +25 -0
- data/test/block_def_activity/stack_activity_test.rb +31 -0
- data/test/broadcast_receiver_test.rb +2 -2
- data/test/handle_activity/image_button_activity.rb +21 -0
- data/test/handle_activity/image_button_activity_test.rb +21 -0
- data/test/handle_activity/image_button_and_button_activity.rb +24 -0
- data/test/handle_activity/image_button_and_button_activity_test.rb +27 -0
- data/test/handle_activity/option_menu_activity.rb +21 -0
- data/test/handle_activity/option_menu_activity_test.rb +20 -0
- data/test/handle_activity/psych_activity.rb +31 -0
- data/test/handle_activity/psych_activity_test.rb +16 -0
- data/test/handle_activity/stack_activity.rb +21 -0
- data/test/handle_activity/stack_activity_test.rb +32 -0
- data/test/minimal_app_test.rb +4 -4
- data/test/rake_test.rb +15 -1
- data/test/ruboto_gen_test.rb +7 -4
- data/test/service_test.rb +110 -21
- data/test/test_helper.rb +17 -14
- data/test/updated_example_test_methods.rb +5 -14
- metadata +30 -7
@@ -0,0 +1,22 @@
|
|
1
|
+
package org.ruboto;
|
2
|
+
|
3
|
+
public class Log {
|
4
|
+
public static final String TAG = "RUBOTO";
|
5
|
+
|
6
|
+
public static void d(String message) {
|
7
|
+
android.util.Log.d(TAG, message);
|
8
|
+
}
|
9
|
+
|
10
|
+
public static void i(String message) {
|
11
|
+
android.util.Log.i(TAG, message);
|
12
|
+
}
|
13
|
+
|
14
|
+
public static void e(String message) {
|
15
|
+
android.util.Log.e(TAG, message);
|
16
|
+
}
|
17
|
+
|
18
|
+
public static void e(String message, Throwable t) {
|
19
|
+
android.util.Log.e(TAG, message, t);
|
20
|
+
}
|
21
|
+
|
22
|
+
}
|
@@ -1,626 +1,152 @@
|
|
1
1
|
package org.ruboto;
|
2
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
3
|
import java.io.BufferedOutputStream;
|
15
4
|
import java.io.BufferedReader;
|
16
5
|
import java.io.File;
|
17
6
|
import java.io.FileOutputStream;
|
18
|
-
import java.io.FileReader;
|
19
|
-
import java.io.FilenameFilter;
|
20
7
|
import java.io.IOException;
|
21
8
|
import java.io.InputStream;
|
22
9
|
import java.io.OutputStream;
|
23
|
-
import java.io.PrintStream;
|
24
10
|
import java.lang.reflect.InvocationTargetException;
|
25
11
|
import java.lang.reflect.Method;
|
26
|
-
import java.util.List;
|
27
12
|
|
28
|
-
import
|
13
|
+
import android.content.Context;
|
14
|
+
import android.content.res.AssetManager;
|
15
|
+
import android.os.Environment;
|
29
16
|
|
30
17
|
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 isDebugBuild = false;
|
37
|
-
private static PrintStream output = null;
|
38
|
-
private static boolean initialized = false;
|
39
|
-
|
40
|
-
private static String localContextScope = "SINGLETON";
|
41
|
-
private static String localVariableBehavior = "TRANSIENT";
|
42
|
-
|
43
|
-
public static final String TAG = "RUBOTO"; // for logging
|
44
|
-
private static String JRUBY_VERSION;
|
45
|
-
private static String RUBOTO_CORE_VERSION_NAME;
|
46
|
-
|
47
|
-
/*************************************************************************************************
|
48
|
-
*
|
49
|
-
* Static Methods: ScriptingContainer config
|
50
|
-
*/
|
51
|
-
|
52
|
-
public static void setLocalContextScope(String val) {
|
53
|
-
localContextScope = val;
|
54
|
-
}
|
55
|
-
|
56
|
-
public static void setLocalVariableBehavior(String val) {
|
57
|
-
localVariableBehavior = val;
|
58
|
-
}
|
59
|
-
|
60
|
-
/*************************************************************************************************
|
61
|
-
*
|
62
|
-
* Static Methods: JRuby Execution
|
63
|
-
*/
|
64
|
-
|
65
|
-
public static final FilenameFilter RUBY_FILES = new FilenameFilter() {
|
66
|
-
public boolean accept(File dir, String fname) {
|
67
|
-
return fname.endsWith(".rb");
|
68
|
-
}
|
69
|
-
};
|
70
|
-
|
71
|
-
public static synchronized boolean isInitialized() {
|
72
|
-
return initialized;
|
73
|
-
}
|
74
|
-
|
75
|
-
public static boolean usesPlatformApk() {
|
76
|
-
return RUBOTO_CORE_VERSION_NAME != null;
|
77
|
-
}
|
78
|
-
|
79
|
-
public static String getPlatformVersionName() {
|
80
|
-
return RUBOTO_CORE_VERSION_NAME;
|
81
|
-
}
|
82
|
-
|
83
|
-
public static synchronized boolean setUpJRuby(Context appContext) {
|
84
|
-
return setUpJRuby(appContext, output == null ? System.out : output);
|
85
|
-
}
|
86
|
-
|
87
|
-
public static synchronized boolean setUpJRuby(Context appContext, PrintStream out) {
|
88
|
-
if (!initialized) {
|
89
|
-
setDebugBuild(appContext);
|
90
|
-
Log.d(TAG, "Setting up JRuby runtime (" + (isDebugBuild ? "DEBUG" : "RELEASE") + ")");
|
91
|
-
System.setProperty("jruby.bytecode.version", "1.6");
|
92
|
-
System.setProperty("jruby.interfaces.useProxy", "true");
|
93
|
-
System.setProperty("jruby.management.enabled", "false");
|
94
|
-
System.setProperty("jruby.objectspace.enabled", "false");
|
95
|
-
System.setProperty("jruby.thread.pooling", "true");
|
96
|
-
System.setProperty("jruby.native.enabled", "false");
|
97
|
-
// System.setProperty("jruby.compat.version", "RUBY1_8"); // RUBY1_9 is the default
|
98
|
-
|
99
|
-
// Uncomment these to debug Ruby source loading
|
100
|
-
// System.setProperty("jruby.debug.loadService", "true");
|
101
|
-
// System.setProperty("jruby.debug.loadService.timing", "true");
|
102
|
-
|
103
|
-
|
104
|
-
ClassLoader classLoader;
|
105
|
-
Class<?> scriptingContainerClass;
|
106
|
-
String apkName = null;
|
107
|
-
|
108
|
-
try {
|
109
|
-
scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer");
|
110
|
-
System.out.println("Found JRuby in this APK");
|
111
|
-
classLoader = Script.class.getClassLoader();
|
112
|
-
try {
|
113
|
-
apkName = appContext.getPackageManager().getApplicationInfo(appContext.getPackageName(), 0).sourceDir;
|
114
|
-
} catch (NameNotFoundException e) {}
|
115
|
-
} catch (ClassNotFoundException e1) {
|
116
|
-
String packageName = "org.ruboto.core";
|
117
|
-
try {
|
118
|
-
PackageInfo pkgInfo = appContext.getPackageManager().getPackageInfo(packageName, 0);
|
119
|
-
apkName = pkgInfo.applicationInfo.sourceDir;
|
120
|
-
RUBOTO_CORE_VERSION_NAME = pkgInfo.versionName;
|
121
|
-
} catch (PackageManager.NameNotFoundException e2) {
|
122
|
-
out.println("JRuby not found in local APK:");
|
123
|
-
e1.printStackTrace(out);
|
124
|
-
out.println("JRuby not found in platform APK:");
|
125
|
-
e2.printStackTrace(out);
|
126
|
-
return false;
|
127
|
-
}
|
128
|
-
|
129
|
-
System.out.println("Found JRuby in platform APK");
|
130
|
-
if (true) {
|
131
|
-
classLoader = new PathClassLoader(apkName, Script.class.getClassLoader());
|
132
|
-
} else {
|
133
|
-
// Alternative way to get the class loader. The other way is rumoured to have memory leaks.
|
134
|
-
try {
|
135
|
-
Context platformAppContext = appContext.createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE + Context.CONTEXT_IGNORE_SECURITY);
|
136
|
-
classLoader = platformAppContext.getClassLoader();
|
137
|
-
} catch (PackageManager.NameNotFoundException e) {
|
138
|
-
System.out.println("Could not create package context even if application info could be found. Should never happen.");
|
139
|
-
return false;
|
140
|
-
}
|
141
|
-
}
|
142
|
-
|
143
|
-
try {
|
144
|
-
scriptingContainerClass = Class.forName("org.jruby.embed.ScriptingContainer", true, classLoader);
|
145
|
-
} catch (ClassNotFoundException e) {
|
146
|
-
// FIXME(uwe): ScriptingContainer not found in the platform APK...
|
147
|
-
e.printStackTrace();
|
148
|
-
return false;
|
149
|
-
}
|
150
|
-
}
|
151
|
-
|
152
|
-
try {
|
153
|
-
try {
|
154
|
-
JRUBY_VERSION = (String) Class.forName("org.jruby.runtime.Constants", true, classLoader).getDeclaredField("VERSION").get(String.class);
|
155
|
-
} catch (java.lang.NoSuchFieldException nsfex) {
|
156
|
-
nsfex.printStackTrace();
|
157
|
-
JRUBY_VERSION = "ERROR";
|
158
|
-
}
|
159
|
-
|
160
|
-
Class scopeClass = Class.forName("org.jruby.embed.LocalContextScope", true, scriptingContainerClass.getClassLoader());
|
161
|
-
Class behaviorClass = Class.forName("org.jruby.embed.LocalVariableBehavior", true, scriptingContainerClass.getClassLoader());
|
162
|
-
|
163
|
-
ruby = scriptingContainerClass
|
164
|
-
.getConstructor(scopeClass, behaviorClass)
|
165
|
-
.newInstance(Enum.valueOf(scopeClass, localContextScope),
|
166
|
-
Enum.valueOf(behaviorClass, localVariableBehavior));
|
167
|
-
|
168
|
-
Class compileModeClass = Class.forName("org.jruby.RubyInstanceConfig$CompileMode", true, classLoader);
|
169
|
-
callScriptingContainerMethod(Void.class, "setCompileMode", Enum.valueOf(compileModeClass, "OFF"));
|
170
|
-
|
171
|
-
// Class traceTypeClass = Class.forName("org.jruby.runtime.backtrace.TraceType", true, classLoader);
|
172
|
-
// Method traceTypeForMethod = traceTypeClass.getMethod("traceTypeFor", String.class);
|
173
|
-
// Object traceTypeRaw = traceTypeForMethod.invoke(null, "raw");
|
174
|
-
// callScriptingContainerMethod(Void.class, "setTraceType", traceTypeRaw);
|
18
|
+
private static String[] scriptsDir = new String[]{"scripts"};
|
175
19
|
|
176
|
-
|
177
|
-
// container.getProvider().getRubyInstanceConfig().setProfilingMode(mode);
|
20
|
+
private final String name;
|
178
21
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
Log.d(TAG, "Setting JRuby current directory to " + defaultCurrentDir);
|
187
|
-
callScriptingContainerMethod(Void.class, "setCurrentDirectory", defaultCurrentDir);
|
188
|
-
|
189
|
-
if (out != null) {
|
190
|
-
output = out;
|
191
|
-
setOutputStream(out);
|
192
|
-
} else if (output != null) {
|
193
|
-
setOutputStream(output);
|
194
|
-
}
|
195
|
-
|
196
|
-
String jrubyHome = "file:" + apkName + "!";
|
197
|
-
Log.i(TAG, "Setting JRUBY_HOME: " + jrubyHome);
|
198
|
-
System.setProperty("jruby.home", jrubyHome);
|
199
|
-
|
200
|
-
String extraScriptsDir = scriptsDirName(appContext);
|
201
|
-
Log.i(TAG, "Checking scripts in " + extraScriptsDir);
|
202
|
-
if (configDir(extraScriptsDir)) {
|
203
|
-
Log.i(TAG, "Added extra scripts path: " + extraScriptsDir);
|
204
|
-
}
|
205
|
-
initialized = true;
|
206
|
-
} catch (ClassNotFoundException e) {
|
207
|
-
handleInitException(e);
|
208
|
-
} catch (IllegalArgumentException e) {
|
209
|
-
handleInitException(e);
|
210
|
-
} catch (SecurityException e) {
|
211
|
-
handleInitException(e);
|
212
|
-
} catch (InstantiationException e) {
|
213
|
-
handleInitException(e);
|
214
|
-
} catch (IllegalAccessException e) {
|
215
|
-
handleInitException(e);
|
216
|
-
} catch (InvocationTargetException e) {
|
217
|
-
handleInitException(e);
|
218
|
-
} catch (NoSuchMethodException e) {
|
219
|
-
handleInitException(e);
|
220
|
-
}
|
221
|
-
}
|
222
|
-
return initialized;
|
223
|
-
}
|
224
|
-
|
225
|
-
public static void setOutputStream(PrintStream out) {
|
226
|
-
if (ruby == null) {
|
227
|
-
output = out;
|
228
|
-
} else {
|
229
|
-
try {
|
230
|
-
Method setOutputMethod = ruby.getClass().getMethod("setOutput", PrintStream.class);
|
231
|
-
setOutputMethod.invoke(ruby, out);
|
232
|
-
Method setErrorMethod = ruby.getClass().getMethod("setError", PrintStream.class);
|
233
|
-
setErrorMethod.invoke(ruby, out);
|
234
|
-
} catch (IllegalArgumentException e) {
|
235
|
-
handleInitException(e);
|
236
|
-
} catch (SecurityException e) {
|
237
|
-
handleInitException(e);
|
238
|
-
} catch (IllegalAccessException e) {
|
239
|
-
handleInitException(e);
|
240
|
-
} catch (InvocationTargetException e) {
|
241
|
-
handleInitException(e);
|
242
|
-
} catch (NoSuchMethodException e) {
|
243
|
-
handleInitException(e);
|
244
|
-
}
|
245
|
-
}
|
246
|
-
}
|
247
|
-
|
248
|
-
private static void handleInitException(Exception e) {
|
249
|
-
Log.e(TAG, "Exception starting JRuby");
|
250
|
-
Log.e(TAG, e.getMessage() != null ? e.getMessage() : e.getClass().getName());
|
251
|
-
e.printStackTrace();
|
252
|
-
ruby = null;
|
253
|
-
}
|
254
|
-
|
255
|
-
@SuppressWarnings("unchecked")
|
256
|
-
public static <T> T callScriptingContainerMethod(Class<T> returnType, String methodName, Object... args) {
|
257
|
-
Class<?>[] argClasses = new Class[args.length];
|
258
|
-
for (int i = 0; i < argClasses.length; i++) {
|
259
|
-
argClasses[i] = args[i].getClass();
|
260
|
-
}
|
261
|
-
try {
|
262
|
-
Method method = ruby.getClass().getMethod(methodName, argClasses);
|
263
|
-
System.out.println("callScriptingContainerMethod: method: " + method);
|
264
|
-
T result = (T) method.invoke(ruby, args);
|
265
|
-
System.out.println("callScriptingContainerMethod: result: " + result);
|
266
|
-
return result;
|
267
|
-
} catch (RuntimeException re) {
|
268
|
-
re.printStackTrace();
|
269
|
-
} catch (IllegalAccessException e) {
|
270
|
-
e.printStackTrace();
|
271
|
-
} catch (InvocationTargetException e) {
|
272
|
-
printStackTrace(e);
|
273
|
-
} catch (NoSuchMethodException e) {
|
274
|
-
e.printStackTrace();
|
275
|
-
}
|
276
|
-
return null;
|
277
|
-
}
|
278
|
-
|
279
|
-
public static String execute(String code) {
|
280
|
-
Object result = exec(code);
|
281
|
-
return result != null ? result.toString() : "nil";
|
282
|
-
// TODO: Why is callMethod returning "main"?
|
283
|
-
// return result != null ? callMethod(result, "inspect", String.class) : "null";
|
284
|
-
}
|
285
|
-
|
286
|
-
public static Object exec(String code) {
|
287
|
-
// return callScriptingContainerMethod(Object.class, "runScriptlet", code);
|
288
|
-
try {
|
289
|
-
Method runScriptletMethod = ruby.getClass().getMethod("runScriptlet", String.class);
|
290
|
-
return runScriptletMethod.invoke(ruby, code);
|
291
|
-
} catch (NoSuchMethodException nsme) {
|
292
|
-
throw new RuntimeException(nsme);
|
293
|
-
} catch (IllegalAccessException iae) {
|
294
|
-
throw new RuntimeException(iae);
|
295
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
296
|
-
if (isDebugBuild) {
|
297
|
-
throw ((RuntimeException) ite.getCause());
|
298
|
-
} else {
|
299
|
-
return null;
|
300
|
-
}
|
301
|
-
}
|
302
|
-
}
|
303
|
-
|
304
|
-
public static void defineGlobalConstant(String name, Object object) {
|
305
|
-
put(name, object);
|
306
|
-
}
|
307
|
-
|
308
|
-
public static void put(String name, Object object) {
|
309
|
-
// callScriptingContainerMethod(Void.class, "put", name, object);
|
310
|
-
try {
|
311
|
-
Method putMethod = ruby.getClass().getMethod("put", String.class, Object.class);
|
312
|
-
putMethod.invoke(ruby, name, object);
|
313
|
-
} catch (NoSuchMethodException nsme) {
|
314
|
-
throw new RuntimeException(nsme);
|
315
|
-
} catch (IllegalAccessException iae) {
|
316
|
-
throw new RuntimeException(iae);
|
317
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
318
|
-
throw new RuntimeException(ite);
|
319
|
-
}
|
320
|
-
}
|
321
|
-
|
322
|
-
public static void defineGlobalVariable(String name, Object object) {
|
323
|
-
defineGlobalConstant(name, object);
|
324
|
-
}
|
325
|
-
|
326
|
-
/*************************************************************************************************
|
327
|
-
*
|
328
|
-
* Static Methods: Scripts Directory
|
329
|
-
*/
|
330
|
-
|
331
|
-
public static void setDir(String dir) {
|
332
|
-
scriptsDir = dir;
|
333
|
-
scriptsDirFile = new File(dir);
|
334
|
-
if (ruby != null) {
|
335
|
-
Log.d(TAG, "Changing JRuby current directory to " + scriptsDir);
|
336
|
-
callScriptingContainerMethod(Void.class, "setCurrentDirectory", scriptsDir);
|
337
|
-
}
|
338
|
-
}
|
339
|
-
|
340
|
-
public static String getDir() {
|
341
|
-
return scriptsDir;
|
342
|
-
}
|
343
|
-
|
344
|
-
public static File getDirFile() {
|
345
|
-
return scriptsDirFile;
|
346
|
-
}
|
347
|
-
|
348
|
-
private static void setLoadPath(List<String> loadPath) {
|
349
|
-
// callScriptingContainerMethod(Void.class, "setLoadPaths", loadPath);
|
350
|
-
try {
|
351
|
-
Method setLoadPathsMethod = ruby.getClass().getMethod("setLoadPaths", List.class);
|
352
|
-
setLoadPathsMethod.invoke(ruby, loadPath);
|
353
|
-
} catch (NoSuchMethodException nsme) {
|
354
|
-
throw new RuntimeException(nsme);
|
355
|
-
} catch (IllegalAccessException iae) {
|
356
|
-
throw new RuntimeException(iae);
|
357
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
358
|
-
throw new RuntimeException(ite);
|
359
|
-
}
|
360
|
-
}
|
361
|
-
|
362
|
-
private static List<String> getLoadPath() {
|
363
|
-
return (List<String>)callScriptingContainerMethod(List.class, "getLoadPaths");
|
364
|
-
}
|
365
|
-
|
366
|
-
public static Boolean configDir(String scriptsDir) {
|
367
|
-
if (new File(scriptsDir).exists()) {
|
368
|
-
Log.i(TAG, "Found extra scripts dir: " + scriptsDir);
|
369
|
-
setDir(scriptsDir);
|
370
|
-
exec("$:.unshift '" + scriptsDir + "' ; $:.uniq!");
|
371
|
-
return true;
|
372
|
-
} else {
|
373
|
-
Log.i(TAG, "Extra scripts dir not present: " + scriptsDir);
|
374
|
-
return false;
|
375
|
-
}
|
376
|
-
}
|
377
|
-
|
378
|
-
private static void copyScripts(String from, File to, AssetManager assets) {
|
379
|
-
try {
|
380
|
-
byte[] buffer = new byte[8192];
|
381
|
-
for (String f : assets.list(from)) {
|
382
|
-
File dest = new File(to, f);
|
383
|
-
|
384
|
-
if (dest.exists()) {
|
385
|
-
continue;
|
386
|
-
}
|
387
|
-
|
388
|
-
Log.d(TAG, "copying file from " + from + "/" + f + " to " + dest);
|
389
|
-
|
390
|
-
if (assets.list(from + "/" + f).length == 0) {
|
391
|
-
InputStream is = assets.open(from + "/" + f);
|
392
|
-
OutputStream fos = new BufferedOutputStream(new FileOutputStream(dest), 8192);
|
393
|
-
|
394
|
-
int n;
|
395
|
-
while ((n = is.read(buffer, 0, buffer.length)) != -1) {
|
396
|
-
fos.write(buffer, 0, n);
|
397
|
-
}
|
398
|
-
is.close();
|
399
|
-
fos.close();
|
400
|
-
} else {
|
401
|
-
dest.mkdir();
|
402
|
-
copyScripts(from + "/" + f, dest, assets);
|
403
|
-
}
|
404
|
-
}
|
405
|
-
} catch (IOException iox) {
|
406
|
-
Log.e(TAG, "error copying scripts", iox);
|
407
|
-
}
|
408
|
-
}
|
409
|
-
|
410
|
-
public static void copyAssets(Context context, String directory) {
|
411
|
-
File dest = new File(scriptsDirFile.getParentFile(), directory);
|
412
|
-
if (dest.exists() || dest.mkdir()) {
|
413
|
-
copyScripts(directory, dest, context.getAssets());
|
414
|
-
} else {
|
415
|
-
throw new RuntimeException("Unable to create scripts directory: " + dest);
|
416
|
-
}
|
417
|
-
}
|
418
|
-
|
419
|
-
private static void setDebugBuild(Context context) {
|
420
|
-
PackageManager pm = context.getPackageManager();
|
421
|
-
PackageInfo pi;
|
422
|
-
try {
|
423
|
-
pi = pm.getPackageInfo(context.getPackageName(), 0);
|
424
|
-
isDebugBuild = ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
|
425
|
-
} catch (NameNotFoundException e) {
|
426
|
-
isDebugBuild = false;
|
427
|
-
}
|
428
|
-
}
|
429
|
-
|
430
|
-
private static String scriptsDirName(Context context) {
|
431
|
-
File storageDir = null;
|
432
|
-
if (isDebugBuild) {
|
433
|
-
|
434
|
-
// FIXME(uwe): Simplify this as soon as we drop support for android-7 or JRuby 1.5.6 or JRuby 1.6.2
|
435
|
-
Log.i(TAG, "JRuby VERSION: " + JRUBY_VERSION);
|
436
|
-
if (!JRUBY_VERSION.equals("1.5.6") && !JRUBY_VERSION.equals("1.6.2") && android.os.Build.VERSION.SDK_INT >= 8) {
|
437
|
-
put("script_context", context);
|
438
|
-
storageDir = (File) exec("script_context.getExternalFilesDir(nil)");
|
439
|
-
} else {
|
440
|
-
storageDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/files");
|
441
|
-
Log.e(TAG, "Calculated path to sdcard the old way: " + storageDir);
|
442
|
-
}
|
443
|
-
// FIXME end
|
444
|
-
|
445
|
-
if (storageDir == null || (!storageDir.exists() && !storageDir.mkdirs())) {
|
446
|
-
Log.e(TAG,
|
447
|
-
"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.");
|
448
|
-
storageDir = context.getFilesDir();
|
449
|
-
}
|
450
|
-
} else {
|
451
|
-
storageDir = context.getFilesDir();
|
452
|
-
}
|
453
|
-
return storageDir.getAbsolutePath() + "/scripts";
|
454
|
-
}
|
455
|
-
|
456
|
-
private static void copyScriptsIfNeeded(Context context) {
|
457
|
-
String to = scriptsDirName(context);
|
458
|
-
Log.i(TAG, "Checking scripts in " + to);
|
459
|
-
|
460
|
-
/* the if makes sure we only do this the first time */
|
461
|
-
if (configDir(to)) {
|
462
|
-
Log.i(TAG, "Copying scripts to " + to);
|
463
|
-
copyAssets(context, "scripts");
|
464
|
-
}
|
22
|
+
public static void addDir(String dir) {
|
23
|
+
String[] oldScriptsDir = scriptsDir;
|
24
|
+
scriptsDir = new String[scriptsDir.length + 1];
|
25
|
+
scriptsDir[0] = dir;
|
26
|
+
for(int i = 0 ; i < oldScriptsDir.length ; i++) {
|
27
|
+
scriptsDir[i + 1] = oldScriptsDir[i];
|
28
|
+
}
|
465
29
|
}
|
466
30
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
31
|
+
public static String toCamelCase(String s) {
|
32
|
+
String[] parts = s.replace(".rb", "").split("_");
|
33
|
+
for (int i = 0 ; i < parts.length ; i++) {
|
34
|
+
parts[i] = parts[i].substring(0,1).toUpperCase() + parts[i].substring(1);
|
35
|
+
}
|
36
|
+
return java.util.Arrays.toString(parts).replace(", ", "").replaceAll("[\\[\\]]", "");
|
37
|
+
}
|
38
|
+
|
39
|
+
public static String toSnakeCase(String s) {
|
40
|
+
return s.replaceAll(
|
41
|
+
String.format("%s|%s|%s",
|
42
|
+
"(?<=[A-Z])(?=[A-Z][a-z])",
|
43
|
+
"(?<=[^A-Z])(?=[A-Z])",
|
44
|
+
"(?<=[A-Za-z])(?=[^A-Za-z])"
|
45
|
+
),
|
46
|
+
"_"
|
47
|
+
).toLowerCase();
|
48
|
+
}
|
49
|
+
|
50
|
+
// Private static methods
|
51
|
+
|
52
|
+
// private static void copyAssets(Context context, String directory) {
|
53
|
+
// File dest = new File(new File(scriptsDirFile).getParentFile(), directory);
|
54
|
+
// if (dest.exists() || dest.mkdir()) {
|
55
|
+
// copyScripts(directory, dest, context.getAssets());
|
56
|
+
// } else {
|
57
|
+
// throw new RuntimeException("Unable to create scripts directory: " + dest);
|
58
|
+
// }
|
59
|
+
// }
|
60
|
+
|
61
|
+
// private static void copyScripts(String from, File to, AssetManager assets) {
|
62
|
+
// try {
|
63
|
+
// byte[] buffer = new byte[8192];
|
64
|
+
// for (String f : assets.list(from)) {
|
65
|
+
// File dest = new File(to, f);
|
66
|
+
//
|
67
|
+
// if (dest.exists()) {
|
68
|
+
// continue;
|
69
|
+
// }
|
70
|
+
//
|
71
|
+
// Log.d("copying file from " + from + "/" + f + " to " + dest);
|
72
|
+
//
|
73
|
+
// if (assets.list(from + "/" + f).length == 0) {
|
74
|
+
// InputStream is = assets.open(from + "/" + f);
|
75
|
+
// OutputStream fos = new BufferedOutputStream(new FileOutputStream(dest), 8192);
|
76
|
+
//
|
77
|
+
// int n;
|
78
|
+
// while ((n = is.read(buffer, 0, buffer.length)) != -1) {
|
79
|
+
// fos.write(buffer, 0, n);
|
80
|
+
// }
|
81
|
+
// is.close();
|
82
|
+
// fos.close();
|
83
|
+
// } else {
|
84
|
+
// dest.mkdir();
|
85
|
+
// copyScripts(from + "/" + f, dest, assets);
|
86
|
+
// }
|
87
|
+
// }
|
88
|
+
// } catch (IOException iox) {
|
89
|
+
// Log.e("error copying scripts", iox);
|
90
|
+
// }
|
91
|
+
// }
|
476
92
|
|
477
93
|
/*************************************************************************************************
|
478
94
|
*
|
479
|
-
*
|
95
|
+
* Constructors
|
480
96
|
*/
|
481
|
-
|
482
|
-
public String getName() {
|
483
|
-
return name;
|
484
|
-
}
|
485
|
-
|
486
|
-
public File getFile() {
|
487
|
-
return new File(getDir(), name);
|
488
|
-
}
|
489
|
-
|
490
|
-
public Script setName(String name) {
|
97
|
+
public Script(String name) {
|
491
98
|
this.name = name;
|
492
|
-
return this;
|
493
|
-
}
|
494
|
-
|
495
|
-
public String getContents() throws IOException {
|
496
|
-
InputStream is;
|
497
|
-
if (new File(scriptsDir + "/" + name).exists()) {
|
498
|
-
is = new java.io.FileInputStream(scriptsDir + "/" + name);
|
499
|
-
} else {
|
500
|
-
is = getClass().getClassLoader().getResourceAsStream(name);
|
501
|
-
}
|
502
|
-
BufferedReader buffer = new BufferedReader(new java.io.InputStreamReader(is), 8192);
|
503
|
-
StringBuilder source = new StringBuilder();
|
504
|
-
while (true) {
|
505
|
-
String line = buffer.readLine();
|
506
|
-
if (line == null) {
|
507
|
-
break;
|
508
|
-
}
|
509
|
-
source.append(line).append("\n");
|
510
|
-
}
|
511
|
-
buffer.close();
|
512
|
-
return source.toString();
|
513
99
|
}
|
514
100
|
|
515
101
|
/*************************************************************************************************
|
516
102
|
*
|
517
|
-
*
|
103
|
+
* Instance methods
|
518
104
|
*/
|
519
|
-
|
520
|
-
public static String getScriptFilename() {
|
521
|
-
return (String)callScriptingContainerMethod(String.class, "getScriptFilename");
|
522
|
-
}
|
523
|
-
|
524
|
-
public static void setScriptFilename(String name) {
|
525
|
-
callScriptingContainerMethod(Void.class, "setScriptFilename", name);
|
526
|
-
}
|
527
|
-
|
528
105
|
public String execute() throws IOException {
|
529
|
-
|
530
|
-
return Script.execute(getContents());
|
106
|
+
return JRubyAdapter.execute(getContents());
|
531
107
|
}
|
532
108
|
|
533
|
-
|
109
|
+
public String getContents() throws IOException {
|
110
|
+
InputStream is = null;
|
111
|
+
BufferedReader buffer = null;
|
534
112
|
try {
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
} catch (IllegalAccessException iae) {
|
540
|
-
throw new RuntimeException(iae);
|
541
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
542
|
-
printStackTrace(ite);
|
543
|
-
if (isDebugBuild) {
|
544
|
-
throw new RuntimeException(ite);
|
113
|
+
if (new File(scriptsDir + "/" + name).exists()) {
|
114
|
+
is = new java.io.FileInputStream(scriptsDir + "/" + name);
|
115
|
+
} else {
|
116
|
+
is = getClass().getClassLoader().getResourceAsStream(name);
|
545
117
|
}
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
} catch (IllegalAccessException iae) {
|
565
|
-
throw new RuntimeException(iae);
|
566
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
567
|
-
printStackTrace(ite);
|
568
|
-
}
|
569
|
-
return null;
|
118
|
+
buffer = new BufferedReader(new java.io.InputStreamReader(is), 8192);
|
119
|
+
StringBuilder source = new StringBuilder();
|
120
|
+
while (true) {
|
121
|
+
String line = buffer.readLine();
|
122
|
+
if (line == null) {
|
123
|
+
break;
|
124
|
+
}
|
125
|
+
source.append(line).append("\n");
|
126
|
+
}
|
127
|
+
return source.toString();
|
128
|
+
} finally {
|
129
|
+
if (is != null) {
|
130
|
+
is.close();
|
131
|
+
}
|
132
|
+
if (is != null) {
|
133
|
+
buffer.close();
|
134
|
+
}
|
135
|
+
}
|
570
136
|
}
|
571
137
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
}
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
582
|
-
printStackTrace(ite);
|
583
|
-
}
|
584
|
-
return null;
|
585
|
-
}
|
138
|
+
// public File getFile() {
|
139
|
+
// for (String dir : scriptsDir) {
|
140
|
+
// File f = new File(dir, name);
|
141
|
+
// if (f.exists()) {
|
142
|
+
// return f;
|
143
|
+
// }
|
144
|
+
// }
|
145
|
+
// return new File(scriptsDir[0], name);
|
146
|
+
// }
|
586
147
|
|
587
|
-
|
588
|
-
|
589
|
-
try {
|
590
|
-
Method callMethodMethod = ruby.getClass().getMethod("callMethod", Object.class, String.class, Class.class);
|
591
|
-
return (T) callMethodMethod.invoke(ruby, receiver, methodName, returnType);
|
592
|
-
} catch (NoSuchMethodException nsme) {
|
593
|
-
throw new RuntimeException(nsme);
|
594
|
-
} catch (IllegalAccessException iae) {
|
595
|
-
throw new RuntimeException(iae);
|
596
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
597
|
-
printStackTrace(ite);
|
148
|
+
public String getName() {
|
149
|
+
return name;
|
598
150
|
}
|
599
|
-
return null;
|
600
|
-
}
|
601
|
-
|
602
|
-
private static void printStackTrace(Throwable t) {
|
603
|
-
PrintStream out;
|
604
|
-
try {
|
605
|
-
Method getOutputMethod = ruby.getClass().getMethod("getOutput");
|
606
|
-
out = (PrintStream) getOutputMethod.invoke(ruby);
|
607
|
-
} catch (java.lang.NoSuchMethodException nsme) {
|
608
|
-
throw new RuntimeException("ScriptingContainer#getOutput method not found.", nsme);
|
609
|
-
} catch (java.lang.IllegalAccessException iae) {
|
610
|
-
throw new RuntimeException("ScriptingContainer#getOutput method not accessable.", iae);
|
611
|
-
} catch (java.lang.reflect.InvocationTargetException ite) {
|
612
|
-
throw new RuntimeException("ScriptingContainer#getOutput failed.", ite);
|
613
|
-
}
|
614
|
-
|
615
|
-
// TODO(uwe): Simplify this when Issue #144 is resolved
|
616
|
-
try {
|
617
|
-
t.printStackTrace(out);
|
618
|
-
} catch (NullPointerException npe) {
|
619
|
-
// TODO(uwe): printStackTrace should not fail
|
620
|
-
for (java.lang.StackTraceElement ste : t.getStackTrace()) {
|
621
|
-
out.append(ste.toString() + "\n");
|
622
|
-
}
|
623
|
-
}
|
624
|
-
}
|
625
151
|
|
626
152
|
}
|