JRuby for BlazeDS その1
JRubyで記述したサービスを BlazeDS経由で Flexから呼び出したくなった。
実運用のためのサービスをJRubyで記述する気はないが、モックアップを手早く作り上げるのには適していると思ったからだ。
Springが対応しているJRubyの最新版は現時点で 1.0.3である。
そのまま使おうとすると下記の点で不便だ。
・ActionScriptの Date型が Rubyの Time型に自動変換されてくれない。
java.util.Dateへの変換は BlazeDSが自動で行ってくれるが、JRuby1.0はそれを Rubyの Time型にまで変換してはくれない。
・ActionScriptの(動的プロパティ持ち)オブジェクトが文字列キーのハッシュになってしまう。
今風に、ハッシュのキーはシンボルにしたい。person['name']じゃなくて person[:name]のほうがかっこいい。
RubyのTime や Dateといったオブジェクトが ActionScriptのDate型に変換されてくれない。
サーバ側で java.util.Dateにまで変換してやれば、ActionScript側には Date型で届いてくれるのだが、JRuby1.0はその変換をしてくれない。
JRuby 1.0.3の org/jruby/javasupport/JavaUtil.java に対して下記のようなクイックハックを敢行した。
以前のエントリに書いたが、今の Springは JRuby 1.1に対応していない。
将来 Springが JRuby1.1に対応したらこのパッチは要らなくなるかもしれない。
続く
実運用のためのサービスをJRubyで記述する気はないが、モックアップを手早く作り上げるのには適していると思ったからだ。
Springが対応しているJRubyの最新版は現時点で 1.0.3である。
そのまま使おうとすると下記の点で不便だ。
Flex → JRuby
・ActionScriptの Date型が Rubyの Time型に自動変換されてくれない。
java.util.Dateへの変換は BlazeDSが自動で行ってくれるが、JRuby1.0はそれを Rubyの Time型にまで変換してはくれない。
・ActionScriptの(動的プロパティ持ち)オブジェクトが文字列キーのハッシュになってしまう。
今風に、ハッシュのキーはシンボルにしたい。person['name']じゃなくて person[:name]のほうがかっこいい。
JRuby → Flex
RubyのTime や Dateといったオブジェクトが ActionScriptのDate型に変換されてくれない。
サーバ側で java.util.Dateにまで変換してやれば、ActionScript側には Date型で届いてくれるのだが、JRuby1.0はその変換をしてくれない。
というわけでパッチ
JRuby 1.0.3の org/jruby/javasupport/JavaUtil.java に対して下記のようなクイックハックを敢行した。
38a39,41
> import java.util.Calendar;
> import java.util.Date;
> import java.util.Map;
43a47
> import org.jruby.RubyHash;
81c85,108
<
---
> } else if (javaClass == Date.class
> || (javaClass == null && rubyObject.respondsTo("tv_sec"))
> || (javaClass == null && rubyObject.respondsTo("yday")) ) {
> // Timeオブジェクト用
> if (rubyObject.respondsTo("tv_sec")) {
> Long tv_sec =
> ((RubyNumeric)rubyObject.callMethod(context, "tv_sec")).getLongValue();
> return new Date(tv_sec * 1000);
> }
> // Dateオブジェクト用
> if (rubyObject.respondsTo("yday")) {
> long year =
> ((RubyNumeric)rubyObject.callMethod(context, "year")).getLongValue();
> long yday =
> ((RubyNumeric)rubyObject.callMethod(context, "yday")).getLongValue();
> Calendar cal = Calendar.getInstance();
> cal.set(Calendar.YEAR, (int) year);
> cal.set(Calendar.DAY_OF_YEAR, (int) yday);
> cal.set(Calendar.MILLISECOND, 0);
> cal.set(Calendar.SECOND, 0);
> cal.set(Calendar.MINUTE, 0);
> cal.set(Calendar.HOUR_OF_DAY, 0);
> return cal.getTime();
> }
235c262,274
<
---
> } else if (javaClass == Date.class) {
> // ActionScriptのDateオブジェクト用
> return runtime.newTime(((Date)object).getTime());
> } else if (javaClass == flex.messaging.io.amf.ASObject.class) {
> // ActionScriptのオブジェクト用
> RubyHash rh = new RubyHash(runtime);
> for (Object e:((Map)object).entrySet()) {
> Map.Entry entry = (Map.Entry)e;
> rh.put(
> runtime.newSymbol((String)entry.getKey()),
> convertJavaToRuby(runtime, entry.getValue()));
> }
> return rh;
以前のエントリに書いたが、今の Springは JRuby 1.1に対応していない。
将来 Springが JRuby1.1に対応したらこのパッチは要らなくなるかもしれない。
続く

0 件のコメント:
コメントを投稿
<< ホーム