    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.fukurou.db;
    017
    018import java.sql.DatabaseMetaData;
    019import java.sql.SQLException;
    020import java.util.Locale;
    021import java.util.Properties;
    022import static org.opengion.fukurou.system.HybsConst.CR;                         // 6.1.0.0 (2014/12/26) refactoring
    023import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;      // 6.1.0.0 (2014/12/26) refactoring
    024import org.opengion.fukurou.system.OgRuntimeException ;         // 6.4.2.0 (2016/01/29)
    025
    026/**
    027 * JAXBで自動生成されたDBIDクラスを拡張したクラスです。
    028 * (継承しているわけではない)
    029 * <BR>
    030 * 以下の属性が追加されています。<BR>
    031 * dbProductName<BR>
    032 * dbProductVersion<BR>
    033 * driverName<BR>
    034 * driverVersion<BR>
    035 *
    036 * @og.rev 4.0.0.0 (2007/10/25) 新規作成
    037 * @og.rev 5.1.7.0 (2010/06/01) メソッドの修正、Cloneable の追加(浅いコピー)
    038 * @og.rev 5.6.6.0 (2013/07/05) 表題(title)属性を追加
    039 *
    040 * @version  4.0
    041 * @author       高橋正和
    042 * @since        JDK5.0,
    043 */
    044public class EDbid implements Cloneable {
    045
    046        private         String  dbidKey                 = "DEFAULT";
    047        private         String  title                   ;                                               // 5.6.6.0 (2013/07/05) 表題(title)属性を追加
    048        private         String  url                             ;
    049        private         String  user                    ;
    050        private         String  password                = "";                                   // 5.7.2.0 (2014/01/10) パスワードは空文字を初期値とする。
    051        private         boolean readonly                ;
    052        private         int             mincount                = 3;
    053        private         int             maxcount                = 30;
    054        private         int             pooltime                = 3000;         // (秒数)
    055        private         boolean isUseAppInfo    = true;
    056        private         boolean isParamMetaData ;                                               // 5.3.8.0 (2011/08/01)
    057
    058        private         String  dbProductName   ;
    059        private         String  dbProductVersion;
    060        private         String  driverName              ;
    061        private         String  driverVersion   ;
    062
    063        /* 5.5.2.0 (2012/05/01) DBConfigでpropertiesの指定を可能にします */
    064        private final Properties props = new Properties();
    065
    066        /**
    067         * デフォルトコンストラクター
    068         *
    069         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    070         */
    071        public EDbid() { super(); }             // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    072
    073        /**
    074         * dbidKeyの取得
    075         *
    076         * 内部的には、大文字のみで管理します。
    077         *
    078         * @return      dbidキー
    079         */
    080        public String getDbidKey() {
    081                return dbidKey;
    082        }
    083
    084        /**
    085         * dbidキーの設定
    086         *
    087         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    088         * 内部的には、大文字のみで管理します。
    089         *
    090         * @og.rev 4.1.0.1 (2008/01/21) 登録時に、大文字に変換する。
    091         *
    092         * @param value 接続先ID
    093         */
    094        protected void setDbidKey( final String value ) {
    095                if( isNotNull( value ) ) { dbidKey = value.toUpperCase( Locale.JAPAN ); }
    096        }
    097
    098        /**
    099         * 表題(title)属性の取得
    100         *
    101         * この、dbidKey を表す表題を取得します。ラベル（名前）のようなものです。
    102         *
    103         * @og.rev 5.6.6.0 (2013/07/05) 新規追加
    104         *
    105         * @return      表題(title)
    106         */
    107        public String getTitle() {
    108                return title;
    109        }
    110
    111        /**
    112         * 表題(title)の設定
    113         *
    114         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    115         *
    116         * @og.rev 5.6.6.0 (2013/07/05) 新規追加
    117         * @og.rev 5.6.8.0 (2013/09/06) title が未設定の時は、dbidKey をセットしておきます。
    118         *
    119         * @param value 表題(title)
    120         */
    121        protected void setTitle( final String value ) {
    122                if( isNotNull( value ) ) { title = value; }
    123                else                                     { title = dbidKey; }           // 5.6.8.0 (2013/09/06)
    124        }
    125
    126        /**
    127         * ＵＲＬの取得。
    128         *
    129         * @return      ＵＲＬ
    130         */
    131        public String getUrl() {
    132                return url;
    133        }
    134
    135        /**
    136         * ＵＲＬの設定
    137         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    138         *
    139         * @param value ＵＲＬ文字列
    140         */
    141        protected void setUrl( final String value ) {
    142                if( isNotNull( value ) ) { url = value; }
    143        }
    144
    145        /**
    146         * ユーザーの取得。
    147         *
    148         * @return      ユーザー
    149         */
    150        public String getUser() {
    151                return user;
    152        }
    153
    154        /**
    155         * userの設定
    156         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    157         *
    158         * @param value user文字列
    159         */
    160        protected void setUser( final String value ) {
    161                if( isNotNull( value ) ) { user = value; }
    162        }
    163
    164        /**
    165         * パスワードの取得。
    166         *
    167         * @return      パスワード
    168         */
    169        public String getPassword() {
    170                return password;
    171        }
    172
    173        /**
    174         * パスワードの設定
    175         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    176         *
    177         * @param value パスワード文字列
    178         */
    179        protected void setPassword( final String value ) {
    180                if( isNotNull( value ) ) { password = value; }
    181        }
    182
    183        /**
    184         * readonlyの取得。
    185         *
    186         * @return      [true:読み取り専用/false:通常]
    187         */
    188        public boolean isReadonly() {
    189                return readonly ;
    190        }
    191
    192        /**
    193         * readonlyの設定
    194         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    195         *
    196         * @param value  readonly文字列 [true/false]
    197         */
    198        protected void setReadonly( final String value ) {
    199                if( isNotNull( value ) ) { readonly = Boolean.parseBoolean( value ); }          // 6.1.0.0 (2014/12/26) refactoring
    200        }
    201
    202        /**
    203         * 最小数の取得。
    204         *
    205         * @return      最小数
    206         */
    207        public int getMincount() {
    208                return mincount;
    209        }
    210
    211        /**
    212         * 最小数の設定
    213         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    214         *
    215         * @param value 最小数(数字タイプ文字列)
    216         */
    217        protected void setMincount( final String value ) {
    218                if( isNotNull( value ) ) { mincount = Integer.parseInt( value ); }              // 6.0.2.4 (2014/10/17) メソッド間違い
    219        }
    220
    221        /**
    222         * 最大数の取得。
    223         *
    224         * @return      最大数
    225         */
    226        public int getMaxcount() {
    227                return maxcount;
    228        }
    229
    230        /**
    231         * 最大数の設定
    232         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    233         *
    234         * @param value 最大数(数字タイプ文字列)
    235         */
    236        protected void setMaxcount( final String value ) {
    237                if( isNotNull( value ) ) { maxcount = Integer.parseInt( value ); }              // 6.0.2.4 (2014/10/17) メソッド間違い
    238        }
    239
    240        /**
    241         * プールに保管して置く時間(秒数)の取得。
    242         *
    243         * @return      プールに保管する時間(秒数)
    244         */
    245        public int getPooltime() {
    246                return pooltime;
    247        }
    248
    249        /**
    250         * プールに保管して置く時間(秒数))の設定
    251         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    252         *
    253         * @param value プールに保管して置く時間(秒数)(数字タイプ文字列)
    254         */
    255        protected void setPooltime( final String value ) {
    256                if( isNotNull( value ) ) { pooltime = Integer.parseInt( value ); }              // 6.0.2.4 (2014/10/17) メソッド間違い
    257        }
    258
    259        /**
    260         * ApplicationInfoオブジェクトを使用するかどうか[true/false]の情報を取得。
    261         *
    262         * @return      使用するかどうか
    263         */
    264        public boolean isApplicationInfo() {
    265                return isUseAppInfo ;
    266        }
    267
    268        /**
    269         * ApplicationInfoオブジェクトを使用するかどうか[true/false]の情報を設定
    270         * 引数が、null でなく、ゼロ文字列でもない場合のみ、セットします。
    271         *
    272         * @param value ApplicationInfoオブジェクトを使用するかどうか [true/false]
    273         */
    274        protected void setApplicationInfo( final String value ) {
    275                if( isNotNull( value ) ) { isUseAppInfo = Boolean.parseBoolean( value ); }      // 6.1.0.0 (2014/12/26) refactoring
    276        }
    277
    278        /**
    279         * メタデータを受け取って dbProductName,dbProductVersion,driverName,driverVersion を一括で設定します。
    280         *
    281         * @og.rev 4.0.0.0 (2007/10/30) 保持情報オブジェクト化に伴う変更
    282         * @og.rev 5.3.8.0 (2011/08/01) postgreSQL時のカラムタイプ判定の必要有無(ApplicationInfo.useParameterMetaData)
    283         * @og.rev 6.4.9.5 (2016/09/09) DERBY も、isParamMetaData=true を返します。
    284         * @og.rev 8.0.0.0 (2021/09/30) FIREBIRD も、isParamMetaData=true を返します。
    285         *
    286         * @param meta メタデータオブジェクト
    287         * @throws SQLException データベースアクセスエラー
    288         */
    289        public void setMetaDataInfo( final DatabaseMetaData meta ) throws SQLException {
    290                dbProductName   = meta.getDatabaseProductName() ;
    291                dbProductVersion= meta.getDatabaseProductVersion() ;
    292                driverName              = meta.getDriverName() ;
    293                driverVersion   = meta.getDriverVersion() ;
    294
    295                // dbProductName は、大文字にしておいても問題は無いが、今は影響範囲を小さくしておきます。
    296                final String dbName = dbProductName.toUpperCase( Locale.JAPAN );                // 6.4.9.5 (2016/09/09) 大文字化します。
    297
    298                isUseAppInfo    = isUseAppInfo && "ORACLE".equalsIgnoreCase( dbProductName ) ;
    299                isParamMetaData = dbName.contains( "POSTGRES" )
    300                                                || dbName.contains( "FIREBIRD" )                                                // 8.0.0.0 (2021/09/30)
    301                                                || dbName.contains( "DERBY" );                                                  // 6.4.9.5 (2016/09/09)
    302        }
    303
    304        /**
    305         * DBプロダクト名の取得。
    306         *
    307         * @return      DBプロダクト名
    308         */
    309        public String getDbProductName() {
    310                return dbProductName;
    311        }
    312
    313        /**
    314         * DBプロダクト・バージョンの取得。
    315         *
    316         * @return      DBプロダクト・バージョン
    317         */
    318        public String getDbProductVersion() {
    319                return dbProductVersion;
    320        }
    321
    322        /**
    323         * ドライバー名の取得。
    324         *
    325         * @return      ドライバー名
    326         */
    327        public String getDriverName() {
    328                return driverName;
    329        }
    330
    331        /**
    332         * ドライバーのバージョンの取得。
    333         *
    334         * @return      ドライバーのバージョン
    335         */
    336        public String getDriverVersion() {
    337                return driverVersion;
    338        }
    339
    340        /**
    341         * ParamMetaData を利用するかどうか[true/false]を返します。
    342         *
    343         * これは、PostgreSQL の時は、trueになります。
    344         *
    345         * @og.rev 5.3.8.0 (2011/08/01) 新規追加
    346         *
    347         * @return      利用するかどうか[true/false]
    348         */
    349        public boolean useParamMetaData() {
    350                return isParamMetaData ;
    351        }
    352
    353        /**
    354         * propMapへの追加。
    355         *
    356         * @og.rev 5.5.2.0 (2012/05/01) 新規追加
    357         * @param key プロパティのキー
    358         * @param val ポロパティの値
    359         */
    360        protected void addProp( final String key, final String val ) {
    361                props.put ( key, val );
    362        }
    363
    364        /**
    365         * propMapへの追加。
    366         * 最初の=でkeyとvalueを分割する
    367         *
    368         * @og.rev 5.5.2.0 (2012/05/01) 新規追加
    369         * @og.rev 5.5.2.1 (2012/05/07) propsへの追加漏れ,カンマを=に変更
    370         * @param prop プロパティのキーと値の組み合わせ
    371         */
    372        protected void addProp( final String prop ) {
    373                if( prop!=null && prop.indexOf( '=' ) > 0 ){
    374                        final String key = prop.substring( 0 , prop.indexOf('=') );
    375                        final String val = prop.substring( prop.indexOf('=') + 1 );
    376                        addProp( key, val ); // 5.5.2.1 (2012/05/07)
    377                }
    378        }
    379
    380        /**
    381         * propMapの取得。
    382         *
    383         * @og.rev 5.5.2.0 (2012/05/01) 新規追加
    384         * @og.rev 6.3.9.0 (2015/11/06) 内部Propertiesオブジェクトではなく、複製して返します。
    385         *
    386         * @return 複製Propertiesオブジェクト
    387         */
    388        public Properties getProps(){
    389                return new Properties( props );                 // 6.3.9.0 (2015/11/06)
    390        }
    391
    392        /**
    393         * 文字列がnullでも空文字列でもないかどうかを評価します。
    394         *
    395         * スペース文字は、trim() してから、!isEmpty() で判断しますので、false になります。
    396         *
    397         * @og.rev 5.1.7.0 (2010/06/01) 新規作成
    398         *
    399         * @param value 評価する文字列
    400         *
    401         * @return 結果(true:nullでも空文字列でもない)
    402         */
    403        private boolean isNotNull( final String value ) {
    404                return value != null && !value.trim().isEmpty() ;                       // 6.0.2.5 (2014/10/31) refactoring
    405        }
    406
    407        /**
    408         * 自分自身の clone を返します。
    409         *
    410         * Cloneable の実装で、内部的には、Object クラスの clone メソッドを読んでいます。
    411         *
    412         * @og.rev 5.1.7.0 (2010/06/01) 新規作成
    413         *
    414         * @return      自分自身の clone を返します。
    415         * @throws      RuntimeException clone が失敗しました場合
    416         * @og.rtnNotNull
    417         */
    418        @Override
    419        public EDbid clone() {
    420                try {
    421                        return (EDbid)super.clone() ;
    422                }
    423                catch( final CloneNotSupportedException ex ) {
    424                        final String errMsg = "clone が失敗しました。"
    425                                                                + ex.getMessage() ;
    426                        throw new OgRuntimeException( errMsg,ex );
    427                }
    428        }
    429
    430        /**
    431         * 自分自身の clone を返します。
    432         *
    433         * ここでは、dbidKey を指定した、clone() を作成します。
    434         * Titleも、指定した、dbidKey をセットしておきます。
    435         *
    436         * @og.rev 6.4.3.4 (2016/03/11) 新規作成
    437         *
    438         * @param id 接続先ID
    439         * @return      dbidKeyを指定して、自分自身のcloneを返します。
    440         * @og.rtnNotNull
    441         */
    442        public EDbid clone( final String id ) {
    443                final EDbid obj = this.clone();
    444                obj.setDbidKey( id );
    445                obj.setTitle( id );
    446
    447                return obj;
    448        }
    449
    450        /**
    451         * 簡易な内部情報の文字列化します。
    452         *
    453         * @og.rev 5.3.4.0 (2011/04/01) toString() の簡易版
    454         * @og.rev 5.5.2.1 (2012/05/07) properties情報を出力するようにする
    455         * @og.rev 5.6.6.0 (2013/07/05) 表題(title)属性を追加
    456         *
    457         * @return 内部情報の文字列
    458         * @og.rtnNotNull
    459         */
    460        public String info() {
    461                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    462                        .append( "DBID=["  ).append( dbidKey ).append( "] , " )
    463                        .append( "TITLE=[" ).append( title   ).append( "] , " )                 // 5.6.6.0 (2013/07/05) 表題(title)属性を追加
    464                        .append( "URL=["   ).append( url     ).append( "] , " )
    465                        .append( "USER=["  ).append( user    ).append( ']'  )
    466                        .append( CR )
    467                        .append( "DB Product=[" ).append( dbProductName )
    468                        .append( '(' ).append( dbProductVersion ).append( ')' ).append( ']' )
    469                        .append( CR )
    470                        .append( "DB Driver =[" ).append( driverName )
    471                        .append( '(' ).append( driverVersion ).append( ')' ).append( ']' )
    472                        .append( CR )
    473                        .append( "PROPERTIES=[" ).append( props.toString() ).append( ']' ) // 5.5.2.1 (2012/05/07)
    474                        .append( CR );
    475                return buf.toString();
    476        }
    477
    478        /**
    479         * 内部情報を文字列化します。
    480         *
    481         * @og.rev 5.3.4.0 (2011/04/01) info() メソッドを利用するように変更
    482         *
    483         * @return      内部情報の文字列
    484         * @og.rtnNotNull
    485         */
    486        @Override
    487        public String toString() {
    488                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    489                        .append( info() )
    490                //      .append( "DBID=[" ).append( dbidKey ).append( "]," )
    491                //      .append( "URL =[" ).append( url     ).append( "]," )
    492                //      .append( "USER=[" ).append( user    ).append( "]," )
    493                //      .append( CR )
    494                //      .append( "DB Product=[" ).append( dbProductName )
    495                //      .append( "(" ).append( dbProductVersion ).append( ")" ).append( "]" )
    496                //      .append( CR )
    497                //      .append( "DB Driver =[" ).append( driverName )
    498                //      .append( "(" ).append( driverVersion ).append( ")" ).append( "]" )
    499                //      .append( CR )
    500                        .append( "MINCOUNT=[" ).append( mincount ).append( "]," )
    501                        .append( "MAXCOUNT=[" ).append( maxcount ).append( "]," )
    502                        .append( "POOLTIME=[" ).append( pooltime ).append( "]," )
    503                        .append( "READONLY=[" ).append( readonly ).append( "]," )
    504                        .append( "APPINFO =[" ).append( isUseAppInfo ).append( ']' )            // 6.0.2.5 (2014/10/31) char を append する。
    505                        .append( CR );
    506                return buf.toString();
    507        }
    508}