intra-mart Accel Platform IM-共通マスタ 拡張プログラミングガイド 第2版 2015-08-01

3. APIの拡張

3.1. APIの概観

IM-共通マスタのAPIの構造について説明します。
マネージャの内部は実際にデータアクセスを行う実装とは分離されており、Plug-inの仕組みを利用してデータベースへのアクセサを組み込むことでマネージャとしての機能を提供しています。
これにより独自にPlug-inとして実装クラスを作り、インタフェースを変更せずに全く異なる実装を動作させることも出来ます。

3.1.1. マネージャクラスと実行クラスのインタフェース

マネージャは全てAbstractManagerを継承した形になっています。
Manager自身は直接データベースへアクセスすることはありません。
データベースへ直接アクセスを行う実体のクラスはインタフェースを介して別のパッケージへ分離されています。
会社組織マネージャでのクラス構造を【図:会社組織マネージャの例】に示します。
図のように各マネージャに対して、実装クラスのインタフェース5種(Writer, Reader, Listener, Exporter, Importer)が必ず定義されています。
../../_images/ex_company_department_manager.png

【図:会社組織マネージャの例】

  • 共通/抽象クラス
  • AbstractManager
    各マネージャの共通処理を管理する抽象クラスです。
  • 会社APIパッケージ
  • CompanyManager
    会社組織マネージャの実装クラスです。
  • CompanyWriter
    会社組織エンティティへの書き込みをサポートするインタフェース。
    実装クラスが複数定義されていた場合は最も優先度の高いものを一つだけ採用します。
  • CompanyReader
    会社組織エンティティからの読み出しをサポートするインタフェース。
    実装クラスが複数定義されていた場合は最も優先度の高いものを一つだけ採用します。
  • CompanyListener
    会社組織マネージャにおけるリスナのインタフェース。
    Plug-in として定義されている実装クラス全てを使用します。
  • CompanyExporter
    会社組織エンティティのエクスポート処理をサポートするインタフェース。
    実装クラスが複数定義されていた場合は最も優先度の高いものを一つだけ採用します。
  • CompanyImporter
    会社組織エンティティのインポート処理をサポートするインタフェース。
    実装クラスが複数定義されていた場合は最も優先度の高いものを一つだけ採用します。

各インタフェースの詳細についてはIM-共通マスタのAPI リストを参照してください。

3.1.2. モデルクラスのインタフェース

マネージャのメソッドを実行した際に返されるモデルオブジェクトは数種類のインタフェースを組み合わせて実装されています。
モデルとして使用されているインタフェース群の構成を【図:モデルクラスのインタフェース群】に示します。
../../_images/modelclass_interface.png

【図:モデルクラスのインタフェース群】

各インタフェースの概要を以下に説明します。詳細についてはAPI リストを参照してください。

  • ICategoryType
    分類(ユーザ分類、組織分類、パブリックグループ分類)の付属するモデルであることを表します。
  • IRecorder
    更新日、更新ユーザを記録するモデルです。
  • ISortable
    ソートキーを保持しており、任意の順序を設定できるモデルであることを表します。
  • IRank
    ランクによる順位付けが可能なモデルであることを表します。
  • IWithLocale
    国際化情報を取り扱えるモデルであることを表します。
  • IDisable
    削除フラグを保持しており、論理削除を行うことが可能なモデルであることを表します。
  • TreeNode
    階層型構造を保持できるモデルであることを表します。
  • ListNode
    一覧化されたモデルのビューであることを表します。
  • ITerm
    期間化可能なモデルであることを表します。

3.2. API(マネージャ)へのリスナーの追加

ここではリスナーの追加方法について説明します。
マネージャがデータベースの情報に何らかの変更をしようとするタイミングで、任意の処理を追加することが出来ます。これをリスナーと呼びます。
各アプリケーションからIM-共通マスタへのデータの変更は各マネージャを通して行う必要がありますが、リスナーを追加しておけばIM-共通マスタの情報の更新と連動して独自のデータも更新したり、追加のチェック処理を実装したりすることが出来ます。
リスナーは各マネージャに対応するリスナーインタフェースを使用して実装します。
リスナーインタフェースに定義されているメソッドは大きく追加・変更・削除のものがあり、それぞれマネージャがデータベースを操作するタイミングで呼び出されます。
リスナーの動作の概要を 【図:リスナーの動作概要】 に示します。
../../_images/listener_actions_summary.png

