001/*
002 * Copyright (c) 2017 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.fileexec;
017
018//      import java.nio.file.Paths;                                                     // 6.8.1.5 (2017/09/08)
019
020import java.util.logging.Logger;
021import java.util.logging.Level;
022import java.util.function.Supplier;                                             // 6.8.1.0 (2017/07/14)
023import java.util.function.Function;                                             // 7.2.5.0 (2020/06/01)
024
025/**
026 * XLoggerは、Throwable を引数に取るwarningと、Level 600 の debug メソッドを
027 * 持つ、Logger の拡張クラスです。
028 * ここでは、継承するのではなく、委譲で、最低限のメソッドだけに対応しています。
029 * (LogManager とか、色々とややこしそうなので、調査する暇が無い)
030 *
031 * WARNING(900) → INFO(800) → CONFIG(700) → XXXX(600) → FINE(500) → ALL(Integer.MIN_VALUE)
032 * となっていますが、FINE では、多すぎ、INFO は、通常使用、間に、DEBUG的な、
033 * ロギングが欲しい場合に使用します。
034 * CONFIG を使いたいところですが、「CONFIGは静的な構成メッセージのメッセージ・レベルです。」と
035 * JavaDocにわざわざ、書かれていることから、使用を避けます。
036 *
037 * @og.rev 7.0.0.0 (2017/07/07) 新規作成
038 *
039 * @version  7.0
040 * @author   Kazuhiko Hasegawa
041 * @since    JDK1.8,
042 */
043// public class XLogger {
044public final class XLogger {                    // 8.5.4.2 (2024/01/12) PMD 7.0.0 ClassWithOnlyPrivateConstructorsShouldBeFinal
045        // 7.2.5.0 (2020/06/01) 各クラスで、class.getSimpleName() を渡すようにしたので短縮不要。
046//      /** 初期設定されているリソースバンドルのbaseName {@value} */
047//      public static final String OMIT_NAME = "org.opengion.fukurou." ;        // fileexec は残す
048
049        // 8.5.4.2 (2024/01/12) PMD 7.0.0 FieldDeclarationsShouldBeAtStartOfClass
050//      private static final Level DEBUG = new LEVEL_DEBUG();
051        private static final Level L_DEBUG = new LEVEL_DEBUG();                                 // 6.9.7.0 (2018/05/14) PMD Field DEBUG has the same name as a method
052
053        private final Logger LOGGER;
054
055        /**
056         * デバッグレベルを新規に定義します。
057         *
058         * OFF:Integer.MAX_VALUE , SEVERE:1000 , WARNING:900 , INFO:800 , CONFIG:700 , FINE:500 , FINER:400 , FINEST:300 , ALL:Integer.MIN_VALUE
059         * LEVEL_DEBUG:600 で定義することで、INFO より細かいが、FINE より荒いログ出力が可能です。
060         * 他のアプリケーションで、INFO は許せても、FINE は許せない場合があるので、独自のログ出力が、可能です。
061         */
062        private static final class LEVEL_DEBUG extends Level {
063                private static final long serialVersionUID = 681020170714L ;            // 6.8.1.0 (2017/07/14)
064                /**
065                 * デバッグレベルのコンストラクター
066                 */
067                public LEVEL_DEBUG() { super( "DEBUG",600 ); }
068        }               // 8.5.4.2 (2024/01/12) PMD 7.0.0 UnnecessarySemicolon
069
070        /**
071         * 名前を指定して、XLoggerオブジェクトを作成します。
072         *
073         * @og.rev 6.8.1.5 (2017/09/08) logフォルダの存在チェックと作成
074         *
075         * @param       name     ロガーの名前。通常は、クラス.class.getName() を渡せばよいです。
076         */
077        private XLogger( final String name ) {
078//              FileUtil.mkdirs( Paths.get( "log" ) );          // Logger の log フォルダが無ければ作成します。
079
080                LOGGER = Logger.getLogger( name );
081        }
082
083        /**
084         * 名前を指定して、XLoggerオブジェクトを作成します。
085         *
086         * @og.rev 7.2.1.0 (2020/03/13) ロガーの名前から、共通部分を削除します。
087         * @og.rev 7.2.5.0 (2020/06/01) 各クラスで、class.getSimpleName() を渡すようにした。
088         *
089         * @param       name     ロガーの名前。通常は、クラス.class.getName() を渡せばよいです。
090         * @return      XLoggerオブジェクト
091         */
092        public static XLogger getLogger( final String name ) {
093//              String key = name ;
094//              if( key.startsWith( OMIT_NAME ) ) {
095//                      key = name.substring( OMIT_NAME.length() );
096//              }
097
098//              return new XLogger( name );             // 今は、個別に作成していますが、本来は、同じオブジェクトを返すようにすべき。
099                return new XLogger( name );             // 各クラスで static で持つのでキャッシュしません。
100        }
101
102        /**
103         * INFO レベルのログをとります。
104         *
105         * 引数は Supplier のみなので、実行直前まで処理されません。
106         * よって、呼出元では、log level guards する必要はありません。
107         *
108         * @og.rev 7.3.0.0 (2021/01/06) PMD:GuardLogStatement:  Logger calls should be surrounded by log level guards.
109         *
110         * @param       msgSupplier     呼び出されると、目的のログ・メッセージを生成する関数
111         * @see         Logger#info( Supplier )
112         */
113        public void info( final Supplier<String> msgSupplier ) {
114                if( LOGGER.isLoggable( Level.INFO ) ) {
115                        LOGGER.info( msgSupplier );
116                }
117        }
118
119        /**
120         * WARNING レベルのログをとります。
121         *
122         * 引数は Supplier のみなので、実行直前まで処理されません。
123         * よって、呼出元では、log level guards する必要はありません。
124         *
125         * @og.rev 7.3.0.0 (2021/01/06) PMD:GuardLogStatement:  Logger calls should be surrounded by log level guards.
126         *
127         * @param       msgSupplier     呼び出されると、目的のログ・メッセージを生成する関数
128         * @see         Logger#warning( Supplier )
129         */
130        public void warning( final Supplier<String> msgSupplier ) {
131                if( LOGGER.isLoggable( Level.WARNING ) ) {
132                        LOGGER.warning( msgSupplier );
133                }
134        }
135
136        /**
137         * WARNING レベルのログが、処理されるか、判定します。
138         *
139         * 引数が Supplier のみでない場合は、実行前に、log level guards してください。
140         *
141         * @og.rev 7.3.0.0 (2021/01/06) 新規追加
142         *
143         * @return  args        WARNINGレベルのログを出力する場合は、trueを返します。
144         */
145        public boolean isWarningEnabled() {
146                return LOGGER.isLoggable( Level.WARNING );
147        }
148
149        /**
150         * WARNING レベルのログをとります。
151         *
152         * 引数処理が発生しますので、呼出元で、log level guards してください。
153         *
154         * if( XLogger.isWarningEnabled() ) {
155         *    XLogger.warning( id,args1,args2,… );
156         * }
157         *
158         * @og.rev 7.2.5.0 (2020/06/01) メソッド追加。
159         *
160         * @param id    リソースのキーとなるID。
161         * @param args  リソースを、MessageFormat.format で加工する場合の引数。
162         * @see         Logger#warning( Supplier )
163         */
164        public void warning( final String id , final Object... args ) {
165                LOGGER.warning( MsgUtil.errPrintln( id,args ) );
166        }
167
168        /**
169         * WARNING レベルのログをとります。
170         *
171         * これは、Throwable を引数に取る拡張されたメソッドです。
172         * 引数処理が発生しますので、呼出元で、log level guards してください。
173         *
174         * @param       th      ログ・メッセージに関連したThrowable。
175         * @param       msgSupplier     呼び出されると、目的のログ・メッセージを生成する関数
176         * @see         Logger#log( Level,Throwable,Supplier )
177         */
178        public void warning( final Throwable th , final Supplier<String> msgSupplier ) {
179                LOGGER.log( Level.WARNING , th , msgSupplier );
180        }
181
182        /**
183         * WARNING レベルのログをとります。
184         *
185         * これは、Throwable を引数に取る拡張されたメソッドです。
186         * 引数処理が発生しますので、呼出元で、log level guards してください。
187         *
188         * @og.rev 7.2.5.0 (2020/06/01) メソッド追加。
189         *
190         * @param th    発生元のThrowable( null値は許容されます )
191         * @param id    リソースのキーとなるID。
192         * @param args  リソースを、MessageFormat.format で加工する場合の引数。
193         * @see         Logger#log( Level,Throwable,Supplier )
194         */
195        public void warning( final Throwable th , final String id , final Object... args ) {
196                LOGGER.log( Level.WARNING , MsgUtil.errPrintln( id,args ) , th );                       // 1.4.0 (2019/10/01) StackTraceの重複を避けるため
197        }
198
199        /**
200         * 600 レベルのログをとります。
201         *
202         * Supplierを引数に、Level = 600 のログをとります。
203         *
204         * 引数は Supplier のみなので、実行直前まで処理されません。
205         * よって、呼出元では、log level guards する必要はありません。
206         *
207         * @og.rev 7.3.0.0 (2021/01/06) PMD:GuardLogStatement:  Logger calls should be surrounded by log level guards.
208         *
209         * @param       msgSupplier     呼び出されると、目的のログ・メッセージを生成する関数
210         * @see         Logger#log( Level,Supplier )
211         */
212        public void debug( final Supplier<String> msgSupplier ) {
213//              LOGGER.log( DEBUG , msgSupplier );
214                if( LOGGER.isLoggable( L_DEBUG ) ) {
215                        LOGGER.log( L_DEBUG , msgSupplier );
216                }
217        }
218
219        /**
220         * WARNING レベルのログが、処理されるか、判定します。
221         *
222         * 引数が Supplier のみでない場合は、実行前に、log level guards してください。
223         *
224         * @og.rev 7.3.0.0 (2021/01/06) 新規追加
225         *
226         * @return  args        WARNINGレベルのログを出力する場合は、trueを返します。
227         */
228        public boolean isDebugEnabled() {
229                return LOGGER.isLoggable( L_DEBUG );
230        }
231
232        /**
233         * 数値の変数を受け取って表示する、600 レベルのログをとります。
234         *
235         * Supplierを引数に、Level = 600 のログをとります。
236         * 関数型インタフェースは引数にfinal変数しか使えませんが、数値は大抵可変なので
237         * final化せずに、引数として渡すことが出来るようにします。
238         * 引数処理が発生しますので、呼出元で、log level guards してください。
239         *
240         * @og.rev 7.2.5.0 (2020/06/01) メソッド追加。
241         *
242         * @param       num                     数値引数
243         * @param       msgFunction     呼び出されると、目的のログ・メッセージを生成する関数
244         * @see         Logger#log( Level,Supplier )
245         */
246        public void debug( final int num , final Function<Integer,String> msgFunction ) {
247                LOGGER.log( L_DEBUG , () -> msgFunction.apply( num ) );
248        }
249}