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.fukurou.util.StringUtil;
021import org.opengion.hayabusa.common.HybsSystem;
022import org.opengion.hayabusa.common.HybsSystemException;
023import org.opengion.hayabusa.db.DBTableModel;
024import org.opengion.hayabusa.html.TableFormatter;
025
026/**
027 * JavaScript のツリー階層を持ったテーブル表示を行う、ツリーテーブル表示クラスです。
028 *
029 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
030 * 各HTMLのタグに必要な setter/getterメソッドのみ,追加定義しています。
031 *
032 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。
033 *
034 * @og.group 画面表示
035 *
036 * @version  4.0
037 * @author   Hiroki Nakamura
038 * @since    JDK5.0,
039 */
040public class ViewForm_HTMLCustomTreeBOM extends ViewForm_HTMLTable  {
041        //* このプログラムのVERSION文字列を設定します。   {@value} */
042        private static final String VERSION = "5.1.6.0 (2010/05/01)" ;
043
044        private TableFormatter          headerFormat    = null;
045        private TableFormatter[]        bodyFormats             = null;
046        private int                                     bodyFormatsCount = 0;
047
048        private static final int BODYFORMAT_MAX_COUNT = 10;
049
050        /**
051         * DBTableModel から HTML文字列を作成して返します。
052         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
053         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
054         *
055         * @og.rev 4.3.1.0 (2008/09/08) フォーマットが設定されていない場合のエラー追加
056         *
057         * @param  stNo     表示開始位置
058         * @param  pgSize   表示件数
059         *
060         * @return  DBTableModelから作成された HTML文字列
061         */
062        @Override
063        public String create( final int stNo, final int pgSize )  {
064                // このクラスでは、テーブル全データを使用します。
065                if( getRowCount() == 0 ) { return ""; } // 暫定処置
066
067                // 4.3.1.0 (2008/09/08)
068                if( headerFormat == null ) {
069                        String errMsg = "ViewTagで canUseFormat() = true の場合、Formatter は必須です。";
070                        throw new HybsSystemException( errMsg );
071                }
072
073                int startNo = 0;
074                int pageSize = getRowCount();
075
076                int lastNo = getLastNo( startNo, pageSize );
077
078                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
079
080                headerFormat.makeFormat( getDBTableModel() );
081
082                if( bodyFormatsCount == 0 ) {
083                        bodyFormats[0] = headerFormat ;
084                        bodyFormatsCount ++ ;
085                }
086                else {
087                        for( int i=0; i<bodyFormatsCount; i++ ) {
088                                bodyFormats[i].makeFormat( getDBTableModel() );
089                        }
090                }
091
092                out.append( getHeader() );
093
094                int level;
095                boolean isFld;
096                for( int row=startNo; row<lastNo; row++ ) {
097                        // カラム==0は、レベルを指定する。
098                        level = Integer.parseInt( getValueLabel(row,0) );
099                        isFld = false;
100                        if( row+1<lastNo ) {
101                                int nextLevel = Integer.parseInt( getValueLabel(row+1,0) );
102                                isFld = level < nextLevel ;
103                        }
104                        out.append( getLevelScript( level,isFld ) );
105
106                        // 開始
107                        for( int i=0; i<bodyFormatsCount; i++ ) {
108                                TableFormatter bodyFormat = bodyFormats[i];
109
110                                int cl = 0;
111                                for( ; cl < bodyFormat.getLocationSize(); cl++ ) {
112                                        String fmt = bodyFormat.getFormat(cl);
113                                        int loc = bodyFormat.getLocation(cl);
114                                        if( ! bodyFormat.isNoClass() && loc >= 0 ) {
115                                                StringBuilder newtg = new StringBuilder( HybsSystem.BUFFER_LARGE );
116                                                newtg.append("<td class=\"");
117                                                newtg.append( getColumnDbType(loc) );
118                                                newtg.append("\" ");
119                                                String tdclass = newtg.toString();
120                                                fmt = StringUtil.replace( bodyFormat.getFormat(cl) ,"<td", tdclass );
121                                        }
122                                        out.append( fmt );
123                                        if( loc >= 0 ) {
124                                                switch( bodyFormat.getType(cl) ) {
125                                                case '#' : out.append( getColumnLabel(loc) );           break;
126                                                case '$' : out.append( getRendererValue(row,loc) );     break;
127                                                case '!' : out.append( getValue(row,loc) );                     break;
128                                                default  : out.append( getValueLabel(row,loc) );        break;
129                                                }
130                                        }
131                                }
132                                out.append( StringUtil.replace( bodyFormat.getFormat(cl), "</tr>", "" ) );
133                        }
134                        // 終了
135
136                        out.append( "', '', 'gold')" );
137                        if( level != 0 ) {
138                                out.append( ")" );
139                        }
140                        out.append( HybsSystem.CR );
141                }
142                out.append( getFutter() );
143
144                return out.toString();
145        }
146
147        /**
148         * DBTableModel から テーブルのヘッダータグ文字列を作成して返します。
149         * JavaScript の TreeBody では、JavaScriptに関連する定義もこのヘッダーに
150         * 含めます。
151         *
152         * @return  テーブルのヘッダータグ文字列
153         */
154        @Override
155        protected String getHeader() {
156                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
157
158                buf.append("<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\"  summary=\"bomTable\" id=\"viewTable\">"); // 3.9.0.1 (2007/12/18)
159                buf.append( HybsSystem.CR );
160                buf.append("<script type=\"text/javascript\">");
161                buf.append( HybsSystem.CR );
162                buf.append("<!--");
163                buf.append( HybsSystem.CR );
164                buf.append("aux0 = gFld('");
165                // 開始
166                int cl = 0;
167                for( ; cl < headerFormat.getLocationSize(); cl++ ) {
168                        buf.append( StringUtil.replace( headerFormat.getFormat(cl) ,"td","th" ));
169                        int loc = headerFormat.getLocation(cl);
170                        if( loc >= 0 ) { buf.append( getColumnLabel(loc) ); }
171                        // ヘッダーフォーマット部では、何もしません。
172                }
173                buf.append( StringUtil.replace( StringUtil.replace( headerFormat.getFormat(cl) ,"td","th" ), "</tr>", "" ) );
174                // 終了
175
176                buf.append("', '', 'gold')");
177                buf.append( HybsSystem.CR );
178
179                return buf.toString();
180        }
181
182        /**
183         * DBTableModel から テーブルのフッタータグ文字列を作成して返します。
184         * JavaScript の TreeBody では、JavaScriptに関連する定義もこのフッターに
185         * 含めます。
186         *
187         * @return  テーブルのフッタータグ文字列
188         */
189        protected String getFutter() {
190                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
191
192                buf.append("initializeDocument()").append( HybsSystem.CR );
193                buf.append("//-->").append( HybsSystem.CR );
194                buf.append("</script>").append( HybsSystem.CR );
195                buf.append("</table>").append( HybsSystem.CR );
196
197                return buf.toString();
198        }
199
200        /**
201         * 行のレベルに応じた JavaScript関数のヘッダー部分を返します。
202         *
203         * @og.rev 3.5.2.1 (2003/10/27) JavaScript 内のダブルコーテーションをシングルコーテーションに変更する。
204         *
205         * @param       lvl             ツリーのレベル
206         * @param       isFld   フォルダかどうか[true:フォルダ/false:最下層]
207         *
208         * @return  JavaScript関数のヘッダー部分
209         */
210        private String getLevelScript( final int lvl,final boolean isFld ) {
211
212                String auxX = "\taux" + ( lvl );
213                String auxY = "aux" + ( lvl-1 );
214
215                final String rtn ;
216                if( isFld ) {
217                        rtn = auxX + " = insFld(" + auxY + ", gFld('";
218                }
219                else {
220                        rtn = "\tinsFld(" + auxY + ", gLnk('CONTENTS','";
221                }
222
223                return rtn;
224        }
225
226        /**
227         * フォーマットを設定します。
228         *
229         * @param       list    TableFormatterのリスト
230         */
231        @Override
232        public void setFormatterList( final List<TableFormatter> list ) {               // 4.3.3.6 (2008/11/15) Generics警告対応
233                bodyFormats = new TableFormatter[BODYFORMAT_MAX_COUNT];
234
235                bodyFormatsCount = 0;
236                for( int i=0; i<list.size(); i++ ) {
237                        TableFormatter format = list.get( i );          // 4.3.3.6 (2008/11/15) Generics警告対応
238                        switch( format.getFormatType() ) {
239                        case TYPE_HEAD : headerFormat = format; break;
240                        case TYPE_BODY : bodyFormats[bodyFormatsCount++] = format; break;
241                        default : String errMsg = "FormatterType の定義外の値が指定されました。";
242                        // 4.3.4.4 (2009/01/01)
243                                          throw new HybsSystemException( errMsg );
244                        }
245                }
246
247                if( headerFormat == null ) {
248                        String errMsg = "og:thead タグの、フォーマットの指定は必須です。";
249                        throw new HybsSystemException( errMsg );
250                }
251        }
252
253        /**
254         * フォーマットメソッドを使用できるかどうかを問い合わせます。
255         *
256         * @return  使用可能(true)/ 使用不可能 (false)
257         */
258        @Override
259        public boolean canUseFormat() {
260                return true;
261        }
262
263        /**
264         * ビューで表示したカラムの一覧をカンマ区切りで返します。
265         *
266         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
267         *
268         * @return      ビューで表示したカラムの一覧
269         */
270        @Override
271        public String getViewClms() {
272                DBTableModel table = getDBTableModel();
273                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
274                for( int i=0; i<headerFormat.getLocationSize(); i++ ) {
275                        if( buf.length() > 0 ) { buf.append( ',' ); }
276                        buf.append( table.getColumnName( headerFormat.getLocation( i ) ) );
277                }
278                return buf.toString();
279        }
280}