タイトルAppleScript Working》4 _ AppleScriptからJavaを呼び出す(3)カテゴリーAppleScript, AppleScript Working
作成日2002/2/7 17:19:28作成者新居雅行
それでは、このデータベースから値を取り出して、テーブル(NSTableView)のコントロールに取り出し結果を表示するといったプログラムを作成してみよう。まず、ユーザインタフェースの部分は、もちろん、Interface Builderで作成する。ここでは、プロジェクトとしてAppleScriptアプリケーションとして作ったものを利用するが、そこには最初からMainMenu.nibというnibファイルが用意されているので、それをダブルクリックし、最初から用意されているウインドウにユーザインタフェースを作り込むことにしよう。以下の図のようなものを作成したが、要は、ボタンが1つあり、このボタンは、Infoパレットで、clickedイベントを発生するようにしておき、そのプログラムをデフォルトのプログラムファイルであるApplication.applescriptに設定してある。また、テキストフィールド、テーブルをそれぞれ配置した。同じ種類のコンポーネントがないので、今回は、AppleScript Nameの設定を行わない方法でプログラムを組んでみよう。
それから、ツールパレットのAppleScriptのカテゴリから、青い四角いボックスを配置しておき、ASKDataSourceというインスタンスを作っておく。そして、NSTextViewのDataSourceとつなげておく。これは前回説明した通りのデータソースの確保である。

◇作成したウインドウとデータソースへの接続
 

なお、NSTableViewは3列を表示できるようにしておき、列幅は適当にドラッグして設定しておこう。
これでユーザインタフェースは作成できた。ちなみに、テキストフィールドに検索条件を記入すると、その文字を含む題名の映画をテーブルの一覧するという動作をさせたい。
続いて、データベースアクセスをおこなうクラスをJavaで作る。「ファイル」メニューの「新規ファイル」(Command+N)を選択して、Java classを選び、ここではDBAccessというクラスを定義した。プログラムはテキストでも示そう。

◇JavaのDBAccessクラスを定義する
 


// DBAccess.java

import java.sql.*;
import java.util.*;
import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

public class DBAccess {

static public NSArray getData(String criteria){
try{
Class.forName("com.openbase.jdbc.ObDriver");
Connection con = DriverManager.getConnection(
"jdbc:openbase://localhost/WOMovies","","");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(
"SELECT * FROM MOVIE WHERE TITLE LIKE ’%"
+ criteria + "%’");
List tableContents = new ArrayList();
while(rs.next()){
Object obj[] = {rs.getString(1), rs.getString("TITLE"),
rs.getString("CATEGORY")};
tableContents.add(new NSArray(obj));
}
rs.close();
con.close();
return new NSArray(tableContents.toArray());
}
catch(Exception e){
System.out.println(e.getMessage());
return null;
}
}
}

プログラムの細かな点はJDBCに立ち入ることなので、ここでは概要を説明したい。getDataメソッドは1つの引数を取るが、その引数を検索条件として、MOVIEテーブルからレコードを取り出す。SELECTステートメントとして、LIKE演算子やワイルドカードを使ってSQLコマンドを作っているが、つまりは、TITLEカラムのデータに、引数に指定された文字列が含むものであれば、すべて抽出するとういSELECT文となっている。
データベースの接続には、JDBCドライバのクラスのフルパス記述や、あるは接続文字列の指定が必要だが、これは、OpenBaseのドキュメントを参考に、プログラムにあるように決めた。なお、これは、接続先としてlocalhostを指定している。つまり、実行するマシンで稼働しているOpenBaseを対象にデータベースアクセスするわけだ。このあたりのプログラムは、JDBCの定番的な流れである。
そして、取り出した結果を、2次元配列として戻したいのだが、NSArrayを要素に持つNSArrayを作れば、それは2次元配列としてAppleScript側に伝わる。1レコード分はまとめてNSArrayを作ってしまえばいいが、レコードを順に調べていき、それらを逐次記憶するためにArrayListクラスを使っている。このクラスを使って最終的にtoArrayメソッドで配列を得て、そこから、NSArrayを得ているのである。
続いて、AppleScript側のプログラムを紹介しよう。ボタンをクリックすると、以下のようなハンドルが呼び出される。

on clicked theObject
set crit to text field 1 of window of theObject
set dbData to call method "getData:" of class "DBAccess" with ツ
parameter string value of crit

set theTable to table view 1 of scroll view 1 of window of theObject
set ds to data source 1 of theTable
if (count data columns of ds) is 0 then
make new data column at the end of data columns of ds
make new data column at the end of data columns of ds
make new data column at the end of data columns of ds
end if
delete data rows of ds
repeat with aRow in dbData
set newRow to make new data row at the end of data rows of ds
set contents of data cell 1 of newRow to item 1 of aRow
set contents of data cell 2 of newRow to item 2 of aRow
set contents of data cell 3 of newRow to item 3 of aRow
end repeat
end clicked

まず、最初に、JavaのDBAccessクラスのgetDataメソッドを呼び出している。テキストフィールドの値を、メソッドの引数として指定しているわけだ。これで、call methodステートメントの戻り値は、データベースから取り出した結果が含まれた2次元の配列となる。
あとは、前回のプログラムとかなり近い。データソースにカラムが用意されているかどうかを調べて、なければ作成する。そして、まず、行を全部削除してから、各行に、各カラムのデータを設定している。
実際の動きを見るのが早いかもしれない。
まず、アプリケーションを起動すれば、ウインドウが表示される。テキストフィールドに、ここでは条件として「Hoo」を指定してボタンをクリックしてみた。

◇検索条件を入れてボタンをクリック
 

すると、テーブルの部分に、条件に合ったレコードが取り出さされる。繰り返し、検索を行ってもかまわないようにしてある。

◇検索結果が表示された
 


◇別の検索を行った結果
 

ここで、検索条件に何も指定しないで、ボタンをクリックしてみよう。その場合、すべてのレコードが取り出されて、100行以上に渡ってテーブルへの書き込みが行われる。データベースのアクセスはローカルだとすぐに終わるのだが、テーブルのデータソースの行の追加といったしょりに時間がかかるあたりが分かるだろう。

このように、データベースアクセスのためのクラスをJavaで用意しておくことができるが、もちろん、汎用的なフェッチメソッドを作るのもいいし、特定の用途のものをつくるのもいいだろう。クラス変数を使えば、コネクションをキープしたままいくつかのメソッドで処理することもできるし、取り出したデータをクラス内にキャッシュするということもできるだろう。こうしたJavaでのデータベースアクセスの形態は、まさに3階層システムになっているというわけだ。つまり、ユーザインタフェースをAppleScriptで組み、ビジネスロジックをJavaで組むというわけである。
call methodはある意味ではアドホック的な手段ではあるが、AppleScriptのソースがベタな感じになるという気はするものの、手軽にこうしてAppleScript以外の手段とリンクできるようになっている点は発展性を強く感じるところだ。もちろん、フレームワークとしてしっかりしたものを作り、AppleScriptの用語集などを備えた、AppleScriptでのクラスやコマンドとして使えるものを用意するのが最終的な手段ではあるだろうけど、必要な機能のObjective-CやJavaで作られたソースを自分のプロジェクトに組み込んで、call methodで使うというのが、Mac OS X時代のお手軽OSAXではないかと思われる。
(この項、以上)
関連リンク