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;                                                // 6.4.2.1 (2016/02/05) パッケージの移動。fukurou.util → fukurou.db
017
018import java.sql.Connection;
019import java.sql.CallableStatement;
020import java.sql.SQLException;
021
022import org.opengion.fukurou.system.OgRuntimeException ;                                 // 6.4.2.0 (2016/01/29)
023import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;              // 6.4.2.1 (2016/02/05) refactoring
024
025/**
026 * <P>ApplicationInfo.java は、共通的に使用される 内部情報を格納するオブジェクトです。</P>
027 *
028 * 内部情報とは、接続ユーザーのクライアント情報と、実行状況のアプリケーション情報があります。
029 *
030 * クライアント情報とは、"i=192.168.51.81,h=null,u=C12345" 的な文字列で、
031 * i=の後ろに IPアドレス、h=の後ろにホスト名、u=の後ろにユーザー名をセットして、
032 * DBMS_APPLICATION_INFO.SET_CLIENT_INFO( "i=192.168.51.81,h=null,u=C12345" ) を
033 * CALL します。
034 *
035 * アプリケーション情報とは、"o=SELECT,p=GEXXXX" 的な文字列で、o=の後ろに 操作、
036 * p=の後ろにプログラムIDをセットして、
037 * DBMS_APPLICATION_INFO.SET_MODULE( "GE0010","o=操作,p=プログラムID" ) を
038 * CALL します。
039 *
040 * このPL/SQL を使用するコネクションについて実行すると、アクセスログ記録を行う為の
041 * 情報として取り出すことが可能になります。
042 * 確認は、V$SESSION の MODULE , ACTION , CLIENT_INFO で行います。
043 *
044 * このクラスは、同期化されていません。
045 *
046 * @og.rev 3.8.7.0 (2006/12/15) 新規追加
047 *
048 * @version     0.9.0   2000/10/12
049 * @author      Kazuhiko Hasegawa
050 * @since       JDK1.1,
051 */
052public final class ApplicationInfo {
053        /** SET_CLIENT_INFO( "i=192.168.51.81,h=null,u=C12345" ) */
054        public static final String CLIENT_INFO = "{ call DBMS_APPLICATION_INFO.SET_CLIENT_INFO( ? ) }" ;
055        /** SET_MODULE( "GE0010","o=操作,p=プログラムID" ) */
056        public static final String MODULE      = "{ call DBMS_APPLICATION_INFO.SET_MODULE( ?,? ) }" ;
057
058        private String gamenId          ;
059        private String clientInfo       = "";
060        private String moduleInfo       = "";
061
062        /**
063         * デフォルトコンストラクター
064         *
065         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
066         */
067        public ApplicationInfo() { super(); }           // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
068
069        /**
070         * ユーザーID,IPアドレス,ホスト名 を指定して、クライアント情報を設定します。
071         *
072         * クライアント情報とは、"i=192.168.51.81,h=null,u=C12345" 的な文字列で、
073         * i=の後ろに IPアドレス、h=の後ろにホスト名、u=の後ろにユーザー名をセット
074         * しています。
075         *
076         * @param       userId  ユーザーID
077         * @param       ipAdrs  IPアドレス
078         * @param       host    ホスト名
079         */
080        public void setClientInfo( final String userId,final String ipAdrs,final String host ) {
081                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
082                append( "i=" , ipAdrs , buf );
083                append( "h=" , host   , buf );
084                append( "u=" , userId , buf );
085
086                clientInfo = buf.toString() ;
087        }
088
089        /**
090         * 画面ID,操作,プログラムIDを指定して、アプリケーションに関する情報を設定します。
091         *
092         * クライアント情報とは、"o=SELECT,p=GEXXXX" 的な文字列で、
093         * o=の後ろに 操作、p=の後ろにプログラムIDをセットしています。
094         *
095         * @param       gamenId 画面ID
096         * @param       ope             オペレーション(操作)
097         * @param       prgId   プログラムID
098         */
099        public void setModuleInfo( final String gamenId,final String ope,final String prgId ) {
100                this.gamenId    = gamenId       ;
101
102                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
103                append( "o=" , ope   , buf );
104                append( "p=" , prgId , buf );
105
106                moduleInfo = buf.toString() ;
107        }
108
109        /**
110         * setModuleInfo で最後に設定された 画面IDを返します。
111         *
112         * なにも設定されていない初期状態は、null です。
113         *
114         * @return      画面ID
115         * @see #setModuleInfo( String,String,String )
116         */
117        public String getGamenId() {
118                return gamenId ;
119        }
120
121        /**
122         * key と val を連結した文字列を作成します。
123         * 引数の val が null の場合は、何も操作しません。
124         * buf にすでになにかが登録済みの場合は、"," を追加してから、連結します。
125         *
126         * @param       key     キー
127         * @param       val     値
128         * @param       buf     連結するStringBuilderオブジェクト
129         */
130        private void append( final String key,final String val,final StringBuilder buf ) {
131                if( val != null ) {
132                        if( buf.length() == 0 ) { buf.append( key ).append( val ); }
133                        else { buf.append( ',' ).append( key ).append( val ); }
134                }
135        }
136
137        /**
138         * アクセスログ記録を行う為の DBMS_APPLICATION_INFO.SET_CLIENT_INFO と、
139         * DBMS_APPLICATION_INFO.SET_MODULE を CALL します。
140         *
141         * SET_CLIENT_INFO( "i=192.168.51.81,h=null,u=C12345" ) では、
142         * クライアント情報として、"i=192.168.51.81,h=null,u=C12345" 的な文字列で、
143         * i=の後ろに IPアドレス、h=の後ろにホスト名、u=の後ろにユーザー名をセットしています。
144         *
145         * SET_MODULE( "GE0010","o=操作,p=プログラムID" )では、
146         * アプリケーションに関する情報として、"o=操作,p=プログラムID" をセットしています。
147         * 確認は、V$SESSION の MODULE , ACTION , CLIENT_INFO で行います。
148         *
149         * @og.rev 8.5.4.2 (2024/01/12) PMD 7.0.0 CloseResource 対応
150         *
151         * @param   conn 接続先(コネクション)
152         */
153        public void callAppInfo( final Connection conn ) {
154                // 8.5.4.2 (2024/01/12) PMD 7.0.0 CloseResource 対応
155//              CallableStatement callStmt ;
156                try {
157//                      callStmt = conn.prepareCall( CLIENT_INFO );
158                        try ( CallableStatement callStmt = conn.prepareCall( CLIENT_INFO ) ) {
159                                callStmt.setString( 1,clientInfo );
160                                callStmt.executeUpdate();
161        //                      callStmt.close();
162                        }
163
164                        try ( CallableStatement callStmt = conn.prepareCall( MODULE ) ) {
165        //                      callStmt = conn.prepareCall( MODULE );
166                                callStmt.setString( 1,gamenId );
167                                callStmt.setString( 2,moduleInfo );
168                                callStmt.executeUpdate();
169        //                      callStmt.close();
170                        }
171                }
172                catch( final SQLException ex) {
173                        final String errMsg = "履歴収集処理を実行できませんでした。"
174                                        + ex.getMessage() + ":" + ex.getSQLState() ;
175                        throw new OgRuntimeException( errMsg,ex );
176                }
177        }
178}