当ブログに掲載しているサンプルは、すべて利用者の自己責任という形でお願いします。
ただし、明らかな不具合がある場合、ご連絡いただければ、訂正記事を出します。
また、こちらのサンプルは、別のサイト等への公開、転載は一切禁止しています。
どうしてもと言う場合は、筆者にあらかじめご連絡ください。

テクてく Lotus 技術者 Slack に参加しよう!

2012年9月21日金曜日

XPagesで文書のロックをやってみよう!

ふと気がついたのですが、もう9月も後半だったんですね。驚きました。
どうりで最近、朝晩が涼しくなったんですね。このような季節の変わり目は体調を崩しやすいので気をつけましょうね(前にもこんなことを書いたような気が・・・)



さて、今日も本文を見る前にこちらのボタンをポチッとクリックしてやってくださいね。
にほんブログ村 IT技術ブログへ
ホントに押してくれないと、そのうち見せなくしますよ!だからお願いしますね。

では、今日の話題です。
またまた、XPages でxxしてみよう!ということで、 今回は文書のロックに挑戦です。

文書のロック自体は、Lotus Domino 6からの新機能です。ですので、当然XPagesでも出来るだろうとの予測で始めています(ブログの記事なんてこんなもんです)。

文書のロックの仕組み自体の説明はここでは割愛します。
詳しく知りたい場合は、日本IBM殿のサイトにあるLotus Notes/Domino 文書ロックの仕組みFAQを参照願います。

ということで、ある程度の準備が出来ているという前提で進めます。
まず、ノーツアプリケーションのプロパティで「文書のロックを許可」にチェックを付けておきます(下図)。
ノーツアプリケーションのプロパティ

・・・というつもりで進めていくつもりだったのですが、
なんか旨く実装できませんでした(筆者の技術力が低いからなのか、そもそもダメなのかは分かってません)。

なので、 擬似的な形になりますが、「こんな形で実装しました。」という報告にさせてください(嫌だ!と言っても、そうするんですが・・・)。

実装方法としては、次のようにしました。
  1. 文書のロック、ロック解除は、ビュー上で行う。
  2. 文書をロックしているユーザをビュー上に表示する。
  3. 文書の編集は、フォームを表示するためのXPage上で行う。
  4. 別のユーザが文書がロックしている場合、編集モードに移行することが出来ないようにする。
  5. 文書の保存やキャンセル等、XPage 画面を閉じるのは普通に行う。

では、それぞれについて詳しく見ていきましょう。

まずは、 1.文書のロック、ロック解除~です。
(XPages アプリケーションの)ビュー上で行うので、 ビューで文書が選択できるようにします。
ビューコントロールの一番左の列に、一つ列を挿入します。
プロパティビューの「表示」タブで、「列の値を表示」のチェックを外して、さらに「チェックボックス」にチェックを付けます(下図参照)。
チェックボックスの列を追加

今度は、選択した文書をロックするためのプログラムを記述するので、ボタンを配置します。
ボタンのラベルは「選択した文書をロックする」とします。
イベントビューを開いて、スクリプトの実行を追加します。
スクリプトエディタには、以下のように記述します。
var panelName = "viewPanel1";
var ids = getComponent( panelName ).getSelectedIds();

if ( ids.length != 1 ) {
    view.postScript( "alert('文書は一つだけ選択してください。')" );
    return false;
}

try {
    // 選択文書を取得する
    var doc:NotesDocument = database.getDocumentByID(ids[0]);

    // ノーツアプリケーションに文書のロックを許可する
    if (!database.isDocumentLockingEnabled()) {
        database.setDocumentLockingEnabled(true);
    }
   
    // 文書がロックされていなければ、ロックする
    doc.lock( @UserName() );
   
} catch(e) {
    var docOwner = doc.getLockHolders();
    view.postScript( "alert('文書は" + docOwner + "にロックされています。')" );
    return false;
}
SSJS(文書をロックする)

var panelName = "viewPanel1";
で、  ビューコントロールの名称を設定しています。
var ids = getComponent( panelName ).getSelectedIds();
で、選択した文書を取得していますが、分かりやすくするために、選択して良い文書は1つとしています。

