    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.system;                                                            // 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system
    017
    018import java.io.IOException;
    019import java.io.Closeable;
    020import java.sql.Connection;
    021import java.sql.ResultSet;
    022import java.sql.Statement;
    023import java.sql.SQLException;
    024import java.util.zip.ZipFile;           // 5.5.2.6 (2012/05/25)
    025
    026import static org.opengion.fukurou.system.HybsConst.CR;                         // 6.1.0.0 (2014/12/26) refactoring
    027
    028/**
    029 * Closer.java は、共通的に使用される close処理を集約した、クラスです。
    030 *
    031 * 各種 close() 処理では、Exception が発生しても、どうすることも出来ない
    032 * ケースが多々あります。また、close() 処理中の Exception の為だけに、
    033 * try ～ catch 節を用意しなければならず、finally 節内からの さらなる
    034 * throw など、コーディング上、本流以外の箇所で、色々と問題が発生します。
    035 * ここでは、とりあえず、LogWriter.log するだけにしていますが、
    036 * 将来的には、エラーを別ファイルにセーブしたり、データベースに書き込んだり
    037 * 出来ると思います。
    038 *
    039 * また、close 処理とは異なりますが、commit や、rollback など、finally 節に
    040 * 書き込んで、必ず処理したいが、Exception 発生時に、どうしようもない処理も、
    041 * ここに集約していきます。
    042 *
    043 * @og.rev 6.4.2.0 (2016/01/29) エラー処理を統一的に行います。
    044 * @og.rev 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system
    045 *
    046 * @version  4.0
    047 * @author       Kazuhiko Hasegawa
    048 * @since    JDK5.0,
    049 */
    050public final class Closer {
    051        // 6.4.2.0 (2016/01/29) エラー処理を統一的に行います。
    052        private static final String IO_CLOSE_ERR        = "ストリーム close 処理でエラーが発生しました。" ;
    053        private static final String COMMIT_ERR          = "Connection を commit することが出来ません。" ;
    054        private static final String ROLLBACK_ERR        = "Connection を rollback することが出来ません。" ;
    055        private static final String CONN_CLOSE_ERR      = "Connection を close することが出来ません。" ;
    056        private static final String STMT_CLOSE_ERR      = "Statement を close することが出来ません。" ;
    057        private static final String RESULT_CLOSE_ERR= "ResultSet を close することが出来ません。" ;
    058        private static final String ZIP_CLOSE_ERR       = "ZipFile/JarFile を close することが出来ません。" ;
    059        private static final String UNNONE_ERR          = "予期せぬエラーが発生しました。" ;
    060
    061        /**
    062         * すべてが staticメソッドなので、コンストラクタを呼び出さなくしておきます。
    063         *
    064         */
    065        private Closer() {}
    066
    067        /**
    068         * io関連の close 処理時の IOException を無視して、close 処理を行います。
    069         * ここでは、処理中のエラーは、System.err に出力するだけで無視します。
    070         *
    071         * これにより、try ～ catch ～ finally 処理で、close を finally 処理から
    072         * 例外を送出させなくてすむようになります。
    073         * 引数が、null の場合は、何も処理しません。(正常:trueを返します。)
    074         *
    075         * @og.rev 4.0.0.0 (2007/02/08) 新規追加
    076         *
    077         * @param obj Closeableインターフェースを実装したIO関連オブジェクト
    078         *
    079         * @return 正常:true/異常:false
    080         */
    081        public static boolean ioClose( final Closeable obj ) {
    082                boolean isOK = true;
    083
    084                try {
    085                        if( obj != null ) { obj.close(); }
    086                }
    087                catch( final IOException ex ) {
    088                        isOK = false;
    089                        logWriter( IO_CLOSE_ERR , obj.toString() , ex );
    090                }
    091                catch( final RuntimeException ex ) {
    092                        isOK = false;
    093                        logWriter( UNNONE_ERR , obj.toString() , ex );
    094                }
    095
    096                return isOK;
    097        }
    098
    099        /**
    100         * Connection オブジェクトを commit します。
    101         * ここでは、処理中のエラーは、System.err に出力するだけで無視します。
    102         *
    103         * @og.rev 4.0.0.0 (2007/02/08) 新規追加
    104         *
    105         * @param conn コネクションオブジェクト
    106         *
    107         * @return 正常:true/異常:false
    108         */
    109        public static boolean commit( final Connection conn ) {
    110                boolean isOK = true;
    111
    112                try {
    113                        if( conn != null ) { conn.commit(); }
    114                }
    115                catch( final SQLException ex ) {
    116                        logWriter( COMMIT_ERR , ex.getSQLState() , ex );
    117                }
    118                catch( final RuntimeException ex ) {
    119                        isOK = false;
    120                        logWriter( UNNONE_ERR , ex.getMessage() , ex );
    121                }
    122
    123                return isOK;
    124        }
    125
    126        /**
    127         * Connection オブジェクトをrollbackします。
    128         * ここでは、処理中のエラーは、標準出力に出力するだけで無視します。
    129         *
    130         * @og.rev 4.0.0.0 (2007/02/08) 新規追加
    131         *
    132         * @param conn コネクションオブジェクト
    133         *
    134         * @return 正常:true/異常:false
    135         */
    136        public static boolean rollback( final Connection conn ) {
    137                boolean isOK = true;
    138
    139                try {
    140                        if( conn != null ) { conn.rollback(); }
    141                }
    142                catch( final SQLException ex ) {
    143                        logWriter( ROLLBACK_ERR , ex.getSQLState() , ex );
    144                }
    145                catch( final RuntimeException ex ) {
    146                        isOK = false;
    147                        logWriter( UNNONE_ERR , ex.getMessage() , ex );
    148                }
    149
    150                return isOK;
    151        }
    152
    153        /**
    154         * Connection オブジェクトをcloseします。
    155         * ここでは、処理中のエラーは、標準出力に出力するだけで無視します。
    156         *
    157         * ここでは、現実の Connection の close() メソッドを呼び出しますので、
    158         * キャッシュ等で使用しているコネクションには適用しないでください。
    159         *
    160         * @og.rev 4.0.0.0 (2007/02/08) 新規追加
    161         * @og.rev 5.5.5.0 (2012/07/28) commit追加
    162         * @og.rev 5.9.4.0 (201601//08) commit前にvalidのチェックを行う(10秒でタイムアウト)
    163         *
    164         * @param conn コネクションオブジェクト
    165         *
    166         * @return 正常:true/異常:false
    167         */
    168        public static boolean connClose( final Connection conn ) {
    169                boolean isOK = true;
    170
    171                try {
    172                        if( conn != null && ! conn.isClosed() ) {
    173                                if( conn.isValid(10) ){         // 5.9.4.0 (2016/01/08)
    174                                        conn.commit();                  // 5.5.5.0 (2012/07/28)
    175                                }
    176                                conn.close();
    177                        }
    178                }
    179                catch( final SQLException ex ) {
    180                        logWriter( CONN_CLOSE_ERR , ex.getSQLState() , ex );
    181                }
    182                catch( final RuntimeException ex ) {
    183                        isOK = false;
    184                        logWriter( UNNONE_ERR , ex.getMessage() , ex );
    185                }
    186
    187                return isOK;
    188        }
    189
    190        /**
    191         * Statement オブジェクトをクローズします。
    192         * ここでは、処理中のエラーは、標準出力に出力するだけで無視します。
    193         *
    194         * @og.rev 4.0.0.0 (2007/02/08) 新規追加
    195         *
    196         * @param stmt Statementオブジェクト
    197         *
    198         * @return 正常:true/異常:false
    199         */
    200        public static boolean stmtClose( final Statement stmt ) {
    201                boolean isOK = true;
    202
    203                try {
    204                        if( stmt != null ) { stmt.close(); }
    205                }
    206                catch( final SQLException ex ) {
    207                        logWriter( STMT_CLOSE_ERR , ex.getSQLState() , ex );
    208                }
    209                catch( final RuntimeException ex ) {
    210                        isOK = false;
    211                        logWriter( UNNONE_ERR , ex.getMessage() , ex );
    212                }
    213
    214                return isOK;
    215        }
    216
    217        /**
    218         * ResultSet オブジェクトをクローズします。
    219         * ここでは、処理中のエラーは、標準出力に出力するだけで無視します。
    220         *
    221         * @og.rev 4.0.0.0 (2007/02/08) 新規追加
    222         *
    223         * @param result ResultSetオブジェクト
    224         *
    225         * @return 正常:true/異常:false
    226         */
    227        public static boolean resultClose( final ResultSet result ) {
    228                boolean isOK = true;
    229
    230                try {
    231                        if( result != null ) { result.close(); }
    232                }
    233                catch( final SQLException ex ) {
    234                        logWriter( RESULT_CLOSE_ERR , ex.getSQLState() , ex );
    235                }
    236                catch( final RuntimeException ex ) {
    237                        isOK = false;
    238                        logWriter( UNNONE_ERR , ex.getMessage() , ex );
    239                }
    240
    241                return isOK;
    242        }
    243
    244        /**
    245         * ZipFile オブジェクトをクローズします。
    246         * Jar ファイルも、このメソッドでクローズします。
    247         * ここでは、処理中のエラーは、標準出力に出力するだけで無視します。
    248         *
    249         * @og.rev 5.5.2.6 (2012/05/25) findbugs対応に伴い、新規追加
    250         *
    251         * @param zipFile ZipFileオブジェクト
    252         *
    253         * @return 正常:true/異常:false
    254         */
    255        public static boolean zipClose( final ZipFile zipFile ) {
    256                boolean isOK = true;
    257
    258                try {
    259                        if( zipFile != null ) { zipFile.close(); }
    260                }
    261                catch( final IOException ex ) {
    262                        logWriter( ZIP_CLOSE_ERR , zipFile.getName() , ex );
    263                }
    264                catch( final RuntimeException ex ) {
    265                        isOK = false;
    266                        logWriter( UNNONE_ERR , ex.getMessage() , ex );
    267                }
    268
    269                return isOK;
    270        }
    271
    272        /**
    273         * AutoCloseable オブジェクトをクローズします。
    274         * これは、Java1.7 で導入された、try-with-resourcesブロックの終了時に自動的に呼び出される
    275         * close() メソッドを、使用します。
    276         * 基本的には、try-with-resourcesブロックを使用すべきですが、Exception を発生させたくないため
    277         * ここで、close() する処理を残しておきます。
    278         * ちなみに、IO系や、SQL系も、AutoCloseable を継承していますが、独自のエラーメッセージを出せないため、
    279         * エラーの内容がわかっている場合は、個々に適したクロースメソッドを呼び出してください。
    280         *
    281         * @og.rev 6.4.2.0 (2016/01/29) エラー処理を統一的に行います。
    282         *
    283         * @param autoClose AutoCloseableオブジェクト
    284         *
    285         * @return 正常:true/異常:false
    286         */
    287        public static boolean autoClose( final AutoCloseable autoClose ) {
    288                boolean isOK = true;
    289
    290                try {
    291                        if( autoClose != null ) { autoClose.close(); }
    292                }
    293                catch( final Throwable th ) {
    294                        isOK = false;
    295                        logWriter( UNNONE_ERR , th.getMessage() , th );
    296                }
    297
    298                return isOK;
    299        }
    300
    301        /**
    302         * Exception 発生時の処理を、統一します。
    303         * ここでは、LogWriter に、書き出します。
    304         *
    305         * @og.rev 6.4.2.0 (2016/01/29) エラー処理を統一的に行います。
    306         *
    307         * @param msg  エラー時のメッセージ
    308         * @param cmnt コメント
    309         * @param th   Throwableオブジェクト
    310         */
    311        private static void logWriter( final String msg , final String cmnt , final Throwable th ) {
    312                final String errMsg = msg + th.getMessage() + ":" + cmnt + CR;
    313                LogWriter.log( errMsg );
    314                LogWriter.log( th );
    315        }
    316}