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 }