みなさんこんにちは。最近HHK(ハッピーハッキングキーボード)を購入し「また一歩野望に近づいた」プラグイン担当のPです。今回から4回にわたり、一太郎Arkのプラグイン作成講座を連載させていただくことになりました。物書きとしては超初心者の私ですが、がんばって書きますのでどうぞよろしくお願いします。なお、このページは印刷されることを前提として作成されていますので、プリントアウトしてじっくり腰を据えてプラグイン作成を楽しんでください。

 第1回は、プラグインについての技術的な解説と、一太郎Ark製品版のCD-ROMに入っている「プラグインサンプル1:スプラッシュウインドウを変更する」の作成方法について説明します。

※実際にプラグインを作るためにはJDK1.2.2が必要ですので、入手しておいてください。


○プラグインって何?
「プラグイン」とは、簡単な操作で一太郎Arkに組み込むことができる「追加機能」のことです。一太郎Arkでは、新機能が入ったプラグインをあとから手軽に追加したり、使わなくなったプラグインを取り外してスリムにすることができます。

 プラグインは「〜.jar」というファイルの中に格納されています。このファイルのことを「プラグインモジュール」、略してモジュールと呼ぶことにします。モジュールの中には1つ以上のプラグインを格納することができます。

 標準的な拡張子はJava2の標準圧縮ファイルである「〜.jar」ですが、実は一太郎Arkにとってプラグインモジュールの拡張子は関係ありません。そのため、「〜.jar_old」なんていう名前に変更しておいても読み込まれてしまいますので注意が必要です。

 一太郎Arkのメニュー「ツール(T)−プラグインの設定(P)」から、「プラグインの設定ダイアログ」を開くことができます。このダイアログでは、プラグインの状態を見たり、プラグインを使用停止・使用開始させることができます。

図1
【図1】プラグインの設定ダイアログ

 「停止」の状態になったプラグインは、次回の一太郎Ark起動時にも「停止」の状態で読み込まれます。ユーザが明示的に「使用開始」すれば、「動作中」の状態になります。

 プラグインの状態が「エラー」になっている場合があります。これは、プラグインの実行中に何らかのエラーが発生し、正しく動いていない可能性があることを示しています。

 また、プラグインを選んで「プロパティ」を実行することにより、各プラグイン固有の説明を確認したり、設定を変更することができます。

図2
【図2】プラグインのプロパティダイアログの情報

図3
【図3】プラグインのプロパティダイアログの設定

 ここで変更した設定内容は、通常ark.propertiesに書き込まれますので、次回起動時にも内容は保存されています。

○どのように組み込まれる?
 一太郎Arkは起動時(スプラッシュウインドウが出るよりも前)に、ある決まった2カ所に置かれているモジュールを順に読み込んで、中に格納されたプラグインを初期化し、組み込んでいきます。

 1カ所は、「ark10.jar」と同じ場所の「plugins」というディレクトリです。標準的なWindows環境の場合は「C:\Program Files\justsystem\ark\plugins」になります。

 この場所に置かれたプラグインを「システムプラグイン」と呼びます。ark10.jarと同じ場所にあるので、一太郎Arkを使うすべてのユーザが共通して使うプラグインを置くのに適しています。一太郎Arkを普通にインストールすると「印刷」「エスケープメニュー」といったプラグインが標準で使えるようになりますが、これらのプラグインはこの場所に置かれています。

 もう1カ所は、「ark.properties」と同じ場所の「plugins」というディレクトリ、つまり「<user.home>/.ark/plugins」です。標準的なWindows環境の場合は「C:\windows\.ark\plugins」になります。

 この場所に置かれたプラグインを「ユーザプラグイン」と呼びます。ark.propertiesと同じ場所にあるので、各ユーザ専用のプラグインを置くのに適しています。

図4
【図4】システムプラグインとユーザプラグイン


 新しいプラグインをインストールするためには、上記2カ所のどちらかにモジュールを置くだけでOKです。また、アンインストールするためには、モジュールを削除すれば完了です。

 あるモジュールを、システムプラグインディレクトリとユーザプラグインディレクトリの両方に入れたらどうなるのでしょう?答えは、ユーザプラグインディレクトリのほうが読み込まれます。

 一太郎Arkは、ユーザプラグイン→システムプラグインの順で読み込んでいきます。それぞれのディレクトリ内では、モジュールが(ファイルシステム上に)書き込まれている順番通りに読み込まれます。もし同じプラグインがいくつもあったときは、先に読み込まれた方が優先で、あとのものは読み込まれません。これは「プラグインID」という内部のIDが重複していないかチェックすることで実現しています。

 正しく読み込まれたものだけがプラグインの設定ダイアログに出てきますので、プラグインIDが重複しているために読み込まれなかったプラグインはダイアログに出てきません。自作のプラグインをテストするときには注意が必要です。

