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