rhodes 1.5.4 → 1.5.5

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.
Files changed (60) hide show
  1. data/Manifest.txt +11 -1
  2. data/Rakefile +1 -1
  3. data/lib/extensions/digest/ext/Rakefile +11 -6
  4. data/lib/extensions/digest/ext/build.bat +2 -0
  5. data/lib/extensions/uri/uri.rb +29 -0
  6. data/lib/extensions/uri/uri/common.rb +727 -0
  7. data/lib/extensions/uri/uri/ftp.rb +198 -0
  8. data/lib/extensions/uri/uri/generic.rb +1128 -0
  9. data/lib/extensions/uri/uri/http.rb +100 -0
  10. data/lib/extensions/uri/uri/https.rb +20 -0
  11. data/lib/extensions/uri/uri/ldap.rb +190 -0
  12. data/lib/extensions/uri/uri/ldaps.rb +12 -0
  13. data/lib/extensions/uri/uri/mailto.rb +266 -0
  14. data/lib/framework/rhodes.rb +2 -2
  15. data/lib/framework/rhom/rhom_db_adapter.rb +12 -26
  16. data/lib/framework/rhom/rhom_object_factory.rb +8 -1
  17. data/lib/framework/version.rb +2 -2
  18. data/lib/rhodes.rb +2 -2
  19. data/platform/android/Rhodes/AndroidManifest.xml +2 -2
  20. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +87 -42
  21. data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +58 -7
  22. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/MainView.java +2 -0
  23. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +35 -19
  24. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +4 -0
  25. data/platform/android/build/android.rake +30 -25
  26. data/platform/bb/build/rhodes_build.files +1 -1
  27. data/platform/bb/rhodes/rhodes.jdp +1 -1
  28. data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +1 -1
  29. data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +300 -0
  30. data/platform/bb/rhodes/src/com/rho/rubyext/GeoLocation.java +42 -5
  31. data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +3 -4
  32. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +33 -107
  33. data/platform/iphone/Classes/RhoRunnerAppDelegate.m +2 -0
  34. data/platform/iphone/Info.plist +1 -1
  35. data/platform/iphone/rbuild/iphone.rake +1 -1
  36. data/platform/iphone/rhoextlib/rhoextlib.xcodeproj/project.pbxproj +4 -0
  37. data/platform/shared/common/RhoMutexLock.h +8 -1
  38. data/platform/shared/common/RhodesApp.cpp +1 -1
  39. data/platform/shared/db/DBAdapter.cpp +77 -8
  40. data/platform/shared/db/DBAdapter.h +24 -9
  41. data/platform/shared/db/DBResult.cpp +19 -0
  42. data/platform/shared/db/DBResult.h +7 -5
  43. data/platform/shared/net/HttpServer.cpp +2 -0
  44. data/platform/shared/ruby/ext/rho/rhoruby.c +55 -0
  45. data/platform/shared/ruby/ext/rho/rhoruby.h +9 -0
  46. data/platform/shared/ruby/ext/rho/rhosupport.c +13 -4
  47. data/platform/shared/ruby/ext/sqlite3_api/sqlite3_api_wrap.c +21 -0
  48. data/platform/shared/ruby/thread_pthread.c +4 -4
  49. data/platform/shared/ruby/thread_win32.c +4 -4
  50. data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +19 -1
  51. data/platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java +57 -24
  52. data/platform/shared/rubyJVM/src/com/rho/net/NetRequest.java +6 -1
  53. data/platform/shared/rubyJVM/src/com/rho/sync/SyncSource.java +2 -2
  54. data/platform/shared/rubyJVM/src/com/rho/sync/SyncThread.java +5 -5
  55. data/platform/shared/sync/SyncSource.cpp +1 -1
  56. data/platform/shared/sync/SyncThread.cpp +6 -9
  57. data/platform/wm/rhodes/Rhodes.cpp +4 -0
  58. data/rakefile.rb +1 -1
  59. metadata +13 -3
  60. data/platform/bb/rhodes/src/rhomobile/Alert.java +0 -65