○どんなことができる?
 プラグインは、何ができるのでしょう?答えは「一太郎Ark本体とほとんど同じことができる」です。

 技術的な面からプラグインの組み込まれかたを見てみます。

図5
【図5】クラスローダ階層図


 プラグインは、Java2のクラスローダという仕組みを使って一太郎Ark本体と関連付けられます。図にあるように、本体のクラスローダと各プラグインモジュールのクラスローダには親子関係があります。したがって、プログラム的には、本体とまったく同じ環境で処理を行うことが可能です。本体と同じく、Javaができることはなんでもできますし、ArkのコアであるDOMのAPIを叩くことも可能です。

 しかし、各プラグインのクラスローダ間には親子関係がありません。まったく同じパッケージ名を持つ同じ名前のクラスであっても、別のクラスとして扱われます。したがって、プラグイン間での連携をおこなうとき、単純に代入したりキャストしたりできませんので注意が必要です。逆に、同じクラス名で内容が異なっているようクラスがそれぞれのプラグインモジュールに入っていても、別クラスとして扱われるため、問題なく動作します。

 「処理を行うタイミング」については、一太郎Ark本体に比べて制限があります。

 プラグインに処理が移るのは「初期化・破棄」「動作開始・停止」「アクション実行(メニューを選択したときなどに実行される)」といった、あらかじめ決められたタイミングです。残念ながら、たとえばユーザのマウス操作のタイミングをプラグインが直接とって処理を行うことはできません。

タイミング処理方法
プラグイン初期化ArkPlugin#init()に記述
プラグイン動作開始ArkPlugin#start()に記述
プラグイン動作停止ArkPlugin#stop()に記述
プラグイン破棄ArkPlugin#destroy()に記述
アクション実行
 ・メニュー選択
 ・ショートカットキー
 ・そのほか
javax.swing.Actionとして記述し、UIPluginインターフェースを使って一太郎Ark本体に登録
メニュー項目追加
 ・ツール(T)メニュー内に出現
UIPlugin.MenuItemクラスのオブジェクト構造で表現し、UIPluginインターフェースを使って一太郎Ark本体に登録
ファイル入出力
 ・ファイルダイアログに出現
 ・リンクへのジャンプで利用
FileTypePluginインターフェースを実装し、一太郎Ark本体に登録
キーカスタマイズ
 ・単純な1ストローク
 ・階層化された複数ストローク
 ・差し替え/追加
定義ファイル(XML形式)を用意し、一太郎Ark本体に登録
リソース差し替え
 ・イメージファイル
 ・文字列リソース
 ・動作定義
リソースファイル(Property形式)を用意し、一太郎Ark本体に登録
【図6】プラグインが処理を実行できるタイミング

 プログラム以外のプラグイン、たとえばスプラッシュウインドウやツールバーのアイコンデータといった「リソース」を入れ替えたり、メニューに表示する文字列を中国語にするようなものについては、専用のAPIが用意されていますので、比較的手軽に作成することが可能です。プラグインサンプル1では、このAPIを利用しています。

 今回は詳しく説明しませんが、Java2のセキュリティ機能を使うと、ユーザがモジュールごとにセキュリティポリシーを設定することができます。これにより、プラグインが操作可能なJavaのAPIに制限をかけることが可能です。


○準備
 なにはともあれ、まずはプラグインを作成してみましょう。今回は、一太郎Ark本体のリソースを差し替えるプラグイン、「プラグインサンプル1:スプラッシュウインドウを変更する」を作ります。

 一太郎Ark製品版CD-ROMの「\CONTRIB\SAMPLE」に、プラグインのサンプルソースが入っています。「PLUGIN1.ZIP」をどこかテンポラリなディレクトリにコピーして展開してください。JDKに付属するjar.exeを使うなら「jar xf PLUGIN1.ZIP」です。

○compile.bat
 はじめに「compile.bat」を修正します。

