rhodes 2.0.0.rc2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/Manifest.txt +5331 -0
- data/README.textile +3 -3
- data/lib/build/jake.rb +63 -3
- data/lib/framework/rho/rhofsconnector.rb +6 -1
- data/lib/framework/rhom/rhom.rb +8 -2
- data/platform/android/Rhodes/jni/include/rhodes.h +2 -0
- data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_Rhodes.h +8 -0
- data/platform/android/Rhodes/jni/src/rhodes.cpp +19 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +4 -0
- data/platform/android/build/android.rake +56 -3
- data/platform/bb/build/bb.rake +43 -1
- data/platform/iphone/Classes/RhoAlert.m +1 -1
- data/platform/shared/rubyJVM/src/com/rho/file/RandomAccessFile.java +6 -1
- data/platform/shared/rubyJVM/src/com/rho/net/NetRequest.java +1 -1
- data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubyIO_Methods.java +5 -0
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/InputStreamExecutor.java +1 -1
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyFile.java +20 -0
- data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyIO.java +41 -8
- data/platform/wm/build/wm.rake +19 -0
- data/res/generators/templates/application/public/css/android.css +22 -13
- data/res/generators/templates/application/public/images/android/disclosure.png +0 -0
- data/rhobuild.yml +39 -0
- data/rhodes.gemspec +1 -1
- data/spec/phone_spec/app/Data/test.png +0 -0
- data/spec/phone_spec/app/Spec/controller.rb +3 -0
- data/spec/phone_spec/app/Spec/index.erb +2 -0
- data/spec/phone_spec/app/Spec/rhofile_spec.rb +17 -0
- metadata +7 -4
data/README.textile
CHANGED
@@ -20,7 +20,7 @@ Rhodes features an application generator called rhogen that generates a control
|
|
20
20
|
|
21
21
|
rhogen app appname
|
22
22
|
|
23
|
-
This will generate a config.rb and an index.html file. Currently config.rb is focused on describing what source to sync with. Modify the URL that you see in this file with whatever your RhoSync server URL and source ID are for this particular "source" or data model. It is assumed that you've already set up a RhoSync "source adapter" as described by the "RhoSync docs":http://wiki.rhomobile.com/index.php/
|
23
|
+
This will generate a config.rb and an index.html file. Currently config.rb is focused on describing what source to sync with. Modify the URL that you see in this file with whatever your RhoSync server URL and source ID are for this particular "source" or data model. It is assumed that you've already set up a RhoSync "source adapter" as described by the "RhoSync docs":http://wiki.rhomobile.com/index.php/RhoSync.
|
24
24
|
|
25
25
|
h3. Generate a Model and Associated Controller and Templates
|
26
26
|
|
@@ -36,9 +36,9 @@ This will generate a controller as the file controller.rb and several views as a
|
|
36
36
|
|
37
37
|
h2. MORE RESOURCES
|
38
38
|
|
39
|
-
There is a "tutorial available":http://rhomobile.com/
|
39
|
+
There is a "tutorial available":http://wiki.rhomobile.com/index.php/Tutorial on the "Rhomobile site":http://www.rhomobile.com. This includes thorough and current platform by platform build instructions.
|
40
40
|
|
41
|
-
The "Rhodes
|
41
|
+
The "Rhodes Developer Reference":http://wiki.rhomobile.com/index.php/Rhodes for full documentation on the Rhodes framework.
|
42
42
|
|
43
43
|
For further questions "email us":mailto:info@rhomobile.com or join the "Google Group":http://groups.google.com/group/rhomobile.
|
44
44
|
|
data/lib/build/jake.rb
CHANGED
@@ -94,7 +94,59 @@ class Jake
|
|
94
94
|
conf
|
95
95
|
end
|
96
96
|
|
97
|
-
def self.
|
97
|
+
def self.before_run_spec()
|
98
|
+
$total ||= 0
|
99
|
+
$passed ||= 0
|
100
|
+
$failed ||= 0
|
101
|
+
$faillog = []
|
102
|
+
$getdump = false
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.process_spec_output(line)
|
106
|
+
puts line if line =~ /\| - it/ or line =~ /\| describe/
|
107
|
+
|
108
|
+
if $getdump
|
109
|
+
if line =~ /^I/
|
110
|
+
$getdump = false
|
111
|
+
else
|
112
|
+
$faillog << line
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
if line =~ /\*\*\*Failed:\s+(.*)/
|
117
|
+
$failed += $1.to_i
|
118
|
+
return false
|
119
|
+
elsif line =~ /\*\*\*Total:\s+(.*)/
|
120
|
+
$total += $1.to_i
|
121
|
+
elsif line =~ /\*\*\*Passed:\s+(.*)/
|
122
|
+
$passed += $1.to_i
|
123
|
+
end
|
124
|
+
|
125
|
+
if line =~ /\| FAIL:/
|
126
|
+
$faillog << line.gsub(/I.*APP\|/,"\n\n***")
|
127
|
+
$getdump = true
|
128
|
+
end
|
129
|
+
|
130
|
+
return true
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.process_spec_results(start)
|
134
|
+
finish = Time.now
|
135
|
+
|
136
|
+
rm_rf $app_path + "/faillog.txt"
|
137
|
+
File.open($app_path + "/faillog.txt", "w") { |io| $faillog.each {|x| io << x } } if $failed.to_i > 0
|
138
|
+
|
139
|
+
puts "************************"
|
140
|
+
puts "\n\n"
|
141
|
+
puts "Tests completed in #{finish - start} seconds"
|
142
|
+
puts "Total: #{$total}"
|
143
|
+
puts "Passed: #{$passed}"
|
144
|
+
puts "Failed: #{$failed}"
|
145
|
+
puts "\n"
|
146
|
+
puts "Failures stored in faillog.txt" if $failed.to_i > 0
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.run2(command, args, options = {}, &block)
|
98
150
|
argv = []
|
99
151
|
currentdir = ""
|
100
152
|
retval = ""
|
@@ -133,8 +185,16 @@ class Jake
|
|
133
185
|
else
|
134
186
|
IO.popen(argv) do |f|
|
135
187
|
while line = f.gets
|
136
|
-
|
137
|
-
|
188
|
+
if block_given?
|
189
|
+
res = yield(line)
|
190
|
+
if !res
|
191
|
+
#puts "f.pid : #{f.pid}"
|
192
|
+
Process.kill( 9, f.pid )
|
193
|
+
end
|
194
|
+
else
|
195
|
+
puts line
|
196
|
+
$stdout.flush
|
197
|
+
end
|
138
198
|
end
|
139
199
|
end
|
140
200
|
end
|
@@ -33,7 +33,12 @@ module Rho
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def get_blob_path(relative_path)
|
36
|
-
|
36
|
+
cur_dir = __rhoGetCurrentDir()
|
37
|
+
if cur_dir && cur_dir.length()>0
|
38
|
+
File.join(cur_dir, relative_path)
|
39
|
+
else
|
40
|
+
relative_path
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
end
|
data/lib/framework/rhom/rhom.rb
CHANGED
@@ -41,7 +41,7 @@ module Rhom
|
|
41
41
|
c_id.nil? ? nil : c_id['client_id']
|
42
42
|
end
|
43
43
|
|
44
|
-
def database_full_reset
|
44
|
+
def database_full_reset(reset_client_info=false)
|
45
45
|
SyncEngine.stop_sync
|
46
46
|
|
47
47
|
::Rho::RHO.get_user_db().execute_sql("UPDATE client_info SET reset=1")
|
@@ -51,7 +51,8 @@ module Rhom
|
|
51
51
|
::Rho::RHO.get_user_db().execute_sql("UPDATE sources SET token=0")
|
52
52
|
|
53
53
|
::Rho::RHO.get_db_partitions().each_value do |db|
|
54
|
-
db.destroy_tables(
|
54
|
+
db.destroy_tables(
|
55
|
+
:exclude => (reset_client_info ? ['sources'] : ['sources','client_info']) )
|
55
56
|
end
|
56
57
|
|
57
58
|
hash_migrate = {}
|
@@ -62,6 +63,11 @@ module Rhom
|
|
62
63
|
database_full_reset
|
63
64
|
SyncEngine.logout
|
64
65
|
end
|
66
|
+
|
67
|
+
def database_fullclient_reset_and_logout
|
68
|
+
database_full_reset(true)
|
69
|
+
SyncEngine.logout
|
70
|
+
end
|
65
71
|
|
66
72
|
def search(args)
|
67
73
|
searchParams = ""
|
@@ -117,6 +117,14 @@ JNIEXPORT void JNICALL Java_com_rhomobile_rhodes_Rhodes_doRequest
|
|
117
117
|
JNIEXPORT void JNICALL Java_com_rhomobile_rhodes_Rhodes_makeLink
|
118
118
|
(JNIEnv *, jclass, jstring, jstring);
|
119
119
|
|
120
|
+
/*
|
121
|
+
* Class: com_rhomobile_rhodes_Rhodes
|
122
|
+
* Method: initClassLoader
|
123
|
+
* Signature: (Ljava/lang/ClassLoader;)V
|
124
|
+
*/
|
125
|
+
JNIEXPORT void JNICALL Java_com_rhomobile_rhodes_Rhodes_initClassLoader
|
126
|
+
(JNIEnv *, jobject, jobject);
|
127
|
+
|
120
128
|
#ifdef __cplusplus
|
121
129
|
}
|
122
130
|
#endif
|
@@ -308,6 +308,25 @@ static bool set_capabilities(JNIEnv *env)
|
|
308
308
|
return true;
|
309
309
|
}
|
310
310
|
|
311
|
+
static jobject g_classLoader = NULL;
|
312
|
+
static jmethodID g_loadClass = NULL;
|
313
|
+
|
314
|
+
jclass rho_find_class(JNIEnv *env, const char *c)
|
315
|
+
{
|
316
|
+
jstring className = env->NewStringUTF(c);
|
317
|
+
jclass cls = (jclass)env->CallObjectMethod(g_classLoader, g_loadClass, className);
|
318
|
+
env->DeleteLocalRef(className);
|
319
|
+
return cls;
|
320
|
+
}
|
321
|
+
|
322
|
+
RHO_GLOBAL void JNICALL Java_com_rhomobile_rhodes_Rhodes_initClassLoader
|
323
|
+
(JNIEnv *env, jobject, jobject cl)
|
324
|
+
{
|
325
|
+
g_classLoader = env->NewGlobalRef(cl);
|
326
|
+
jclass javaLangClassLoader = env->FindClass("java/lang/ClassLoader");
|
327
|
+
g_loadClass = env->GetMethodID(javaLangClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
328
|
+
}
|
329
|
+
|
311
330
|
RHO_GLOBAL void JNICALL Java_com_rhomobile_rhodes_Rhodes_createRhodesApp
|
312
331
|
(JNIEnv *env, jobject, jstring path)
|
313
332
|
{
|
@@ -141,6 +141,8 @@ public class Rhodes extends Activity {
|
|
141
141
|
|
142
142
|
public native static void makeLink(String src, String dst);
|
143
143
|
|
144
|
+
private native void initClassLoader(ClassLoader c);
|
145
|
+
|
144
146
|
private void initRootPath() {
|
145
147
|
Log.d(TAG, "Check if the SD card is mounted...");
|
146
148
|
String state = Environment.getExternalStorageState();
|
@@ -478,6 +480,8 @@ public class Rhodes extends Activity {
|
|
478
480
|
uiThreadId = ct.getId();
|
479
481
|
|
480
482
|
RhodesInstance.setInstance(this);
|
483
|
+
|
484
|
+
initClassLoader(this.getClassLoader());
|
481
485
|
|
482
486
|
initRootPath();
|
483
487
|
try {
|
@@ -931,11 +931,11 @@ namespace "package" do
|
|
931
931
|
end
|
932
932
|
end
|
933
933
|
|
934
|
-
def get_app_log(appname, device)
|
934
|
+
def get_app_log(appname, device, silent = false)
|
935
935
|
pkgname = 'com.rhomobile.' + appname.downcase.gsub(/[^A-Za-z_0-9]/, '')
|
936
936
|
path = File.join('/sdcard/rhomobile', pkgname, 'RhoLog.txt')
|
937
937
|
cc_run($adb, [device ? '-d' : '-e', 'pull', path, $app_path]) or return false
|
938
|
-
puts "RhoLog.txt stored to " + $app_path
|
938
|
+
puts "RhoLog.txt stored to " + $app_path unless silent
|
939
939
|
return true
|
940
940
|
end
|
941
941
|
|
@@ -1080,7 +1080,57 @@ end
|
|
1080
1080
|
|
1081
1081
|
namespace "run" do
|
1082
1082
|
namespace "android" do
|
1083
|
+
|
1084
|
+
task :spec => ["device:android:debug"] do
|
1085
|
+
run_emulator
|
1086
|
+
do_uninstall('-e')
|
1087
|
+
|
1088
|
+
log_name = $app_path + '/RhoLog.txt'
|
1089
|
+
File.delete(log_name) if File.exist?(log_name)
|
1090
|
+
|
1091
|
+
load_app_and_run
|
1092
|
+
|
1093
|
+
Jake.before_run_spec
|
1094
|
+
start = Time.now
|
1095
|
+
|
1096
|
+
puts "wating for log"
|
1097
|
+
|
1098
|
+
while !File.exist?(log_name)
|
1099
|
+
get_app_log($appname, false, true)
|
1100
|
+
sleep(1)
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
puts "start read log"
|
1104
|
+
|
1105
|
+
end_spec = false
|
1106
|
+
while !end_spec do
|
1107
|
+
get_app_log($appname, false, true)
|
1108
|
+
io = File.new(log_name, "r")
|
1109
|
+
|
1110
|
+
io.each do |line|
|
1111
|
+
#puts line
|
1112
|
+
|
1113
|
+
end_spec = !Jake.process_spec_output(line)
|
1114
|
+
break if end_spec
|
1115
|
+
end
|
1116
|
+
io.close
|
1117
|
+
|
1118
|
+
sleep(5) unless end_spec
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
#TODO: stop app
|
1122
|
+
Jake.process_spec_results(start)
|
1123
|
+
|
1124
|
+
$stdout.flush
|
1125
|
+
|
1126
|
+
end
|
1127
|
+
|
1083
1128
|
task :emulator => "device:android:debug" do
|
1129
|
+
run_emulator
|
1130
|
+
load_app_and_run
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def run_emulator
|
1084
1134
|
apkfile = Jake.get_absolute $targetdir + "/" + $appname + "-debug.apk"
|
1085
1135
|
puts `"#{$adb}" start-server`
|
1086
1136
|
|
@@ -1103,8 +1153,11 @@ namespace "run" do
|
|
1103
1153
|
puts "Emulator is up and running" if running
|
1104
1154
|
$stdout.flush
|
1105
1155
|
puts `"#{$adb}" -e wait-for-device`
|
1106
|
-
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
def load_app_and_run
|
1107
1159
|
puts "Loading package into emulator"
|
1160
|
+
apkfile = Jake.get_absolute $targetdir + "/" + $appname + "-debug.apk"
|
1108
1161
|
count = 0
|
1109
1162
|
done = false
|
1110
1163
|
while count < 20
|
data/platform/bb/build/bb.rake
CHANGED
@@ -52,7 +52,7 @@ def stopmds
|
|
52
52
|
Jake.run("cmd.exe",args, mdshome, true, true)
|
53
53
|
end
|
54
54
|
|
55
|
-
def startsim
|
55
|
+
def startsim(hidden=false)
|
56
56
|
sim = $config["env"]["paths"][$bbver]["sim"]
|
57
57
|
jde = $config["env"]["paths"][$bbver]["jde"]
|
58
58
|
|
@@ -68,6 +68,7 @@ def startsim
|
|
68
68
|
args << "/pin=0x2100000A"
|
69
69
|
args << "/no-compact-filesystem"
|
70
70
|
args << "/JvmDisableBacklightTimeout"
|
71
|
+
args << "/start-hidden" if hidden
|
71
72
|
#args << "/keep-lcd-on"
|
72
73
|
|
73
74
|
if $bbver !~ /^4\.[012](\..*)?$/
|
@@ -741,6 +742,47 @@ namespace "run" do
|
|
741
742
|
startmds
|
742
743
|
startsim
|
743
744
|
end
|
745
|
+
|
746
|
+
task :spec => ["clean:bb", "run:bb:stopmdsandsim", "package:bb:production_sim"] do
|
747
|
+
jde = $config["env"]["paths"][$bbver]["jde"]
|
748
|
+
cp_r File.join($targetdir,"/."), jde + "/simulator"
|
749
|
+
rm_rf jde + "/simulator/sdcard/Rho"
|
750
|
+
|
751
|
+
log_name = Jake.get_absolute($app_config["applog"] )
|
752
|
+
File.delete(log_name) if File.exist?(log_name)
|
753
|
+
|
754
|
+
startmds
|
755
|
+
startsim(true)
|
756
|
+
|
757
|
+
Jake.before_run_spec
|
758
|
+
start = Time.now
|
759
|
+
|
760
|
+
while !File.exist?(log_name)
|
761
|
+
sleep(1)
|
762
|
+
end
|
763
|
+
|
764
|
+
io = File.new(log_name, "r")
|
765
|
+
end_spec = false
|
766
|
+
while !end_spec do
|
767
|
+
io.each do |line|
|
768
|
+
#puts line
|
769
|
+
|
770
|
+
end_spec = !Jake.process_spec_output(line)
|
771
|
+
break if end_spec
|
772
|
+
end
|
773
|
+
sleep(1) unless end_spec
|
774
|
+
end
|
775
|
+
|
776
|
+
io.close
|
777
|
+
|
778
|
+
stopsim
|
779
|
+
stopmds
|
780
|
+
|
781
|
+
Jake.process_spec_results(start)
|
782
|
+
|
783
|
+
$stdout.flush
|
784
|
+
|
785
|
+
end
|
744
786
|
end
|
745
787
|
|
746
788
|
desc "Builds everything, loads and starts bb sim and mds"
|
@@ -34,8 +34,13 @@ public class RandomAccessFile
|
|
34
34
|
{
|
35
35
|
String name = (file != null ? file.getAbsolutePath() : null);
|
36
36
|
int imode = -1;
|
37
|
-
if (mode.equals("r"))
|
37
|
+
if (mode.equals("r") || mode.equals("rb"))
|
38
38
|
imode = Connector.READ;
|
39
|
+
else if (mode.equals("w") || mode.equals("wb"))
|
40
|
+
{
|
41
|
+
imode = Connector.WRITE;
|
42
|
+
m_bWriteAccess = true;
|
43
|
+
}
|
39
44
|
else if (mode.startsWith("rw")) {
|
40
45
|
imode = Connector.READ_WRITE;
|
41
46
|
m_bWriteAccess = true;
|
@@ -644,7 +644,7 @@ public class NetRequest
|
|
644
644
|
return strRes;
|
645
645
|
}
|
646
646
|
|
647
|
-
|
647
|
+
public static final String readFully(InputStream in, String strContType) throws Exception
|
648
648
|
{
|
649
649
|
String strRes = "";
|
650
650
|
byte[] byteBuffer = new byte[1024*4];
|
@@ -9,6 +9,11 @@ klass.getSingletonClass().defineMethod( "read", new RubyVarArgMethod(){
|
|
9
9
|
protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block ){
|
10
10
|
return RubyIO.read(receiver, args, block);}
|
11
11
|
});
|
12
|
+
klass.getSingletonClass().defineMethod( "binread", new RubyVarArgMethod(){
|
13
|
+
protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block ){
|
14
|
+
return RubyIO.binread(receiver, args, block);}
|
15
|
+
});
|
16
|
+
|
12
17
|
klass.defineMethod( "gets", new RubyVarArgMethod(){
|
13
18
|
protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block ){
|
14
19
|
return ((RubyIO)receiver).gets(args);}
|
@@ -5,6 +5,9 @@
|
|
5
5
|
|
6
6
|
package com.xruby.runtime.builtin;
|
7
7
|
|
8
|
+
import java.io.InputStream;
|
9
|
+
|
10
|
+
import com.rho.RhoRuby;
|
8
11
|
import com.xruby.runtime.lang.*;
|
9
12
|
//import com.xruby.runtime.lang.annotation.RubyLevelClass;
|
10
13
|
//import com.xruby.runtime.lang.annotation.RubyLevelMethod;
|
@@ -154,6 +157,23 @@ public class RubyFile extends RubyIO {
|
|
154
157
|
//@RubyLevelMethod(name="size", singleton=true)
|
155
158
|
public static RubyValue size(RubyValue receiver, RubyValue arg) {
|
156
159
|
String fileName = arg.toStr();
|
160
|
+
InputStream stream = null;
|
161
|
+
|
162
|
+
if ( fileName.startsWith("/apps"))
|
163
|
+
{
|
164
|
+
try {
|
165
|
+
stream = RhoRuby.loadFile("/" + fileName);
|
166
|
+
if ( stream != null )
|
167
|
+
{
|
168
|
+
RubyValue res = ObjectFactory.createInteger(stream.available());
|
169
|
+
stream.close();
|
170
|
+
return res;
|
171
|
+
}
|
172
|
+
} catch (Exception e) {
|
173
|
+
e.printStackTrace();
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
157
177
|
File file = new File(fileName);
|
158
178
|
if (!file.isFile() && !file.isDirectory()) {
|
159
179
|
throw new RubyException(RubyRuntime.RuntimeErrorClass, "No such file or directory - " + fileName);
|