高度なカスタマイズ > サービスおよびインフラストラクチャのカスタマイズ > システム設定コレクターのプラグイン > システム設定コレクターのプラグインの作成 > 手順 - カスタムプラグインの作成 > プラグインの設計
  
プラグインの設計
システム設定コレクターで使用するプラグインを設計するときには、以下の事項を考慮する必要があります。
1. プラグインのクラス名に "Plugin" が含まれている必要はありませんが、含まれていると便利です。クラス名のサフィックスとして "Plugin" を含めることにより、その目的を簡単に識別できます。プラグインのソースファイル名は、<クラス名>Plugin.java という形式である必要があります。<クラス名> もプラグインの目的を示す名前であると便利です。たとえば、PTC 提供の SiteXConfPlugin は、<Windchill>/site.xconf ファイルを収集します。
2. プラグイン開発者は、プラグインで妥当な Java パッケージ構造を維持する必要があります。一般的に、PTC 提供のプラグインでは、その目的と PluginType に関連するパッケージ構造が維持されています (PluginType クラスの詳細については、ソリューションを参照してください)。PTC のプラグインの多くは、com.ptc.customersupport.mbeans.plugins パッケージに含まれています。カスタムプラグインをこのパッケージに含めると、カスタムプラグインを簡単にデバッグできるだけではなく、カスタムプラグインの展開後の場所を識別することもできます。これは厳守する必要のある要件ではなく、パッケージ構造は開発者が設定できます。
3. すべてのプラグインが PluginMBean インタフェースを実装する必要があります。PluginMBean インタフェースクラスを実装することにより、プラグインは JMX コンソールから実行できる属性とオペレーションを公開できます。さらに、PluginMBean クラスにより、すべてのプラグインが順守する必要のある、コレクションフレームワークにとってはきわめて重要な API 契約が確実に履行されます (ソリューションの CollectorMBean および Collector クラスの説明を参照してください)。
4. すべてのプラグインが AbstractPlugin クラスを拡張する必要があります。AbstractPlugin は、PluginMBean インタフェースを実装する際の複雑さのほとんどをラップします。これにより、プラグインの作成において共通して使用される多くのメソッドのデフォルト実装が提供されます。当然、メソッドのデフォルトの実装は、各種機能を提供するためにオーバーライドできます。
以下に例を示します。
public class CustomPlugin extends AbstractPlugin
implements PluginMBean {}
この例は、PluginMBean インタフェースを実装し、AbstractPlugin クラスを拡張する CustomPlugin クラスを示しています。この例ではインタフェースの必須メソッド、つまり collect(…) メソッドが実装されておらず、この単純なクラスはコンパイルされないことに注意してください。Windchill に付属するサンプルプラグイン実装全体を確認するには、サンプルコードを参照してください。
5. すべてのプラグインオブジェクトコンストラクタがスーパークラスのメソッド呼び出しを行う必要があります。これは、すべてのプラグインが SelfAwareMBean として初期化される必要があるからです (SelfAwareMBean の詳細については、ソリューションを参照してください)。すべてのプラグインがプラグイン階層を通じて AbstractPlugin クラスを拡張する必要があるため、AbstractPlugin クラスがプラグインを SelfAwareMBean として登録するために適切なメソッド呼び出しを行います。したがって、プラグイン開発者は、実際のプラグインの MBean の登録については考慮する必要はなく、プラグインが構築中に super() 演算子を呼び出すことと、プラグインの継承によって最終的には AbstractPlugin.java が拡張されることが確実に行われるようにする必要があるだけです。
例:
public CustomPlugin() throws NotCompliantMBeanException {
super(null);
// TODO Other initialization of this particular plugin
}
public CustomPlugin(final String displayName,
final String beanName, final String description,
final String pluginVersion)
throws NotCompliantMBeanException {
super(null, displayName, beanName, description, pluginVersion);
// TODO Other initialization of this particular plugin
}
これらのコンストラクタは、AbstractPlugin のコンストラクタを一致させ、super 演算子を通じて AbstractPlugin の呼び出しを行うために実装されます。これにより、CustomPlugin が SelfAwarePlugin として登録されます。
コンストラクタによる super の呼び出しでは、クラスオブジェクトが使用されます。具象クラスが判明している場合はそれを指定でき、判明していない場合は null を使用できます。Java は、イントロスペクションを使用してクラス名を決定します。たとえば、CustomPlugin は PluginMBean を実装するので、super の呼び出しは次のように設定することもできます。
super(PluginMBean.class);
より簡潔なコンストラクタを設計するには、継承に依存するオプションを調べてみてください。
6. PluginMBean インタフェースを実装し、AbstractPlugin を拡張するので、プラグインは 2 つの collect(…) メソッドを実装する必要があります。これらのメソッドは、本質的には、Collector クラスとコレクションフレームワークに対して作業を編成し、引き渡します。
例:
@Override
public Map<String, Object> collect(final long callNumber,
final long maxAgeInDays,final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
@Override
public Map<String, Object> collect(String topicIdentifier,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
ここに示されている collect(…) メソッドの実装は、特別な処理は行わず、単に明確に説明することを目的としています。これらは、プラグインコレクションが実行する必要のある作業を行い、必要とされる正しい Map<文字列、オブジェクト> 値を返します。
抽象クラスを通じて依存できる collect(…) メソッドのデフォルト実装には多数あります。多くの場合、プラグインは、collect(…) メソッドのパラメータを collectData(…) メソッドに渡すことによって AbstractPlugin.java の collectData(…) メソッドを呼び出す必要があるだけです。collectData(…) メソッドは、collect(…) メソッドで直接コレクションフレームワークを呼び出す際の複雑さをラップします。collect(…) メソッドは、PluginMBean インタフェース API に必要不可欠です。非常に高度なプラグインでは collectData(…) のデフォルトの動作だけでは十分ではないので、開発者が必要に応じて collect(…) メソッドを実装するためには、その柔軟性が必要であるからです。さらに、抽象クラスは、その他のメソッドにも依存できます。これらのメソッドの多くが collectXYZ(…) という形式であり、特定のプラグインの collect(…) メソッドの実装によって呼び出すことができます。これらの collect (…) メソッドは、プラグインが行う作業の抽象タイプの特定の収集実装をラップします。たとえば、GatherFolderPlugin.java クラスには、収集対象の特定のフォルダを (プラグインの初期化で正しく設定されていれば) コレクションフレームワークに渡すように実装されている collect(…) メソッドがあります。
collect(…) メソッドは Map<文字列、オブジェクト> を返す必要があります。この戻り Map 値は、プラグインが実行されたサーバーとプラグインのステータスを確認するためにプラグインフレームワークによって使用されます。この戻り値は、実際には Map; Map<String, Map<文字列、文字列>> 内の Map です。外側の Map にはサーバー情報が含まれていますが、内側の Map にはそのサーバーのプラグイン実行ステータスが含まれています。
カスタマイザが collect(…) メソッドのデフォルト実装に依存せず、抽象クラスの親 collectData(…) またはその他の collect(…) メソッドのどちらかを使用する場合は、戻り Map 値が正しく構築されており、それに有効な値が含まれていることを慎重に確認する必要があります。
collect(…) のデフォルト実装の使用と、メソッドの戻り Map<文字列、オブジェクト> 値の詳細については、カスタマイズポイントを参照してください。
7. 最後に、プラグインが行う必要のある実際の作業と、それを行うための最適な方法を検討します。これを行うには、さまざまなクラスを連動して処理を行うように組み合わせたり、すべての処理を 1 つのクラスにラップしたりします。
さらに、ソリューションで説明したようにプラグイン実装を簡素化するために使用できるユーティリティメソッドと抽象クラスが多数あります。プラグインは、プラグインの作成目的であるタスクに応じて、非常に複雑に設計することも、非常にシンプルに設計することもできます。
8. 要するに、適切に設計されているプラグインは、少なくとも以下の特性を持っている必要があります。
PluginMBean インタフェースを実装する。
直接または継承を通じて AbstractPlugin クラスを拡張する。
2 つのコンストラクタが super() 演算子を使用して最終的には AbstractPlugin を呼び出す。
2 つの collect(…) メソッド (親 collect(…) の実装に依存しない場合) を使用する。