001 rem set CLASSPATH=.;ark10.jar
002 del *.class
003 javac %1 %2 %3 %4 %5 %6 %7 %8 %9 *.java
【図7】compile.bat

 プラグインが実行されるときはark10.jarの中に入っているすべてのpublicなクラスにアクセスできますが、そのようなプラグインプログラムをコンパイルするためには、コンパイル時にark10.jarが見えている必要があります。

 compile.batの1行目にある「rem set CLASSPATH=.;ark10.jar」のremをとり、自分の環境に合わせて書き換えてください。CLASSPATHに、これからコンパイルするプラグインのソースファイルが置かれたディレクトリ、Ark本体のJarファイルの順に記述します

 例えば「set CLASSPATH=.;C:\Progra~1\justsystem\ark\ark10.jar」などのようにします。

○manifest.mf
 つぎに「manifest.mf」です。これはいまのところ修正は必要ありません。
001 Manifest-Version: 1.0
002
003 Name: PluginSample1.class
004 Ark-Plugin: true
005 Plugin-Version: 1.0
006
007 Name: Resource
008 Legal-Copyright: version.legal_copyright
009 File-Version: version.file_version
010 Product-Name: version.product_name
011 File-Description: version.file_description
012 Version-Resource: true
013 Company-Name: version.company_name
014 Product-Version: version.product_version
【図8】manifest.mf

 1行目はmanifestファイルのおまじないです。
 2行目には改行を入れてください。
 3行目はプラグイン本体のクラス名です。
 4行目は、3行目に書いたクラスがArkのプラグインであることを表しています。
 5行目は、このプラグインが想定している、Ark本体側のプラグインAPIバージョンです。
 7行目以降は、Justsystem製のプラグインには必ず書かれていますが、なくても動作に影響はありませんので、今回は説明を省略します。

 1つのモジュールに複数のプラグインを格納したい場合には、3行目〜5行目の内容をプラグインの数だけ記述してください。そのときは、各プラグインの定義のあいだには改行をいれて区切る必要があります。

○resconv.bat
 「resconv.bat」は、リソースをコンパイル(コンバート)するためのバッチファイルです。
001 native2ascii -encoding MS932 <Resource.properties.sjis >Resource_ja.properties
【図9】resconv.bat

 以下で説明するリソースファイル「Resource.properties.sjis」から「Resource_ja.properties」を作るために使います。リソースの変更後は、必ず実行してください。

○Resource.properties

○Resource.properties.sjis

○Resource_ja.properties
 「Resource.properties」には、プラグインのプロパティダイアログで使われる、プラグインの説明が入っています。

001 plugin_sample1.name       =Plugin Sample1
002 plugin_sample1.class      =Sample
003 plugin_sample1.version    =1.0
004 plugin_sample1.vendor     =JUSTSYSTEM Corp.
005 plugin_sample1.description=Replace the splash image.
006
007 version.company_name      =JUSTSYSTEM Corp.
008 version.file_description  =Plugin Sample1
009 version.file_version      =1.0
010 version.legal_copyright   =Copyright (C) 1999 JUSTSYSTEM Corp.
011 version.product_name      =Ichitaro Ark Plugin
012 version.product_version   =1.0
【図10】Resource.properties

 「Resource.properties」は英語用、「Resource_ja.properties」は日本語用の内容を書きます。「Resource_ja.properties」を直接書くのは難しいため、「Resource.properties.sjis」を書いておいて「resconv.bat」で変換します。

 内容は「<キー>=<値>」という形式で記述します。キーの右側にある空白は無視されますが、値に含まれる空白は無視されませんので、ファイル名などを記述するときは右側に空白が入らないよう注意してください。

 キーの「plugin_sample1」という部分はこのプラグインの「プラグインID」で、プラグインのプログラム本体(PluginSample1.java)のなかで定義したものです。

 「name」はプラグイン名、「class」は分類、「version」はこのプラグインのバージョン番号、「vendor」は作成者、「description」は説明を書きます。

 7行目以降の定義は、Justsystem製のプラグインには必ず書かれていますが、なくても動作に影響はありませんので、今回は説明を省略します。

○PluginSample1.java
 次に「PluginSample1.java」ですが、今回はスペースの都合で詳しく説明することができません。