doc.lock( @UserName() );
で文書をロックしています。すでにロックされている場合は、例外が発生するので、catchして、現在文書をロックしているユーザ名を 表示して、処理を中断しています。

同様にして、文書のロックを解除するためのボタンを配置します。
ボタンのラベルは、「選択した文書のロックを解除する」とします。
イベントには、次のコードを記述します。
スクリプトエディタには、以下のように記述します。
var panelName = "viewPanel1";
var ids = getComponent( panelName ).getSelectedIds();

if ( ids.length > 1 ) {
    return false;
}

try {
    // 選択文書を取得する
    var doc:NotesDocument = database.getDocumentByID(ids[0]);

    // ノーツアプリケーションに文書のロックを許可する
    if (!database.isDocumentLockingEnabled()) {
        database.setDocumentLockingEnabled(true);
    }
   
    // 文書のロックを解除する
    doc.unlock();
   
} catch(e) {
    var docOwner = doc.getLockHolders();
    view.postScript( "alert('文書は" + docOwner + "にロックされています。')" );
    return false;
}
SSJS(文書のロック解除)

基本的には、文書のロックと同じです。
doc.lock()の代わりに、doc.unlock();となっているところが違います。
こちらも、別のユーザがロックしている場合は、例外が発生するので、catchして、現在文書をロックしているユーザ名を 表示して、処理を中断しています。


今度は、2.文書をロックしているユーザをビュー上に表示する。です。
こちらは、まずビューそのものに列を追加します。
列の値は、「$Writers」とします。
後は、XPage のビューにこの列を表示するようにするだけです。

実装した後、簡単なテストをした結果が下図です。
文書のロックをXPageのビューで表現してみた

赤枠の部分がすでにロックしてある文書の行です。「ロックユーザ」という列にロックしているユーザ名が表示されています。
※画面下の方にある「競合文書」は今回の話では関係ありませんので、無視してください。



次に、3.文書の編集は~と、4.別のユーザが~です。
これは、
文書を編集モードに移行する際、他の人がすでにロックしていたら、その旨を表示して、処理を中断する。
という実装になります。

通常、編集ボタンの内容は、シンプルアクションの「文書モードの変更」を利用するかと思いますが(下図)、その場合、文書がロックされているかどうかの判断ができません。
シンプルアクション(文書モードの変更)

そこで、このボタンのイベントは(SSJS・・・サーバーサイドJavaScript)を使って、以下のように記述します。
// 自文書(バックエンド)を取得する
var doc:NotesDocument = document1.getDocument( true );

if ( doc.getLockHolders().isEmpty() ) {
        context.setDocumentMode( "edit" );
} else {
    var docOwner = doc.getLockHolders();
    view.postScript( "alert('文書は" + docOwner + "にロックされています。')" );
    return false;
}
編集ボタンのSSJSコード

最初に、NotesDocumentオブジェクトを取得しています。
次に、文書をロックしているのが誰なのかを取得して、""(空の文字列)であれば、編集モードに移行します。
""でない場合は、文書がロックされていると言うことなので、誰が文書をロックしているのかをダイアログで表示するようにしています(doc.getLockHolders()は、現在文書をロックしているユーザーを取得します)。
ちなみに、ロックされている文書を編集しようとすると、こんな画面になります。
エラーダイアログ(IEの場合)
エラーダイアログ(Firefoxの場合)

文書を編集モードにするのは、
context.setDocumentMode( "edit" );
で実行しています。


続いて、保存ボタンとキャンセルボタンです。
こちらは、特に何もしません。普通に文書の保存やページを開くのシンプルアクションを設定して終わりです。


ということで、実装自体はこれで終わりです。

他の人に編集させないようにするためには、一度文書をロックしてから、編集するという運用なので、手間はかかりますが、なんとか実現はできています。

問題としては、ロックしないで編集しているときに、他の人がロックしてしまうと、競合文書(保存時の競合)が発生してしまうことでしょうか。
まぁ、サンプルなのでそこはご勘弁を・・・

どなたか、もっと上手いやり方があれば、是非ご教授ください。




【PR】ノーツ/ドミノに関するお問い合わせは下記まで【PR】
単純なDBのカスタマイズから他アプリケーションとの連携までご要望にお応えします
Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ

0 件のコメント: