title: JenaEngineの使い方

JenaEngineの使い方
========================================

(2006,10/06:他のプログラムからJenaEngineを使う時に
ソースファイルをいじる必要が無く、JenaCheck.jarのバイナリ
をクラスパスに含めるだけで使用できるように変更しました。)

jp.ac.do_johodai.j314.sw.jeパッケージは，
Jenaの推論エンジンを，今回の科研の研究に
使うのに便利な形で呼び出せるようにした
JenaEngineクラスがあります．これの使い方の
例を示します．

このJenaEngineは，最低限Pelletとそれに
含まれるJenaのパッケージに依存しているので，
クラスパスなどの環境設定で指定しておいて下さい．
また，使用するビルトインを追加することで，
他のパッケージにも依存するようになります．
jp.ac.do_johodai.j314.sw.jeパッケージで提供
しているビルトインと依存するパッケージの関係を
以下に示します．

* 他のパッケージに依存しないビルトイン
  - BindBuiltin
  - ReadBuiltin
* Axis2に依存するビルトイン
  - SendN3Builtin
* a23に依存するビルトイン
  - A3NewBuiltin
  - A3SetVisibleBuiltin
  - A3ChangeBuiltin
  - A3PrintBuiltin
  - A3ReadBuiltin
  - A3YesNoBuiltin

これらのBuiltinが必要な場合には，それぞれのパッケージを
クラスパスなどの環境設定で指定しておいて下さい．
さらに以下のプログラム例のように，使用するビルトインを
registerBuiltinメソッドを用いて登録する必要があります．
(Jenaのデフォルトのビルトインを使用する場合は登録の
必要はありません．)

プログラム例

    import jp.ac.do_johodai.j314.sw.je.*;
    
    public class Test {
        public static void main(String args[]) {
           JenaEngine je = new JenaEngine();
           je.registerBuiltin(new ReadBuiltin()); // 必要なビルトインを登録
           je.loadRDF("file:///tmp/test.n3");
           je.loadRules("test.rules");
           String query = "SELECT * WHERE{?x ?y ?z}";
           System.out.println(je.execSPARQL(query));
        }
    }

だいたいこんな感じです．使えるメソッドなどはjavadocを参照して下さい．
ただ，上で使っているメソッドは同期型の呼出しなのでデッドロックの可能性
があります．非同期の呼出しを行なうには以下のようにします．

    import jp.ac.do_johodai.j314.sw.je.*;
    import com.hp.hpl.jena.query.*;
    
    public class Test implements JEListener {
        public void exec() {
            JenaEngine je = new JenaEngine();
            String query = "SELECT * WHERE{?x ?y ?z}";
            JEMessage m = new JEMessage(JEMessage.Type.SPARQL,this,query);
            je.recieveRequest(m);
        }
    
        public void performResultMessage(JEMessage m) {
            if (m.getType()==JEMessage.Type.SPARQL) {
                Object result = m.getResult();
                if (result instanceof ResultSet) {
                    ResultSetFormatter.out(System.out,(ResultSet)result);
                }
            }
        }
    
        public static void main(String args[]) {
            Test t = new Test();
            t.exec();
        }
    }

だいたい，こんなところです．初めにJEMessageオブジェクトを
作成します．JEMessageオブジェクトを作成する時にどんな
種類の呼出しを行うのかと，誰が返事を受け取るのかと，
リクエストに必要な引数を指定します．
実際に呼出しを実行する場合は全てrecieveRequest
というメソッドを用いており，呼出しの結果はすぐには返って
きません．かわりにperformResultMessageというメソッドを
作っておいてそこで受け取ります．上のソースでは，受け取った
内容が，本当に呼出した時のリクエストタイプと同じかどうか
チェックしてから処理をしています．さらにSPARQLのクエリの
場合には，SELECT,CONSTRUCT,ASK,DISCRIPTIONの違いによって
何が返ってくるかわからないので，SELECTの返り値である
ResultSetオブジェクトであるかどうかもチェックしています．
ResultSetが返ってきたら，あとはJenaのcom.hp.hpl.jena.query
パッケージ上のプログラムになります．

非同期の例では，RDFモデルに何も入ってないので返ってくる
結果も空です．RDFモデルを読み込ませるには
JEMessage.Type.INSERT_N3やLOAD_RDFタイプのメッセージを
作って呼出します．

ちなみに上のプログラムは日本語が入っている結果が返って
くると文字化けします．文字化けを避けるには以下のような
テクニックを使って下さい．

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ResultSetFormatter.out(baos,(ResultSet)result);
    System.out.println(baos.toString("UTF-8"));
