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.process;
017    
018    import org.opengion.fukurou.util.Argument;
019    import org.opengion.fukurou.util.Closer ;
020    import org.opengion.fukurou.util.FileUtil ;
021    import org.opengion.fukurou.util.StringUtil ;
022    import org.opengion.fukurou.util.LogWriter;
023    import org.opengion.fukurou.mail.MailTX ;
024    
025    import java.util.Map ;
026    import java.util.LinkedHashMap ;
027    import java.io.PrintWriter ;
028    import java.io.StringWriter ;
029    
030    /**
031     * Process_Logger は、画面出力?ファイルログ、エラーメールを管?る?
032     * ロギング関係? LoggerProcess インターフェースの実?ラスです?
033     *
034     * MainProcess で使用されるログと、各種 Process で使用されるディスプレイ?
035     * 管?ます?また?エラー発生時の、メール送信機?も?ここで用意します?
036     *
037     * 引数??中にスペ?スを含??合?、ダブルコー??ション("") で括って下さ??
038     * 引数??の ?』?前後には、スペ?スは挟めません。??key=value の様に
039     * 繋げてください?
040     *
041     * @og.formSample
042     *  Process_Logger -logFile=ABC.txt -dispFile=System.out
043     *
044     *   [ -logFile=ログ出力??? ] ??-logFile=[ファイル?System.out/System.err] (初期値:null)
045     *   [ -dispFile=画面出力???] ??-dispFile=[ファイル?System.out/System.err](初期値:null)
046     *   [ -host=メールサー?      ] ??-host=メールサーバ?
047     *   [ -from=送信From           ] ??-from=送信?ドレス
048     *   [ -to=受信To               ] ??-to=送信先アドレスをカンマ区?で並べ?
049     *   [ -charset=???ク?????       ] ??-charset=メール送信時?キャラクタセ? [ISO-2022-JP / Windows-31J]
050     *   [ -subject=タイトル        ] ??-subject=タイトル
051     *   [ -message=本?形        ] ??-message=本?形??
052     *   [ -msgFile=本?形?ァ???   ] ??-msgFile=本?格納して?ファイルのアドレス
053     *   [ -{@XXXX}=YYYY       ] ??メ?ージ本?? {@XXXX} ??を?YYYY ??に変換します?
054     *
055     * @version  4.0
056     * @author   Kazuhiko Hasegawa
057     * @since    JDK5.0,
058     */
059    public class Process_Logger extends AbstractProcess implements LoggerProcess {
060    
061            private String logFile          = null;         // ログ出力?
062            private String dispFile         = null;         // 画面出力?
063    
064            private PrintWriter logWriter = null;
065            private PrintWriter dispWriter = null;
066    
067            /** メール送信時??ォルトキャラクタセ? {@value}  */
068            public static final String DEFAULT_CHARSET = "ISO-2022-JP" ;
069            private String host = "mail.opengion.org";
070            private String from = "DUMMY@DUMMY";
071            private String to   = null;
072            private String subject     = null;                      // 5.3.1.0 (2011/03/10)
073            private boolean useErrMail = false;
074    
075            private static final Map<String,String> mustProparty   ;  // ?プロパティ???チェ?用 Map
076            private static final Map<String,String> usableProparty ;  // ?プロパティ?整合?チェ? Map
077    
078            static {
079                    mustProparty = new LinkedHashMap<String,String>();
080    
081                    usableProparty = new LinkedHashMap<String,String>();
082                    usableProparty.put( "logFile",          "ログ出力???ファイル名を?しま?初期値:null)" +
083                                                                                            CR + "『System.out?『System.err』?特殊な名称です?" );
084                    usableProparty.put( "dispFile",         "画面出力???ファイル名を?しま?初期値:null)" +
085                                                                                            CR + "『System.out?『System.err』?特殊な名称です?" );
086                    usableProparty.put( "host",             "メールサーバ?" );
087                    usableProparty.put( "from",             "送信?ドレス" );
088                    usableProparty.put( "to",               "送信先アドレスをカンマ区?で並べ? );
089                    usableProparty.put( "charset",  "メール送信時?キャラクタセ? [ISO-2022-JP / Windows-31J]" );
090                    usableProparty.put( "subject",  "タイトル" );
091                    usableProparty.put( "message",  "本?形?? );
092                    usableProparty.put( "msgFile",  "本?形を?納して?ファイルのアドレス" );
093                    usableProparty.put( "{@",               "{@XXXX}=YYYY 汎用?変換" +
094                                                                            CR + "メ?ージ本?? {@XXXX} ??を?YYYY ??に変換します?"  );
095                    usableProparty.put( "{@ARG.",   "{@ARG.XXX} 予?字変換 上記引数を割り当てます?" );
096                    usableProparty.put( "{@DATE.",  "{@DATE.XXX} 予?字変換 の?を変換します?" +
097                                                                            CR + "(SimpleDateFormat 形式?日付?時刻?" );
098                    usableProparty.put( "{@ENV.",   "{@ENV.XXX} 予?字変換 ????プロパ??の?を変換します?" +
099                                                                            CR + "(java -Dkey=value オプションで引き渡します?)" );
100            }
101    
102            /**
103             * ?ォルトコンストラクター?
104             * こ?クラスは、動??されます??ォルトコンストラクターで?
105             * super クラスに対して、?な初期化を行っておきます?
106             *
107             */
108            public Process_Logger() {
109                    super( "org.opengion.fukurou.process.Process_Logger",mustProparty,usableProparty );
110            }
111    
112            /**
113             * プロセスの初期化を行います?初めに??、呼び出されます?
114             * 初期処?ファイルオープン??オープン?に使用します?
115             *
116             * @og.rev 5.3.4.0 (2011/04/01) タイトル追?
117             *
118             * @param   paramProcess ??タベ?スの接続???などを持って?オブジェク?
119             */
120            public void init( final ParamProcess paramProcess ) {
121                    Argument arg = getArgument();
122    
123                    logFile  = arg.getProparty( "logFile"  );       // ログ出力?
124                    dispFile = arg.getProparty( "dispFile" );       // 画面出力?
125    
126                    if( logWriter == null && logFile != null ) {
127                            logWriter = FileUtil.getLogWriter( logFile );
128                    }
129    
130                    if( dispWriter == null && dispFile != null ) {
131                            dispWriter = FileUtil.getLogWriter( dispFile );
132                    }
133    
134                    host = arg.getProparty( "host",host );  // メールサーバ?
135                    from = arg.getProparty( "from",from );  // 送信?ドレス
136                    to   = arg.getProparty( "to"  ,to   );  // 送信先アドレス
137                    subject    = arg.getProparty( "subject" );              // 5.3.4.0 (2011/04/01) タイトル
138                    useErrMail = ( host != null ) && ( from != null ) && ( to != null ) ;
139            }
140    
141            /**
142             * プロセスの終?行います??に??、呼び出されます?
143             * 終???ファイルクローズ??クローズ?に使用します?
144             *
145             * @param   isOK ト?タルで、OK?たかど?[true:成功/false:失敗]
146             */
147            public void end( final boolean isOK ) {
148                    if( logWriter != null ) {
149                            logWriter.flush();
150                            Closer.ioClose( logWriter );
151                    }
152    
153                    if( dispWriter != null ) {
154                            dispWriter.flush();
155                            Closer.ioClose( dispWriter );
156                    }
157            }
158    
159            /**
160             * ログファイルにメ?ージを表示します?
161             *
162             * @param       msg     表示するメ?ージ
163             */
164            @Override
165            public void logging( final String msg ) {
166                    if( logWriter != null ) {
167                            logWriter.println( msg ) ;
168                    }
169            }
170    
171            /**
172             * ?スプレイにメ?ージを表示します?
173             *
174             * @param       msg     表示するメ?ージ
175             */
176            @Override
177            public void println( final String msg ) {
178                    if( dispWriter != null ) {
179                            dispWriter.println( msg ) ;
180                    }
181            }
182    
183            /**
184             * エラーログにメ?ージを表示します?
185             * ここに書き込まれたメ?ージは??常ログと、特殊ログの
186             * 両方に書き込まれます?
187             * 特殊ログとは、メール連絡等?ことです?
188             *
189             * @param       msg     表示するメ?ージ
190             * @param       th      Throwable例外オブジェク?
191             */
192            public void errLog( final String msg,final Throwable th ) {
193                    String sendMsg = msg;
194                    if( logWriter != null ) {
195                            if( th != null ) {
196                                    StringWriter errMsg = new StringWriter();
197                                    errMsg.append( msg ).append( CR );
198                                    th.printStackTrace( new PrintWriter( errMsg ) );
199                                    sendMsg = errMsg.toString();
200                            }
201                            logWriter.println( sendMsg ) ;
202                    }
203                    println( sendMsg ) ;
204                    if( useErrMail ) { sendmail( sendMsg ) ; }
205            }
206    
207            /**
208             * メール送信を行います?
209             *
210             * @og.rev 5.3.4.0 (2011/04/01) タイトル追?
211             *
212             * @param       msg     送信するメ?ージ
213             */
214            private void sendmail( final String msg ) {
215    
216                    Argument arg = getArgument();
217    
218                    String charset = arg.getProparty( "charset", DEFAULT_CHARSET );
219                    MailTX mail = new MailTX( host,charset );
220                    mail.setFrom( from );
221                    mail.setTo( StringUtil.csv2Array( to ) );
222    //              mail.setSubject( arg.getProparty( "subject" ) );
223                    mail.setSubject( subject );                                                                     // 5.3.4.0 (2011/04/01)
224    
225                    String message = arg.getFileProparty("message","msgFile",false);
226    
227                    // {@XXX} 変換は、Argument クラスの機?を使??
228                    message = arg.changeParam( message );
229                    message = message + CR + msg ;
230                    mail.setMessage( message );
231                    mail.sendmail();
232            }
233    
234            /**
235             * ログ出力用のPrintWriterを設定します?
236             * 通常は、引数の -logFile=XXXX で?しますが、直接 PrintWriter ?
237             * 渡す?があるケース(JSPなどで使用するケース)で使用します?
238             * 引数より、こちら?設定?ほ?、優先されます?
239             * ※ JspWriter を渡す?合? PrintWriter は、flushing および、close 処?
240             * 行わな?NonFlushPrintWriter を設定してください?
241             *
242             * @param  logWriter    ログ出力用のPrintWriter
243             */
244            public void setLoggingWriter( final PrintWriter logWriter ) {
245                    this.logWriter = logWriter;
246            }
247    
248            /**
249             * 画面表示用のPrintWriterを設定します?
250             * 通常は、引数の -dispFile=XXXX で?しますが、直接 PrintWriter ?
251             * 渡す?があるケース(JSPなどで使用するケース)で使用します?
252             * 引数より、こちら?設定?ほ?、優先されます?
253             * ※ JspWriter を渡す?合? PrintWriter は、flushing および、close 処?
254             * 行わな?NonFlushPrintWriter を設定してください?
255             *
256             * @param  dispWriter   画面表示用のPrintWriter
257             */
258            public void setDisplayWriter( final PrintWriter dispWriter ) {
259                    this.dispWriter = dispWriter;
260            }
261    
262            /**
263             * プロセスの処?果のレポ?ト表現を返します?
264             * 処??ログラ?、?力件数、?力件数などの??です?
265             * こ???をそのまま、標準?力に出すことで、結果レポ?トと出来るよ?
266             * 形式で出してください?
267             *
268             * @og.rev 5.3.4.0 (2011/04/01) タイトル追?
269             *
270             * @return   処?果のレポ??
271             */
272            public String report() {
273                    return "[" + getClass().getName() + "]" + CR
274                                    + TAB + "Subject      : " + subject + CR
275                                    + TAB + "Log     File : " + logFile + CR
276                                    + TAB + "Display File : " + dispFile ;
277            }
278    
279            /**
280             * こ?クラスの使用方法を返します?
281             *
282             * @return      こ?クラスの使用方?
283             */
284            public String usage() {
285                    StringBuilder buf = new StringBuilder();
286    
287                    buf.append( "Process_Logger は、画面出力?ファイルログ、エラーメールを管?る?"                     ).append( CR );
288                    buf.append( "ロギング関係? LoggerProcess インターフェースの実?ラスです?"                               ).append( CR );
289                    buf.append( CR );
290                    buf.append( "MainProcess で使用されるログと、各種 Process で使用されるディスプレイ?          ).append( CR );
291                    buf.append( "管?ます?また?エラー発生時の、メール送信機?も?ここで用意します?"              ).append( CR );
292                    buf.append( CR );
293                    buf.append( "引数??中に空白を含??合?、ダブルコー??ション(\"\") で括って下さ??" ).append( CR );
294                    buf.append( "引数??の ?』?前後には、空白は挟めません。??key=value の様に"             ).append( CR );
295                    buf.append( "繋げてください?                                                                                                                              ).append( CR );
296                    buf.append( CR ).append( CR );
297    
298                    buf.append( getArgument().usage() ).append( CR );
299    
300                    return buf.toString();
301            }
302    
303            /**
304             * こ?クラスは、main メソ?から実行できません?
305             *
306             * @param       args    コマンド引数配?
307             */
308            public static void main( final String[] args ) {
309                    LogWriter.log( new Process_Logger().usage() );
310            }
311    }