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.process;
017
018import org.opengion.fukurou.db.ConnectionFactory;
019import org.opengion.fukurou.util.Argument;
020import org.opengion.fukurou.db.ApplicationInfo;
021import org.opengion.fukurou.system.LogWriter;
022
023import java.util.Set ;
024import java.util.Map ;
025import java.util.LinkedHashMap ;
026import java.net.InetAddress;
027// import java.net.UnknownHostException;
028import java.net.NetworkInterface;                                                                       // 7.3.1.1 (2021/02/25)
029import java.util.Enumeration;                                                                           // 7.3.1.1 (2021/02/25)
030
031import java.sql.Connection;
032
033/**
034 * Process_DBParam は、他のプロセスへ共通のデータベース接続を割り当てる為の、
035 * ParamProcess インターフェースの実装クラスです。
036 *
037 * DB接続 が必要な Process (DBCountFilter、DBMerge、DBReader、DBWriterなど)を
038 * 使用して処理する場合に、接続を指定することができます。
039 * DBID(接続先) は、Process_DBParam の -configFile で指定する DBConfig.xml ファイルを使用します。
040 *
041 * @og.formSample
042 *  Process_DBParam -infoUSER=C00000 -infoPGID=GE1234 -configFile=DBConfig.xml
043 *
044 *   [ -infoUSER=実行ユーザー       ] : DB接続履歴取得用の実行ユーザー(例:C00000)
045 *   [ -infoPGID=実行プログラムID   ] : DB接続履歴取得用の実行プログラムID(例:GE1234)
046 *   [ -configFile=実行プログラムID ] : DB接続情報設定 XMLファイル(例:DBConfig.xml)
047 *   [ -display=[false/true]        ] : trueは、接続状況を詳細表示します(初期値:false)
048 *
049 * @og.rev 4.0.0.0 (2007/11/22) DBConfig.xml による DBID(接続先)指定に変更。
050 * @og.rev 6.3.1.0 (2015/06/28) 履歴取得用パラメータの必須解除
051 *
052 * @version  4.0
053 * @author   Kazuhiko Hasegawa
054 * @since    JDK5.0,
055 */
056public class Process_DBParam extends AbstractProcess implements ParamProcess {
057        /** 実行しているサーバーの名称 */
058        private static final String HOST_NAME ;
059        /** 実行しているサーバーのIPアドレス */
060        private static final String HOST_ADRS ;
061
062//      static {
063//              String dmnHost ;
064//              String dnmAdrs ;
065//              try {
066//                      final InetAddress address = InetAddress.getLocalHost();
067//                      dmnHost = address.getHostName() ;
068//                      dnmAdrs = address.getHostAddress() ;
069//              }
070//              catch( final UnknownHostException ex ) {
071//                      dmnHost = "Unknown";
072//                      dnmAdrs = "Unknown";
073//              }
074//              HOST_NAME = dmnHost;
075//              HOST_ADRS = dnmAdrs;
076//      }
077
078        /**
079         * ホスト名と、IPアドレスを取得
080         *
081         * Java VM が実行しているホスト名と、IPアドレスを取得します。
082         * InetAddress.getLocalHost().getHostName() で求められる値は、Virtual アドレスなどの
083         * 複数考えられる為、出来るだけ直接設定されているIPアドレスに近い値を取得するようにします。
084         * でも、完全には特定できないと思われます。
085         *
086         * @og.rev 7.3.1.1 (2021/02/25) ホスト名と、IPアドレスを取得
087         */
088        static {
089                String dmnHost = "Unknown" ;
090                String dmnAdrs = "Unknown" ;
091                try {
092                        boolean isNext = true;
093                        final Enumeration<NetworkInterface> enuIfs = NetworkInterface.getNetworkInterfaces();
094                        while( isNext && enuIfs.hasMoreElements() ) {
095                                final NetworkInterface ni = enuIfs.nextElement();
096
097                                final String displayName = ni.getDisplayName();
098                                if( displayName.contains("Virtual") ) { continue; }
099
100                                final Enumeration<InetAddress> enuIP = ni.getInetAddresses();
101                                while( isNext && enuIP.hasMoreElements() ) {
102                                        final InetAddress adrs = enuIP.nextElement();
103
104                                        if( adrs.isLinkLocalAddress() || adrs.isLoopbackAddress() ) { continue; }
105
106                                        dmnHost = adrs.getHostName() ;                  // adrs.getCanonicalHostName() はとりあえず使わないでおく。
107                                        dmnAdrs = adrs.getHostAddress() ;
108                                        isNext = false;
109                                        break;
110                                }
111                        }
112                }
113                catch( final Throwable th ) {
114                        System.err.println( "HOST_NAME and HOST_ADRS Unknown!" );
115                }
116                HOST_NAME = dmnHost;
117                HOST_ADRS = dmnAdrs;
118        }
119
120        private ApplicationInfo appInfo ;
121        private boolean                 display ;                       // 表示しない
122
123        // 5.3.4.0 (2011/04/01) bulkData 関係のメソッドを追加
124        private Set<String> bulkData ;
125
126        /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */
127        private static final Map<String,String> MUST_PROPARTY   ;       // [プロパティ]必須チェック用 Map
128        /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */
129        private static final Map<String,String> USABLE_PROPARTY ;       // [プロパティ]整合性チェック Map
130
131        static {
132                MUST_PROPARTY = new LinkedHashMap<>();
133                // 6.3.1.0 (2015/06/28) 必須から外します。
134
135                USABLE_PROPARTY = new LinkedHashMap<>();
136                USABLE_PROPARTY.put( "infoUSER" , "DB接続履歴取得用の実行ユーザー" );
137                USABLE_PROPARTY.put( "infoPGID" , "DB接続履歴取得用の実行プログラムID" );
138                USABLE_PROPARTY.put( "configFile", "DB接続情報設定 XMLファイル" );
139                USABLE_PROPARTY.put( "display"  , "trueは、接続状況を詳細表示します(初期値:false)" );            // 6.3.1.0 (2015/06/28) 追加
140        }
141
142        /**
143         * デフォルトコンストラクター。
144         * このクラスは、動的作成されます。デフォルトコンストラクターで、
145         * super クラスに対して、必要な初期化を行っておきます。
146         *
147         */
148        public Process_DBParam() {
149                super( "org.opengion.fukurou.process.Process_DBParam",MUST_PROPARTY,USABLE_PROPARTY );
150        }
151
152        /**
153         * ApplicationInfoオブジェクトを登録します。
154         * これは、通常の初期処理ではなく、タグリブから起動される場合のみ
155         * 呼ばれるメソッドです。
156         * 初期処理メソッド(init)では、appInfo がセット済みの場合は、
157         * ConnectionFactoryの初期化を行いません。
158         *
159         * @og.rev 4.3.1.1 (2008/09/04) 新規追加(taglib呼出専用)
160         *
161         * @param   appInfo アプリ情報オブジェクト
162         */
163        public void setAppInfo( final ApplicationInfo appInfo ) {
164                this.appInfo = appInfo;
165        }
166
167        /**
168         * プロセスの初期化を行います。初めに一度だけ、呼び出されます。
169         * 初期処理(ファイルオープン、DBオープン等)に使用します。
170         *
171         * @og.rev 4.3.1.1 (2008/09/04) taglib呼出時は、ConnectionFactoryの初期化を行わない
172         * @og.rev 6.3.1.0 (2015/06/28) display属性の追加
173         *
174         * @param   paramProcess データベースの接続先情報などを持っているオブジェクト
175         */
176        @Override
177        public void init( final ParamProcess paramProcess ) {
178                final Argument arg = getArgument();                     // 6.3.1.0 (2015/06/28) display属性の追加のため。
179
180                // 4.3.1.1 (2008/09/04) taglib呼出時は、ConnectionFactoryの初期化を行わない
181                if( appInfo == null ) {
182
183                        final String infoUSER   = arg.getProparty( "infoUSER" );                // DB接続履歴取得用の実行ユーザー
184                        final String infoPGID   = arg.getProparty( "infoPGID" );                // DB接続履歴取得用の実行プログラムID
185                        final String configFile = arg.getProparty( "configFile" );              // DB接続情報設定 XMLファイル
186
187                        appInfo = new ApplicationInfo();
188                        // JavaVM 起動時のユーザーID,IPアドレス,ホスト名をセットします。
189                        appInfo.setClientInfo( infoUSER,HOST_ADRS,HOST_NAME );
190
191                        // 画面ID,操作,プログラムID
192                        appInfo.setModuleInfo( infoPGID,null,"fukurou" );
193
194                        // DBID接続情報の取得先の設定
195                        ConnectionFactory.init( null,configFile );
196                }
197
198                display = arg.getProparty( "display",display );         // 6.3.1.0 (2015/06/28)
199        }
200
201        /**
202         * 指定の 接続先ID に対する コネクションを返します。
203         *
204         * @param       key     接続先ID
205         *
206         * @return      コネクション
207         * @throws      RuntimeException DB接続先が未設定の場合
208         * @og.rtnNotNull
209         */
210        @Override
211        public Connection getConnection( final String key ) {
212                return ConnectionFactory.connection( key,appInfo );
213        }
214
215        /**
216         * 検索した結果が設定された Set オブジェクトを設定します。
217         *
218         * @og.rev 5.3.4.0 (2011/04/01) 新規追加
219         *
220         * @param       bulkData        検索した結果が設定されたSetオブジェクト
221         */
222        @Override
223        public void setBulkData( final Set<String> bulkData ) {
224                this.bulkData = bulkData;
225        }
226
227        /**
228         * 検索した結果が設定された Set オブジェクトを返します。
229         *
230         * @og.rev 5.3.4.0 (2011/04/01) 新規追加
231         *
232         * @return      検索した結果が設定された Setオブジェクト
233         */
234        @Override
235        public Set<String> getBulkData() {
236                return bulkData ;
237        }
238
239        /**
240         * プロセスの終了を行います。最後に一度だけ、呼び出されます。
241         * 終了処理(ファイルクローズ、DBクローズ等)に使用します。
242         *
243         * @og.rev 4.0.0.0 (2007/11/27) commit,rollback,remove 処理を追加
244         *
245         * @param   isOK トータルで、OKだったかどうか[true:成功/false:失敗]
246         */
247        @Override
248        public void end( final boolean isOK ) {
249                // 何もありません。(PMD エラー回避)
250        }
251
252        /**
253         * プロセスの処理結果のレポート表現を返します。
254         * 処理プログラム名、入力件数、出力件数などの情報です。
255         * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような
256         * 形式で出してください。
257         *
258         * @return   処理結果のレポート
259         */
260        @Override
261        public String report() {
262                // 7.2.9.5 (2020/11/28) PMD:Consider simply returning the value vs storing it in local variable 'XXXX'
263                return "[" + getClass().getName() + "]" + CR
264//              final String report = "[" + getClass().getName() + "]" + CR
265                                                        + ConnectionFactory.information( display ) ;
266
267//              return report ;
268        }
269
270        /**
271         * このクラスの使用方法を返します。
272         *
273         * @return      このクラスの使用方法
274         * @og.rtnNotNull
275         */
276        @Override
277        public String usage() {
278                final StringBuilder buf = new StringBuilder( BUFFER_LARGE )
279                        .append( "Process_DBParam は、他のプロセスへ共通のデータベース接続を割り当てる為の、"        ).append( CR )
280                        .append( "ParamProcess インターフェースの実装クラスです。"                                                               ).append( CR )
281                        .append( CR )
282                        .append( "DB接続 が必要な Process (DBCountFilter、DBMerge、DBReader、DBWriterなど)を"       ).append( CR )
283                        .append( "使用して処理する場合に、接続を指定することができます。"                                          ).append( CR )
284                        .append( "DBID(接続先) は、-configFile で指定する DBConfig.xml ファイルを使用します。"       ).append( CR )
285                        .append( CR )
286                        .append( "引数文字列中に空白を含む場合は、ダブルコーテーション(\"\") で括って下さい。"    ).append( CR )
287                        .append( "引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に"           ).append( CR )
288                        .append( "繋げてください。"                                                                                                                             ).append( CR )
289                        .append( CR )
290                        .append( "[ -infoUSER=実行ユーザー       ] : DB接続履歴取得用の実行ユーザー(例:C00000)"              ).append( CR )
291                        .append( "[ -infoPGID=実行プログラムID   ] : DB接続履歴取得用の実行プログラムID(例:GE1234)"    ).append( CR )
292                        .append( "[ -configFile=実行プログラムID ] : DB接続情報設定 XMLファイル(例:DBConfig.xml)"         ).append( CR )
293                        .append( "[ -display=[false/true]        ] : trueは、接続状況を詳細表示します(初期値:false)"     ).append( CR )
294                        .append( CR ).append( CR )
295                        .append( getArgument().usage() ).append( CR );
296
297                return buf.toString();
298        }
299
300        /**
301         * このクラスは、main メソッドから実行できません。
302         *
303         * @param       args    コマンド引数配列
304         */
305        public static void main( final String[] args ) {
306                LogWriter.log( new Process_DBParam().usage() );
307        }
308}