【図:リスナーの動作概要】

用意されているリスナーインタフェースについては「マネージャの拡張に関する情報 」に一覧を掲載していますが、各メソッドがどのようなタイミングで呼び出されるかについてはIM-共通マスタのAPIリスト、及び「IM-共通マスタ Listener定義一覧」に詳細に記載していますので、そちらを参照して下さい。

リスナーの実装の為に必要な作業は次の二つです。

  • リスナークラスの実装
  • plugin.xml の作成

以降、順に説明します。

3.2.1. リスナークラスの実装

リスナーインタフェースを実装したリスナークラスを実装します。

リスナーの処理はJavaで実装します。マネージャによってそれぞれリスナーのインタフェースが定義されていますので、行いたい処理によって対応するインタフェースを実装する必要があります。

下記の【リスト:会社組織マネージャのリスナーの例】では会社組織マネージャのリスナーの例です。会社組織の役職が登録される際に別の処理を実装するために、CompanyListenerインタフェースを実装し、createCompanyPost メソッドをオーバーライドして処理を記述しています。

public class SynchronousCompanyListener implements CompanyListener {
/**
* 役職を作成した際に呼び出されるListener メソッド
*/
@Override
public void createCompanyPost(IAppCmnInfo info, List<CompanyPost> list)
   throws BizApiException {
try{
   ICompanyPostBizKey postBizKey = list.get(list.size() - 1);
   if(!postBizKey.getCompanyCd().equals(postBizKey.getDepartmentSetCd())){
      return;
   }
   /*・・略・・*/
   } catch (AccessSecurityException ex) {
      throw new BizApiException(ex);
   }
}
   /*・・略・・*/

【リスト:会社組織マネージャのリスナーの例】

各リスナーインタフェースにはいくつかのメソッドが定義されており、特定のタイミングでマネージャから呼び出されます。
マネージャと対応するリスナーインタフェースの詳細は、別途公開されているドキュメント「IM-共通マスタ Listener定義一覧」にまとめられていますので、そちらを参照して必要なインタフェースを実装して下さい。

実装したリスナークラスのクラスファイルは intra-mart Accel Platform のclasspath の通ったパスに配備します。

3.2.2. plugin.xmlの作成

APIのリスナーはPlug-inの形で追加しますのでplugin.xmlを作成してPluginManagerによって読み込めるようにします。
プラグインはあらかじめ用意された拡張ポイントに対して機能を追加する機能です。
リスナーを追加する際は各マネージャが用意している拡張ポイントに対してプラグインを設定するという形で追加します。
各マネージャが用意している拡張ポイントについては「マネージャの拡張ポイント一覧 」を参照してください。
会社組織マネージャの拡張ポイントへプラグインを設定する設定ファイル「plugin.xml」の例を【リスト:会社組織マネージャへの拡張を行うplugin.xml】に示します。
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
   <extension
      point="jp.co.intra_mart.foundation.master.accessor.company" >
      <accessor
         name="standard"
         id="jp.co.intra_mart.standard"
         version="8.0.0"
         rank="1" >
         <listener class="jp.co.intra_mart.system.master.sync.SynchronousCompanyListener" />
      </accessor>
   </extension>
</plugin>

【リスト:会社組織マネージャへの拡張を行うplugin.xml】

plugin.xml の書き方や構成についての詳細はPluginManager のAPI ドキュメントを参照してください。
ここではリスナーの追加に当たって必要な範囲で説明します。
  • extension タグ
  • point 属性: プラグインを追加する拡張ポイントを指定します。この例では会社組織マネージャの拡張ポイントを指定しています。
  • accessor タグ
  • name、id、version、rank などの属性はPluginManager によって依存関係の管理などに使用されます。
    PluginManager のドキュメントを参照して下さい。
  • listener タグ
  • listener として追加する実装の情報を記述するタグです。
  • class 属性にはPlug-in として追加するリスナーインタフェースを実装したクラスのFQDNを指定します。

このxmlファイルをPluginManagerの管理するディレクトリに配置します。具体的には以下のパスになります。

<(展開したwar)/WEB-INF/plugin/%plugin_id%/plugin.xml>

plugin.xml を変更した場合は、intra-mart の再起動が必要になります。

以上でリスナーの実装は完了です。