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.util.List;
019import java.util.ArrayList;
020
021import org.opengion.fukurou.system.ThrowUtil;                                                   // 6.5.0.1 (2016/10/21)
022import static org.opengion.fukurou.system.HybsConst.CR;                                 // 6.1.0.0 (2014/12/26) refactoring
023import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;              // 6.4.3.1 (2016/02/12) refactoring
024
025/**
026 * エラーメッセージを受け渡すときに使用するクラスです。
027 * 結果値として、0:正常 1:警告 2:異常 8:EXCEPTION 9:ORACLEエラー を持っています。
028 *
029 * @og.rev 6.5.0.1 (2016/10/21) 連結を、StringBuilder#appendのように、自分自身に出来るように、修正します。
030 *
031 * @og.group エラー処理
032 *
033 * @version  4.0
034 * @author   Kazuhiko Hasegawa
035 * @since    JDK5.0,
036 */
037public final class ErrorMessage {
038        /** 結果値 0:正常 {@value} */
039        public static final int OK        = 0;
040        /** 結果値 1:警告 {@value} */
041        public static final int WARNING   = 1;
042        /** 結果値 2:異常 {@value} */
043        public static final int NG        = 2;
044        /** 結果値 8:EXCEPTION {@value} */
045        public static final int EXCEPTION = 8;
046        /** 結果値 9:ORACLEエラー {@value} */
047        public static final int ORCL_ERR  = 9;
048
049        private int                     maxKekka        = OK;
050        private String          title           = "";
051        private final List<ErrMsg> list = new ArrayList<>();
052
053        private boolean  setPgStep      ;       // 3.8.9.5 (2007/09/12)
054
055        /**
056         * デフォルトコンストラクター
057         * 詳細メッセージを指定しないで ErrorMessage を構築します。
058         * (明示しないと、引き通付きコンストラクタのみのクラスになってしまいます。)
059         */
060        public ErrorMessage() {
061                setTitle( "NO TITLE" );
062        }
063
064        /**
065         * タイトルを指定して ErrorMessage を構築します。
066         *
067         * @param       title   タイトル
068         */
069        public ErrorMessage( final String title ) {
070                setTitle( title );
071        }
072
073        /**
074         * 指定されたエラー情報を追加登録します。
075         * これは、行番号0、結果:NG IDは無し(ゼロ文字列)です。
076         * 引数の メッセージ が null の場合は、何もしません。
077         *
078         * @og.rev 6.5.0.1 (2016/10/21) 連結を、StringBuilder#appendのように、自分自身に出来るように、修正します。
079         * @og.rev 6.9.0.0 (2018/01/31) null引数の場合は、NGも登録せず、スルーします。
080         *
081         * @param    args String... メッセージの引数(可変引数)
082         * @return      自分自身
083         */
084        public ErrorMessage addMessage( final String... args ) {
085                if( args != null ) {
086                        addMessage( 0,NG,"",args );
087                }
088                return this;
089        }
090
091        /**
092         * 指定されたエラー情報を追加登録します。
093         *
094         * ただし、id が null の場合は、登録しません。
095         *
096         * @og.rev 6.5.0.1 (2016/10/21) 連結を、StringBuilder#appendのように、自分自身に出来るように、修正します。
097         *
098         * @param       no      行番号
099         * @param       kekka   結果 0:正常 1:警告 2:異常
100         * @param       id      メッセージID
101         * @param    args String... メッセージの引数(可変引数)
102         * @return      自分自身
103         */
104        public ErrorMessage addMessage( final int no,final int kekka,final String id,final String... args ) {
105                if( id != null ) {
106                        final ErrMsg msg = new ErrMsg( no,kekka,null,null,id,args );
107                        list.add( msg );
108                        if( maxKekka < kekka ) {  maxKekka = kekka; }
109                }
110                return this;
111        }
112
113        /**
114         * 指定されたThrowableオブジェクトを元に、エラー情報を追加登録します。
115         * この処理が、一番最初の場合は、行番号0、IDは無し(ゼロ文字列)です。
116         * 結果は、NG で登録します。
117         * ここでは、最後に登録された ErrMsg を元に、行番号、id をコピーして使用します。
118         * 引数の Throwableオブジェクト が null の場合は、何もしません。
119         *
120         * @og.rev 6.5.0.1 (2016/10/21) 新規追加
121         * @og.rev 6.9.0.0 (2018/01/31) null引数の場合は、NGも登録せず、スルーします。
122         * @og.rev 6.9.2.1 (2018/03/12) スタックトレース情報の処理方法を変更
123         *
124         * @param    th   printStackTraceすべき元のThrowableオブジェクト
125         * @return      自分自身
126         * @see         #addMessage(Throwable,boolean)
127         */
128        public ErrorMessage addMessage( final Throwable th ) {
129                return addMessage( th , false );
130        }
131
132        /**
133         * 指定されたThrowableオブジェクトを元に、エラー情報を追加登録します。
134         *
135         * isST 引数により、スタックトレース情報を利用するかどうか指定できます。
136         * 結果は、NG で登録します。
137         * この処理が、一番最初の場合は、行番号0、IDは無し(ゼロ文字列)です。
138         * ここでは、最後に登録された ErrMsg を元に、行番号、id をコピーして使用します。
139         * 引数の Throwableオブジェクト が null の場合は、何もしません。
140         *
141         * @og.rev 6.5.0.1 (2016/10/21) 新規追加
142         * @og.rev 6.9.0.0 (2018/01/31) null引数の場合は、NGも登録せず、スルーします。
143         * @og.rev 6.9.2.1 (2018/03/12) スタックトレース情報の処理方法を変更
144         *
145         * @param    th   printStackTraceすべき元のThrowableオブジェクト
146         * @param    isST スタックトレース情報を使用するかどうか。
147         * @return      自分自身
148         * @see         ThrowUtil#ogStackTrace(Throwable)
149         * @see         ThrowUtil#ogThrowMsg(String,Throwable)
150         */
151        public ErrorMessage addMessage( final Throwable th , final boolean isST ) {
152                if( th != null ) {
153                        final String thMsg = isST       ? ThrowUtil.ogStackTrace( th )
154//                                                                              : ThrowUtil.ogThrowMsg( th.getMessage(),th );
155                                                                                : ThrowUtil.ogThrowMsg( null,th );
156
157                        final int size = list.size();
158                        if( size == 0 ) {
159                                addMessage( 0 , NG , "" , thMsg );
160                        }
161                        else {
162                                final ErrMsg msg = list.get( size-1 );                  // 最後のErrMsgを取り出す。
163                                addMessage( msg.getNo() , NG , msg.getId() , thMsg );
164                        }
165                }
166
167                return this;
168        }
169
170        /**
171         * 指定されたエラーオブジェクトを追加登録します。
172         * 追加するErrMsgが、内部の結果値より大きい場合は、その結果値にセットします。
173         * つまり、内部結果値は、登録されたすべてのエラーオブジェクトの最大値です。
174         * 引数の ErrMsgオブジェクト が null の場合は、何もしません。
175         *
176         * @og.rev 6.5.0.1 (2016/10/21) 連結を、StringBuilder#appendのように、自分自身に出来るように、修正します。
177         * @og.rev 6.9.0.0 (2018/01/31) null引数の場合は、NGも登録せず、スルーします。
178         *
179         * @param       msg     エラーオブジェクト
180         * @return      自分自身
181         */
182        public ErrorMessage addMessage( final ErrMsg msg ) {
183                if( msg != null ) {
184                        list.add( msg );
185                        if( maxKekka < msg.getKekka() ) {  maxKekka = msg.getKekka(); }
186                        if( msg.getPg() != null || msg.getStep() != null ) { setPgStep = true; }  // 3.8.9.5 (2007/09/12)
187                }
188
189                return this;
190        }
191
192        /**
193         * 指定された ErrorMessageオブジェクトを追加登録します。
194         * タイトルは元のまま変わりません。
195         * 現状の ErrorMessage の続きに、追加していきます。
196         * 引数の ErrorMessageオブジェクト が null の場合は、何もしません。
197         *
198         * @og.rev 6.5.0.1 (2016/10/21) 連結を、StringBuilder#appendのように、自分自身に出来るように、修正します。
199         *
200         * @param   msg ErrorMessageオブジェクト
201         * @return      自分自身
202         */
203        public ErrorMessage append( final ErrorMessage msg ) {
204                if( msg != null ) {
205                        if( maxKekka < msg.getKekka() ) {  maxKekka = msg.getKekka(); }
206
207                        // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
208//                      final ErrMsg[] emsg = msg.toArray();
209//                      for( int i=0; i<emsg.length; i++ ) {
210//                              list.add( emsg[i] );
211//                      }
212                        for( final ErrMsg emsg : msg.toArray() ) {
213                                list.add( emsg );
214                        }
215                }
216                return this;
217        }
218
219        /**
220         * 指定された ErrorMessageオブジェクトを行番号指定で追加登録します。
221         * タイトルは元のまま変わりません。
222         * 現状の ErrorMessage の続きに、追加していきます。
223         * 引数の ErrorMessageオブジェクト が null の場合は、何もしません。
224         *
225         * @og.rev 6.5.0.1 (2016/10/21) 連結を、StringBuilder#appendのように、自分自身に出来るように、修正します。
226         *
227         * @param       no      行番号
228         * @param   msg ErrorMessageオブジェクト
229         * @return      自分自身
230         */
231        public ErrorMessage append( final int no,final ErrorMessage msg ) {
232                if( msg != null ) {
233                        if( maxKekka < msg.getKekka() ) {  maxKekka = msg.getKekka(); }
234
235                        // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
236//                      final ErrMsg[] emsg = msg.toArray();
237//                      for( int i=0; i<emsg.length; i++ ) {
238//                              list.add( emsg[i].copy( no ) );
239//                      }
240                        for( final ErrMsg emsg : msg.toArray() ) {
241                                list.add( emsg.copy( no ) );
242                        }
243                }
244                return this;
245        }
246
247        /**
248         *  このリスト内の要素を適切な順序で繰り返し処理する反復子を返します。
249         *
250         * @og.rev 4.0.0.0 (2004/12/31) 新規追加
251         * @og.rev 4.3.2.0 (2008/09/11) private ⇒ public に変更。
252         *
253         * @return  すべての要素を正しい順序で保持するErrMsg配列
254         * @og.rtnNotNull
255         */
256        public ErrMsg[] toArray() {
257//              return list.toArray( new ErrMsg[list.size()] ) ;
258                return list.toArray( new ErrMsg[0] ) ;  // 8.5.4.2 (2024/01/12) PMD 7.0.0 OptimizableToArrayCall 対応
259        }
260
261        /**
262         * リスト内のキーと値のマッピングの数を返します。
263         *
264         * @return   リスト内の size
265         */
266        public int size() {
267                return list.size() ;
268        }
269
270        /**
271         *  タイトルを返します。
272         *
273         * @return   タイトル
274         */
275        public String getTitle() {
276                return title;
277        }
278
279        /**
280         *  タイトルをセットします。
281         *
282         * @param       title   タイトル
283         */
284        public void setTitle( final String title ) {
285                this.title = title;
286        }
287
288        /**
289         *  このエラーメッセージの中で、最大の結果値(エラーの最大レベル)を返します。
290         *
291         * @return   結果   OK, WARNING, NG, ORCL_ERR
292         */
293        public int getKekka() {
294                return maxKekka;
295        }
296
297        /**
298         *  すべてのメッセージが 正常(OK)かを返します。
299         *
300         * @return   結果 すべてOK:true / それ以外 false
301         */
302        public boolean isOK() {
303                return maxKekka == OK ;
304        }
305
306        /**
307         *  配列中にPG名またはステップ名が設定されているかを返します。
308         *
309         * @og.rev 3.8.9.5 (2007/09/12) 新規作成
310         *
311         * @return   PG名またはステップ名が設定されているか
312         */
313        public boolean isSetPgStep() {
314                return setPgStep;
315        }
316
317        /**
318         *  メッセージの連結リストを返します。
319         *
320         * @return   メッセージの連結リスト
321         * @og.rtnNotNull
322         */
323        @Override               // Object
324        public String toString() {
325                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
326                        .append( getTitle() ).append( CR );
327                // 6.1.1.0 (2015/01/17) refactoring
328                for( final ErrMsg msg : list ) {
329                        rtn.append( msg ).append( CR );
330                }
331
332                return rtn.toString();
333        }
334}