@@ -36,4 +36,6 @@ public interface MainView {
36
36
 
37
37
  public void switchTab(int index);
38
38
  public int activeTab();
39
+
40
+ public void loadData(String data, int index);
39
41
  }
@@ -74,7 +74,13 @@ public class SimpleMainView implements MainView {
74
74
  reload(0);
75
75
  }
76
76
  };
77
-
77
+
78
+ private class ActionExit implements View.OnClickListener {
79
+ public void onClick(View v) {
80
+ Rhodes.exit();
81
+ }
82
+ };
83
+
78
84
  private class ActionCustomRunnable implements Runnable {
79
85
  private boolean callback;
80
86
  private String url;
@@ -138,22 +144,11 @@ public class SimpleMainView implements MainView {
138
144
  view.addView(bottom);
139
145
 
140
146
  if (params != null) {
141
- LinearLayout left = new LinearLayout(r);
142
- left.setGravity(Gravity.LEFT);
143
- left.setOrientation(LinearLayout.HORIZONTAL);
144
- left.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT, 1));
145
- bottom.addView(left);
146
-
147
- LinearLayout right = new LinearLayout(r);
148
- right.setGravity(Gravity.RIGHT);
149
- right.setOrientation(LinearLayout.HORIZONTAL);
150
- right.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT, 1));
151
- bottom.addView(right);
152
-
153
- LinearLayout current = left;
154
-
155
147
  String rootPath = r.getRootPath() + "/apps/";
156
148
 
149
+ LinearLayout group = null;
150
+ // First group should have gravity LEFT
151
+ int gravity = Gravity.LEFT;
157
152
  for (int i = 0, lim = params.size(); i < lim; ++i) {
158
153
  Object param = params.elementAt(i);
159
154
  if (!(param instanceof Map<?,?>))
@@ -193,8 +188,13 @@ public class SimpleMainView implements MainView {
193
188
  icon = r.getResources().getDrawable(AndroidR.drawable.refresh);
194
189
  onClick = new ActionRefresh();
195
190
  }
191
+ else if (action.equalsIgnoreCase("close") || action.equalsIgnoreCase("exit")) {
192
+ icon = r.getResources().getDrawable(AndroidR.drawable.exit);
193
+ onClick = new ActionExit();
194
+ }
196
195
  else if (action.equalsIgnoreCase("separator")) {
197
- current = right;
196
+ group = null;
197
+ gravity = Gravity.CENTER;
198
198
  continue;
199
199
  }
200
200
 
@@ -204,8 +204,9 @@ public class SimpleMainView implements MainView {
204
204
  throw new IllegalArgumentException("'icon' should be String");
205
205
  String iconPath = rootPath + (String)iconObj;
206
206
  Bitmap bitmap = BitmapFactory.decodeFile(iconPath);
207
- if (bitmap != null)
208
- icon = new BitmapDrawable(bitmap);
207
+ if (bitmap == null)
208
+ throw new IllegalArgumentException("Can't find icon: " + iconPath);
209
+ icon = new BitmapDrawable(bitmap);
209
210
  }
210
211
 
211
212
  if (icon == null) {
@@ -238,8 +239,19 @@ public class SimpleMainView implements MainView {
238
239
 
239
240
  button.setOnClickListener(onClick);
240
241
  button.setLayoutParams(new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
241
- current.addView(button);
242
+ if (group == null) {
243
+ group = new LinearLayout(r);
244
+ group.setGravity(gravity);
245
+ group.setOrientation(LinearLayout.HORIZONTAL);
246
+ group.setLayoutParams(new LinearLayout.LayoutParams(FILL_PARENT, FILL_PARENT, 1));
247
+ bottom.addView(group);
248
+ }
249
+ group.addView(button);
242
250
  }
251
+
252
+ // Last group should have gravity RIGHT
253
+ if (group != null)
254
+ group.setGravity(Gravity.RIGHT);
243
255
  }
244
256
  }
245
257
 
@@ -282,5 +294,9 @@ public class SimpleMainView implements MainView {
282
294
  public int activeTab() {
283
295
  return 0;
284
296
  }
297
+
298
+ public void loadData(String data, int index) {
299
+ webView.loadData(data, "text/html", "utf-8");
300
+ }
285
301
 
286
302
  }
@@ -212,4 +212,8 @@ public class TabbedMainView implements MainView {
212
212
  return host.getCurrentTab();
213
213
  }
214
214
 
215
+ public void loadData(String data, int index) {
216
+ getWebView(index).loadData(data, "text/html", "utf-8");
217
+ }
218
+
215
219
  }
