    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.hayabusa.taglib;
    017
    018import static org.opengion.fukurou.util.StringUtil.nval;
    019
    020import java.util.ArrayList;
    021import java.util.Collections;
    022import java.util.Enumeration;
    023import java.util.HashMap;
    024import java.util.List;
    025import java.util.Map;
    026
    027import org.opengion.fukurou.util.StringUtil;
    028import org.opengion.fukurou.util.TagBuffer;
    029import org.opengion.hayabusa.common.HybsSystem;
    030import org.opengion.hayabusa.common.HybsSystemException;
    031import org.opengion.hayabusa.db.DBColumn;
    032import org.opengion.hayabusa.db.DBEditConfig;
    033import org.opengion.hayabusa.db.DBLastSql;
    034import org.opengion.hayabusa.db.DBTableModel;
    035
    036/**
    037 * 画面表示、集計に関する設定情報の表示、登録を行うためのタグです。
    038 * (このタグは標準の設定編集画面に組み込んで使用され、各画面JSPから呼び出すことはありません)
    039 *
    040 * このタグは、ユーザー単位に管理されるエディット設定オブジェクトに対するI/Fの機能を
    041 * 提供しています。このエディット設定オブジェクトについては、画面毎に設定を行うため、
    042 * タグの呼び出しには、画面IDが必須となっています。
    043 *
    044 * 具体的な機能としては、3つの機能を提供します。
    045 * (1)設定画面表示(command="GET")
    046 *    ユーザー単位に管理されるエディット設定オブジェクトをHTMLに変換して表示
    047 *    また、表示カラムの一覧(カンマ区切り)については、画面側のJavaScriptで再設定を行うため、
    048 *    その値を"viewClms"という名前のhiddenタグで出力します。
    049 * (2)エディット名一覧(command="LIST")
    050 *    指定の画面IDに対して、設定されているエディット名の一覧をプルダウン(selectタグ)に
    051 *    変換して表示します。(name="editName")
    052 * (3)設定情報登録/削除(command="SET"/"DELETE")
    053 *    (1)で設定された内容に対して、エディット名を指定してその内容を保存/削除します。
    054 *    情報の保存は、command="GET"で表示される項目名と連動していますので、単独での使用は
    055 *    できません。
    056 *
    057 * @og.formSample
    058 * ●形式：一般ユーザーが直接組み込むことはありません。
    059 * ●body：なし
    060 *
    061 * ●Tag定義：
    062 *   &lt;og:editConfig
    063 *       command          ○【TAG】command を指定します(必須)。
    064 *       gamenId          ○【TAG】画面ID を指定します(必須)。
    065 *       editName           【TAG】エディット名 を指定します
    066 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    067 *   /&gt;
    068 *
    069 * ●使用例
    070 *     &lt;og:editConfig command="{&#064;command}" gamenId="{&#064;gamenId}" editName="{&#064;editName}" /&gt;
    071 *
    072 *     &lt;og:editConfig
    073 *         command        = command設定 (GET/LIST/SET/REMOVE)
    074 *         gamenId        = "GE0000"    画面ID
    075 *       [ editName ]     = "EDITNAME"  エディット名
    076 *     /&gt;
    077 *
    078 * @og.group エディット設定
    079 *
    080 * @og.rev 5.3.6.0 (2011/06/01)
    081 *
    082 * @version  5.0
    083 * @author       Hiroki Nakamura
    084 * @since    JDK6.0,
    085 */
    086public class EditConfigTag extends CommonTagSupport {
    087        //* このプログラムのVERSION文字列を設定します。   {@value} */
    088        private static final String VERSION = "5.7.5.2 (2014/04/11)" ;
    089
    090        private static final long serialVersionUID = 575220140411L ;
    091
    092        private static final String VIEW_PREFIX                 = "EDIT_VIEW_";
    093        private static final String SUM_PREFIX                  = "EDIT_SUM_";
    094        private static final String GROUP_PREFIX                = "EDIT_GROUP_";
    095        private static final String SUBTOTAL_PREFIX             = "EDIT_SUBTOTAL_";
    096        private static final String TOTAL_PREFIX                = "EDIT_TOTAL_";
    097        private static final String ORDERBY_PREFIX              = "EDIT_ORDERBY_";
    098        private static final String DESC_PREFIX                 = "EDIT_DESC_";
    099        private static final String GRANDTOTAL_PREFIX   = "EDIT_GRANDTOTAL_";
    100        private static final String COMMON_PREFIX               = "EDIT_COMMON_";
    101
    102        private String  command                 = null;         // EW" 、アップロード="COPY|INSERT"
    103        private String  gamenId                 = null;
    104        private String  editName                = null;
    105
    106        private transient DBTableModel table            = null;         // 5.5.2.4 (2012/05/16) transient 定義追加
    107        private transient DBEditConfig config           = null;         // 5.5.2.4 (2012/05/16) transient 定義追加
    108
    109        private boolean orderOnly               = false; // 5.5.5.2 (2012/08/10)
    110
    111        /**
    112         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    113         *
    114         * @return      後続処理の指示(SKIP_BODY)
    115         */
    116        @Override
    117        public int doStartTag() {
    118                return(SKIP_BODY);                              // Body を評価しない
    119        }
    120
    121        /**
    122         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    123         *
    124         * @og.rev 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
    125         *
    126         * @return      後続処理の指示
    127         */
    128        @Override
    129        public int doEndTag() {
    130                debugPrint();
    131
    132                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    133
    134                // エディット情報をHTMLに変換して表示します。
    135                // 表示に当たって、最後に発行されたQUERYのtableId、scopeをチェックした上で
    136                // 表示するかを判断します。
    137                if( "GET".equals( command ) ) {
    138                        DBLastSql lastSql = (DBLastSql)getSessionAttribute( HybsSystem.DB_LAST_SQL_KEY );
    139                        if( lastSql != null ) {
    140                                if( !lastSql.isViewEditable() ) {
    141                                        // この画面は、項目の並び替えはできません。
    142                                        String rtn = "<b style=\"font-color:red;\">" + getResource().getLabel( "GEE0003" ) + "</b>";
    143                                        jspPrint( rtn );
    144                                }
    145                                else if( lastSql.isGuiMatch( gamenId ) ) {
    146                                        setScope( lastSql.getScope() );
    147                                        table = (DBTableModel)getObject( lastSql.getTableId() );
    148                                        if( table != null ) {
    149                                                config = getUser().getEditConfig( gamenId, editName );
    150                                                String viewClms = null;
    151                                                if( config == null ) {
    152                                                        viewClms = lastSql.getViewClmNames();
    153                                                        config = new DBEditConfig();
    154                                                }
    155                                                else {
    156//                                                      viewClms = config.getViewClms();
    157                                                        viewClms = config.getViewClms( lastSql.getOrgClmNames() );
    158                                                }
    159                                                buf.append( makeEditTable( viewClms ) );
    160                                        }
    161                                }
    162                        }
    163                }
    164                // エディット情報を保存します。
    165                else if( "SET".equals( command ) ) {
    166                        if( editName == null || editName.length() == 0 ) {
    167//                              String msg = "エディット名が指定されていません。";
    168//                              throw new HybsSystemException( msg );
    169                                String errMsg = "エディット名が指定されていません。";
    170                                throw new HybsSystemException( errMsg );        // 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
    171                        }
    172                        saveEditConfig();
    173                }
    174                // エディット情報を削除します。
    175                else if( "DELETE".equals( command ) ) {
    176                        if( editName == null || editName.length() == 0 ) {
    177//                              String msg = "エディット名が指定されていません。";
    178//                              throw new HybsSystemException( msg );
    179                                String errMsg = "エディット名が指定されていません。";
    180                                throw new HybsSystemException( errMsg );        // 5.7.1.2 (2013/12/20) msg ⇒ errMsg 変更
    181                        }
    182                        deleteEditConfig();
    183                }
    184                // 指定された画面IDに対するエディット情報の一覧(プルダウン)を表示します。
    185                else if( "LIST".equals( command ) ) {
    186                        DBEditConfig[] configs = getUser().getEditConfigs( gamenId );
    187                        if( configs != null && configs.length > 0 ) {
    188                                buf.append( getEditSelect( configs ) ).append( HybsSystem.CR );
    189                        }
    190                }
    191
    192                jspPrint( buf.toString() );
    193
    194                return(EVAL_PAGE);
    195        }
    196
    197        /**
    198         * タグリブオブジェクトをリリースします。
    199         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    200         *
    201         * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応
    202         */
    203        @Override
    204        protected void release2() {
    205                super.release2();
    206                command = "GET";
    207                gamenId = null;
    208                editName = null;
    209                table = null;
    210                config = null;
    211                orderOnly               = false; //5.5.5.2 (2012/08/10)
    212        }
    213
    214        /**
    215         * エディット情報をHTMLに変換して表示します。
    216         *
    217         * @og.rev 5.4.2.0 (2011/12/01) 入替え対象のカラム列でのみスクロールが表示されるように対応します。
    218         * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応
    219         *
    220         * @param viewClms 表示カラム(カンマ区切り)
    221         *
    222         * @return エディット情報のHTML
    223         */
    224        private String makeEditTable( final String viewClms ) {
    225                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    226
    227                boolean useSum = getUseSum( viewClms );
    228                String[] viewGroups = StringUtil.csv2Array( viewClms, '|' );
    229                buf.append( "<input type=\"hidden\" name=\"viewClms\" id=\"viewClms\" value=\"" + viewClms + "\"/>" );
    230                buf.append( "<div />" );
    231                buf.append( "<div style=\"float:left;\">" );
    232                buf.append( makeLabelRow( useSum ) );
    233                buf.append( "</div>" );
    234                buf.append( "<div id=\"clmLayer\" style=\" float:left; width: 670px;overflow-x:scroll;\">" );
    235                for( int i=0; i<viewGroups.length; i++ ) {
    236                        if( i > 0 ) {
    237                                buf.append( makeSeparateRow( useSum ) );
    238                        }
    239                        buf.append( "<table class=\"clmGroup\" style=\"float:left;\"><tr>" );
    240                        String[] clms = StringUtil.csv2Array( viewGroups[i] );
    241                        for( int j=0; j<clms.length; j++ ) {
    242                                String clm = ( !clms[j].startsWith( "!" ) ? clms[j] : clms[j].substring( 1 ) );
    243                                if( "rowCount".equals( clm ) ) { continue; }
    244                                boolean isView = ( !clms[j].startsWith( "!" ) ? true : false );
    245                                buf.append( makeColumnRow( clm, isView, useSum, config ) );
    246                        }
    247                        buf.append( "</tr></table>" );
    248                }
    249                buf.append( "</div>" );
    250
    251                String grandTotalLabel = "<b>" + getDBColumn( GRANDTOTAL_PREFIX + "LABEL" ).getLongLabel() + ":</b>";
    252                buf.append( "<div style=\"clear:both;\">" );
    253                buf.append( "<table>" );
    254//              buf.append( makeCheckbox( GRANDTOTAL_PREFIX, config.useGrandTotal(), "h", grandTotalLabel ) );
    255                buf.append( makeCheckbox( GRANDTOTAL_PREFIX, config.useGrandTotal(), "h", grandTotalLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    256                buf.append( "</table>" );
    257                buf.append( "</div>" );
    258
    259                return buf.toString();
    260        }
    261
    262        /**
    263         * エディット情報のヘッダー(ラベル行)のHTMLを生成します。
    264         *
    265         * @og.rev 5.4.2.0 (2011/12/01) 表示項目の全チェック機能を追加
    266         * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応
    267         *
    268         * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか
    269         *
    270         * @return エディット情報のヘッダー(ラベル行)のHTML
    271         */
    272        private String makeLabelRow( final boolean useSum ) {
    273                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL );
    274                String commonLabel = "<b>" + getDBColumn( COMMON_PREFIX + "LABEL" ).getLongLabel() + ":</b>";
    275                String canEditCommon = HybsSystem.sys( "EDIT_COMMON_ROLES" );
    276
    277                String groupLabel = "<b>" + getDBColumn( GROUP_PREFIX + "LABEL" ).getLongLabel() + "</b>";
    278                groupLabel += "<img id=\"groupBtn\" src=\"" + HybsSystem.sys( "JSP" ) + "/image/ball-green.gif\" />";
    279
    280                buf.append( "<table><tr>" );
    281                buf.append( "<td style=\"margin:0px; padding:0px;\"><table>" );
    282                if( getUser().isAccess( canEditCommon ) ) {
    283//                      buf.append( makeCheckbox( COMMON_PREFIX, config.isCommon(), "h", commonLabel ) );
    284                        buf.append( makeCheckbox( COMMON_PREFIX, config.isCommon(), "h", commonLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    285                }
    286                else {
    287                        buf.append( makeLabel   ( commonLabel ) );
    288                }
    289//              buf.append( makeLabel   ( VIEW_PREFIX           + "LABEL" ) );
    290                String viewLabel = "<b>" + getDBColumn( VIEW_PREFIX + "LABEL" ).getLongLabel() + ":</b>";
    291//              buf.append( makeCheckbox( "VIEW_ALL_CHECK", true, "h", viewLabel ) );
    292                buf.append( makeCheckbox( "VIEW_ALL_CHECK", true, "h", viewLabel, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    293                if( useSum ) {
    294                        buf.append( makeLabel   ( SUM_PREFIX            + "LABEL" ) );
    295                }
    296                buf.append( makeCell    ( groupLabel, "h" ) );
    297                buf.append( makeLabel   ( SUBTOTAL_PREFIX       + "LABEL" ) );
    298                buf.append( makeLabel   ( TOTAL_PREFIX          + "LABEL" ) );
    299                buf.append( makeLabel   ( ORDERBY_PREFIX        + "LABEL" ) );
    300                buf.append( makeLabel   ( DESC_PREFIX           + "LABEL" ) );
    301                buf.append( "</table></td>" );
    302                buf.append( "</tr></table>" );
    303                return buf.toString();
    304        }
    305
    306        /**
    307         * エディット情報のカラム列のHTMLを生成します。
    308         *
    309         * @og.rev 5.5.5.2 (2012/08/10) orderOnly対応
    310         * @og.rev 5.7.5.2 (2014/04/11) 降順はorderOnlyに関わらず編集可能にする
    311         *
    312         * @param clm カラム
    313         * @param isView 表示対象かどうか
    314         * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか
    315         * @param config エディット設定オブジェクト
    316         *
    317         * @return エディット情報のカラム列のHTMLを生成します。
    318         */
    319        private String makeColumnRow( final String clm, final boolean isView, final boolean useSum, final DBEditConfig config ) {
    320                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL );
    321
    322                int clmNo = table.getColumnNo( clm, false  );
    323                DBColumn column = ( clmNo < 0 ? getDBColumn( clm ) : table.getDBColumn( clmNo ) );
    324                buf.append( "<td name=\"" ).append( clm ).append( "\" class=\"sortItem\" style=\"margin:0px; padding:0px;\">" );
    325                buf.append( "<table>" );
    326                buf.append( makeLabel   ( column.getLongLabel() ) );
    327//              buf.append( makeCheckbox( VIEW_PREFIX                   + clm, isView                                           , "0", null ) );
    328                buf.append( makeCheckbox( VIEW_PREFIX                   + clm, isView                                           , "0", null, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    329                if( useSum ) {
    330                        boolean isSumClm = isNumberClm( clm );
    331//                      buf.append( makeCheckbox( SUM_PREFIX            + clm, config.isSumClm( clm )           , "1", isSumClm , null ) );
    332                        buf.append( makeCheckbox( SUM_PREFIX            + clm, config.isSumClm( clm )           , "1", isSumClm , null, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    333                }
    334//              buf.append( makeCheckbox( GROUP_PREFIX          + clm, config.isGroupClm( clm )         , "0", null ) );
    335//              buf.append( makeCheckbox( SUBTOTAL_PREFIX       + clm, config.isSubTotalClm( clm )      , "1", null ) );
    336//              buf.append( makeCheckbox( TOTAL_PREFIX          + clm, config.isTotalClm( clm )         , "0", null ) );
    337//              buf.append( makeInput   ( ORDERBY_PREFIX                + clm, config.getOrder( clm )           , "1", null ) );
    338//              buf.append( makeCheckbox( DESC_PREFIX                   + clm, config.isOrderByDesc( clm )      , "0", null ) );
    339                buf.append( makeCheckbox( GROUP_PREFIX          + clm, config.isGroupClm( clm )         , "0", null, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    340                buf.append( makeCheckbox( SUBTOTAL_PREFIX       + clm, config.isSubTotalClm( clm )      , "1", null, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    341                buf.append( makeCheckbox( TOTAL_PREFIX          + clm, config.isTotalClm( clm )         , "0", null, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    342                buf.append( makeInput   ( ORDERBY_PREFIX                + clm, config.getOrder( clm )           , "1", null ) );
    343//              buf.append( makeCheckbox( DESC_PREFIX                   + clm, config.isOrderByDesc( clm )      , "0", null, orderOnly ) ); // 5.5.5.2 (2012/08/10)
    344                buf.append( makeCheckbox( DESC_PREFIX                   + clm, config.isOrderByDesc( clm )      , "0", null, false ) ); // 5.7.5.1 (2014/04/11)
    345                buf.append( "</table>" );
    346                buf.append( "</td>" );
    347
    348                return buf.toString();
    349        }
    350
    351        /**
    352         * チェックボックスのHTML文字列を生成します。
    353         * 生成したHTMLは以下のようになります。
    354         * 例)&lt;tr&gt;&lt;td class="row_[bgCnt]" ...&gt;[prefix]&lt;input type="checkbox" name="[clm]" ... /&gt;&lt;/td&gt;&lt;/tr&gt;
    355         *
    356         * @param clm カラム
    357         * @param checked 初期チェックするかどうか
    358         * @param bgCnt 背景色ゼブラカラーの指定("0"or"1"or"h")
    359         * @param prefix チェックボックスのタグの前に挿入するHTML文字列
    360         * @param readonly リードオンリー
    361         *
    362         * @og.rev 5.5.5.2 (2012/08/10) readOnly追加
    363         *
    364         * @return チェックボックスのHMTL文字列
    365         */
    366//      private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final String prefix ) {
    367        private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final String prefix, final boolean readonly ) {
    368                return makeCheckbox( clm, checked, bgCnt, true, prefix, readonly );
    369        }
    370
    371        /**
    372         * チェックボックスのHTML文字列を生成します。
    373         * 生成したHTMLは以下のようになります。
    374         * 例)&lt;tr&gt;&lt;td class="row_[bgCnt]" ...&gt;[prefix]&lt;input type="checkbox" name="[clm]" ... /&gt;&lt;/td&gt;&lt;/tr&gt;
    375         *
    376         * @param clm カラム
    377         * @param checked 初期チェックするかどうか
    378         * @param bgCnt 背景色ゼブラカラーの指定("0"or"1"or"h")
    379         * @param isChbox チェックボックスを生成するかどうか(falseの場合、チェックボックスのinputタグは生成されません)
    380         * @param prefix チェックボックスのタグの前に挿入するHTML文字列
    381         * @param readonly リードオンリー
    382         *
    383         * @og.rev 5.5.5.2 (2012/08/10) readOnly追加
    384         *
    385         * @return チェックボックスのHMTL文字列
    386         */
    387//      private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final boolean isChbox, final String prefix ) {
    388        private String makeCheckbox( final String clm, final boolean checked, final String bgCnt, final boolean isChbox, final String prefix, final boolean readonly ) {
    389                if( isChbox ) {
    390                        String suffix = "";
    391                        TagBuffer tag = new TagBuffer( "input" );
    392                        tag.add( "type", "checkbox" );
    393                        tag.add( "name", clm );
    394                        tag.add( "value", "1" );
    395                        if( checked ) {
    396                                tag.add( "checked", "checked" );
    397                        }
    398                        if( readonly ){ // 5.5.5.2 (2012/08/10)
    399                                tag.add( "disabled", "disabled" );
    400                                if( checked ){
    401                                        TagBuffer tag2 = new TagBuffer( "input" );
    402                                        tag2.add( "type", "hidden" );
    403                                        tag2.add( "name", clm );
    404                                        tag2.add( "value", "1" );
    405                                        suffix += tag2.makeTag();
    406                                }
    407
    408                        }
    409//                      return makeCell( ( prefix == null ? "" : prefix ) + tag.makeTag(), bgCnt );
    410                        return makeCell( ( prefix == null ? "" : prefix ) + tag.makeTag() + suffix, bgCnt ); // 5.5.5.2 (2012/08/10)
    411                }
    412                else {
    413                        return makeCell( ( prefix == null ? "" : prefix ) + "&nbsp;", bgCnt );
    414                }
    415        }
    416
    417        /**
    418         * テキスト入力HTML文字列を生成します。
    419         * 生成したHTMLは以下のようになります。
    420         * 例)&lt;tr&gt;&lt;td class="row_[bgCnt]" ...&gt;[prefix]&lt;input type="text" name="[clm]" ... /&gt;&lt;/td&gt;&lt;/tr&gt;
    421         *
    422         * @param clm カラム
    423         * @param value 初期チェックするかどうか
    424         * @param bgCnt 背景色ゼブラカラーの指定("0"or"1"or"h")
    425         * @param prefix チェックボックスのタグの前に挿入するHTML文字列
    426         *
    427         * @return チェックボックスのHMTL文字列
    428         */
    429        private String makeInput( final String clm, final String value, final String bgCnt, final String prefix ) {
    430                TagBuffer tag = new TagBuffer( "input" );
    431                tag.add( "type", "text" );
    432                tag.add( "name", clm );
    433                tag.add( "value", value );
    434                tag.add( "style", "width: 10px; font-size:10px;" );
    435                tag.add( "maxlength", "2" );
    436                tag.add( "class", "S9" );
    437
    438                return makeCell( ( prefix == null ? "" : prefix ) + tag.makeTag(), bgCnt );
    439        }
    440
    441        /**
    442         * 左右分割されている際の分割列のHTML文字列を生成します。
    443         *
    444         * @param useSum 集計対象のカラム(=NUMBER型)が存在しているか
    445         *
    446         * @return チェックボックスのHMTL文字列
    447         */
    448        private String makeSeparateRow( final boolean useSum ) {
    449                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL );
    450
    451                buf.append( "<table style=\"float:left;\"><tr>" );
    452                buf.append( "<td style=\"margin:0px; padding:0px;\"><table>" );
    453                buf.append( makeCell( "&nbsp", "h" ) );             // ラベル
    454                buf.append( makeCell( "&nbsp", "h" ) );             // 表示
    455                if( useSum ) {
    456                        buf.append( makeCell( "&nbsp", "h" ) );             // 集計項目
    457                }
    458                buf.append( makeCell( "&nbsp", "h" ) ); // 集計キー
    459                buf.append( makeCell( "&nbsp", "h" ) );     // 小計キー
    460                buf.append( makeCell( "&nbsp", "h" ) ); // 合計キー
    461                buf.append( makeCell( "&nbsp", "h" ) ); // 表示順
    462                buf.append( makeCell( "&nbsp", "h" ) ); // 昇順・降順
    463                buf.append( "</table></td>");
    464                buf.append( "</tr></table>" );
    465
    466                return buf.toString();
    467        }
    468
    469        /**
    470         * ラベルのHTML文字列を生成します。
    471         *
    472         * @param clm カラム
    473         *
    474         * @return ラベルのHTML文字列
    475         */
    476        private String makeLabel( final String clm ) {
    477                return makeCell( getDBColumn( clm ).getLongLabel(), "h" );
    478        }
    479
    480        /**
    481         * セルのHTML文字列を生成します。
    482         *
    483         * @param body tdタグ内のHTML文字列
    484         * @param bgCnt 背景色ゼブラカラーの指定("0"or"1"or"h")
    485         *
    486         * @return セルのHTML文字列
    487         */
    488        private String makeCell( final String body, final String bgCnt ) {
    489                return "<tr><td align=\"center\" style=\"height:22px;\" class=\"row_" + bgCnt + "\">" + body + "</td></tr>";
    490        }
    491
    492        /**
    493         * このエディット設定で集計対象のカラム(=NUMBER型)が存在しているかを返します。
    494         *
    495         * @param viewClms カラム
    496         *
    497         * @return 集計対象のカラム(=NUMBER型)が存在しているか
    498         */
    499        private boolean getUseSum( final String viewClms ) {
    500                if( viewClms == null ) { return false; }
    501
    502                boolean rtn = false;
    503                String[] clms = StringUtil.csv2Array( viewClms.replace( '|', ',' ) );
    504                for( int j=0; j<clms.length; j++ ) {
    505                        String clm = ( !clms[j].startsWith( "!" ) ? clms[j] : clms[j].substring( 1 ) );
    506                        rtn = isNumberClm( clm );
    507                        if( rtn ) { break; }
    508                }
    509                return rtn;
    510        }
    511
    512        /**
    513         * 引数のカラムがNUMBER型かどうかをチェックします。
    514         *
    515         * @param clm カラム
    516         *
    517         * @return NUMBER型かどうか
    518         */
    519        private boolean isNumberClm( final String clm ) {
    520                if( clm == null ) { return false; }
    521
    522                int no = table.getColumnNo( clm, false );
    523                if( no >= 0 ) {
    524                        DBColumn dbClm = table.getDBColumn( table.getColumnNo( clm ) );
    525                        if( dbClm != null ) {
    526                                if( "NUMBER".equals( dbClm.getClassName()) ) {
    527                                        return true;
    528                                }
    529                        }
    530                }
    531                return false;
    532        }
    533
    534        /**
    535         * エディット設定情報を保存します。
    536         */
    537        private void saveEditConfig() {
    538                String viewClms         = getRequest().getParameter( "viewClms" );
    539                String sumClms          = getColumns( SUM_PREFIX );
    540                String groupClms        = getColumns( GROUP_PREFIX );
    541                String subTotalClms = getColumns( SUBTOTAL_PREFIX );
    542                String totalClms        = getColumns( TOTAL_PREFIX );
    543                String useGrandTotal= getRequest().getParameter( GRANDTOTAL_PREFIX );
    544                String orderByClms      = getOrderByColumns();
    545                String isCommon         = getRequest().getParameter( COMMON_PREFIX );
    546
    547                DBEditConfig config
    548                        = new DBEditConfig( editName, viewClms, sumClms, groupClms
    549                                                                , subTotalClms, totalClms, useGrandTotal, orderByClms, isCommon );
    550
    551                getUser().addEditConfig( gamenId, editName, config );
    552        }
    553
    554        /**
    555         * エディット設定情報を削除します。
    556         */
    557        private void deleteEditConfig() {
    558                getUser().deleteEditConfig( gamenId, editName );
    559        }
    560
    561        /**
    562         * パラメーターから引数のプレフィックスをキーに、チェックされたカラム一覧(カンマ区切り)を返します。
    563         *
    564         * @param prefixKey 各キーの取得するためのプレフィックス
    565         *
    566         * @return カラム一覧(カンマ区切り)
    567         */
    568        private String getColumns( final String prefixKey ) {
    569                StringBuilder buf = new StringBuilder();
    570
    571                Enumeration<?> enume = getParameterNames();
    572                while( enume.hasMoreElements() ) {
    573                        String key = (String)(enume.nextElement());
    574                        if( key.startsWith( prefixKey ) ) {
    575                                String val = getRequest().getParameter( key );
    576                                if( "1".equals( val ) ) {
    577                                        String clm = key.substring( prefixKey.length() );
    578                                        if( buf.length() > 0 ) { buf.append( "," ); }
    579                                        buf.append( clm );
    580                                }
    581                        }
    582                }
    583
    584                return buf.toString();
    585        }
    586
    587        /**
    588         * 表示順のカラム一覧(カンマ区切り)を返します。
    589         *
    590         * @return 表示順のカラム一覧(カンマ区切り)
    591         */
    592        private String getOrderByColumns() {
    593                Enumeration<?> enume = getParameterNames();
    594                List<Integer> orderNo = new ArrayList<Integer>();
    595                Map<Integer,String> orderClm = new HashMap<Integer,String>();
    596                while( enume.hasMoreElements() ) {
    597                        String key = (String)(enume.nextElement());
    598                        if( key.startsWith( ORDERBY_PREFIX ) ) {
    599                                String val = getRequest().getParameter( key );
    600                                if( val != null && val.length() > 0 ) {
    601                                        String clm = key.substring( ORDERBY_PREFIX.length() );
    602                                        String desc = getRequest().getParameter( DESC_PREFIX + clm );
    603                                        if( "1".equals( desc ) ) {
    604                                                clm = "!"  + clm;
    605                                        }
    606                                        // 数字項目以外が入力された場合は無視
    607                                        Integer odno = null;
    608                                        try {
    609                                                odno = Integer.valueOf( val );
    610                                        }
    611                                        catch ( NumberFormatException ex ) {
    612                                                continue;
    613                                        }
    614                                        String str = orderClm.get( odno );
    615                                        // 同じ番号の場合でも重ならないように振り直しする。
    616                                        while( str != null ) {
    617                                                odno = Integer.valueOf( odno.intValue() + 1 );
    618                                                str = orderClm.get( odno );
    619                                        }
    620                                        orderClm.put( odno, clm );
    621                                        orderNo.add( odno );
    622                                }
    623                        }
    624                }
    625
    626                Collections.sort( orderNo );
    627
    628                StringBuilder buf = new StringBuilder();
    629                for( Integer i : orderNo ) {
    630                        if( buf.length() > 0 ) { buf.append( "," ); }
    631                        String clm = orderClm.get( i );
    632                        buf.append( clm );
    633                }
    634
    635                return buf.toString();
    636        }
    637
    638        /**
    639         * エディット設定一覧のプルダウンメニューを作成します。
    640         *
    641         * @param       configs DBEditConfig配列
    642         *
    643         * @return      エディット一覧のプルダウン
    644         */
    645        private String getEditSelect( final DBEditConfig[] configs ) {
    646                DBColumn column = getDBColumn( "editName" );
    647
    648                StringBuilder buf = new StringBuilder();
    649                buf.append( "<span class=\"label editName\">" )
    650                        .append( column.getLongLabel() )
    651                        .append( ":</span><span class=\"editName\">" )
    652                        .append( "<select name=\"editName\">" )
    653                        .append( "<option />" );
    654                for( DBEditConfig config : configs ) {
    655                        String name = config.getEditName();
    656                        buf.append( "<option value=\"" ).append( name ).append( "\"" );
    657                        if( config.isCommon() ) {
    658                                buf.append( " class=\"commonEdit\"" );
    659                        }
    660                        buf.append( "\">" );
    661                        buf.append( name ).append( "</option>" );
    662                }
    663                buf.append( "</select></span>" );
    664                return buf.toString();
    665        }
    666
    667        /**
    668         * 【TAG】command を指定します。
    669         *
    670         * @og.tag
    671         * command を指定します。
    672         * [GET/LIST/SET/DELETE]のみが設定可能です。それ以外の場合、何も処理されません。
    673         *
    674         * @param       cmd コマンド[GET/LIST/SET/DELETE]
    675         */
    676        public void setCommand( final String cmd ) {
    677                command = nval( getRequestParameter( cmd ),command );
    678        }
    679
    680        /**
    681         * 【TAG】画面ID を指定します。
    682         *
    683         * @og.tag
    684         * 画面ID を指定します。
    685         *
    686         * @param       key 画面ID
    687         */
    688        public void setGamenId( final String key ) {
    689                gamenId = nval( getRequestParameter( key ),gamenId );
    690        }
    691
    692        /**
    693         * 【TAG】エディット名 を指定します。
    694         *
    695         * @og.tag
    696         * エディット名 を指定します。
    697         * commandがSETまたはDELETEの場合は必須です。
    698         * commandがGETまたはLISTの場合は無効です。
    699         *
    700         * @param       name エディット名
    701         */
    702        public void setEditName( final String name ) {
    703                editName = nval( getRequestParameter( name ),editName );
    704        }
    705
    706        /**
    707         * 【TAG】チェックボックスのリードオンリー化を行います
    708         *
    709         * @og.tag
    710         * 順番の入れ替えと、表示順の設定のみを行う場合にtrueにします。
    711         * 表示/非表示切替や、集計機能は利用できなくなります。
    712         * （チェックボックスのリードオンリーはできないため、実際にはdisable+hiddenで出力しています）
    713         *
    714         * @og.rev 5.5.5.2 (2012/08/10) 新規追加
    715         *
    716         * @param   flag  [true:リードオンリー/それ以外:編集可]
    717         */
    718        public void setOrderOnly( final String flag ) {
    719                orderOnly = nval( getRequestParameter( flag ),orderOnly );
    720        }
    721
    722        /**
    723         * このオブジェクトの文字列表現を返します。
    724         * 基本的にデバッグ目的に使用します。
    725         *
    726         * @return このクラスの文字列表現
    727         */
    728        @Override
    729        public String toString() {
    730                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
    731                                .println( "VERSION"             ,VERSION                )
    732                                .println( "command"             ,command                )
    733                                .println( "gamenId"             ,gamenId                )
    734                                .println( "editName"    ,editName               )
    735                                .println( "Other..."    ,getAttributes().getAttribute() )
    736                                .fixForm().toString() ;
    737        }
    738}