レベル: 中級 福井 清香, 情報マネジメント技術/ソフトウェア開発研究所, IBM
2006年 11月 24日 DB2Alphablox(以下Alphablox)は、データ分析を行うWebアプリケーションを作成・使用する際の強力な支援ツールです。JSP用に用意されたタグのみでリレーショナル・データベースや多次元データベースを照会するアプリケーションを開発できることが特徴ですが、Alphablox Java APIを使うことでよりカスタマイズされたアプリケーションの構築も可能になります。本稿ではAlphabloxから多次元データベースに接続するアプリケーションにてAlphablox Java APIを使ってデータ・セキュリティーを実現する方法について解説します。
Alphablox Java APIを使ったデータ・セキュリティー実現方法
多次元データベースを参照するアプリケーションを構築する際、ユーザーに応じて参照可能なデータを制御したいという要件がよくあります。例えば、組織次元に対して自分の所属する組織以下のデータのみ参照可能にしたい、といったような場合です。このような要望は多くの場合、製品の既存機能や作りこみでは対応し切れません。しかし、AlphabloxのJava APIを使うことでそれが実現可能となります。以前Alphabloxをテーマに執筆されたdeveloperWorksの記事の一つ「OLAPサーバーを利用したDB2 Alphabloxアプリケーション開発ガイド : アウトライン、メンバーの制御」では照会文およびディメンション・ルートの文字列の置換によるデータ・セキュリティーを実現する方法が紹介されています。ここでは別の方法として、Alphablox Java APIを使ってデータ制御を以下の2種類のパターンで実現する方法を紹介します。
-
ドリルダウンイベントの発生時に世代によってドリルダウンを禁止
-
「すべて展開」などのドリルダウン・イベント発生後に表示メンバーをフィルタリング
1. ドリルダウン・イベントの発生時に世代によってドリルダウンを禁止
AlphabloxのDataBloxに用意された機能であるディメンション・ルートを使うことで、ユーザーに対して次元のツリーの中である点より下のキューブ・メンバーのみ参照を許可する、といった制御が可能です。一方、ある一定の世代より下のキューブ・メンバーを参照できないように制御したい、といった要件も考えられます。例えば、地区の売上の合計は参照可能でも地区の各店舗の売上は参照できないようにする、といった要件です(図1を参照)。
図1 ツリー構造の中の参照範囲
この場合はAlphablox Java APIの中でインターフェースとして用意されているDrillDownFilterが使用可能です。このインターフェースを実装したクラスをDataBloxのイベント・フィルターとして指定することで、ドリルダウン・イベントが発生した際はその世代によってドリルダウンの操作を禁止することが可能です。イベント・フィルターを実装した1つの例として、以下にDrillDownFilterインターフェースを実装したドリルダウンイベントフィルターの具体的なサンプルを示します。
import com.alphablox.blox.filter.DrillDownFilter;
import com.alphablox.blox.uimodel.BloxModel;
import com.alphablox.blox.uimodel.core.MessageBox;
/**
* 指定した世代より下へのドリルダウンイベントを禁止するイベントフィルター
*/
public class MyDrillDownFilter implements DrillDownFilter {
BloxModel bloxModel;
// コンストラクター
public MyDrillDownFilter(BloxModel bloxModel) {
this.bloxModel = bloxModel;
}
public void drillDown(com.alphablox.blox.filter.DrillDownEvent dde)
throws Exception {
// ドリルダウンしたメンバーから次元の別名を取得
String dimensionName = dde.getMember().getDimension().getDisplayName();
// 次元名が"All Locations"の場合
if (dimensionName.equals("All Locations")) {
// この次元は世代3までドリルダウン可能という設定にする
int allowedLevel = 3;
// ドリルダウンを行った世代をドリルダウンイベントから取得
int generationLevel = dde.getMember().getGenerationLevel();
// ドリルダウンを行った世代が表示可能な世代より大きい場合
if (generationLevel >= allowedLevel) {
// ドリルダウンイベントをキャンセル
dde.cancelEvent();
// Alphabloxのメッセージダイアログを使って警告を表示
MessageBox msgBox =
new MessageBox("これより下へはドリルダウン出来ません", "データ操作警告", MessageBox.MESSAGE_OK, null);
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
bloxModel.getDispatcher().showDialog(msgBox);
}
}
}
}
|
このクラスをイベント・フィルターとして設定したDataBloxに対して、世代3より下にドリルダウンを行おうとすると、以下の図2のようなAlphabloxのメッセージ・ダイアログが表示され、ドリルダウンができないよう制御されます。
図2 イベント・フィルターによるメッセージ・ダイアログ
この例のように、ドリルダウン・イベントからドリルダウンを実行した世代を調べ、結果によってはドリルダウン・イベントをキャンセルすることでメンバー表示の制御が可能です。このように定義したクラスをイベント・フィルターとしてDataBloxに追加する方法については以下の資料をご参照ください。
完全な drillDownEventFilter の例
Alphabloxは他にもいろいろなイベント・フィルターをあらかじめインターフェースとして持っています。イベント・フィルターのリストは以下に記載されています。
イベント・フィルター用にインプリメントするメソッド
上記資料にあるように、ExpandFilterもイベント・フィルターとして用意されています。グリッドのオプションにて展開縮小モード(+-記号のクリックによる展開・縮小)を使用している場合は、DrillDownFilterの代わりにこのExpandFilterを同様に実装します。
2. 「すべて展開」などのドリルダウン・イベント発生後に表示メンバーをフィルタリング
ドリルダウン時に1つ下の世代を表示させる通常のドリルダウンの場合は、1のイベント・フィルターにてセキュリティーを実現可能です。一方、グリッド上の右クリック・メニューの「すべて展開」や、ドリルダウン・オプションを「子孫まで展開」「リーフメンバーを展開」に変更した場合のドリルダウンの制御は別の手段が必要です。この場合はキューブ・メンバーをすべて展開した後に表示可能な世代のみを画面に表示される、といった制御が有効です。この場合はイベント・フィルターではなくイベント・リスナーの実装が必要です。以下にDrillDownListenerを実装した例を示します。
import java.util.ArrayList;
import java.util.List;
import com.alphablox.blox.DataBlox;
import com.alphablox.blox.data.mdb.Dimension;
import com.alphablox.blox.data.mdb.MDBMetaData;
import com.alphablox.blox.data.mdb.Member;
import com.alphablox.blox.event.DrillDownListener;
/**
* 指定した世代より下が「すべて展開」やドリルダウンオプションの「子孫まで展開」
* リーフメンバーを展開」で選択された場合にメンバーを制御するイベントリスナークラス
*/
public class MyDrillDownListener implements DrillDownListener {
// コンストラクター
public MyDrillDownListener() {
}
// ドリルダウンイベントを検知し、イベントの直後に呼ばれるメソッド
public void drillDown(com.alphablox.blox.event.DrillDownEvent dde)
throws Exception {
// 世代3までドリルダウン可能という設定にする
int allowedLevel = 3;
// ドリルダウンが実行されているDataBloxを取得
DataBlox dataBlox = dde.getDataBlox();
// DataBloxで選択されているメンバー情報を取得するため、メタデータを取得
MDBMetaData metadata = (MDBMetaData) dataBlox.getMetaData();
// “All Locations”次元のオブジェクトをメタデータから取得
Dimension dimension = metadata.resolveDimension("All Locations");
// 次元オブジェクトを引数に指定してDataBloxで現在選択されているメンバーを取得
Member[] selectedMembers = dataBlox.getSelectedMembers(dimension);
// 表示可能なメンバーリストを保持するArrayListを定義
List keepedMemberList = new ArrayList();
// 現在選択されているメンバーのうち、世代が3かそれより小さいメンバーをArrayListに格納
for (int i = 0; i < selectedMembers.length; i++) {
if (selectedMembers[i].getGenerationLevel() <= allowedLevel)
keepedMemberList.add(selectedMembers[i]);
}
// ArrayListをMemberオブジェクトの配列に変換
Member[] keepedMembersArray = (Member[]) keepedMemberList
.toArray(new Member[keepedMemberList.size()]);
// Member配列をDataBloxにセットすることで、表示するメンバーを変更
dataBlox.setSelectedMembers(keepedMembersArray);
}
}
|
このように、DataBloxで現在選択されているキューブ・メンバーをMemberオブジェクトの配列として取得し、世代によってフィルタリングした結果のMemberオブジェクトの配列をDataBloxにセットすることでキューブ・メンバーの制御が可能です。以下にイベント・リスナーを設定せずにすべて展開を実行した画面と、イベント・リスナーを設定してグリッド上で「すべて展開」を実行した画面の比較を示します。図3のほうはリーフメンバーまですべて表示されているのに対し、図4の方は世代3までのメンバーのみが表示されていることがわかります。
図3 イベント・リスナーを設定していない画面で「すべて展開」を実行
図4 イベント・リスナーを設定した画面で「すべて展開」を実行
この例のようにDataBloxからメンバー配列にてキューブ・メンバーを取得・セットする方法を応用することで、いろいろな要件に応じて表示するキューブ・メンバーをJava APIで制御することが可能になります。例えばメンバー・フィルターでのキューブ・メンバーの選択結果を制御したい場合、MemberSelectListenerを同様に実装することでメンバー選択結果をフィルタリングすることができます。また、複数のユーザーで共有するブックマークを使用しているシステムでは、ブックマークのビューの視点は変えないまま、ブックマークのロード時に表示するキューブ・メンバーをユーザーの組織などによって変えたいという場合があります。例えば売上情報を参照するブックマークをロードする際、それぞれのユーザーが所属する組織の切り口で売上情報を表示したい、といった要件です。この場合も上記例と同様にBookmarkLoadListenerを実装し、ブックマークのロード結果のメンバーを置き換えることが可能です。
まとめ
ここで挙げた例のように、Alphabloxでは、イベント・フィルター、イベント・リスナーを使うことでさまざまな操作の制御が可能です。また、DataBloxにセットされているメンバーの配列を置換することによって、セキュリティー以外にもさまざまな要件を実現するためのキューブ・メンバーの操作を実装することが可能になります。これらの機能を使いこなし、ユーザーの操作に応じて必要なデータを表示させることで、ユーザーは複雑な操作をすることなく効率的にデータの参照・分析を行えるようになります。よりカスタマイズされたAlphabloxアプリケーション構築のために本稿が助けになれば幸いです。
参考文献
著者について  | |  | 福井 清香はソフトウェア開発研究所のエンジニアで、Business Intelligenceの分野におけるプロジェクトでの開発・支援業務を担当しています。 |
記事の評価
|