    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.plugin.view;
    017
    018import java.util.List;
    019
    020import org.opengion.hayabusa.common.HybsSystem;
    021import org.opengion.hayabusa.common.HybsSystemException;
    022import org.opengion.hayabusa.html.TableFormatter;
    023
    024/**
    025 * ヘッダ、フッタ、ボディを指定して作成する、自由レイアウトが可能な、カスタムテーブル表示クラスです。
    026 * 従来は、内部バグのため、thead,tbody,tfoot タグを使わないと処理できませんでしたが、
    027 * viewタグの BODY 部にフォーマットを記述するだけで処理するように改善しました。(5.6.3.3 (2013/04/19))
    028 *
    029 * このタグでは、BODY部、または、bodyFormats を繰り返す処理を行います。
    030 * ヘッダ があれば、最初に、１度のみ実行し、フッタがあれば、最後に実行します。
    031 * このクラスが他と異なるのは、ヘッダのみ記述した場合、ヘッダとして使われず、ボディとしてのみ繰返し
    032 * 使われます。また、bodyFormats のみの記述も可能です。
    033 *
    034 * このクラスは、ViewForm_HTMLFormatTable クラスの代替えとしても使用できます。
    035 * その場合は、thead のみ指定すれば、同じフォームが tbody にも適用されます。
    036 * これは、まさに、ViewForm_HTMLFormatTable と同じです。
    037 * (※ 上記仕様が、未実装でしたので、対応しました。 5.6.3.3 (2013/04/19) )
    038 *
    039 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
    040 * 各HTMLのタグに必要な setter/getterメソッドのみ，追加定義しています。
    041 *
    042 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。
    043 *
    044 * <table border="1" frame="box" rules="all" >
    045 *   <caption>ヘッダ と ボディ の組み合わせ</caption>
    046 *   <tr><th>番号</th><th>headerFormat</th><th>bodyFormats</th><th>現状動作    </th><th>変更後(5.6.3.3以降)      </th></tr>
    047 *   <tr><td>①  </td><td>なし        </td><td>なし       </td><td>headerのみ  </td><td>body の繰り返し          </td></tr>
    048 *   <tr><td>②  </td><td>なし        </td><td>あり       </td><td>エラー      </td><td>bodyFormats のみ繰り返す </td></tr>
    049 *   <tr><td>③  </td><td>あり        </td><td>なし       </td><td>headerのみ  </td><td>body の繰り返し          </td></tr>
    050 *   <tr><td>④  </td><td>あり        </td><td>あり       </td><td>それぞれ動作</td><td>← 同じ                  </td></tr>
    051 *   <tr><td>⑤  </td><td>なし        </td><td>なし       </td><td>エラー      </td><td>← 同じ                  </td></tr>
    052 * </table>
    053 *
    054 * @og.rev 3.7.1.1 (2005/05/23) 新規作成
    055 * @og.rev 5.6.3.3 (2013/04/19) 処理変更
    056 * @og.group 画面表示
    057 *
    058 * @version  4.0
    059 * @author       Kazuhiko Hasegawa
    060 * @since    JDK5.0,
    061 */
    062public class ViewForm_CustomData extends ViewForm_HTMLTable     {
    063        //* このプログラムのVERSION文字列を設定します。   {@value} */
    064        private static final String VERSION = "5.6.3.3 (2013/04/19)" ;
    065
    066        private TableFormatter          headerFormat    = null;
    067        private TableFormatter[]        bodyFormats             = null;
    068        private TableFormatter          footerFormat    = null;
    069        private int                                     bodyFormatsCount = 0;
    070
    071        private static final int BODYFORMAT_MAX_COUNT = 10;
    072
    073        // 4.3.4.4 (2009/01/01)
    074//      /**
    075//       * デフォルトコンストラクター
    076//       *
    077//       */
    078//      public ViewForm_CustomData() {
    079//              super();
    080//      }
    081
    082        /**
    083         * DBTableModel から HTML文字列を作成して返します。
    084         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
    085         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
    086         *
    087         * @og.rev 4.3.1.0 (2008/09/08) フォーマットが設定されていない場合のエラー追加・編集行のみを表示する属性(isSkipNoEdit)追加
    088         * @og.rev 5.6.3.3 (2013/04/19) headerFormatのみ、bodyFormatsのみ対応
    089         *
    090         * @param  startNo        表示開始位置
    091         * @param  pageSize   表示件数
    092         *
    093         * @return      DBTableModelから作成された HTML文字列
    094         */
    095        @Override
    096        public String create( final int startNo, final int pageSize )  {
    097                if( getRowCount() == 0 ) { return ""; } // 暫定処置
    098
    099                // 4.3.1.0 (2008/09/08)
    100                // 5.6.3.3 (2013/04/19) headerFormatのみ、bodyFormatsのみ対応
    101//              if( headerFormat == null ) {
    102//                      String errMsg = "ViewTagで canUseFormat() = true の場合、Formatter は必須です。";
    103//                      throw new HybsSystemException( errMsg );
    104//              }
    105
    106                headerLine       = null;                // 3.5.3.1 (2003/10/31) キャッシュクリア
    107
    108                int lastNo = getLastNo( startNo, pageSize );
    109
    110                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
    111
    112                // 5.6.3.3 (2013/04/19) headerFormatのみ、bodyFormatsのみ対応
    113                if( headerFormat != null ) {
    114                        headerFormat.makeFormat( getDBTableModel() );   // 3.5.6.2 (2004/07/05) 移動
    115                }
    116
    117                if( bodyFormatsCount != 0 ) {
    118                        for( int i=0; i<bodyFormatsCount; i++ ) {
    119                                bodyFormats[i].makeFormat( getDBTableModel() );
    120                        }
    121                }
    122
    123                out.append( getHeader() );
    124                for( int row=startNo; row<lastNo; row++ ) {
    125//                      if( isSkip( row ) ) { continue; }               // 3.5.3.1 (2003/10/31)
    126                        if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08)
    127                        for( int i=0; i<bodyFormatsCount; i++ ) {
    128                                TableFormatter bodyFormat = bodyFormats[i];
    129                                if( ! bodyFormat.isUse( row,getDBTableModel() ) ) { continue; }         // 3.5.4.0 (2003/11/25)
    130
    131                                int cl = 0;
    132                                for( ; cl < bodyFormat.getLocationSize(); cl++ ) {
    133                                        String fmt = bodyFormat.getFormat(cl);
    134                                        int loc = bodyFormat.getLocation(cl);   // 3.5.5.0
    135                                        out.append( fmt );                      // 3.5.0.0
    136
    137                                        if( loc >= 0 ) {
    138                                                switch( bodyFormat.getType(cl) ) {
    139                                                        case '#' : out.append( getColumnLabel(loc) );           break;
    140                                                        case '$' : out.append( getRendererValue(row,loc) );     break;
    141                                                        case '!' : out.append( getValue(row,loc) );                     break;
    142                                                        default  : out.append( getValueLabel(row,loc) );        break;
    143                                                }
    144                                        }
    145                                        else {
    146                                                out.append( bodyFormat.getSystemFormat(row,loc) );
    147                                        }
    148                                }
    149                                out.append( bodyFormat.getFormat(cl) );
    150                        }
    151                }
    152
    153                if( footerFormat != null ) {
    154                        out.append( getTableFoot() );
    155                }
    156
    157                return out.toString();
    158        }
    159
    160        /**
    161         * 内容をクリア(初期化)します。
    162         *
    163         */
    164        @Override
    165        public void clear() {
    166                super.clear();
    167                headerFormat                    = null;
    168                bodyFormats                             = null;
    169                footerFormat                    = null;
    170                bodyFormatsCount                = 0;
    171        }
    172
    173        /**
    174         * DBTableModel から テーブルのヘッダータグ文字列を作成して返します。
    175         *
    176         * @return      テーブルのヘッダータグ文字列
    177         */
    178        @Override
    179        protected String getHeader() {
    180                if( headerFormat == null ) { return ""; }       // 存在しないケース
    181                if( headerLine != null ) { return headerLine; }         // キャッシュを返す。
    182
    183                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    184
    185                int cl = 0;
    186                for( ; cl < headerFormat.getLocationSize(); cl++ ) {
    187                        buf.append( headerFormat.getFormat(cl) );
    188                        int loc = headerFormat.getLocation(cl);
    189                        if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); }
    190                }
    191                buf.append( headerFormat.getFormat(cl) ).append( HybsSystem.CR );
    192
    193                headerLine = buf.toString();
    194                return headerLine;
    195        }
    196
    197        /**
    198         * DBTableModel から テーブルのタグ文字列を作成して返します。
    199         *
    200         * @return      テーブルのタグ文字列
    201         */
    202        protected String getTableFoot() {
    203                footerFormat.makeFormat( getDBTableModel() );
    204
    205                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    206
    207                int cl = 0;
    208                for( ; cl < footerFormat.getLocationSize(); cl++ ) {
    209                        int loc = footerFormat.getLocation(cl);
    210                        if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); }
    211                }
    212                buf.append( footerFormat.getFormat(cl) ).append( HybsSystem.CR );
    213
    214                return buf.toString();
    215        }
    216
    217        /**
    218         * フォーマットを設定します。
    219         *
    220         * @og.rev 5.6.3.3 (2013/04/19) headerFormatのみの場合、bodyFormats として使う。
    221         *
    222         * @param       list    TableFormatterのリスト
    223         */
    224        @Override
    225        public void setFormatterList( final List<TableFormatter> list ) {         // 4.3.3.6 (2008/11/15) Generics警告対応
    226                bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
    227
    228                bodyFormatsCount = 0;
    229                for( int i=0; i<list.size(); i++ ) {
    230                        TableFormatter format = list.get( i );          // 4.3.3.6 (2008/11/15) Generics警告対応
    231
    232                        switch( format.getFormatType() ) {
    233                                case TYPE_HEAD : headerFormat = format; break;
    234                                case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break;
    235                                case TYPE_FOOT : footerFormat = format; break;
    236                                default : String errMsg = "FormatterType の定義外の値が指定されました。";
    237                                                // 4.3.4.4 (2009/01/01)
    238                                                  throw new HybsSystemException( errMsg );
    239                        }
    240                }
    241
    242                // 5.6.3.3 (2013/04/19) headerFormatのみの場合、bodyFormats として使う。
    243                if( bodyFormatsCount == 0 ) {           // bodyFormats がない場合は、headerFormatをコピーする。
    244                        if( headerFormat == null ) {
    245                                String errMsg = "thead タグか、または、tbody タグによるフォーマットの指定は必須です。";
    246                                throw new HybsSystemException( errMsg );
    247                        }
    248                        else {
    249                                bodyFormats[bodyFormatsCount++] = headerFormat;
    250                                headerFormat = null;
    251                        }
    252                }
    253        }
    254
    255        /**
    256         * フォーマットメソッドを使用できるかどうかを問い合わせます。
    257         *
    258         * @return  使用可能(true)/ 使用不可能 (false)
    259         */
    260        @Override
    261        public boolean canUseFormat() {
    262                return true;
    263        }
    264
    265        /**
    266         * 表示項目の編集(並び替え)が可能かどうかを返します
    267         *
    268         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
    269         *
    270         * @return      表示項目の編集(並び替え)が可能かどうか(false:不可能)
    271         */
    272        @Override
    273        public boolean isEditable() {
    274                return false;
    275        }
    276}