#topicpath
----
#contents
**そもそも拡張ポイントって [#oc4dc566]
Eclipseのプラグイン作成をするときは、すでに与えられた拡張ポイントの定義に従ってplugin.xmlに内容を記述していきます。そうしておくと、Eclipse側がその内容に従ってクラスをロードします。つまりplugin.xmlに内容を記述(= Eclipseにコンポーネントを登録)しておくとEclipseが必要に応じてローディングしてくれる、というObserverパタンのようなフレームワークになってるわけです。

ビューを作るときはorg.eclipse.ui.viewsを使いながら、さらにorg.eclipse.ui.IViewPartを実装するという重複感になにか違和感を持っていたんですが、何となくすっきりしました。Eclipse側ではorg.eclipse.ui.viewsという箇所に登録したモノは、org.eclipse.ui.IViewPartでクラスをインスタンス化する、というルールになっているわけですね。

さて、Eclipseには既存の箇所(拡張ポイント)に登録する側ではなく、登録される側の立場になることもできます。つまり新しい拡張ポイントを定義して、その定義に従って決まった処理をさせるようなことができるわけです。たとえばLog4jの設定ファイルを指定する拡張ポイントを定義しておいて、ユーザがその拡張ポイントにファイル名を登録すると、その設定ファイルでLog4jの初期化を行ってくれる、なんて仕組みができます。たとえば、こんな感じです。

 <extension
   point="nu.mine.kino.log4j.log4jConfig">
   <log4jConfig filename="lib/log4j.xml"/>
 </extension>

と書いておくと
 DOMConfigurator.configure(new File([Plugin_Directory],"lib/log4j.xml"));
を勝手にやってくれる、なんて事をすることができます。

これはorg.eclipse.ui.viewsに内容をを書いておくとIViewPart型でクラスをロードして描画してくれる、と同じ仕組みですね。

**実際にやってみる [#z1726fe9]
さて、実際に自分で拡張ポイントを作成するには
-plugin.xmlのextension-point タグで拡張ポイントのIDやスキーマファイル名などを決める
-スキーマファイルでタグのスキーマを定義する
-登録された情報を取得して、クラスをロードするなどの処理を記述する
-ユーザに使ってもらう
という手順になります。

まず拡張ポイントを新規に作るには、extension-pointタグを使います。

***plugin.xml(抜粋) [#ffb92c67]
 <plugin
   id="nu.mine.kino.log4j"
   .........
   </requires>
   ↓ 拡張ポイントの作成
   <extension-point id="log4jConfig" name="Log4j" 
     schema="schema/log4jConfig.exsd"/>
 
   ↓ 作った拡張ポイントに登録
   <extension
         point="nu.mine.kino.log4j.log4jConfig">
      <log4jConfig filename="lib/log4j.xml"/>
   </extension>
 </plugin>

実際に定義している箇所は
 <extension-point id="log4jConfig" name="Log4j" 
     schema="schema/log4jConfig.exsd"/>
ですが、これで定義した拡張ポイントIDはnu.mine.kino.log4j.log4jConfigで、スキーマ(記述方法)はschema/log4jConfig.exsdですよ、という意味になります。詳細は省きますがschema/log4jConfig.exsdには、log4jConfigタグにはfilename属性がありますよ、といった内容が記述してあります。

拡張ポイントの定義は以上です。次に登録された情報(ここではfilename属性の値)を元に稼働する処理部分を書いていきます。処理を書く場所は、プラグインクラスの
 public void start(BundleContext context);
にしました((ここが適切かどうかはよくわからんです))。

***実際の処理を記述する [#ib348ef8]
実際の処理は以下のようにしてみました。
 public void start(BundleContext context) throws Exception {
   super.start(context);
   // プラグインのレジストリを取得
   IPluginRegistry registry = Platform.getPluginRegistry();
   // レジストリから拡張ポイントをIDを使って取得
   IExtensionPoint point = registry
           .getExtensionPoint("nu.mine.kino.log4j.log4jConfig");
   // 拡張ポイントをつかって、拡張クラス(の配列)を取得
   IExtension[] extensions = point.getExtensions();
   // ↑ これはこのプラグインの記述だけでなく、
   // 他のプラグインが書いてくれた nu.mine.kino.log4j.log4jConfig
   // 拡張ポイントも含まれている。
   
   for (int i = 0; i < extensions.length; i++) {
       // ↓このなかでそれぞれのクラスローダを取得し、それぞれのクラスローダ上で
       // Log4jを初期化している。
       loadExtension(extensions[i]);
   }
 }
長々とやって、ようやく IExtension[] extensions = point.getExtensions(); とIExtensionの配列が取得できました。IExtensionはいろいろなところのplugin.xmlが書いてくれた、nu.mine.kino.log4j.log4jConfig 拡張ポイントの値にアクセスするためのメソッドがあります。続きのloadExtension(extensions[i])はその一つ一つの
   <extension point="nu.mine.kino.log4j.log4jConfig">
に対する処理を記述しました。

***extension pointタグごとの処理 [#de0c253a]
前述通りあとは
 <extension point="nu.mine.kino.log4j.log4jConfig">
  <log4jConfig filename="lib/log4j.xml"/>
 </extension>
に対する処理を書けば終わりです。



----







***TIPS [#yec4b91d]
たとえば拡張ポイントへ登録を
 <extension
       point="kino.plugin.samples.dictionary">
    <dictionary name="stock.dat"/>
    <dictionary name="stock2.dat"/>
 </extension>
 <extension
       point="kino.plugin.samples.dictionary">
    <dictionary name="stock3.dat"/>
 </extension>
と書くことができるとき、

 IPluginRegistry registry = Platform.getPluginRegistry();
 IExtensionPoint point = registry.getExtensionPoint("kino.plugin.samples.dictionary");
 IExtension[] extensions = point.getExtensions();
 <-ここですでに他のプラグインの分も勘定されてる。
 
 // このforは extensionタグ の繰り返し
 for (int i = 0; i < extensions.length; i++) {
     IConfigurationElement[] elements = extensions[i]
             .getConfigurationElements();
 
     // このforは dictionary の繰り返し
     for (int j = 0; j < elements.length; j++) {
         System.out.println(elements[j].getAttribute("name"));
     }
 }


----
この記事は
#vote(おもしろかった[11],そうでもない[0])
#vote(おもしろかった[12],そうでもない[0])
-このやり方でやれば、各プラグインのクラスローダでDOMConfiguratorが呼ばれると思ったんだけど、nu.mine.kino.log4j.log4jConfigのローダに委譲しちゃうんですねえ(たぶん)。ダメじゃんこれじゃ -- [[きの]] &new{2005-02-23 (水) 14:31:25};
-参考~ http://www.atmarkit.co.jp/fjava/rensai2/eclipse02_10/eclipse10.html -- [[きの]] &new{2006-03-08 16:41:28 (水)};

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS