タイトルAppleScript Working》4 _ AppleScriptからJavaを呼び出す(2)カテゴリーAppleScript, AppleScript Working
作成日2002/2/7 17:18:41作成者新居雅行
まず、クラスメソッドの利用なので、of class "SoundPlay" がいずれのコマンドにもつけられている。1行目は引数のないplaySoundメソッドを呼んでいる。2行目は引数が1つのplaySoundメソッドを呼んでいるが、結果的にコロンが1つメソッド名についている。3つ目は引数が2つのplaySoundを呼び出しているが、「playSound:async:」となっている点に中止してもらいたい。いずれにしても、メソッドのインタフェース定義の部分にあるメソッド名に加えて、メッセージキーワードとコロンを含めたものをメソッド名として指定する必要がある。
ここで、まず注意したいのは、正しくないメソッド名を指定してもエラーは出なという点だ。だから、間違えたAppleScriptの記述をしても「何もおこらない」かのような現象になってしまう。
それから、引数のあるものは、with parameter(s)で指定を行う。ここで、文字列を指定すると、Objective-C側のプログラムでは(NSString *)で受ければいいし、論理値ならBOOL、整数ならintのように、いずれにしても、素直に対応付けられる型で受け取ることができる。また、戻り値がある場合も同様だ。複数の引数があるときには、リスト型で順序を間違えないように指定する。ただし、前のプログラム例で、with parameter {"Temple", true} つまり「s」が1つないだけで、これは、「配列の引数が1つ指定されている」とみなされてしまう。そして、1番目の引数に大カッコの中身の値が(NSArray *)で引き渡されてしまうので、2つ目の引数には値は渡らないのである。
なお、Cocoaのクラスのクラスメソッドも同様に呼び出すことができる。クラス名に「NSNumber」などと指定をすれば良い。



――――Javaのクラスを呼び出す
Javaの場合は少し実験をしながら作ったクラスで例を示そう。やはり、AppleScript Applicationをプロジェクトのテンプレートとして選択したアプリケーションで、「ファイル」メニューの「新規ファイル」(Command+N)を選択して、新しいファイルを作るが、Java classを選択して現在のターゲットにそのファイルを追加するようにしておく。ここでは、JavaObj.javaというファイルを作ることにした。そして次のように、クラスメソッドを作った。

// JavaObj.java

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;


public class JavaObj {

static public int actionA(){
return 99;
}
static public int actionB(int a){
return a*99;
}
static public int actionC(int a, int b){
return (a+b)*99;
}
static public NSArray actionD(){
Object obj[] = {new Integer(19), "Sender OK", new Float(0.876)};
return new NSArray(obj);
}
static public NSDictionary actionE(){
Object obj[] = {new Integer(19), "Sender OK", new Float(0.876)};
Object key[] = {"Age", "Message", "The Number"};
return new NSDictionary(obj, key);
}
static int stock = 0;
static public void setStock(int n){stock = n;}
static public int getStock(){return stock;}
}

引数がいくつもある場合や、リスト、レコードを戻せるかといった点を中心にチェックしたわけだが、これらの呼び出しを行うAppleScriptのプログラムは次のようになる。まず、引数に数に応じて、メソッド名をどのように指定しないといけないかを探るシリーズ、actionA〜ActionCの呼び出し結果を見てみよう。以下のステートメントは問題なく動くことをもちろん確認している。メソッドを呼び出した結果を、display dialogでダイアログ表示してみた。

set x to call method "actionA" of class "JavaObj"
display dialog x as string
set x to call method "actionB:" of class "JavaObj" with parameter 10
display dialog x as string
set x to call method "actionC::" of class "JavaObj" with parameters {10, 4}
display dialog x as string

