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    }