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