001 /*
002 * PluginSample1 1.00 1999/09/22
003 *
004 * Copyright 1998-1999 (C) Justsystem Corporation
005 */
006
007 import jp.co.justsystem.ark.plugin.ArkPlugin;
008 import jp.co.justsystem.ark.plugin.ArkPluginContext;
009 import jp.co.justsystem.ark.plugin.PluginResourceFactory;
010 import jp.co.justsystem.ark.plugin.ResourcePlugin;
011 012 013 /** 014 * 【プラグインサンプル1】 015 * 016 * スプラッシュウインドウなどのリソースを差し替える。 017 * 018 * @version 1.00 1999/09/22 019 */ 020 public class PluginSample1 extends ArkPlugin { 021 022  /** 023   * このプラグインのID 024   */ 025   private static final String ID = "plugin_sample1"; 026 027  /** 028   * このプラグインのリソース 029   */ 030   private static final String RESOURCE_BASE = "Resource"; 031   private static final String RESOURCE_MAIN = "MainRes"; 032 033  /** 034   * リソース 035   */ 036   ResourcePlugin    baseResource; 037   ResourcePlugin    mainResource; …
(後略)
【図11】PluginSample1.java(一部)

 25行目にプラグインIDが定義されていますので、このサンプルを元に別のプラグインを作るときはここを変えてください。プラグインIDが重複すると読み込まれず、プラグインの設定ダイアログにも一覧表示されません。

 また、IDを変えたら、リソースファイル内のリソースキー(左辺)も修正してください。

○MainRes.properties
 今回のみそは「MainRes.properties」です。上のPluginSample1.javaの処理によって、このファイルに記述された内容が本体のリソース定義を上書きします。

001 #
002 # splash window
003 #
004 
005 img_splash_window=splash_window_tp.gif
006 
007 #
008 # frame icon
009 #
010 
011 #img_frame_icon=
012 
013 #
014 # menubar
015 #
016 
017 #mb_File.icn=
018 #mb_FileNew.icn=
019 #mb_FileOpen.icn=
020 #mb_FileClose.icn=
…
(中略)
…
271 #html_generator =Ichitaro Ark(Showta/1.0)
272 #http_agent     =Mozilla/Forever(Showta/1.0; Java2; Justsystem Corp.)
【図12】MainRes.properties(一部)

 5行目の記述により、プラグイン作成者が用意したGIFファイルがスプラッシュウインドウとして使われます。

 その下はすべてコメントアウトされていますが、「#」をとって画像ファイル名を記述すれば、それぞれの場所で使われる画像ファイルを差し替えることができます。

 画像ファイルにはGIFがJPEGを使います。ツールバーのアイコンをすべてアニメGIFに差し替えてしまうことも可能です。(とても重くなりますが…)

 270行目付近にあるのは文字列リソースです。User Agent名や、GENERATOR名として使う文字列を差し替えることができます。

 もし、UIが日本語のときと英語のときで別の設定を使いたければ、「MainRes_ja.properties」を別に用意してください。その中で日本語を使う場合は、いったん「MainRes.properties.sjis」などを作ってから、「resconv.bat」を修正して変換するようにします。

 画像ファイルは、まずこのプラグインをロードしたクラスローダで読み込みを試みます。読み込めなければ、一太郎Ark本体をロードしたクラスローダで読み込みを試みます。それでも読み込めない場合はエラーとなり、場合によっては一太郎Arkが内部エラーダイアログを出す場合もあります。

 また、GIFファイルによってはJava2が処理できない形式のものがあります。一般的なブラウザでは表示できるのに、一太郎Arkの本文中に貼り付けると壊れ画像マークになってしまうGIFファイルは、Java2が対応していない形式になっている可能性が高いでしょう。花子フォトレタッチなどの画像処理アプリケーションで保存し直すと、表示できるようになるかもしれません。

○makejar.bat
 修正が終わったらプラグインモジュールを作ります。「resconv.bat」でリソースを変換し、「compile.bat」でプログラムをコンパイルしたら、「makejar.bat」を実行します。
001 jar cvfm PluginSample1.jar manifest.mf *.class
002 jar uvf PluginSample1.jar *.properties
003 jar uvf PluginSample1.jar *.gif
【図14】makejar.bat

 このバッチファイルでは「〜.class」「〜.properties」「〜.gif」「manifest.mf」を圧縮して「PluginSample1.jar」を作成します。もし「〜.jpeg」などを使うときは修正してください。

○プラグインのインストール
 できあがった「PluginSample1.jar」を、システムプラグインのディレクトリかユーザプラグインのディレクトリにコピーして、一太郎Arkを起動してみます。スプラッシュウインドウがTechnology Preview版のものに差し変われば成功です。

図14
【図14】変更後のスプラッシュウインドウ


 次回は、プラグインサンプル1/プラグインサンプル2を例に、プラグインの動作についてもう少し深く解説していく予定です。