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.StringUtil;
020 import org.opengion.fukurou.util.FileUtil;
021 import org.opengion.fukurou.util.LogWriter;
022
023 import java.util.List;
024 import java.util.ArrayList;
025 import java.util.Date;
026
027 /**
028 * MainProcess は、HybsProcess を継承した、ParamProcess,FirstProcess,ChainProcess
029 * の実?ラスを実行するメインメソ?を持つクラスです?
030 * ParamProcess は、唯???に定義できるクラスで、データベ?ス接続やエラーメール
031 * などの共通なパラメータを定義します?なくても構いません?
032 * FirstProcess は、??実行する最初?クラスで、このクラスで??タが作?されます?
033 * ループ???、この FirstProcess で?作?され?LineModel オブジェクトを
034 * ?行づつ下位? ChainProcess に流して?ます?
035 * ChainProcess は、FirstProcess で作?されたデータを?受け取り、??ます?
036 * 処?象から外れる?合?、LineModel ?null に設定する為、下流には流れません?
037 * フィルタチェインの様に使用します?なくても構いませんし??存在しても構いません?
038 *
039 * こ?クラスは、Runnable インターフェースを実?て?す?
040 *
041 * ??ラスに引数を指定する?合??キー=値 形式で?します?
042 * キーと値の間には、スベ?スを?れな?下さ??
043 * 先??- なら引数?# ならコメン?になります?
044 * - で?# でもな?数は、HybsProcess のサブクラスになります?
045 *
046 * Usage: java MainProcess サブChainProcessクラス [[-キー=値] ???] [???]
047 * [ParamProcess実?ラス ]?ParamProcess を実?たクラス
048 * -キー=値 ?各サブクラス毎?引数?- で始まり?= で?します?
049 * -AAA=BBB ?引数は、各クラス毎に独自に?します?
050 * FirstProcess実?ラス ?FirstProcess を実?たクラス
051 * -キー=値 ?各サブクラス毎?引数?- で始まり?= で?します?
052 * -AAA=BBB ?引数は、各クラス毎に独自に?します?
053 * #-AAA=BBB ??頭?- なら引数?# ならコメン?になります?
054 * [ChainProcess実?ラス1]?ChainProcess を実?たクラス???できます?
055 * -CCC=DDD
056 * [ChainProcess実?ラス2]?ChainProcess を実?たクラス???できます?
057 * -EEE=FFF
058 *
059 * @version 4.0
060 * @author Kazuhiko Hasegawa
061 * @since JDK5.0,
062 */
063 public final class MainProcess implements Runnable {
064 private static final String CR = System.getProperty("line.separator");
065
066 /** main 処??リターン値 初期?{@value} */
067 public static final int RETURN_INIT = -1;
068 /** main 処??リターン値 正常値 {@value} */
069 public static final int RETURN_OK = 0;
070 /** main 処??リターン値 正常値 {@value} */
071 public static final int RETURN_WARN = 1;
072 /** main 処??リターン値 異常値 {@value} */
073 public static final int RETURN_NG = 2;
074
075 private List<HybsProcess> list = null;
076 private ParamProcess param = null;
077 private LoggerProcess logger = null;
078 private int kekka = RETURN_INIT;
079
080 /**
081 * HybsProcess クラスを管?て?リストをセ?します?
082 *
083 * 引数のListオブジェクト?、?コピ?で、取り込みます?
084 *
085 * @param list HybsProcessリス?
086 * @throws IllegalArgumentException 引数が?null の場合?
087 */
088 public void setList( final List<HybsProcess> list ) {
089 if( list == null ) {
090 String errMsg = "引数の List に、null は設定できません? ;
091 throw new IllegalArgumentException( errMsg );
092 }
093 this.list = new ArrayList<HybsProcess>( list );
094 }
095
096 /**
097 * HybsProcess クラスを?期化します?
098 *
099 * 主に、ParamProcess クラスの取り出?また?、作?)処??して?す?
100 *
101 * @og.rev 5.1.5.0 (2010/04/01) 出力が?重?重に出力されるのを回避します?
102 */
103 private void init() {
104 if( list == null ) {
105 String errMsg = "リス??null です?まず?setList( List<HybsProcess> ) が?です?";
106 throw new RuntimeException( errMsg );
107 }
108
109 try {
110 // List の?位?、?、LoggerProcess を?備する?
111 HybsProcess process = list.get(0);
112 if( process instanceof LoggerProcess ) {
113 logger = (LoggerProcess)process;
114 logger.init( null );
115 list.remove(0); // List上から?LoggerProcess を削除しておきます?
116 process = list.get(0); // 次の取得を行っておく。?ログラ??都?
117 }
118 else {
119 logger = new Process_Logger();
120 logger.putArgument( "logFile" , "System.out" );
121 logger.putArgument( "dispFile" , "System.out" );
122 logger.init( null );
123 }
124
125 // そ?次は、ParamProcess かど?をチェ?
126 if( process instanceof ParamProcess ) {
127 param = (ParamProcess)process;
128 param.setLoggerProcess( logger );
129 param.init( null );
130 list.remove(0); // List上から?ParamProcess を削除しておきます?
131 }
132 }
133 catch (Throwable th) {
134 StringBuilder errMsg = new StringBuilder();
135 errMsg.append( "初期化中に例外が発生しました? ).append( CR );
136 errMsg.append( th.getMessage() ) ;
137 String errStr = errMsg.toString();
138
139 logger.errLog( errStr,th );
140 LogWriter.log( errStr );
141 // 5.1.5.0 (2010/04/01) 出力が?重?重に出力されるのを回避します?
142 // System.out.println( errStr );
143
144 if( param != null ) { param.end( false ); }
145 logger.end( false );
146
147 throw new RuntimeException( errStr,th ); // 4.0.0 (2005/01/31)
148 }
149 }
150
151 /**
152 * HybsProcess クラスを実行します?
153 *
154 * @og.rev 5.1.2.0 (2010/01/01) 実行中の経過表示を?標準?力ではなく?エラー出力に変更
155 * @og.rev 5.1.5.0 (2010/04/01) 出力が?重?重に出力されるのを回避します?
156 * @og.rev 5.3.4.0 (2011/04/01) タイトル追?
157 * @og.rev 5.5.4.5 (2012/07/27) 処???に結果を?力します?
158 */
159 public void run() {
160 init();
161
162 long st = System.currentTimeMillis();
163 logger.logging( "=================================================================" );
164 logger.logging( new Date( st ) + " 処?開始します?" );
165 logger.logging( getClass().getName() );
166
167 kekka = RETURN_NG;
168 LineModel model = null;
169 int rowNo = 0;
170 int cnt = list.size();
171 try {
172 // 初期?途中でエラーが発生すれ?、終?ます?
173 logger.logging( "初期化??行います?" );
174 // if( param != null ) { logger.logging( param.toString() ); }
175
176 // List には、FirstProcess と ChainProcess のみ存在する?
177 HybsProcess process ;
178 for( int i=0; i<cnt; i++ ) {
179 process = list.get(i);
180 process.setLoggerProcess( logger );
181 process.init( param );
182 // logger.logging( process.toString() );
183 }
184
185 logger.logging( "Process を実行します?" );
186 FirstProcess firstProcess = (FirstProcess)list.get(0);
187 ChainProcess chainProcess ;
188 while( firstProcess.next() ) {
189 model = firstProcess.makeLineModel( rowNo );
190 for( int i=1; i<cnt && model != null ; i++ ) {
191 chainProcess = (ChainProcess)list.get(i);
192 model = chainProcess.action( model );
193 }
194 rowNo++;
195 // 5.1.2.0 (2010/01/01) 実行中の経過表示を?標準?力ではなく?エラー出力に変更します?
196 if( rowNo%50 == 0 ) { System.err.print( "." ); }
197 if( rowNo%1000 == 0 ) { System.err.println( " Count=[" + rowNo + "]" ); }
198 }
199 kekka = RETURN_OK;
200 logger.logging( " Total=[" + rowNo + "]" );
201 System.err.println( " Total=[" + rowNo + "]" ); // 5.5.4.5 (2012/07/27) 処???に結果を?力します?
202 }
203 catch (Throwable th) {
204 kekka = RETURN_NG;
205
206 StringBuilder errMsg = new StringBuilder();
207 errMsg.append( CR ); // 5.1.5.0 (2010/04/01) 先に改行しておきます?
208 errMsg.append( "??タ処?に例外が発生しました?[" );
209 errMsg.append( rowNo ).append( "]行目" ).append( CR );
210 errMsg.append( th.getMessage() ).append( CR ) ;
211
212 if( model != null ) { errMsg.append( model.toString() ).append( CR ) ; }
213
214 for( int i=0; i<cnt; i++ ) {
215 HybsProcess process = list.get(i);
216 errMsg.append( process.toString() );
217 }
218 String errStr = errMsg.toString();
219 logger.errLog( errStr,th );
220 LogWriter.log( errStr );
221 // 5.1.5.0 (2010/04/01) 出力が?重?重に出力されるのを回避します?
222 // System.out.println( errStr );
223 // throw new RuntimeException( errStr,th ); // 4.0.0 (2005/01/31)
224 }
225 finally {
226 // 終??全ての endメソ?をコールします?
227 logger.logging( "終???行います?" );
228 StringBuilder buf = new StringBuilder();
229 // 5.3.4.0 (2011/04/01) ロガーのreport()を呼びます?(タイトルを追?
230 if( param != null ) {
231 buf.append( logger.report() ).append( CR );
232 buf.append( param.report() );
233 }
234
235 boolean isOK = (kekka == RETURN_OK);
236 for( int i=0; i<cnt; i++ ) {
237 HybsProcess process = list.get(i);
238 if( process != null ) {
239 buf.append( CR ).append( process.report() );
240 process.end( isOK );
241 }
242 }
243 // ??に、ParamProcess を終?ます?
244 if( param != null ) { param.end( isOK ); } // 5.5.4.5 (2012/07/27) ??のProcessの end() の?にします?
245
246 buf.append( CR );
247 logger.logging( buf.toString() );
248 logger.logging( "実行結果は、[" + errCode(kekka) + "] です?" );
249 long ed = System.currentTimeMillis();
250 logger.logging( "合計???= " + (ed-st) + " (ms) です?" );
251 logger.logging( new Date( ed ) + " 終?ました? );
252
253 // // ??に、ParamProcess を終?ます?
254 // if( param != null ) { param.end( isOK ); }
255 logger.end( isOK );
256 }
257 }
258
259 /**
260 * 処??実行結果を返します?
261 *
262 * @return 実行結果
263 * @see #RETURN_INIT
264 */
265 public int getKekka() { return kekka; }
266
267 /**
268 * 処?行うメインメソ?です?
269 *
270 * @og.rev 4.0.0.0 (2007/11/22) ConnDataFactory の使用を?
271 *
272 * @param args コマンド引数配?
273 */
274 public static void main( final String[] args ) {
275 if( args.length == 0 ) {
276 LogWriter.log( usage() );
277 return ;
278 }
279
280 // 引数の?
281 List<HybsProcess> list = makeHybsProcessList( args );
282
283 // 特別に、LoggerProcess がなければ、標準?力を使用するロガーを登録する?
284 HybsProcess prcs = list.get(0);
285 if( ! (prcs instanceof LoggerProcess) ) {
286 LoggerProcess logger = new Process_Logger();
287 logger.setDisplayWriter( FileUtil.getLogWriter( "System.out" ) );
288 list.add( 0,logger );
289 }
290
291 // 引数リス?HybsProcessリス?を登録
292 MainProcess process = new MainProcess();
293 process.setList( list );
294
295 // 処??実行開?
296 process.run();
297 }
298
299 /**
300 * メインに渡された引数配? より、各 ChainProcess インスタンス を作?します?
301 *
302 * @param args メインに渡された引数配?
303 *
304 * @return ChainProcessインスタンスのList
305 */
306 private static List<HybsProcess> makeHybsProcessList( final String[] args ) {
307 ArrayList<HybsProcess> list = new ArrayList<HybsProcess>();
308
309 HybsProcess process = null;
310 Argument argment = new Argument( MainProcess.class.getName() );
311 for( int i=0; i<args.length; i++ ) {
312 int type = argment.getArgumentType( args[i] ) ;
313
314 switch( type ) {
315 case Argument.CMNT : continue;
316 case Argument.ARGS :
317 process = (HybsProcess)StringUtil.newInstance( args[i] );
318 list.add( process );
319 break;
320 case Argument.PROP :
321 if( process != null ) {
322 process.putArgument( args[i] );
323 }
324 break;
325 default: break;
326 }
327 }
328 return list;
329 }
330
331 /**
332 * エラーコードに対するメ?ージを返します?
333 *
334 * @param code エラーコー?
335 *
336 * @return エラーコードに対するメ?ージ
337 */
338 public String errCode( final int code ) {
339 final String errMsg ;
340 switch( code ) {
341 case RETURN_INIT : errMsg = "初期? ; break;
342 case RETURN_OK : errMsg = "正常" ; break;
343 case RETURN_WARN : errMsg = "警? ; break;
344 case RETURN_NG : errMsg = "異常" ; break;
345 default :errMsg = "未定義エラー" ; break;
346 }
347 return errMsg ;
348 }
349
350 /**
351 * こ?クラスの使用方法を返します?
352 *
353 * @return こ?クラスの使用方?
354 */
355 private static String usage() {
356
357 StringBuilder buf = new StringBuilder();
358
359 buf.append( "ChainProcess を実?た各クラスを??実行します?" ).append( CR );
360 buf.append( "キーと値の間には、スベ?スを?れな?下さ??").append( CR ).append( CR );
361
362 buf.append( "Usage: java MainProcess サブChainProcessクラス [[-キー=値] ???] [???] " ).append( CR );
363 buf.append( " サブChainProcessクラス ?ChainProcess を実?たクラス" ).append( CR );
364 buf.append( " -キー=値 ?各サブクラス毎?引数?- で始まり?= で?します?" ).append( CR );
365 buf.append( " -AAA=BBB ???できます?" ).append( CR );
366 buf.append( " サブChainProcessクラス ???できます?" ).append( CR );
367 buf.append( " -CCC=DDD " ).append( CR );
368
369 return buf.toString();
370 }
371 }