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 * ヘッダ があれば、最初に、1度のみ実行し、フッタがあれば、最後に実行します。
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        /**
074         * DBTableModel から HTML文字列を作成して返します。
075         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
076         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
077         *
078         * @og.rev 4.3.1.0 (2008/09/08) フォーマットが設定されていない場合のエラー追加・編集行のみを表示する属性(isSkipNoEdit)追加
079         * @og.rev 5.6.3.3 (2013/04/19) headerFormatのみ、bodyFormatsのみ対応
080         *
081         * @param  startNo        表示開始位置
082         * @param  pageSize   表示件数
083         *
084         * @return      DBTableModelから作成された HTML文字列
085         */
086        @Override
087        public String create( final int startNo, final int pageSize )  {
088                if( getRowCount() == 0 ) { return ""; } // 暫定処置
089
090                // 5.6.3.3 (2013/04/19) headerFormatのみ、bodyFormatsのみ対応
091                headerLine       = null;                // 3.5.3.1 (2003/10/31) キャッシュクリア
092
093                int lastNo = getLastNo( startNo, pageSize );
094
095                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
096
097                // 5.6.3.3 (2013/04/19) headerFormatのみ、bodyFormatsのみ対応
098                if( headerFormat != null ) {
099                        headerFormat.makeFormat( getDBTableModel() );   // 3.5.6.2 (2004/07/05) 移動
100                }
101
102                if( bodyFormatsCount != 0 ) {
103                        for( int i=0; i<bodyFormatsCount; i++ ) {
104                                bodyFormats[i].makeFormat( getDBTableModel() );
105                        }
106                }
107
108                out.append( getHeader() );
109                for( int row=startNo; row<lastNo; row++ ) {
110                        if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08)
111                        for( int i=0; i<bodyFormatsCount; i++ ) {
112                                TableFormatter bodyFormat = bodyFormats[i];
113                                if( ! bodyFormat.isUse( row,getDBTableModel() ) ) { continue; }         // 3.5.4.0 (2003/11/25)
114
115                                int cl = 0;
116                                for( ; cl < bodyFormat.getLocationSize(); cl++ ) {
117                                        String fmt = bodyFormat.getFormat(cl);
118                                        int loc = bodyFormat.getLocation(cl);   // 3.5.5.0
119                                        out.append( fmt );                      // 3.5.0.0
120
121                                        if( loc >= 0 ) {
122                                                switch( bodyFormat.getType(cl) ) {
123                                                        case '#' : out.append( getColumnLabel(loc) );           break;
124                                                        case '$' : out.append( getRendererValue(row,loc) );     break;
125                                                        case '!' : out.append( getValue(row,loc) );                     break;
126                                                        default  : out.append( getValueLabel(row,loc) );        break;
127                                                }
128                                        }
129                                        else {
130                                                out.append( bodyFormat.getSystemFormat(row,loc) );
131                                        }
132                                }
133                                out.append( bodyFormat.getFormat(cl) );
134                        }
135                }
136
137                if( footerFormat != null ) {
138                        out.append( getTableFoot() );
139                }
140
141                return out.toString();
142        }
143
144        /**
145         * 内容をクリア(初期化)します。
146         *
147         */
148        @Override
149        public void clear() {
150                super.clear();
151                headerFormat                    = null;
152                bodyFormats                             = null;
153                footerFormat                    = null;
154                bodyFormatsCount                = 0;
155        }
156
157        /**
158         * DBTableModel から テーブルのヘッダータグ文字列を作成して返します。
159         *
160         * @return      テーブルのヘッダータグ文字列
161         */
162        @Override
163        protected String getHeader() {
164                if( headerFormat == null ) { return ""; }       // 存在しないケース
165                if( headerLine != null ) { return headerLine; }         // キャッシュを返す。
166
167                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
168
169                int cl = 0;
170                for( ; cl < headerFormat.getLocationSize(); cl++ ) {
171                        buf.append( headerFormat.getFormat(cl) );
172                        int loc = headerFormat.getLocation(cl);
173                        if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); }
174                }
175                buf.append( headerFormat.getFormat(cl) ).append( HybsSystem.CR );
176
177                headerLine = buf.toString();
178                return headerLine;
179        }
180
181        /**
182         * DBTableModel から テーブルのタグ文字列を作成して返します。
183         *
184         * @return      テーブルのタグ文字列
185         */
186        protected String getTableFoot() {
187                footerFormat.makeFormat( getDBTableModel() );
188
189                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
190
191                int cl = 0;
192                for( ; cl < footerFormat.getLocationSize(); cl++ ) {
193                        int loc = footerFormat.getLocation(cl);
194                        if( loc >= 0 ) { buf.append( getSortedColumnLabel(loc) ); }
195                }
196                buf.append( footerFormat.getFormat(cl) ).append( HybsSystem.CR );
197
198                return buf.toString();
199        }
200
201        /**
202         * フォーマットを設定します。
203         *
204         * @og.rev 5.6.3.3 (2013/04/19) headerFormatのみの場合、bodyFormats として使う。
205         *
206         * @param       list    TableFormatterのリスト
207         */
208        @Override
209        public void setFormatterList( final List<TableFormatter> list ) {               // 4.3.3.6 (2008/11/15) Generics警告対応
210                bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
211
212                bodyFormatsCount = 0;
213                for( int i=0; i<list.size(); i++ ) {
214                        TableFormatter format = list.get( i );          // 4.3.3.6 (2008/11/15) Generics警告対応
215
216                        switch( format.getFormatType() ) {
217                                case TYPE_HEAD : headerFormat = format; break;
218                                case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break;
219                                case TYPE_FOOT : footerFormat = format; break;
220                                default : String errMsg = "FormatterType の定義外の値が指定されました。";
221                                                // 4.3.4.4 (2009/01/01)
222                                                  throw new HybsSystemException( errMsg );
223                        }
224                }
225
226                // 5.6.3.3 (2013/04/19) headerFormatのみの場合、bodyFormats として使う。
227                if( bodyFormatsCount == 0 ) {           // bodyFormats がない場合は、headerFormatをコピーする。
228                        if( headerFormat == null ) {
229                                String errMsg = "thead タグか、または、tbody タグによるフォーマットの指定は必須です。";
230                                throw new HybsSystemException( errMsg );
231                        }
232                        else {
233                                bodyFormats[bodyFormatsCount++] = headerFormat;
234                                headerFormat = null;
235                        }
236                }
237        }
238
239        /**
240         * フォーマットメソッドを使用できるかどうかを問い合わせます。
241         *
242         * @return  使用可能(true)/ 使用不可能 (false)
243         */
244        @Override
245        public boolean canUseFormat() {
246                return true;
247        }
248
249        /**
250         * 表示項目の編集(並び替え)が可能かどうかを返します
251         *
252         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
253         *
254         * @return      表示項目の編集(並び替え)が可能かどうか(false:不可能)
255         */
256        @Override
257        public boolean isEditable() {
258                return false;
259        }
260}