(10) データ更新時に排他制御

編集画面にてデータ更新時(保存ボタンクリック時)に、他のユーザー等に既に該当データが更新済みの場合に、標準ページレイアウトと同様にエラーメッセージを表示します。
尚、現時点(2014/10/03)の標準ページレイアウトと異なる点は以下です。

・       変更したユーザーの場合は上書き更新する
・       表示メッセージを既存ページ上部に表示

     拡張対象ページのApexクラス : Exclusive

global with sharing class ExclusiveExtender extends SkyEditor2.Extender{
    Exclusive extension;  // Apexクラス
    String sobjectName;   // 主オブジェクト
    String recordId;      // 主オブジェクト.Id
    Datetime updateDate;  // 主オブジェクト.最終更新日時
    public ExclusiveExtender(Exclusive extension){
        this.extension = extension;
        // Queryに「最終更新日時」項目追加
        extension.mainQuery.addField('SystemModStamp');
    }
    
    global override void init() {
        sobjectName = extension.mainSObjectType.getDescribe().getName();
        recordId = extension.mainRecord.Id;
        if (recordId != null) {
            updateDate = (Datetime)extension.mainRecord.get('SystemModStamp');
        }
    }
    
    global override void preSave() {
        if (recordId != null) {
            // 保存前処理に最新のレコード情報取得
            SObject[] modRecord = Database.query('SELECT Id, SystemModStamp, LastModifiedById, LastModifiedBy.Name FROM ' + sobjectName + ' WHERE Id = :recordId');
            // レコードが削除済みの場合
            if (modRecord.isEmpty()) {
                return;
            // レコードが変更済みの場合
            } else if ((DateTime)modRecord[0].get('SystemModStamp') > updateDate) {
                String lastModId  = (String)modRecord[0].get('LastModifiedById');
                String lastModName = (String)modRecord[0].getSObject('LastModifiedBy').get('Name');
                throw new SkyEditor2.ExtenderException('変更を保存できません<BR>編集していたレコードは、編集セッション中に<a href="/' + lastModId + ' " target="_blank">' + lastModName + '</a>によって変更されました。<BR><BR>もう一度編集する前に、<a href="/' + recordId + '">レコードを再表示</a>してください。');
            }
        }
    }
}



※主オブジェクトが「Account」の場合のテストクラスサンプル

@isTest
private class ExclusiveExtenderTest{
    private static testMethod void ExclusiveExtenderTest() {
        // 主オブジェクトを生成
        Account obj = new Account(Name='Test');
        insert obj;
        Exclusive extension = new Exclusive(new ApexPages.StandardController(obj));
        // データが更新済みの場合
        update obj;
        PageReference page = extension.doSave();
        System.assert(SkyEditor2.Messages.hasErrorMessage());
        // データが削除済みの場合
        delete obj;
        page = extension.doSave();
        System.assert(true);
    }
}