    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 org.opengion.fukurou.system.OgRuntimeException ;         // 6.4.2.0 (2016/01/29)
    019import static org.opengion.fukurou.util.StringUtil.nval;
    020
    021import java.io.File;
    022
    023import org.opengion.fukurou.db.ConnectionFactory;
    024import org.opengion.fukurou.db.DatabaseConfig;
    025import org.opengion.fukurou.util.StringUtil;
    026import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    027import org.opengion.hayabusa.common.HybsSystem;
    028import org.opengion.hayabusa.common.HybsSystemException;
    029import org.opengion.hayabusa.db.DBTableModel;
    030import org.opengion.hayabusa.db.DBTableModelUtil;
    031
    032/**
    033 * DBConfig.xmlの編集を行うためのタグです。
    034 *
    035 * 自分自身のコンテキストのDBConfig.xmlの編集及び、ファイルパスを指定して他の
    036 * コンテキストのDBConfig.xmlの編集を行うことができます。
    037 *
    038 * 編集タイプは、type属性により、「DBドライバークラス」と「DBIDの設定情報」の2つを
    039 * 切り替えることができます。
    040 *
    041 * また、このタグ自体の機能としては、「取得」、「保存」、「情報」に分離されています。
    042 *
    043 * (1)取得(command="GET")
    044 *  type属性で指定された情報を読み取り、DBTableModel形式に変換し、セッションに登録します。
    045 *  (tableIdは"DEFAULT"です)
    046 *
    047 * (2)保存(command="SET")
    048 *  セッションからDBTableModelを読み取り、type属性で指定された情報の形式にオブジェクト化し、
    049 *  DBConfig.xmlに保存します。
    050 *  (DBTableModelを取得するtableIdは"DEFAULT"です)
    051 *
    052 *  保存を実行すると、元のDBConfig.xmlファイルと同じ場所に、タイプスタンプ付きのバックアップ
    053 *  ファイルが自動的に作成されます。
    054 *
    055 *  また、xmlFile(DBConfig.xml)を指定しない状態で、保存(command="SET")を行うと、
    056 *  内部にキャッシュしている接続情報は、一旦全てクリアされます。
    057 *
    058 * (3)情報(command="INFO")
    059 *  DBID情報のキーとタイトルから、プルダウンメニューを作成するための情報を画面出力します。
    060 *  この値を、valueタグで取込み、columnタグのcodeKeyVal変数にセットすれば、DBIDの選択メニューを
    061 *  作成できます。開発用に接続先を切り替える処理等に使います。
    062 *
    063 * @og.formSample
    064 * ●形式：&lt;dbConfigEditor command="..." type="..." xmlFile="..." /&gt;
    065 * ●body：なし
    066 *
    067 * ●Tag定義：
    068 *   &lt;og:dbConfigEditor
    069 *       command            【TAG】DBConfig.xmlに対する操作のコマンド (GET/SET/INFO)を指定します(初期値:GET)
    070 *       type               【TAG】DBConfig.xmlに対する操作のタイプ(DBID/CLASS)を指定します(初期値:DBID)
    071 *       xmlFile            【TAG】編集を行うDBConfig.xmlのファイルのパスを指定します(初期値:自身のDBConfig.xml)
    072 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    073 *   /&gt;
    074 *
    075 * ●使用例
    076 *    ・取得
    077 *        &lt;dbConfigEditor command="GET" type="{&#064;TYPE}" xmlFile="{&#064;DBCXML}" /&gt;
    078 *
    079 *    ・保存
    080 *        &lt;dbConfigEditor command="SET" type="{&#064;MEM.TYPE}" xmlFile="{&#064;MEM.DBCXML}" /&gt;
    081 *
    082 *    ・情報
    083 *        &lt;value command="SET" key="DBID_INFO" &gt;
    084 *          &lt;dbConfigEditor command="INFO" /&gt;
    085 *        &lt;/value&gt;
    086 *
    087 *        &lt;column name="DBID_INFO" codeKeyVal="{&#064;DBID_INFO}" /&gt;
    088 *
    089 * @og.group その他部品
    090 *
    091 * @version  4.0
    092 * @author       Hiroki Nakamura
    093 * @since    JDK5.0,
    094 */
    095public class DBConfigEditorTag extends CommonTagSupport {
    096        /** このプログラムのVERSION文字列を設定します。   {@value} */
    097        private static final String VERSION = "6.4.2.0 (2016/01/29)" ;
    098        private static final long serialVersionUID = 642020160129L ;
    099
    100        private transient DBTableModel  table   ;               // 5.1.9.0 (2010/08/01) transient 追加
    101        private String                  command = "GET";
    102        private String                  type    = "DBID";
    103        private String                  xmlFile ;
    104
    105        /**
    106         * デフォルトコンストラクター
    107         *
    108         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    109         */
    110        public DBConfigEditorTag() { super(); }         // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    111
    112        /**
    113         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    114         *
    115         * @return      後続処理の指示( SKIP_BODY )
    116         */
    117        @Override
    118        public int doStartTag() {
    119                startQueryTransaction( HybsSystem.TBL_MDL_KEY );
    120                return  SKIP_BODY ;
    121        }
    122
    123        /**
    124         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    125         *
    126         * @og.rev 5.6.7.0 (2013/07/27) command="INFO" 対応
    127         *
    128         * @return      後続処理の指示
    129         */
    130        @Override
    131        public int doEndTag() {
    132                debugPrint();
    133
    134                // DatabaseConfigオブジェクトを取得します。
    135                DatabaseConfig dbc = null;
    136                if( xmlFile == null ) {
    137                        dbc = new DatabaseConfig();
    138                }
    139                else {
    140                        if( !( new File( xmlFile ) ).exists() ) {
    141                                throw new HybsSystemException( "編集対象のDBConfig.xmlが存在しません。File=[" + xmlFile + "]" );
    142                        }
    143                        dbc = new DatabaseConfig( xmlFile );
    144                }
    145
    146                // 編集タイプに応じてキー情報をセットします。
    147                String[] keys = null;
    148                if( "DBID".equals( type ) ) {
    149                        keys = DatabaseConfig.getDbidInfoKeys();
    150                }
    151                else if( "CLASS".equals( type ) ) {
    152                        keys = new String[1];
    153                        keys[0] = DatabaseConfig.getDriverKey();
    154                }
    155
    156                // DBConfig.xmlから情報を取得します。
    157                if( "GET".equals( command ) ) {
    158                        table = getDBConfig( dbc, keys );
    159
    160                        if( table != null && !commitTableObject( HybsSystem.TBL_MDL_KEY, table ) ) {
    161                                jspPrint( "QueryTag Query処理が割り込まれました。DBTableModel は登録しません。" );
    162                                return SKIP_PAGE ;
    163                        }
    164                }
    165                // DBConfig.xmlに情報を保存します。
    166                else if( "SET".equals( command ) ) {
    167                        setDBConfig( dbc, keys );
    168
    169                        // xmlFileが指定されていない(=自信のDBConfig.xml)を書き換えた場合は、キャッシュをクリアします。
    170                        if( xmlFile == null ) {
    171                                ConnectionFactory.realClose();
    172                                ConnectionFactory.init( HybsSystem.getContextName(), null );
    173                        }
    174                }
    175                // 5.6.7.0 (2013/07/27) command="INFO" 対応
    176                else if( "INFO".equals( command ) ) {
    177                        jspPrint( dbc.getCodeKeyVal() );
    178                }
    179
    180                return EVAL_PAGE ;
    181        }
    182
    183        /**
    184         * DBConfig.xmlから情報を取得します。
    185         *
    186         * @param       dbc             DatabaseConfigオブジェクト
    187         * @param       keys    編集する情報のカラムキー配列(可変長引数)
    188         *
    189         * @return      テーブルモデル
    190         */
    191        private DBTableModel getDBConfig( final DatabaseConfig dbc, final String... keys ) {
    192                String[][] vals = null;
    193                if( "DBID".equals( type ) ) {
    194                        vals = dbc.getDbidInfo();
    195                }
    196                else if( "CLASS".equals( type ) ) {
    197                        final String[] tmpVals = dbc.getDriverList();
    198                        vals = new String[tmpVals.length][1];
    199                        for( int i=0; i<tmpVals.length; i++ ) {
    200                                vals[i][0] = tmpVals[i];
    201                        }
    202                }
    203
    204                return DBTableModelUtil.makeDBTable( keys, vals, getResource() );
    205        }
    206
    207        /**
    208         * DBConfig.xmlに情報を保存します。
    209         *
    210         * @param dbc DatabaseConfigオブジェクト
    211         * @param keys 編集する情報のカラムキー配列(可変長引数)
    212         */
    213        private void setDBConfig( final DatabaseConfig dbc, final String... keys ) {
    214                table = (DBTableModel)getObject( HybsSystem.TBL_MDL_KEY );
    215
    216                final String tmpKeys = StringUtil.array2csv( table.getNames() );
    217                if( !StringUtil.array2csv( keys ).equals( tmpKeys ) ) {
    218                        throw new OgRuntimeException( "DBTableModelのキーが不正です" );
    219                }
    220
    221                final int row = table.getRowCount();
    222                String[][] vals = new String[row][keys.length];
    223                for( int i=0; i<row; i++ ) {
    224                        vals[i] = table.getValues( i );
    225                }
    226
    227                if( "DBID".equals( type ) ) {
    228                        dbc.setDbidInfo( vals );
    229                }
    230                else if( "CLASS".equals( type ) ) {
    231                        String[] tmpVals = new String[vals.length];
    232                        for( int i=0; i<vals.length; i++ ) {
    233                                tmpVals[i] = vals[i][0];
    234                        }
    235                        dbc.setDriverList( tmpVals );
    236                }
    237        }
    238
    239        /**
    240         * タグリブオブジェクトをリリースします。
    241         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    242         *
    243         */
    244        @Override
    245        protected void release2() {
    246                super.release2();
    247                command                 = "GET";
    248                type                    = "DBID";
    249                xmlFile                 = null;
    250        }
    251
    252        /**
    253         * 【TAG】DBConfig.xmlに対する操作のコマンド (GET/SET/INFO)を指定します(初期値:GET)。
    254         *
    255         * @og.tag
    256         *  GET  ⇒ typeに応じた情報をDBConfig.xmlから読み出し、DBTableModelに登録します。
    257         *  SET  ⇒ typeに応じた情報をDBTableModelから読み出し、DBConfig.xmlに登録します。
    258         *  INFO ⇒ DBConfig.xmlに登録されている DBID のキーとタイトルを連結したコードリソース情報を画面出力します。
    259         *
    260         * なお、保存(SET)を実行すると、元のDBConfig.xmlファイルと同じ場所に、タイプスタンプ付きの
    261         * バックアップファイルが自動的に作成されます。
    262         *
    263         * また、xmlFile(DBConfig.xml)を指定しない状態で、保存(command="SET")を行うと、
    264         * 内部にキャッシュしている接続情報は、一旦全てクリアされます。
    265         *
    266         * @og.rev 5.6.7.0 (2013/07/27) command として使用できる文字列をチェックします。
    267         *
    268         * @param       cmd コマンド
    269         */
    270        public void setCommand( final String cmd ) {
    271                command = nval( getRequestParameter( cmd ),command );
    272
    273                // 5.6.7.0 (2013/07/27) command として使用できる文字列をチェックします。
    274                if( "|GET|SET|INFO|".indexOf( "|" + command + "|" ) < 0 ) {
    275                                final String errMsg = "commandは GET,SET,INFO のどれかです。"
    276                                                        + "command=" + command ;
    277                                throw new HybsSystemException( errMsg );
    278                }
    279        }
    280
    281        /**
    282         * 【TAG】DBConfig.xmlに対する操作のタイプ(DBID/CLASS)を指定します(初期値:DBID)。
    283         *
    284         * @og.tag
    285         *  DBID  ⇒ DBIDの各種情報を読み取り/書き込みします。
    286         *  CLASS ⇒ ロードするDBドライバーの一覧を読み取り/書き込みします。
    287         *
    288         * @og.rev 5.6.7.0 (2013/07/27) type として使用できる文字列をチェックします。
    289         *
    290         * @param       tp タイプ
    291         */
    292        public void setType( final String tp ) {
    293                type = nval( getRequestParameter( tp ),type );
    294
    295                // 5.6.7.0 (2013/07/27) type として使用できる文字列をチェックします。
    296                if( "|DBID|CLASS|".indexOf( "|" + type + "|" ) < 0 ) {
    297                                final String errMsg = "typeは DBID,CLASS のどれかです。"
    298                                                        + "type=" + type ;
    299                                throw new HybsSystemException( errMsg );
    300                }
    301        }
    302
    303        /**
    304         * 【TAG】編集を行うDBConfig.xmlのファイルのパスを指定します(初期値:自身のDBConfig.xml)。
    305         *
    306         * @og.tag
    307         * 何も指定されない場合は、自身のコンテキストのDBConfig.xmlに対する編集となります。
    308         *
    309         * @param       file DBConfig.xmlのファイルパス
    310         */
    311        public void setXmlFile( final String file ) {
    312                xmlFile = nval( getRequestParameter( file ),xmlFile );
    313        }
    314
    315        /**
    316         * このオブジェクトの文字列表現を返します。
    317         * 基本的にデバッグ目的に使用します。
    318         *
    319         * @return このクラスの文字列表現
    320         * @og.rtnNotNull
    321         */
    322        @Override
    323        public String toString() {
    324                return ToString.title( this.getClass().getName() )
    325                                .println( "VERSION"             ,VERSION        )
    326                                .println( "command"             ,command        )
    327                                .println( "type"                ,type           )
    328                                .println( "xmlFile"             ,xmlFile        )
    329                                .println( "Other..."    ,getAttributes().getAttribute() )
    330                                .fixForm().toString() ;
    331        }
    332}