先週は、jrunscriptを材料にスクリプトがどのように実行されているのかを調べてみました。

今週はそれをベースに実際にスクリプトを実行するコードを書いていきましょう。

スクリプトエンジンの情報を取得する

はじめのサンプルはjrunscriptの-qオプションと同じく、使用できるスクリプト言語の一覧とスクリプトエンジンの情報を出力するサンプルです。

サンプルのソース ScriptSample1.java

先週示したように、スクリプトエンジンの一覧はjavax.script.ScriptEngineManagerクラスを使用して取得します。

        // スクリプトエンジンマネージャの生成
        ScriptEngineManager manager = new ScriptEngineManager();

        // スクリプトエンジンファクトリの取得
        List<ScriptEngineFactory> factories = manager.getEngineFactories();

赤字で示したように、ScriptEngineManagerクラスはnewで生成することができます。ScriptEngineManagerオブジェクトにはスクリプトエンジンを生成するためのjavax.script.ScriptEngineFactoryインタフェースの実装クラスインスタンスが登録されています。

ScriptEngineManagerオブジェクトは登録されたScriptEngineFactoryオブジェクトにスクリプトエンジンの生成を委譲します。とはいうものの、どのようなスクリプトエンジンが生成されるのか事前に分からなければなりません。そのため、ScriptEngineFactoryインタフェースには、生成するスクリプトエンジンに関する情報を取得するためのメソッドが定義されています。

その情報を表示させていたのが、先週解説したjrunscrriptの-qオプションです。

ScriptEngineManagerクラスに登録されているScriptEngineFactoryオブジェクトの取得するのがgetEngineFactoriesメソッドです。戻り値の型はListインタフェースになります。

後はforループでScriptEngineFactoryオブジェクトを1つ1つ取り出し、情報を出力します。

        for (ScriptEngineFactory factory: factories) {
            // スクリプト言語の名前とバージョン
            System.out.println(factory.getLanguageName() + " " 
                               + factory.getLanguageVersion());
            // スクリプトエンジンの名前とバージョン
            System.out.println("  Engine: " + factory.getEngineName() + " "
                              + factory.getEngineVersion());
 
            // スクリプト言語の省略形を含めた名前
            List<String> names = factory.getNames();
            System.out.print("  Name: ");
            for (String name: names) {
                System.out.print(name + " ");
            }
            System.out.println();
 
            // スクリプト言語の拡張子
            List<String> exts = factory.getExtensions();
            System.out.print("  Extension: ");
            for (String ext: exts) {
                System.out.print(ext + " ");
            }
            System.out.println();
 
            // スクリプト言語の MimeType
            List<String> types = factory.getMimeTypes();
            System.out.print("  MimeType: ");
            for (String type: types) {
                System.out.print(type + " ");
            }
            System.out.println();
            System.out.println();
        }
    }

ScriptEngineFactoryインタフェースで定義されているスクリプトエンジンの情報に関するメソッドを表1に示します。

表1 ScriptEngineFactoryインタフェースの主なメソッド
メソッド 説明
String getEngineName() スクリプトエンジンの名前を返す
String getEngineVersion() スクリプトエンジンのバージョンを返す
String getLanguageName() スクリプト言語の名前を返す
String getLanguageVersion() スクリプト言語のバージョンを返す
List<String> getNames() スクリプトエンジンの省略形を含んだ名前の一覧を返す
List<String> getExtensions() スクリプトエンジンがサポートするファイル名の拡張子の一覧を返す
List<String> getMimeTypes() スクリプトエンジンの対応するMimeTypeの一覧を返す

では、サンプルを実行してみましょう。

C:\scripting>java ScriptSample1
ECMAScript 1.6
  Engine: Mozilla Rhino 1.6 release 2
  Name: js rhino JavaScript javascript ECMAScript ecmascript
  Extension: js
  MimeType: application/javascript application/ecmascript text/
  javascript text/ecmascript

ECMAScriptの情報が表示され、スクリプトエンジンがRhinoだということが確認できます。

次にJavaFX Scriptを使える状態にして、再度サンプルを実行してみます。

C:\scripting>java ScriptSample1
ECMAScript 1.6
  Engine: Mozilla Rhino 1.6 release 2
  Name: js rhino JavaScript javascript ECMAScript ecmascript
  Extension: js
  MimeType: application/javascript application/ecmascript text/
  javascript text/ecmascript
  
FX 0.1
  Engine: JavaFXEngine 0.1a
  Name: FX
  Extension: fx
  MimeType:

ECMAScriptの後にFXが追記されています。拡張子はfxです。JavaFX Scriptを組み込む方法は、来月、取り上げる予定です。

スクリプトの実行

スクリプトエンジンの情報が取得できたので、今度はスクリプトを実行するサンプルを作ってみます。

サンプルのソース ScriptSample2.java

ScriptSample1ではScriptEngineFactoryインタフェースを使用しましたが、スクリプトエンジンを生成する時には直接ScriptEngineFactoryインタフェースは使用しません。ScriptEngineManagerクラスの、getEngineByNameメソッド、getEngineByExtensionメソッド、もしくはgetEngineByMimeTypeメソッドを使用します。

ScriptEngineManagerクラスはこれらのメソッドで内部的にScriptEngineFactoryインタフェースを使用してスクリプトエンジンを生成しています。ScriptSample2クラスでは、getEngineByNameメソッドを使用してスクリプトエンジンを生成しています。

引数にはScriptEngineFactoryインタフェースの対応するメソッド(getEngineByNameメソッドであれば、getNamesメソッド)で得られる文字列を用います。

Rhinoスクリプトエンジンを取得したいのであれば、getEngineByNameメソッドの引数を先週示したjs、JavaScript、ECMAScriptなどの文字列にします。ここでは、青字で示したようにjsを使用しました。

スクリプトエンジンはjavax.script.ScriptEngineインタフェースで表されます。

    public ScriptSample2() {
        // スクリプトエンジンマネージャの生成
        ScriptEngineManager manager = new ScriptEngineManager();
 
        // スクリプトエンジンの取得 (JavaScript)
        ScriptEngine engine = manager.getEngineByName("js");
 
        try {
            // スクリプトの実行
            engine.eval("print('Hello, World!');");
        } catch (ScriptException ex) {
            System.err.println("スクリプトの実行に失敗しました");
        }
    }

スクリプトの実行には、赤字で示したように、ScriptEngineインタフェースのevalメソッドを使用します。evalには引数の型がStringクラスと、Readerクラスのものがオーバーロードされています。ここでは引数にStringクラスを使用しています。

例外処理を除くと、たった3行でスクリプトが実行できてしまいます。では、このサンプルを実際に実行してみましょう。

C:\scripting>java ScriptSample2
Hello, World!

ちゃんとHello, World!が表示されました。