- 追加された行はこの色です。
- 削除された行はこの色です。
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
さて、Eclipse/プラグイン開発のTIPS集/org.eclipse.core.runtime.IAdaptable の続きです。
さっきのように、ContactクラスがPlatformObjectを拡張している場合は、
org.eclipse.core.runtime.IAdaptable インタフェース
org.eclipse.core.runtime.PlatformObject オブジェクト
org.eclipse.core.runtime.IAdapterFactory ファクトリ
を使ってViewに表示ができました。今度はModelオブジェクトがIAdaptableやPlatformObjectを実装していない場合はどうするか、です。。通常このような場合が多いですよね。モデルをEclipse依存にしたくないですしね。
***モデル [#u660bd10]
モデルは先のクラス構成で、ContactがPlatformObjectを拡張していない、一般的なクラスであると仮定します。
#ref(model.png)
***org.eclipse.core.runtime.adapters拡張ポイント [#w41962c2]
こたえはやはりorg.eclipse.core.runtime.adapters拡張ポイントみたいです。
<extension point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="org.eclipsercp.hyperbola.model.Contact"
class="org.eclipsercp.hyperbola.model.HyperbolaAdapterFactory">
<adapter type="org.eclipse.ui.model.IWorkbenchAdapter"/>
</factory>
</extension>
このように定義しておくと、Contactのインスタンスelementに対して、
Platform.getAdapterManager().loadAdapter
(element, IWorkbenchAdapter.class.getName());
↑adaptableType ↑<adapter type="org.eclipse.ui.model.IWorkbenchAdapter"/>
というメソッドがよばれたときに、
IAdapterFactory adapterFactory = new HyperbolaAdapterFactory();
Platform.getAdapterManager().registerAdapters(adapterFactory,Contact.class);
が自動的に行われます。でメソッドの返り値が
IAdapterFactory#getAdapter(element, IWorkbenchAdapter.class);
になります。
つまりContactがPlatformObjectではないにもかかわらず、IAdapterFactoryを用いて
IWorkbenchAdapter adapter=(IWorkbenchAdapter) Contact.getAdapter(IWorkbenchAdapter.class);
の様なことができるわけですね。これと
IAdapterFactory adapterFactory = new HyperbolaAdapterFactory();
Platform.getAdapterManager().registerAdapters(adapterFactory,Contact.class);
IWorkbenchAdapter adapter = (IWorkbenchAdapter)adapterFactory.getAdapter(IWorkbenchAdapter.class);は等価でしたね。
IWorkbenchAdapter adapter = (IWorkbenchAdapter)adapterFactory.getAdapter(IWorkbenchAdapter.class);
は等価でしたね。
***ちょっとまとめ [#e297a645]
まとめると
-あるモデルがある
-あるモデルに対してgetAdapterして別のオブジェクトを取得したい
-plugin.xmlに
<extension point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="あるモデルのクラス名"
class="IAdapterFactoryの実装クラス名">
<adapter type="別のオブジェクトのクラス名"/>
</factory>
</extension>
と定義しておく
-IAdapterFactoryの実装クラスで
public Object getAdapter(Object adaptableObject, Class adapterType);
public Class[] getAdapterList();
をoverrideする
-public Object getAdapter(Object adaptableObject, Class adapterType);は
adaptableObjectはあるモデルのクラス名
adapterTypeは別のオブジェクトのクラス名
だった場合は「別のオブジェクトのクラス」を返す、という処理を書く
-public Class[] getAdapterList();は「別のオブジェクトのクラス」を返すようにしておく
となるわけです。つまり、ある一般的なクラスに対して、IAdaptableでないにも関わらず動的にgetAdapterが呼べる仕組みということですね。まだ、あたまがまとまってませんが、ものすごい事のような気がしてきました。
***さて、つづき [#ldaa64ed]
さて、Viewerの続きです。ContactはもはやPlatformObjectではないため当然IAdaptableでもありません。これだけだとBaseWorkbenchContentProviderの
protected IWorkbenchAdapter getAdapter(Object element) {
if (!(element instanceof IAdaptable)) {
return null;
}
return (IWorkbenchAdapter) ((IAdaptable) element)
.getAdapter(IWorkbenchAdapter.class);
}
は当然nullになってしまうので、拡張クラスを作ってOverrideします。
public class HogeContentProvider extends BaseWorkbenchContentProvider {
protected IWorkbenchAdapter getAdapter(Object element) {
↑この引数elementはモデル要素: Contact,ContactEntry,ContactGroupでした
IWorkbenchAdapter adapter = null;
// モデルが、IAdaptableならばそのまま使う
if (element instanceof IAdaptable) {
adapter = getAdapter(element);
}
// モデルが、一般的なオブジェクトならば、さっきの動的ローディングをつかう。
if (element != null && adapter == null) {
adapter = (IWorkbenchAdapter) Platform.getAdapterManager()
.loadAdapter(element, IWorkbenchAdapter.class.getName());
}
// この返り値adapterは、org.eclipsercp.hyperbola.model.HyperbolaAdapterFactory
// のgetAdapter(element,IWorkbenchAdapter.class);になるんでしたね。
return adapter;
}
}
Viewerにはこのコンテンツプロバイダをセットすることで、先と同じ結果が得られます。
当然、Viewでorg.eclipsercp.hyperbola.model.HyperbolaAdapterFactoryをnewする必要もないし、当然register,unregisterも必要ないです。モデルオブジェクトもPlatformObjectを拡張している必要もありません。
、、、、ここまでやって、コンテンツプロバイダやラベルプロバイダはIWorkbenchAdapterを使わない一般的なやり方の方がいいような気がしますね。よくわかってないだけかも知れないけど。。
あ、当然ラベルプロバイダも書き換える必要があります。この書きかえ方が...またようわからん。。WorkbenchLabelProvider#getAdapterはfinalだし。。。。じぶんで書くしかないのかなぁ。。
***関連リンク [#c3b6a9f0]
#ls2(Eclipse/プラグイン開発のTIPS集/org.eclipse.core.runtime.IAdaptable)
----
この記事は
#vote(おもしろかった[1],そうでもない[0])
#vote(おもしろかった[6],そうでもない[0])
-ここに書いた情報は、まだあってるかあやしいですよ。。ごちゅうい。。 -- [[きの]] &new{2006-03-27 16:47:16 (月)};
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}