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 * @og.rev 5.7.2.2 (2014/01/24) logger と?重になる為、削除
159 */
160 public void run() {
161 init();
162
163 long st = System.currentTimeMillis();
164 logger.logging( "=================================================================" );
165 logger.logging( new Date( st ) + " 処?開始します?" );
166 logger.logging( getClass().getName() );
167
168 kekka = RETURN_NG;
169 LineModel model = null;
170 int rowNo = 0;
171 int cnt = list.size();
172 try {
173 // 初期?途中でエラーが発生すれ?、終?ます?
174 logger.logging( "初期化??行います?" );
175 // if( param != null ) { logger.logging( param.toString() ); }
176
177 // List には、FirstProcess と ChainProcess のみ存在する?
178 HybsProcess process ;
179 for( int i=0; i<cnt; i++ ) {
180 process = list.get(i);
181 process.setLoggerProcess( logger );
182 process.init( param );
183 // logger.logging( process.toString() );
184 }
185
186 logger.logging( "Process を実行します?" );
187 FirstProcess firstProcess = (FirstProcess)list.get(0);
188 ChainProcess chainProcess ;
189 while( firstProcess.next() ) {
190 model = firstProcess.makeLineModel( rowNo );
191 for( int i=1; i<cnt && model != null ; i++ ) {
192 chainProcess = (ChainProcess)list.get(i);
193 model = chainProcess.action( model );
194 }
195 rowNo++;
196 // 5.1.2.0 (2010/01/01) 実行中の経過表示を?標準?力ではなく?エラー出力に変更します?
197 if( rowNo%50 == 0 ) { System.err.print( "." ); }
198 if( rowNo%1000 == 0 ) { System.err.println( " Count=[" + rowNo + "]" ); }
199 }
200 kekka = RETURN_OK;
201 logger.logging( " Total=[" + rowNo + "]" );
202 // 5.7.2.2 (2014/01/24) logger と?重になる為、削除
203 // System.err.println( " Total=[" + rowNo + "]" ); // 5.5.4.5 (2012/07/27) 処???に結果を?力します?
204 }
205 catch (Throwable th) {
206 kekka = RETURN_NG;
207
208 StringBuilder errMsg = new StringBuilder();
209 errMsg.append( CR ); // 5.1.5.0 (2010/04/01) 先に改行しておきます?
210 errMsg.append( "??タ処?に例外が発生しました?[" );
211 errMsg.append( rowNo ).append( "]行目" ).append( CR );
212 errMsg.append( th.getMessage() ).append( CR ) ;
213
214 if( model != null ) { errMsg.append( model.toString() ).append( CR ) ; }
215
216 for( int i=0; i<cnt; i++ ) {
217 HybsProcess process = list.get(i);
218 errMsg.append( process.toString() );
219 }
220 String errStr = errMsg.toString();
221 logger.errLog( errStr,th );
222 LogWriter.log( errStr );
223 // 5.1.5.0 (2010/04/01) 出力が?重?重に出力されるのを回避します?
224 // System.out.println( errStr );
225 // throw new RuntimeException( errStr,th ); // 4.0.0 (2005/01/31)
226 }
227 finally {
228 // 終??全ての endメソ?をコールします?
229 logger.logging( "終???行います?" );
230 StringBuilder buf = new StringBuilder();
231 // 5.3.4.0 (2011/04/01) ロガーのreport()を呼びます?(タイトルを追?
232 if( param != null ) {
233 buf.append( logger.report() ).append( CR );
234 buf.append( param.report() );
235 }
236
237 boolean isOK = (kekka == RETURN_OK);
238 for( int i=0; i<cnt; i++ ) {
239 HybsProcess process = list.get(i);
240 if( process != null ) {
241 buf.append( CR ).append( process.report() );
242 process.end( isOK );
243 }
244 }
245 // ??に、ParamProcess を終?ます?
246 if( param != null ) { param.end( isOK ); } // 5.5.4.5 (2012/07/27) ??のProcessの end() の?にします?
247
248 buf.append( CR );
249 logger.logging( buf.toString() );
250 logger.logging( "実行結果は、[" + errCode(kekka) + "] です?" );
251 long ed = System.currentTimeMillis();
252 logger.logging( "合計???= " + (ed-st) + " (ms) です?" );
253 logger.logging( new Date( ed ) + " 終?ました? );
254
255 // // ??に、ParamProcess を終?ます?
256 // if( param != null ) { param.end( isOK ); }
257 logger.end( isOK );
258 }
259 }
260
261 /**
262 * 処??実行結果を返します?
263 *
264 * @return 実行結果
265 * @see #RETURN_INIT
266 */
267 public int getKekka() { return kekka; }
268
269 /**
270 * 処?行うメインメソ?です?
271 *
272 * @og.rev 4.0.0.0 (2007/11/22) ConnDataFactory の使用を?
273 *
274 * @param args コマンド引数配?
275 */
276 public static void main( final String[] args ) {
277 if( args.length == 0 ) {
278 LogWriter.log( usage() );
279 return ;
280 }
281
282 // 引数の?
283 List<HybsProcess> list = makeHybsProcessList( args );
284
285 // 特別に、LoggerProcess がなければ、標準?力を使用するロガーを登録する?
286 HybsProcess prcs = list.get(0);
287 if( ! (prcs instanceof LoggerProcess) ) {
288 LoggerProcess logger = new Process_Logger();
289 logger.setDisplayWriter( FileUtil.getLogWriter( "System.out" ) );
290 list.add( 0,logger );
291 }
292
293 // 引数リス?HybsProcessリス?を登録
294 MainProcess process = new MainProcess();
295 process.setList( list );
296
297 // 処??実行開?
298 process.run();
299 }
300
301 /**
302 * メインに渡された引数配? より、各 ChainProcess インスタンス を作?します?
303 *
304 * @param args メインに渡された引数配?
305 *
306 * @return ChainProcessインスタンスのList
307 */
308 private static List<HybsProcess> makeHybsProcessList( final String[] args ) {
309 ArrayList<HybsProcess> list = new ArrayList<HybsProcess>();
310
311 HybsProcess process = null;
312 Argument argment = new Argument( MainProcess.class.getName() );
313 for( int i=0; i<args.length; i++ ) {
314 int type = argment.getArgumentType( args[i] ) ;
315
316 switch( type ) {
317 case Argument.CMNT : continue;
318 case Argument.ARGS :
319 process = (HybsProcess)StringUtil.newInstance( args[i] );
320 list.add( process );
321 break;
322 case Argument.PROP :
323 if( process != null ) {
324 process.putArgument( args[i] );
325 }
326 break;
327 default: break;
328 }
329 }
330 return list;
331 }
332
333 /**
334 * エラーコードに対するメ?ージを返します?
335 *
336 * @param code エラーコー?
337 *
338 * @return エラーコードに対するメ?ージ
339 */
340 public String errCode( final int code ) {
341 final String errMsg ;
342 switch( code ) {
343 case RETURN_INIT : errMsg = "初期? ; break;
344 case RETURN_OK : errMsg = "正常" ; break;
345 case RETURN_WARN : errMsg = "警? ; break;
346 case RETURN_NG : errMsg = "異常" ; break;
347 default :errMsg = "未定義エラー" ; break;
348 }
349 return errMsg ;
350 }
351
352 /**
353 * こ?クラスの使用方法を返します?
354 *
355 * @return こ?クラスの使用方?
356 */
357 private static String usage() {
358
359 StringBuilder buf = new StringBuilder();
360
361 buf.append( "ChainProcess を実?た各クラスを??実行します?" ).append( CR );
362 buf.append( "キーと値の間には、スベ?スを?れな?下さ??").append( CR ).append( CR );
363
364 buf.append( "Usage: java MainProcess サブChainProcessクラス [[-キー=値] ???] [???] " ).append( CR );
365 buf.append( " サブChainProcessクラス ?ChainProcess を実?たクラス" ).append( CR );
366 buf.append( " -キー=値 ?各サブクラス毎?引数?- で始まり?= で?します?" ).append( CR );
367 buf.append( " -AAA=BBB ???できます?" ).append( CR );
368 buf.append( " サブChainProcessクラス ???できます?" ).append( CR );
369 buf.append( " -CCC=DDD " ).append( CR );
370
371 return buf.toString();
372 }
373 }