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     */
016    package org.opengion.fukurou.util;
017    
018    import java.sql.Connection;
019    import java.sql.CallableStatement;
020    import 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=の後ろにプログラãƒ?Dをセãƒ?ƒˆしてã€?
034     * DBMS_APPLICATION_INFO.SET_MODULE( "GE0010","o=操ä½?p=プログラãƒ?D" ) ã‚?
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     */
049    public 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=プログラãƒ?D" ) */
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,操ä½?プログラãƒ?Dを指定して、アプリケーションに関するæƒ??を設定しますã?
081             *
082             * クライアント情報とはã€?o=SELECT,p=GEXXXX" çš?�ªæ–?­—å?でã€?
083             * o=の後ろに 操作ã?p=の後ろにプログラãƒ?Dをセãƒ?ƒˆしてã�?�¾すã?
084             *
085             * @param       gamenId 画面ID
086             * @param       ope             オペレーション(操ä½?
087             * @param       prgId   プログラãƒ?D
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=プログラãƒ?D" )ではã€?
136             * アプリケーションに関するæƒ??としてã€?o=操ä½?p=プログラãƒ?D" をセãƒ?ƒˆしてã�?�¾すã?
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    
162            /**
163             * こã?接続が、PreparedStatement#getParameterMetaData() を使用するかどã�?�‹を判定しますã?
164             *
165             * PreparedStatement に対して、String化された 数字などã‚?setObject( int,String ) するときã?
166             * ORACLE と SQLServer は、そのまま設定すれã?、è?動的に変換されますã?
167             * postgreSQL では、ParameterMetaData#getParameterType(int) で、カラãƒ?‚¿イプを取得しã€?
168             * setObject( int,String,int ) するå¿?¦�がありますã?
169             * そã?判定に、このメソãƒ?ƒ‰を使用しますã?
170             * こã?結果は、あくまで、各種ãƒ??タベã?ス毎ã?実地調査の結果をå?に、判定結果ã‚?
171             * 返すようにしてã�?�¾すã?
172             * ORACLE の場合ã?、使用しなã�?false)が返るように設定してã�?�¾すã?
173             * SQLServer では、ORACLEと同様に、false を返しますã?
174             *
175             * @og.rev 4.0.0.0 (2007/09/25) 新規追åŠ?
176             * @og.rev 5.1.1.0 (2009/12/01) MySQL/PostgreSQL 対å¿?
177             * @og.rev 5.3.8.0 (2011/08/01) å»?­¢( ConnectionFactory#useParameterMetaData(String) に移å‹?)
178             *
179             * @param   conn 接続å?(コネクション)
180             *
181             * @return      使用する場合:true / そã?ä»?false
182             */
183    //      public static boolean useParameterMetaData( final Connection conn ) {
184    ////            return false;
185    //
186    //              try {
187    //                      DatabaseMetaData meta = conn.getMetaData();
188    //                      String dbProductName = meta.getDatabaseProductName();
189    //
190    //      //              if( "ORACLE".equalsIgnoreCase( dbProductName ) ) { return false; }
191    //      //              if( "Microsoft SQL Server".equalsIgnoreCase( dbProductName ) ) { return false; }
192    //
193    //                      if( "PostgreSQL".equalsIgnoreCase( dbProductName ) ) { return true; }
194    //
195    //                      return false ;
196    //              }
197    //              catch (SQLException ex) {
198    //                      String errMsg = "DatabaseMetaData から、getDatabaseProductName を取得できませんでしたã€?
199    //                                      + ex.getMessage() + ":" + ex.getSQLState() ;
200    //                      throw new RuntimeException( errMsg,ex );
201    //              }
202    //      }
203    }