Rhinoを使う場合、以下の二つの用途に分かれると思います。
- JavaはRhinoを実行するだけで、JavaScriptにほとんどの仕事をやらせる
- Javaがメインの仕事をして、JavaScriptに一部の変更の多いロジックを書く
まずは1の実現の仕方です。JavaScriptに色々書いて結果を表示してみます。Java側は以下の通り。
import java.io.File; import java.io.FileReader; import java.io.IOException; import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; public class JSTest { public static void main(String[] args) throws IOException{ File script = new File("my_script.js"); Context cx = Context.enter(); Object jsObject = null; try{ Scriptable global = cx.initStandardObjects(); FileReader r = new FileReader(script); jsObject = cx.evaluateReader(global, r, script.getAbsolutePath(), 1, null); r.close(); /* 戻り値を出力させる */ System.out.println(Context.toString(jsObject)); }finally{ Context.exit(); } } }
前回のコードに一行だけ足してます。Context.toString()は、JavaScriptから戻って来たObjectを文字列に直します。戻り値がObjectになっているのは、JavaScriptの内部表現によってBoolean、String、Number、Scriptable、null、Context.getUndefinedValue()のどれかを返してくるからです。また、見つからなかったときはScriptable.NOT_FOUNDが返ります。詳細はScriptableのjavadocを見て下さい。
では、JavaScriptです。my_script.jsの中身を、例えば以下のようにしてみます。0〜9の数字をカンマでつなげた文字列を返すだけのスクリプトです。
var i = 0; var str = ''; for(i = 0; i < 10; i++){ if(i > 0) str += ","; str += i; } str;
これで、さきほどのjavaコードをコンパイルして実行すると、"0,1,2,3,4,5,6,7,8,9"が画面に表示されます。
$ javac -cp .:js.jar JSTest.java $ java -cp .:js.jar JSTest 0,1,2,3,4,5,6,7,8,9
JavaScriptの中で関数も定義して使えます。詳細はJavaScriptを勉強して下さい(笑)。
function join(comma, array){ var ret = ''; for(var i = 0; i < array.length; i++){ if(i > 0) ret += comma; ret += array[i]; } return ret; } join('===', ['abc', 'def', 'ghi', 'jkf', ]); /* [結果] abc===def===ghi===jkf */
ちなみに、こんな荒技もできます。JavaScriptならでは。
var hoge; hoge = function (){ var hogehoge = "foofoo"; return hogehoge; }; /* [実行結果] function () { var hogehoge = "foofoo"; return hogehoge; } */
Functionオブジェクトを出力すると、コードとして出力されるのです( ̄Д ̄;;。恐るべしJavaScript。他にも色々といじると面白い事実を発見出来たりすると思います。Javaさえコンパイルしておけば何度も手軽に試せるので、お試し下され。
次回は引き続きスクリプトを書きまくります。