@@ -328,7 +328,7 @@ namespace "build" do
328
328
 
329
329
  end
330
330
  # desc "Build RhoBundle for android"
331
- task :rhobundle => ["config:android","build:bundle:noxruby",:extensions,:librhodes] do
331
+ task :rhobundle => ["config:android","build:bundle:noxruby",:generate_sources,:extensions,:librhodes] do
332
332
  # Rake::Task["build:bundle:noxruby"].execute
333
333
 
334
334
  assets = File.join(Jake.get_absolute($androidpath), "Rhodes", "assets")
@@ -345,11 +345,35 @@ namespace "build" do
345
345
  File.open(File.join(assets, "name"), "w") { |f| f.write($appname) }
346
346
  end
347
347
 
348
+ task :generate_sources => "config:android" do
349
+ # Generate gapikey.h
350
+ gapikey_h = File.join($androidpath, "Rhodes", "jni", "include", "gapikey.h")
351
+ gapi_defined = false
352
+ if File.file? gapikey_h
353
+ File.open(gapikey_h, 'r') do |f|
354
+ while line = f.gets
355
+ gapi_defined = true if line =~ /GOOGLE_API_KEY/
356
+ break if gapi_defined
357
+ end
358
+ end
359
+ end
360
+
361
+ if $use_geomapping != gapi_defined or not File.file? gapikey_h
362
+ File.open(gapikey_h, 'w') do |f|
363
+ f.puts "#ifndef RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
364
+ f.puts "#define RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
365
+ f.puts "#define GOOGLE_API_KEY \"#{$gapikey}\"" if $use_geomapping and !$gapikey.nil?
366
+ f.puts "#endif /* RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F */"
367
+ end
368
+ end
369
+ end
370
+
348
371
  task :extensions => "config:android" do
349
372
 
350
373
  ENV["ANDROID_NDK"] = $androidndkpath
351
374
  ENV["ANDROID_API_LEVEL"] = ANDROID_API_LEVEL.to_s
352
375
  ENV["TARGET_TEMP_DIR"] = $extensionsdir
376
+ ENV["RHO_ROOT"] = $startdir
353
377
  ENV["BUILD_DIR"] ||= $startdir + "/platform/android/build"
354
378
 
355
379
  mkdir_p $bindir + "/libs/" + $confdir + "/extensions" unless File.exist? $bindir + "/libs/" + $confdir + "/extensions"
@@ -370,9 +394,11 @@ namespace "build" do
370
394
  extpath = rhoextpath
371
395
  end
372
396
 
373
-
374
-
375
- puts Jake.run('./build', [], extpath) if File.executable? File.join(extpath, 'build')
397
+ if RUBY_PLATFORM =~ /(win|w)32$/
398
+ puts Jake.run('build.bat', [], extpath) if File.exists? File.join(extpath, 'build.bat')
399
+ else
400
+ puts Jake.run('./build', [], extpath) if File.executable? File.join(extpath, 'build')
401
+ end
376
402
  exit 1 unless $? == 0
377
403
 
378
404
  end
@@ -566,27 +592,6 @@ namespace "build" do
566
592
  objdir = File.join $rhobindir, $confdir, "librhodes"
