[Seasar-user:2615] Re: [S2JSF]同じページを繰り返し表示する場合の戻るボタンの動作について

Sea Slug seaslug
2005年 9月 27日 (火) 17:21:45 JST


竹田です。長々とすみません。これが最後です。

2. サーバ側のforeachに関連付けられたリスト変数をsessionに保存されたviewとク
ライアントからポストされた内容から再構成するようにする。

の具体的方法について説明します。

- まず、次のコレクションを継承したインターフェースとその実装を追加します。

public interface RestorableCollection extends Collection {
    public Class getElementClass();
}
public class RestorableArrayList extends ArrayList implements
        RestorableCollection {
    private Class c;
    public Class getElementClass() {
        return c;
    }
    public RestorableArrayList(int initialCapacity) {
        super(initialCapacity);
        // TODO 自動生成されたコンストラクター・スタブ
    }
    public RestorableArrayList(Collection collection) {
        super(collection);
        if (! collection.isEmpty()){
            c = collection.iterator().next().getClass();
        }
    }
    public void add(int index, Object element) {
        typeCheck(element);
        super.add(index, element);
    }
    public boolean add(Object o) {
        typeCheck(o);
        return super.add(o);
    }
    public boolean addAll(Collection c) {
        for (Iterator it = c.iterator(); it.hasNext();){
            typeCheck(it.next());
        }
        return super.addAll(c);
    }
    public boolean addAll(int index, Collection c) {
        for (Iterator it = c.iterator(); it.hasNext();){
            typeCheck(it.next());
        }
        return super.addAll(index, c);
    }
    public Object set(int index, Object element) {
        typeCheck(element);
        return super.set(index, element);
    }
    private void typeCheck(Object element){
        if (c == null){
            c = element.getClass();
        } else {
            if (!c.isInstance(element)){
                throw new IllegalStateException("Irregular element 
collection");
            }
        }
    }
}

- 次にorg.seasar.jsf.component.ForEach#setupRowsを次のように変更します。
    protected void setupRows() {
        Object items = 
BindingUtil.getBindingValue(this,JsfConstants.ITEMS_ATTR);
        if (items == null) {
            rows = new Object[rowCount];
        } else if (items instanceof RestorableCollection){
            RestorableCollection collections = (RestorableCollection)items;
            if (collections.getElementClass() == null){
                rows = new Object[0];
            } else {
                rows =  
(Object[])Array.newInstance(collections.getElementClass(), rowCount);
                collections.clear();
	    for (int i = 0 ; i < rows.length ; ++i){
                    try {
                        rows[i] = 
collections.getElementClass().newInstance();
                        collections.add(rows[i]);
                    } catch (InstantiationException e) {
                        throw new 
InstantiationError(e.getLocalizedMessage());
                    } catch (IllegalAccessException e) {
                        throw new 
IllegalAccessError(e.getLocalizedMessage());
                    }
                }
            }
        } else if (items instanceof Collection) {
            rows = new ArrayList((Collection) items).toArray();
        } else if (items.getClass().isArray()) {
            rows =  (Object[]) items;
        } else {
            throw new IllegalStateException(JsfConstants.ITEMS_ATTR);
        }
    }
   つまり、foreachに関連付けられているリスト変数がRestorableCollection のイ
ンスタンスである場合のみ、サーバ側で保持している情報をいったんクリアして、
viewに保持されている個数分だけ新たに用意します。後はUpdateModelValuesでポス
トされた内容が格納されますので、以降は内容を参照することができるようになりま
す。
   ただし、ポストされない内容は更新されないのでforeachに関連付けられているリ
スト変数の要素のすべての内容が復元されるわけではありません。必要な情報は
hiddenタグを使うなどして必ずポストされるようにする必要があります。
  リスト変数をRestorableCollectionのインスタンスにしなければ、今までどおりク
ライアント側の状態で上書きされることはありません。

 foreach2のサンプルで実験する場合には、foreach2.diconでforEach2DtoListのク
ラスをRestorableArrayListにすれば大丈夫です。

以上、長々とすみませんでした。

_________________________________________________________________
ウィルス駆除も無料の 「MSN Hotmail」  http://www.hotmail.com/ 




Seasar-user メーリングリストの案内