ここで失敗談を1つ。御存じのように、Javaの世界では、文字列はUNICODEで表現される。だから、getBytesメソッドで得られるバイト列は、やはりUNICODEである。それをそのままToolbox関数に渡したらまずいのではないかと考えてしまった。つまり、Toolbox関数をC言語などで呼び出す場合には、Shift-JISのコードでないとだめなのではないかと思い、Shift-JIS変換をしてからOSADoScriptを呼び出してしまっていた。それでも、おおむね動くが、一部におかしな文字が出てきてしまった。「プ」が「フ?」のようになってしまうのである。さんざん悩んだ挙げ句、結論は「Shift-JISに変換する必要なし」ということのようだ。つまり、余計なことはしなくてもよろしいということのようである。だが、後で説明するが、逆にいろいろなことがそれで分かった。
OSADoScriptで実際にスクリプトを実行する。エラーがあると、OSAScriptError関数を使って、エラーの内容を取り出す。ここで、どちらも、取得結果をresultDataというディスクリプタに収めているが、状況に応じてここは修正したほうがいいだろう。いずれにしても、resultDataにあるテキストデータを取り出し、String型として得ないといけない。ディスクリプタなので1つ目はデータの型、2つ目にデータの存在するハンドルとなっている。つまり、2つ目の要素のハンドルからデータを取り出して、文字列にしたいわけだ。そこで、JDirect2に用意されているGenericHandleというクラスを使って、まずToolboxのハンドルをJavaで使えるようにする。そのクラスにあるgetBytesAtによってbyte型配列が得られ、さらにそれをStringのコンストラクタに指定してString型を得た。ちょっとややこしいところだ。なお、ここでも特に文字列のコード変換は必要無く、ちゃんと日本語の文字列が得られるようだ。 さて、ディスクリプタであるsourceData、resultDataは単にint配列というだけでなく、そこからポインタで別途メモリ領域を確保している。これを解放する作業をDisposeDescとして入れておかないといけない。プログラムはJavaだが背景はCで作ったライブラリであるので、メモリ解放は自動ではないのである。
実際に動かすプログラムは、もちろん、JavaのプログラムでString型のデータとして用意する。スクリプト編集プログラムで作ったものをコピー&ペーストで取り込んでもいいが、文法的な間違いがないのであれば、形式はなんでもかまわないようだ。たとえば、tell〜end tellのブロックで次下げがないとか、大文字小文字を適当ということでも文法的に合っていればいいようだ。ここでの一番の問題は、AppleScriptのプログラムをJavaのプログラム中で書くというチョ〜ややこしいことをしないといけないことだ。たとえば、「open folder "HDD:書類"」というプログラムを文字列として得るには、「String aLine = "open folder \"HDD:書類\"";」となる。ダブルクォーテーションの応酬だ。これがけっこう単純ではなく、試行錯誤することになるとは思うので、頭をやわかくして取りかかると良いだろう。 ところがあるレアケースを見つけた。ファイル名の中にダブルクォーテーションがあり、なおかつ日本語の文字がそれよりも前にあるような文字列に問題があった。たとえばMac OS式のフルパスで言えば、「data:フォルダ:this "is" file」というようなファイルだ。これをAppleScriptの文字列にしてたとえばファイルへの参照を変数に代入するには、AppleScriptだと「set target to file "data:フォルダ:this \"is\" file"」となる。ならば、Javaの文字列として指定するには「String aLine = "set target to file \"data:フォルダ:this \\\"is\\\" file\"";」となる。つまり、Javaの文字列では、\は\\、ダブルクォーテーションは、\"で記載しないいけないのである。 ただ、多くはこれでOKのようなのだが、どうやら\をまじめにバックスラッシュにコンバートする場合があるようで、そこでAppleScriptのエラーが出ることがあるのだ。どうやら、その規則をいろいろ考えていると、\より前に日本語の文字列がある場合ではないかという結論が得られた(もし、違っていれば知らせて下さい)。 文字列中でダブルクォーテーションが登場する場合、AppleScript的には\"だが、ここでは「ASCII Character 34」を使って逃れる方法を取った。つまり、「String aLine = "set target to file (\"data:フォルダ:this " & ASCII Character 34 & \"is\" & ASCII Character 34 & \" file\")";」というわけだ。カッコが増えるなどしているが、いずれにしても、こうすると、生成されたJavaの文字列中に\記号が登場しなくなる。同様に、文字列中の\の文字はASCII Character 72に置き換えるということをおこなうといいだろう。 AppleScriptUtilsには参考のために、java.io.Fileオブジェクトから、Mac OSでのフルパス文字列を取り出すメソッドgetMacOSPathも紹介した。ダブルクォーテーションについては上記の処置をしたが、\記号についてはしていない。このメソッドはあくまで1つの参考として、実際には御利用する方が独自のものに合わせて作成してもらいたい。ちなみに、java.io.Fileのパスにした場合、スラッシュのように%2Fで表示されるようなものあり、その処置も含まれている。
こうしてAppleScriptのプログラムをJavaから実行できるようにした。実行のためのパラメータもJavaの文字列として組み立てればよいし、AppleScriptの実行結果もとりあえず得られる。また、AppleScriptを動かすのだから、OSAXの機能をJavaから利用できることにもつながる。もっとも、OSAXがシステムフォルダに入っていないといけないのではあるが、Tanaka’s OSAXをJavaから使えると思うとより利用範囲も広がると言えるだろう。しかしながら、AppleScriptをJava内で書く難しさはすでに説明した通りだ。また、AppleScriptのプログラミングについてもそれなりの知識は要求されることも言えるだろう。さらに、AppleScriptの処理部分は処理速度がかなり落ちる。残念ながらプログラムのオーバーヘッドはかなり高いということになるだろう。しかしながら、Javaのライブラリに用意されていない機能を稼動させる有力な手法であると言える。 |