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