    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         * @param   conn 接続先(コネクション)
    150         */
    151        public void callAppInfo( final Connection conn ) {
    152                CallableStatement callStmt ;
    153                try {
    154                        callStmt = conn.prepareCall( CLIENT_INFO );
    155                        callStmt.setString( 1,clientInfo );
    156                        callStmt.executeUpdate();
    157                        callStmt.close();
    158
    159                        callStmt = conn.prepareCall( MODULE );
    160                        callStmt.setString( 1,gamenId );
    161                        callStmt.setString( 2,moduleInfo );
    162                        callStmt.executeUpdate();
    163                        callStmt.close();
    164                }
    165                catch( final SQLException ex) {
    166                        final String errMsg = "履歴収集処理を実行できませんでした。"
    167                                        + ex.getMessage() + ":" + ex.getSQLState() ;
    168                        throw new OgRuntimeException( errMsg,ex );
    169                }
    170        }
    171}