567
593
  libname = File.join $bindir, "libs", $confdir, "librhodes.so"
568
594
 
569
- # Generate gapikey.h
570
- gapikey_h = File.join(incdir, 'gapikey.h')
571
- gapi_defined = false
572
- if File.file? gapikey_h
573
- File.open(gapikey_h, 'r') do |f|
574
- while line = f.gets
575
- gapi_defined = true if line =~ /GOOGLE_API_KEY/
576
- break if gapi_defined
577
- end
578
- end
579
- end
580
-
581
- if $use_geomapping != gapi_defined or not File.file? gapikey_h
582
- File.open(gapikey_h, 'w') do |f|
583
- f.puts "#ifndef RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
584
- f.puts "#define RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F"
585
- f.puts "#define GOOGLE_API_KEY \"#{$gapikey}\"" if $use_geomapping and !$gapikey.nil?
586
- f.puts "#endif /* RHO_GAPIKEY_H_411BFA4742CF4F2AAA3F6B411ED7514F */"
587
- end
588
- end
589
-
590
595
  args = []
591
596
  args << "-I#{srcdir}/../include"
592
597
  args << "-I#{$shareddir}"
@@ -2,6 +2,7 @@ platform\bb\rhodes\src\com\rho\Jsr75File.java
2
2
  platform\bb\rhodes\src\com\rho\rubyext\GeoLocation.java
3
3
  platform\bb\rhodes\src\com\rho\rubyext\System.java
4
4
  platform\bb\rhodes\src\com\rho\rubyext\XMLParser.java
5
+ platform\bb\rhodes\src\com\rho\rubyext\Alert.java
5
6
  platform\bb\rhodes\src\com\rho\net\BaseSocket.java
6
7
  platform\bb\rhodes\src\com\rho\net\bb\BBHttpConnection.java
7
8
  platform\bb\rhodes\src\com\rho\net\bb\NativeBBHttpConnection.java
@@ -22,7 +23,6 @@ platform\bb\rhodes\src\rhomobile\RhoPhonebook.java
22
23
  platform\bb\rhodes\src\rhomobile\SecondaryResourceFetchThread.java
23
24
  platform\bb\rhodes\src\rhomobile\Utilities.java
24
25
  platform\bb\rhodes\src\rhomobile\WebView.java
25
- platform\bb\rhodes\src\rhomobile\Alert.java
26
26
  platform\bb\rhodes\src\rhomobile\datetime\DateTimePicker.java
27
27
  platform\bb\rhodes\src\rhomobile\datetime\DateTimeScreen.java
28
28
  platform\bb\rhodes\src\rhomobile\RingtoneManager.java
@@ -30,6 +30,7 @@ src\com\rho\Jsr75File.java
30
30
  src\com\rho\rubyext\GeoLocation.java
31
31
  src\com\rho\rubyext\System.java
32
32
  src\com\rho\rubyext\XMLParser.java
33
+ src\com\rho\rubyext\Alert.java
33
34
  src\com\rho\net\BaseSocket.java
34
35
  src\com\rho\net\bb\BBHttpConnection.java
35
36
  src\com\rho\net\bb\NativeBBHttpConnection.java
@@ -39,7 +40,6 @@ src\com\rho\net\TCPSocket.java
39
40
  src\com\rho\RhoMainScreen.java
40
41
  src\com\rho\RhoRubyHelper.java
41
42
  src\com\rho\Version.java
42
- src\rhomobile\Alert.java
43
43
  src\rhomobile\camera\Camera.java
44
44
  src\rhomobile\camera\CameraFilesListener.java
45
45
  src\rhomobile\camera\CameraScreen.java
@@ -6,7 +6,7 @@ import net.rim.device.api.system.ApplicationDescriptor;
6
6
  import net.rim.device.api.system.CodeModuleGroup;
7
7
  import net.rim.device.api.system.DeviceInfo;
8
8
  import net.rim.device.api.io.http.HttpHeaders;