引数のないactionAメソッドはそのままメソッド名を書けばいいが、引数のあるものの場合は、コロンがその引数の数に応じて必要になる。つまり、引数の数だけコロンを続けたものをメソッド名として指定する必要がある。これは、JavaとObjective-Cのブリッジ部分の仕様であるのだろう。この場合は、Objective-Cのメソッド呼び出しの機能で、Javaのメソッドを呼んでいる。Javaのメソッドは、メッセージキーワードのない状態で定義されていると考えれば、Objective-Cのクラスを呼ぶ場合の記述と対応がとれるだろう。
続いて、actionDはNSArray型のデータを戻してみた。actionEはNSDictionary型のデータを戻してみた。

set x to call method "actionD" of class "JavaObj"
display dialog (item 2 of x) as string

set x to call method "actionE" of class "JavaObj"
display dialog (item 2 of x) as string
display dialog (Age of x) as string

ここで、actionDの戻り値は、確かにAppleScriptでのリストになっているのだが、actionEの戻り値はレコードにはなっていない。理由は分からないが、NSDictionaryではだめなのかあるいはAppleScriptシステム側に問題があるかもしれない。
続いて、結論を言えば当たり前なのだが、ここでのJavaObjクラスはstaticであることから、値を覚えるかどうかを試してみたのが、setStock、getStockのメソッドだ。いずれも、static変数のstockへの値の設定や取り出しを行っている。setStockで設定した値を、getStockで取り出されるのは以下のプログラムで確認できる。

call method "setStock" of class "JavaObj" with property 123
set x to call method "getStock" of class "JavaObj"
display dialog x as string

したがって、staticな変数を定義しておけば、call methodをまたがって、同じ値を共有できるということになる。複雑な処理をさせる場合には、こうした手法も有効だろう。
なお、Javaのライブラリを使うには、たとえば次のようにプログラムを作成すればよい。Mathクラスにmaxというメソッドがあり、引数を2つ取る。したがって、メソッド名は「max::」となる。また、クラス名は、フルパスで指定するのが基本のようである。

set x to call method "max::" of class "java.lang.Math" with parameters {3, 4}


――――JDBCを利用したサンプル
Objective-Cのクラスを作るメリットは、比較的示しやすいかもしれない。たとえば、キーチェーンの処理をさせたりといった、システムのAPI呼び出しができるからだ。一方、Javaのメリットとしては、やはり純正Javaライブラリの利用ということになるが、格好のサンプルとして、JDBCを使って、データベースアクセスを行う例を示したい。JavaにはJDBC(Java DataBase Connection)として、SQLデータベースへのアクセスを行う機能が用意されている。サーバサイドがJavaにシフトしていることもあって、JDBCに対応したデータベースが一般的である。最近では、MicrosoftのSQL ServerまでもJBDCドライバをまともに作るということがニュースになったほどだ。JDBCドライバを用意すれば、SQLステートメントの違いなどはデータベースエンジンごとにあるものの、接続やSQL実行、そこからの値の取り出しのプログラムはほとんど共通のものが使える。つまり、データベースエンジンに依存しないデータベースアクセスがJDBCによって可能になっているというわけだ。
いろいろなデータベースが結果的に使えるのであるが、今回のサンプルでは、OpenBase SQLを使用しよう。OpenBase SQLは、WebObjectsに付属しているのでなじみがあるかもしれない。もし、WebObjectsを持っていなくても、OpenBaseの評価版は無償でダウンロードして利用できるので、Mac OS Xにインストールして使ってみよう。GUIの管理ツールがあるなど使い勝手もよく、日本語にも対応している。今回は、OpenBaseがインストールされた状態であるとして、以下の例を示したい。OpenBaseには、「WOMovies」という映画のデータベースのサンプルがある。そのデータベースを起動した状態で、以下の作業を行うものとする。

◇OpenBase International
http://www.openbase.com/

このWOMoviesというサンプルデータベースには、MOVIEというテーブルがあって、映画の一覧表が用意されている。以下は、OpenBase Managerで見たそのテーブルである。

◇サンプルデータベースのWOMoviesにあるMOVIEテーブル
 
(この項、続く)
関連リンク