9
- import rhomobile.Alert;
9
+ import com.rho.rubyext.Alert;
10
10
  import rhomobile.NativeBar;
11
11
  import rhomobile.RhoPhonebook;
12
12
  import rhomobile.RhodesApplication;
@@ -0,0 +1,300 @@
1
+ package com.rho.rubyext;
2
+
3
+ import java.io.InputStream;
4
+ import java.util.Vector;
5
+
6
+ import javax.microedition.media.Player;
7
+
8
+ import net.rim.device.api.system.Application;
9
+ import net.rim.device.api.ui.component.Dialog;
10
+
11
+ import com.rho.RhoClassFactory;
12
+ import com.rho.RhoEmptyLogger;
13
+ import com.rho.RhoLogger;
14
+ import com.rho.RhodesApp;
15
+ import com.rho.SimpleFile;
16
+ import com.xruby.runtime.builtin.*;
17
+ import com.xruby.runtime.lang.*;
18
+
19
+ public class Alert
20
+ {
21
+ private static final RhoLogger LOG = RhoLogger.RHO_STRIP_LOG ? new RhoEmptyLogger() :
22
+ new RhoLogger("Alert");
23
+
24
+ public static final RubyID titleID = RubyID.intern("title");
25
+ public static final RubyID messageID = RubyID.intern("message");
26
+ public static final RubyID iconID = RubyID.intern("icon");
27
+ public static final RubyID callbackID = RubyID.intern("callback");
28
+ public static final RubyID buttonsID = RubyID.intern("buttons");
29
+ public static final RubyID buttonidID = RubyID.intern("id");
30
+
31
+ public static final RubyID alertTypeID = RubyID.intern("alert");
32
+ public static final RubyID questionTypeID = RubyID.intern("question");
33
+ public static final RubyID infoTypeID = RubyID.intern("info");
34
+
35
+ public static void showPopup(final String message)
36
+ {
37
+ Application.getApplication().invokeLater(new Runnable() {
38
+ public void run() {
39
+ Application.getApplication().requestForeground();
40
+ Dialog.alert(message);
41
+ }
42
+ });
43
+ }
44
+
45
+ private static String getHashStringValue(RubyHash hash, RubyID id)
46
+ {
47
+ RubyValue val = hash.get(id.toSymbol());
48
+
49
+ return val != null && val != RubyConstant.QNIL ? val.toStr() : "";
50
+ }
51
+
52
+ private static class PopupHandler implements Runnable
53
+ {
54
+ String m_strMessage = "";
55
+ String m_strCallback = "";
56
+ Vector m_vecButtons = new Vector();
57
+ Vector m_vecIDs = new Vector();
58
+ private static final int atAlert = 1;
59
+ private static final int atQuestion = 2;
60
+ private static final int atInfo = 3;
61
+ int m_nType = 0;
62
+
63
+ PopupHandler(RubyHash hash)
64
+ {
65
+ m_strMessage = getHashStringValue(hash, messageID );
66
+ m_strCallback = getHashStringValue(hash, callbackID );
67
+
68
+ RubyValue valButtons = hash.get(buttonsID.toSymbol());
69
+ if ( valButtons != null && valButtons instanceof RubyArray )
70
+ {
71
+ RubyArray arButtons = (RubyArray)valButtons;
72
+ for ( int i = 0; i < arButtons.size(); i++ )
73
+ {
74
+ RubyValue valButton = arButtons.get(i);
75
+ if ( valButton != null && valButton instanceof RubyString )
76
+ {
77
+ m_vecButtons.addElement(valButton.toStr());
78
+ m_vecIDs.addElement(valButton.toStr());
79
+ }else if ( valButton != null && valButton instanceof RubyHash )
80
+ {
81
+ String strLabel = getHashStringValue((RubyHash)valButton, titleID );
82
+ if ( strLabel.length() > 0 )
83
+ {
84
+ m_vecButtons.addElement(strLabel);
85
+ String strID = getHashStringValue((RubyHash)valButton, buttonidID );
86
+ if ( strID.length() > 0 )
87
+ m_vecIDs.addElement(strID);
88
+ else
89
+ m_vecIDs.addElement(strLabel);
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ RubyValue valIcon = hash.get(iconID.toSymbol());
96
+ if ( valIcon instanceof RubySymbol )
97
+ {
98
+ if ( valIcon == alertTypeID.toSymbol() )
99
+ m_nType = atAlert;
100
+ else if( valIcon == questionTypeID.toSymbol() )
101
+ m_nType = atQuestion;
102
+ else if( valIcon == infoTypeID.toSymbol() )
103
+ m_nType = atInfo;
104
+
105
+ }else
106
+ {
107
+ if (m_vecButtons.size() > 0 )
108
+ m_nType = atQuestion;
109
+ else
110
+ m_nType = atInfo;
111
+ }
112
+ }
113
+
114
+ public void run() {
115
+ Application.getApplication().requestForeground();
116
+
117
+ switch( m_nType )
118
+ {
119
+ case atAlert:
120
+ Dialog.alert(m_strMessage);
121
+ break;
122
+ case atQuestion:
123
+ Object[] btns = new Object[m_vecButtons.size()];
124
+ m_vecButtons.copyInto(btns);
125
+ int nRes = Dialog.ask(m_strMessage,btns,0);
126
+
127
+ try
128
+ {
129
+ RhodesApp.getInstance().callPopupCallback(m_strCallback, (String)m_vecIDs.elementAt(nRes),
130
+ (String)m_vecButtons.elementAt(nRes));
131
+ }catch(Exception exc)
132
+ {
133
+ LOG.ERROR("show_popup callback failed.", exc);
134
+ }
135
+ break;
136
+ case atInfo:
137
+ Dialog.inform(m_strMessage);
138
+ break;
139
+
140
+ }
141
+ }
142
+
143
+ }
144
+
145
+ public static void vibrate(final String duration)
146
+ {
147
+ Application.getApplication().invokeLater(new Runnable() {
148
+ public void run() {
149
+ int dt = 2500;
150
+ try {
151
+ dt = Integer.parseInt(duration);
152
+ } catch (NumberFormatException e) {
153
+ }
154
+
155
+ if (dt > 25500) dt = 25500;
156
+
157
+ if (dt > 0) {
158
+ net.rim.device.api.system.Alert.startVibrate(dt);
159
+ }
160
+ }
161
+ });
162
+ }
163
+
164
+ private static final String[][] filetypes = { {"mp3", "audio/mpeg"}, {"wav","audio/x-wav"} };
165
+ private static String getTypeFromExt(String file_name) {
166
+ int pt = file_name.lastIndexOf('.');
167
+ if (pt<0) {
168
+ return filetypes[0][1];
169
+ }
170
+ String ext = file_name.substring(pt+1);
171
+ for (int cnt = filetypes.length - 1; cnt >= 0; --cnt) {
172
+ if(filetypes[cnt][0].equals(ext)) {
173
+ return filetypes[cnt][1];
174
+ }
175
+ }
176
+ return null;
177
+ }
178
+
179
+ public static void play_file(final String file_name, final String media_type)
180
+ {
181
+ Application.getApplication().invokeLater(new Runnable()
182
+ {
183
+ public void run() {
184
+ String type = media_type == null ? getTypeFromExt(file_name) : media_type;
185
+ if (type != null) {
186
+ LOG.INFO("File type: " + type);
187
+ } else {
188
+ LOG.ERROR("Error - can't play unknown file type");
189
+ return;
190
+ }
191
+
192
+ String types[] =
193
+ javax.microedition.media.Manager.getSupportedContentTypes(null);
194
+ for (int cnt = types.length - 1; cnt >= 0; --cnt) {
195
+ if (type.equals(types[cnt])) {
196
+ LOG.INFO( "Playing file " + file_name + " of type: " + types[cnt]);
197
+
198
+ SimpleFile file = null;
199
+ try {
200
+ //retrieve the file
201
+ Class clazz = Class.forName("rhomobile.RhodesApplication");
202
+ file = RhoClassFactory.createFile();
203
+ String strClassName = file_name;
204
+ if ( !strClassName.startsWith("/apps") )
205
+ strClassName = "/apps" + file_name;
206
+
207
+ InputStream is = file.getResourceAsStream(clazz.getClass(), strClassName);
208
+ //create an instance of the player from the InputStream
209
+ Player player = javax.microedition.media.Manager.createPlayer(is,type);
210
+ player.realize();
211
+ player.prefetch();
212
+ //start the player
213
+ player.start();
214
+ } catch (Exception ex) {
215
+ LOG.ERROR("Error playing " + file_name + " :" + ex.getMessage());
216
+ } finally {
217
+ try{
218
+ if ( file != null )
219
+ file.close();
220
+ }catch(Exception exc){}
221
+ }
222
+ return;
223
+ }
224
+ }
225
+
226
+ LOG.ERROR("Error - media type " + type + " isn't supported.");
227
+ }
228
+ });
229
+ }
230
+
231
+ public static void initMethods(RubyClass klass) {
232
+ klass.getSingletonClass().defineMethod("show_popup", new RubyOneArgMethod()
233
+ {
234
+ protected RubyValue run(RubyValue receiver, RubyValue arg0, RubyBlock block)
235
+ {
236
+ try {
237
+ if ( arg0 instanceof RubyString )
238
+ {
239
+ String message = arg0.toString();
240
+ Alert.showPopup(message);
241
+ }else if ( arg0 instanceof RubyHash)
242
+ {
243
+ PopupHandler handler = new PopupHandler((RubyHash)arg0);
244
+ Application.getApplication().invokeLater(handler);
245
+ }
246
+ else
247
+ throw new RubyException(RubyRuntime.ArgumentErrorClass, "in Alert.show_popup: wrong argument type.Should be String or Hash");
248
+
249
+ return RubyConstant.QNIL;
250
+ } catch(Exception e) {
251
+ LOG.ERROR("show_popup failed", e);
252
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
253
+ }
254
+
255
+ }
256
+ });
257
+ klass.getSingletonClass().defineMethod("vibrate", new RubyVarArgMethod() {
258
+ protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block)
259
+ {
260
+ if ( args != null && args.size() > 1 )
261
+ throw new RubyException(RubyRuntime.ArgumentErrorClass,
262
+ "in Alert.vibrate: wrong number of arguments ( " + args.size() + " for " + 1 + " )");
263
+
264
+ try {
265
+ String duration = "2500";
266
+ if ((args != null) && (args.size() > 0))
267
+ duration = args.get(0).toString();
268
+ Alert.vibrate(duration);
269
+
270
+ return RubyConstant.QNIL;
271
+ } catch(Exception e) {
272
+ LOG.ERROR("vibrate failed", e);
273
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
274
+ }
275
+ }
276
+ });
277
+ klass.getSingletonClass().defineMethod("play_file", new RubyVarArgMethod() {
278
+ protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block)
279
+ {
280
+ if ( args.size() < 1 || args.size() > 2 )
281
+ throw new RubyException(RubyRuntime.ArgumentErrorClass,
282
+ "in Alert.play_file: wrong number of arguments ( " + args.size() + " for " + 2 + " )");
283
+
284
+ try {
285
+ String file_name = args.get(0).toString();
286
+ String media_type = null;
287
+ if ((args.size() > 1) && (args.get(1) != RubyConstant.QNIL))
288
+ media_type = args.get(1).toString();
289
+ Alert.play_file(file_name,media_type);
290
+
291
+ return RubyConstant.QNIL;
292
+ } catch(Exception e) {
293
+ LOG.ERROR("play_file failed", e);
294
+ throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
295
+ }
296
+ }
297
+ });
298
+ }
299
+
300
+ }