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.FileUtil;
020 import org.opengion.fukurou.util.FileString;
021 import org.opengion.fukurou.util.Closer ;
022 import org.opengion.fukurou.util.StringUtil ;
023 import org.opengion.fukurou.util.LogWriter;
024
025 import java.util.Arrays;
026 import java.util.Map ;
027 import java.util.LinkedHashMap ;
028 import java.util.regex.Pattern;
029 import java.util.regex.Matcher;
030
031 import java.io.File;
032 import java.io.PrintWriter;
033 import java.io.BufferedReader;
034 import java.io.IOException;
035
036 /**
037 * Process_Grep は、上流から受け取っ?FileLineModelから、文字?を見つけ??
038 * ChainProcess インターフェースの実?ラスです?
039 *
040 * 正規表現の keyword を上流から受け取っ?FileLineModel から検索します?
041 * 見つかった対象ファイルから、指定???を置換する?合??change ?
042 * -changeFile で、keyword を置換する文字?を指定して下さ??
043 * 置換する文字?には、\t と \n の特殊文字が使用できます?
044 *
045 * 処?象は??常は?行づつ読み取りながら処?行います?存在チェ?の場合??
046 * 見つかった時点で処?中止します?これは、該当?をピ?ア??するのではなく?
047 * 存在して?かど?を判断して、あれ?、下流に流すと?のが目?からです?
048 * keyword を?改行を含?規表現で、検索・置換する?合??useBulkRead 属??
049 * true に設定してください。これ?、?力ファイルを?して読み込みます?
050 * -ignoreCase は、正規表現の検索時にキーの大?小文字を無視するよ??します?
051 * -notEquals は、結果(見つかればtrue)を反転(見つからなければtrue)します?
052 * これは、行単位ではなく?ファイル単位に判定します?で、change ?した??
053 * でも?対象行?、見つかった行です?ただし?下流に対して、見つからな?
054 * 場合だけ??継続させます?
055 * -inEncode は、?力ファイルのエンコード指定になります?
056 * -outEncode は、?力ファイルのエンコードや、changeFileで??置換文字?ファイルの
057 * エンコード指定になります?(changeFile は、? 出力ファイルと同じエンコードです?)
058 * これら?エンコードが無??場合?、System.getProperty("file.encoding") で
059 * 求まる?を使用します?
060 * -changeFile を使用することで、?行???に置換することが可能です?
061 * -outfile では、??行ったファイル名?をセーブします?
062 *
063 * 上?プロセスチェインの??タは上流から渡されます?)からのLineModel の
064 * ファイルオブジェクトより?????が含まれて?か検索します?
065 * 上流?ロセスでは、Name 属?として、?File』を持ち、?は、Fileオブジェク?
066 * である、Process_FileSearch を使用するのが?便利です?それ以外?クラス?
067 * 使用する場合でも?Name属?と、File オブジェクトを持つ LineModel を受け渡?
068 * できれば、使用可能です?
069 *
070 * 引数??中に空白を含??合?、ダブルコー??ション("") で括って下さ??
071 * 引数??の ?』?前後には、空白は挟めません。??key=value の様に
072 * 繋げてください?
073 *
074 * @og.formSample
075 * Process_Grep -keyword=検索?? -ignoreCase=true -outfile=OUTFILE -encode=UTF-8
076 *
077 * -keyword=キーワー? ?検索する語句
078 * [-ignoreCase=大?小文?] ?検索時に大?小文字を区別しな?true)かど?(初期値:区別する[false])
079 * [-notEquals=判定結果の反転] ?判定結果を反転させ?true)かど?(初期値:反転させない[false])
080 * [-inEncode=入力エンコー?] ??力ファイルのエンコードタイ?
081 * [-outEncode=出力エンコード] ??力ファイル?換ファイルのエンコードタイ?
082 * [-change=置換文字? ] ??change="ABCD" \t ?\n などの特殊文字が使用できます?
083 * [-changeFile=置換ファイル ] ??changeFile=change.txt こ?ファイルの記述すべてと置換します?
084 * -change と?changeFile は、同時に?できません?
085 * 置換機?使用時?、?、_backup と?ファイルが作?されます?
086 * [-insert=[CHANGE/BEFORE/AFTER] ] : 置換でなく挿入する場合?位置を指定しま?初期値:CHANGE)
087 * スペ?スで区?て数字を記述すると、挿入位置にオフセ?できます?
088 * [-delete=[false/true] ] : 置換でなく削除しま?初期値:false)
089 * [-useBackup=[false/true] ] ?trueは、backupファイルを作?しま?初期値:false)
090 * [-useBulkRead=[false/true]] ?trueは、?力ファイルを?読込しま?初期値:false)
091 * [-display=[false/true] ] ?trueは、検索状況を表示しま?初期値:false)
092 * [-debug=[false/true] ] ?デバッグ??を標準?力に表示する(true)かしな?false)?初期値:false[表示しない])
093 *
094 * @version 4.0
095 * @author Kazuhiko Hasegawa
096 * @since JDK5.0,
097 */
098 public class Process_Grep extends AbstractProcess implements ChainProcess {
099 private static final String[] INSERT_LIST = new String[] { "CHANGE","BEFORE","AFTER" };
100
101 private Pattern pattern = null;
102 private String keyword = null;
103 private boolean ignoreCase = false;
104 private boolean notEquals = false;
105 private String inEncode = null;
106 private String outEncode = null;
107 private String change = null;
108 private String insert = "CHANGE"; // "CHANGE","BEFORE","AFTER" のどれか
109 private int insOffset = 0; // "BEFORE","AFTER" 時?オフセ?
110 private boolean useBackup = false;
111 private boolean useBulkRead = false; // 4.0.1.0 (2007/12/14)
112 private boolean delete = false;
113 private boolean display = false;
114 private boolean debug = false; // 5.1.2.0 (2010/01/01)
115
116 private int inCount = 0;
117 private int findCount = 0;
118 private int cngCount = 0;
119
120 private static final Map<String,String> mustProparty ; // ?プロパティ???チェ?用 Map
121 private static final Map<String,String> usableProparty ; // ?プロパティ?整合?チェ? Map
122
123 static {
124 mustProparty = new LinkedHashMap<String,String>();
125 mustProparty.put( "keyword", "検索する語句(??)" );
126
127 usableProparty = new LinkedHashMap<String,String>();
128 usableProparty.put( "ignoreCase", "検索時に大?小文字を区別しな?true)かど?? +
129 CR + "(初期値:区別する[false])" );
130 usableProparty.put( "notEquals", "検索時に判定結果を反転させ?true)かど?? +
131 CR + "(初期値:反転させない[false])" );
132 usableProparty.put( "inEncode", "入力ファイルのエンコードタイ? );
133 usableProparty.put( "outEncode", "出力ファイル?換ファイルのエンコードタイ? );
134 usableProparty.put( "change", "置換文字? ? -change=\"ABCD\" \\t ?\\n などの特殊文字が使用できます?" );
135 usableProparty.put( "changeFile", "置換文字?ファイル ? -changeFile=change.txt" +
136 CR + "-change と?changeFile は、同時に?できません? +
137 CR + "置換機?使用時?、?、_backup と?ファイルが作?されます?" );
138 usableProparty.put( "insert", "[CHANGE/BEFORE/AFTER]:置換でなく挿入する場合?位置を指定しま?初期値:CHANGE)" +
139 CR + "スペ?スで区?て数字を記述すると、挿入位置にオフセ?できます?" );
140 usableProparty.put( "delete", "[false/true]:trueは、置換でなく削除しま?初期値:false)" );
141 usableProparty.put( "useBackup", "[false/true]:trueは、backupファイルを作?しま?初期値:false)" );
142 usableProparty.put( "useBulkRead", "[false/true]:trueは、?力ファイルを?読込しま?初期値:false)" );
143 usableProparty.put( "display", "[false/true]:trueは、検索状況を表示しま?初期値:false)" );
144 usableProparty.put( "debug", "????を標準?力に表示する(true)かしな?false)? +
145 CR + "(初期値:false:表示しな?" );
146 }
147
148 /**
149 * ?ォルトコンストラクター?
150 * こ?クラスは、動??されます??ォルトコンストラクターで?
151 * super クラスに対して、?な初期化を行っておきます?
152 *
153 */
154 public Process_Grep() {
155 super( "org.opengion.fukurou.process.Process_Grep",mustProparty,usableProparty );
156 }
157
158 /**
159 * プロセスの初期化を行います?初めに??、呼び出されます?
160 * 初期処?ファイルオープン??オープン?に使用します?
161 *
162 * @param paramProcess ??タベ?スの接続???などを持って?オブジェク?
163 */
164 public void init( final ParamProcess paramProcess ) {
165 Argument arg = getArgument();
166
167 keyword = arg.getProparty("keyword");
168 ignoreCase = arg.getProparty("ignoreCase" ,ignoreCase);
169 notEquals = arg.getProparty("notEquals" ,notEquals);
170 inEncode = arg.getProparty("inEncode" ,System.getProperty("file.encoding"));
171 outEncode = arg.getProparty("outEncode" ,System.getProperty("file.encoding"));
172 useBackup = arg.getProparty("useBackup" ,useBackup);
173 useBulkRead = arg.getProparty("useBulkRead" ,useBulkRead); // 4.0.1.0 (2007/12/14)
174 delete = arg.getProparty("delete" ,delete );
175 insert = arg.getProparty("insert" ,insert );
176 change = arg.getFileProparty( "change","changeFile",outEncode,false );
177 display = arg.getProparty("display" ,display);
178 debug = arg.getProparty( "debug" ,debug ); // 5.1.2.0 (2010/01/01)
179 // if( debug ) { println( arg.toString() ); } // 5.7.3.0 (2014/02/07) ????
180
181 if( change != null ) {
182 int adrs = insert.indexOf( ' ' ); // オフセ?数字?有無
183 if( adrs > 0 ) {
184 insOffset = Integer.parseInt( insert.substring( adrs+1 ) );
185 insert = insert.substring( 0,adrs );
186 }
187
188 boolean isOK = false;
189 for( int i=0; i<INSERT_LIST.length; i++ ) {
190 if( insert.equalsIgnoreCase( INSERT_LIST[i] ) ) {
191 isOK = true; break;
192 }
193 }
194 if( !isOK ) {
195 String errMsg = "insert は? + Arrays.toString( INSERT_LIST )
196 + " から?してください? + CR
197 + "-insert=[" + insert + "]" ;
198 throw new RuntimeException( errMsg );
199 }
200
201 change = StringUtil.replace( change,"\\n",CR );
202 change = StringUtil.replace( change,"\\t","\t" );
203 }
204
205 if( delete ) { change = ""; } // 削除は?" ??と置換します?
206
207 if( ignoreCase ) {
208 pattern = Pattern.compile( keyword,Pattern.CASE_INSENSITIVE );
209 }
210 else {
211 pattern = Pattern.compile( keyword );
212 }
213 }
214
215 /**
216 * プロセスの終?行います??に??、呼び出されます?
217 * 終???ファイルクローズ??クローズ?に使用します?
218 *
219 * @param isOK ト?タルで、OK?たかど?[true:成功/false:失敗]
220 */
221 public void end( final boolean isOK ) {
222 // ここでは処?行いません?
223 }
224
225 /**
226 * 引数の LineModel を??るメソ?です?
227 * 変換処?? LineModel を返します?
228 * 後続??行わな?????タのフィルタリングを行う場?は?
229 * null ??タを返します?つまり?null ??タは、後続??行わな?
230 * フラグの代わりにも使用して?す?
231 * なお?変換処?? LineModel と、オリジナルの LineModel が?
232 * 同?、コピ?(クローン)か?、各処?ソ??決めて?す?
233 * ドキュメントに明記されて???合?、副作用が問題になる?合??
234 * ???とに自?コピ?(クローン)して下さ??
235 *
236 * @og.rev 4.0.1.0 (2007/12/14) ファイルの?処?応?
237 * @og.rev 5.7.2.2 (2014/01/24) エラー時に??タも?力します?
238 *
239 * @param data オリジナルのLineModel
240 *
241 * @return 処?換後?LineModel
242 */
243 public LineModel action( final LineModel data ) {
244 inCount++ ;
245
246 final FileLineModel fileData ;
247 if( data instanceof FileLineModel ) {
248 fileData = (FileLineModel)data ;
249 }
250 else {
251 String errMsg = "??タ?FileLineModel オブジェクトではありません? + CR ;
252 throw new RuntimeException( errMsg );
253 }
254
255 File file = fileData.getFile() ;
256 if( ! file.isFile() ) {
257 if( display ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更
258 return data;
259 }
260
261 final boolean isFind ;
262 try {
263 String fileLine = null;
264 int firstLineNo = -1;
265 if( useBulkRead ) { fileLine = findKeywordAsBulk( file ); }
266 else { firstLineNo = findKeyword( file ); }
267
268 isFind = ( fileLine != null ) || ( firstLineNo >= 0 ) ;
269
270 // 置換??ただし?見つかったとき?み実?
271 if( change != null && isFind ) {
272 // 入力ファイルは、オリジナル_backup ファイルとする。過去のファイルを削除
273 File inFile = new File( file.getPath() + "_backup" );
274 if( inFile.exists() && !inFile.delete() ) {
275 String errMsg = "過去のBKUPファイルを削除できませんでした?" + inFile + "]" + CR
276 + "data=[" + data.dataLine() + "]" + CR ; // 5.7.2.2 (2014/01/24) エラー時に??タも?力します?
277 throw new RuntimeException( errMsg );
278 }
279
280 // オリジナルのファイルを?_backup ファイル名に先に変換する?
281 File fromFile = new File( file.getPath() );
282 if( !fromFile.renameTo( inFile ) ) {
283 String errMsg = "??ファイルをリネ??きませんでした?" + fromFile + "]" + CR
284 + "data=[" + data.dataLine() + "]" + CR ; // 5.7.2.2 (2014/01/24) エラー時に??タも?力します?
285 throw new RuntimeException( errMsg );
286 }
287
288 // 変換処?本?
289 if( useBulkRead ) { changeKeywordAsBulk( fileLine,file ); }
290 else { changeKeyword( inFile,file,firstLineNo ); }
291
292 // backup を使わな??合?、削除する?
293 // 4.0.0.0 (2007/11/29) 入れ子if の統?
294 if( ! useBackup && !inFile.delete() ) {
295 String errMsg = "??ファイルを削除できませんでした?" + inFile + "]" + CR
296 + "data=[" + data.dataLine() + "]" + CR ; // 5.7.2.2 (2014/01/24) エラー時に??タも?力します?
297 throw new RuntimeException( errMsg );
298 }
299 }
300 }
301 catch ( RuntimeException ex ) {
302 String errMsg = "処?にエラーが発生しました?" + data.getRowNo() + "]件目" + CR
303 // + data.toString() ;
304 + "data=[" + data.dataLine() + "]" + CR ; // 5.7.2.2 (2014/01/24) エラー時に??タも?力します?
305 throw new RuntimeException( errMsg,ex );
306 }
307
308 if( display && ( notEquals ^ isFind ) ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更
309 return ( notEquals ^ isFind ) ? data : null ;
310 }
311
312 /**
313 * キーワードが存在して?かど?をチェ?します?
314 * ここでは?行づつ読み取りながら、最初に見つかった時点で制御を返します?
315 * よって、?行にまたが?keyword でのマッチングは出来ませんが?大きな
316 * ファイル等での検索には、効?です?
317 *
318 * @og.rev 4.0.1.0 (2007/12/14) 新規追?
319 *
320 * @param file 検索??ファイルオブジェク?
321 *
322 * @return ??に見つかった行番号(見つからなければ?1 を返す)
323 */
324 private int findKeyword( final File file ) {
325 BufferedReader reader = null;
326
327 int firstLineNo = -1;
328 try {
329 reader = FileUtil.getBufferedReader( file,inEncode );
330 String line ;
331 int lineNo = 0;
332 while((line = reader.readLine()) != null) {
333 lineNo++ ;
334 Matcher mach = pattern.matcher( line );
335 if( mach.find() ) {
336 if( debug ) {
337 String buf = "DEBUG:\t" + file.getPath() + "(" + lineNo + "): " + line ;
338 println( buf );
339 }
340 firstLineNo = lineNo;
341 break;
342 }
343 }
344 }
345 catch ( IOException ex ) {
346 String errMsg = "ファイル読取エラーが発生しました?" + file.getPath() + "]" ;
347 throw new RuntimeException( errMsg,ex );
348 }
349 finally {
350 Closer.ioClose( reader );
351 }
352
353 return firstLineNo;
354 }
355
356 /**
357 * キーワードが存在して?かど?をチェ?します?
358 * ここでは、ファイルをすべて読み取ってから、チェ?します?
359 * よって、?行にまたが?keyword でのマッチングが可能です?
360 *
361 * @og.rev 4.0.1.0 (2007/12/14) 新規追?
362 *
363 * @param file 検索??ファイルオブジェク?
364 *
365 * @return 検索??ファイルの??化情報(ただし?見つからなければ、null)
366 */
367 private String findKeywordAsBulk( final File file ) {
368
369 boolean isFind = false;
370
371 FileString sf = new FileString();
372 sf.setFilename( file.getPath() );
373 sf.setEncode( inEncode );
374 String line = sf.getValue();
375
376 Matcher mach = pattern.matcher( line );
377 if( mach.find() ) {
378 if( debug ) { println( "DEBUG:\t" + file.getPath() ); }
379 isFind = true;
380 }
381
382 return ( isFind ) ? line : null;
383 }
384
385 /**
386 * キーワードを????に置き換えます?
387 * useBackup 属?に true を指定した?合?置き換え後?、backup ファイルは?
388 * オリジナル_backup と?名称に変わります?
389 * ここでは?行づつ読み取りながら、変換処?行います?
390 * よって、?行にまたが?keyword でのマッチングは出来ませんが?大きな
391 * ファイル等での置換でも?メモリの使用量?抑えられます?
392 *
393 * @og.rev 4.0.1.0 (2007/12/14) 置換??独立させます?
394 *
395 * @param inFile 検索??入力ファイルオブジェク?
396 * @param outFile 変換後?出力ファイルオブジェク?
397 * @param firstLineNo キーワードが存在した場合???の行番号
398 */
399 private void changeKeyword( final File inFile,final File outFile,final int firstLineNo ) {
400
401 BufferedReader reader = FileUtil.getBufferedReader( inFile,inEncode );
402 PrintWriter writer = FileUtil.getPrintWriter( outFile,outEncode );
403
404 String line = null;
405 try {
406 int lineNo = 0;
407 while((line = reader.readLine()) != null) {
408 lineNo++ ;
409 if( lineNo >= firstLineNo ) {
410 Matcher mach = pattern.matcher( line );
411
412 String chnStr = null;
413 if( "CHANGE".equals( insert ) ) {
414 chnStr = strChange( mach );
415 }
416 else if( "BEFORE".equals( insert ) ) {
417 chnStr = strBefore( line,mach );
418 }
419 else if( "AFTER".equals( insert ) ) {
420 chnStr = strAfter( line,mach );
421 }
422
423 if( chnStr != null ) {
424 line = chnStr;
425 cngCount++ ; // 変換されれ? カウン?
426 }
427 }
428 writer.println( line ); // readLine() してる?で、最後に改行が??
429 }
430 }
431 catch ( IOException ex ) {
432 String errMsg = "処?にエラーが発生しました?" + line + "]" ;
433 throw new RuntimeException( errMsg,ex );
434 }
435 finally {
436 Closer.ioClose( reader );
437 Closer.ioClose( writer );
438 }
439 }
440 /**
441 * キーワードを????に置き換えます?
442 * useBackup 属?に true を指定した?合?置き換え後?、backup ファイルは?
443 * オリジナル_backup と?名称に変わります?
444 * ここでは、ファイルをすべて読み取ってから、チェ?します?
445 * よって、?行にまたが?keyword でのマッチングが可能です?
446 *
447 * @og.rev 4.0.1.0 (2007/12/14) 置換??独立させます?
448 *
449 * @param fileLine 検索??行文字?
450 * @param outFile 出力ファイルオブジェク?
451 */
452 private void changeKeywordAsBulk( final String fileLine,final File outFile ) {
453 PrintWriter writer = FileUtil.getPrintWriter( outFile,outEncode );
454
455 String line = fileLine ;
456 try {
457 Matcher mach = pattern.matcher( line );
458
459 String chnStr = null;
460 if( "CHANGE".equals( insert ) ) {
461 chnStr = strChange( mach );
462 }
463 else if( "BEFORE".equals( insert ) ) {
464 chnStr = strBefore( line,mach );
465 }
466 else if( "AFTER".equals( insert ) ) {
467 chnStr = strAfter( line,mach );
468 }
469
470 if( chnStr != null ) {
471 line = chnStr;
472 cngCount++ ; // 変換されれ? カウン?
473 }
474
475 writer.print( line ); // 注意:改行コード?、不?
476 }
477 catch ( RuntimeException ex ) {
478 String errMsg = "処?にエラーが発生しました?" + outFile.getPath() + "]" ;
479 throw new RuntimeException( errMsg,ex );
480 }
481 finally {
482 Closer.ioClose( writer );
483 }
484 }
485
486 /**
487 * insert が?"CHANGE" の場合?処?果を求めます?
488 * 変換しなかった?合?、null を返します?
489 * これは、変換カウントを算?する為のフラグ代わりに使用して?す?
490 *
491 * @param mach キーワード?正規表現
492 *
493 * @return 変換結果(対象行で無??合?、null)
494 */
495 private String strChange( final Matcher mach ) {
496 String line = null;
497 if( mach.find() ) {
498 line = mach.replaceAll( change );
499 }
500 return line ;
501 }
502
503 /**
504 * insert が?"BEFORE" の場合?処?果を求めます?
505 * 変換しなかった?合?、null を返します?
506 * これは、変換カウントを算?する為のフラグ代わりに使用して?す?
507 *
508 * @param line 検索?
509 * @param mach キーワード?正規表現
510 *
511 * @return 変換結果(対象行で無??合?、null)
512 */
513 private String strBefore( final String line , final Matcher mach ) {
514 boolean isChng = false;
515 StringBuilder buf = new StringBuilder( line.length() );
516 int indx = 0;
517 while( mach.find() ) {
518 isChng = true;
519 int strt = mach.start() + insOffset;
520 buf.append( line.substring( indx,strt ) );
521 buf.append( change );
522 indx = strt;
523 }
524
525 String rtn = null;
526 if( isChng ) {
527 buf.append( line.substring( indx ) );
528 rtn = buf.toString();
529 }
530
531 return rtn ;
532 }
533
534 /**
535 * insert が?"AFTER" の場合?処?果を求めます?
536 * 変換しなかった?合?、null を返します?
537 * これは、変換カウントを算?する為のフラグ代わりに使用して?す?
538 *
539 * @param line 検索?
540 * @param mach キーワード?正規表現
541 *
542 * @return 変換結果(対象行で無??合?、null)
543 */
544 private String strAfter( final String line , final Matcher mach ) {
545 boolean isChng = false;
546 StringBuilder buf = new StringBuilder( line.length() );
547 int indx = 0;
548 while( mach.find() ) {
549 isChng = true;
550 int end = mach.end() + insOffset;
551 buf.append( line.substring( indx,end ) );
552 buf.append( change );
553 indx = end;
554 }
555 String rtn = null;
556 if( isChng ) {
557 buf.append( line.substring( indx ) );
558 rtn = buf.toString();
559 }
560
561 return rtn ;
562 }
563
564 /**
565 * プロセスの処?果のレポ?ト表現を返します?
566 * 処??ログラ?、?力件数、?力件数などの??です?
567 * こ???をそのまま、標準?力に出すことで、結果レポ?トと出来るよ?
568 * 形式で出してください?
569 *
570 * @return 処?果のレポ??
571 */
572 public String report() {
573 if( findCount < cngCount ) { findCount = cngCount; }
574
575 String report = "[" + getClass().getName() + "]" + CR
576 + TAB + "Search Keyword : " + keyword + CR
577 + TAB + "Search File Count : " + inCount + CR
578 + TAB + "Key Find Count : " + findCount + CR
579 + TAB + "Key Change Count : " + cngCount ;
580
581 return report ;
582 }
583
584 /**
585 * こ?クラスの使用方法を返します?
586 *
587 * @return こ?クラスの使用方?
588 */
589 public String usage() {
590 StringBuilder buf = new StringBuilder();
591
592 buf.append( "Process_Grep は、上流から受け取っ?FileLineModelから、文字?を見つけ?? ).append( CR );
593 buf.append( "ChainProcess インターフェースの実?ラスです?" ).append( CR );
594 buf.append( CR );
595 buf.append( "正規表現の keyword を上流から受け取っ?FileLineModel から検索します?" ).append( CR );
596 buf.append( "見つかった対象ファイルから、指定???を置換する?合??change ? ).append( CR );
597 buf.append( "-changeFile で、keyword を置換する文字?を指定して下さ??" ).append( CR );
598 buf.append( "置換する文字?には、\t と \n の特殊文字が使用できます?" ).append( CR );
599 buf.append( CR );
600 buf.append( "処?象は??常は?行づつ読み取りながら処?行います?存在チェ?の場合?? ).append( CR );
601 buf.append( "見つかった時点で処?中止します?これは、該当?をピ?ア??するのではなく?" ).append( CR );
602 buf.append( "存在して?かど?を判断して、あれ?、下流に流すと?のが目?からです?" ).append( CR );
603 buf.append( "keyword を?改行を含?規表現で、検索・置換する?合??useBulkRead 属?? ).append( CR );
604 buf.append( "true に設定してください。これ?、?力ファイルを?して読み込みます?" ).append( CR );
605 buf.append( "-ignoreCase は、検索時にキーの大?小文字を無視するよ??します?" ).append( CR );
606 buf.append( "-notEquals は、結果(見つかればtrue)を反転(見つからなければtrue)します?" ).append( CR );
607 buf.append( "これは、行単位ではなく?ファイル単位に判定します?で、change ?した?? ).append( CR );
608 buf.append( "でも?対象行?、見つかった行です?ただし?下流に対して、見つからな? ).append( CR );
609 buf.append( "場合だけ??継続させます?" ).append( CR );
610 buf.append( "-inEncode は、?力ファイルのエンコード指定になります?" ).append( CR );
611 buf.append( "-outEncode は、?力ファイルのエンコードや、changeFileで??置換文字?" ).append( CR );
612 buf.append( "ファイルのエンコード指定になります?(changeFile は、? 出力ファイルと)" ).append( CR );
613 buf.append( "同じエンコードです?" ).append( CR );
614 buf.append( "これら?エンコードが無??場合?、System.getProperty(\"file.encoding\") " ).append( CR );
615 buf.append( "で求まる?を使用します?" ).append( CR );
616 buf.append( "-changeFile を使用することで、?行???に置換することが可能です?" ).append( CR );
617 buf.append( CR );
618 buf.append( "上?プロセスチェインの??タは上流から渡されます?)からのLineModel の" ).append( CR );
619 buf.append( "ファイルオブジェクトより?????が含まれて?か検索します?" ).append( CR );
620 buf.append( "上流?ロセスでは、Name 属?として、?File』を持ち、?は、Fileオブジェク? ).append( CR );
621 buf.append( "である、Process_FileSearch を使用するのが?便利です?それ以外?クラス? ).append( CR );
622 buf.append( "使用する場合でも?Name属?と、File オブジェクトを持つ LineModel を受け渡? ).append( CR );
623 buf.append( "できれば、使用可能です?" ).append( CR );
624 buf.append( CR );
625 buf.append( "引数??中に空白を含??合?、ダブルコー??ション(\"\") で括って下さ??" ).append( CR );
626 buf.append( "引数??の ?』?前後には、空白は挟めません。??key=value の様に" ).append( CR );
627 buf.append( "繋げてください? ).append( CR );
628 buf.append( CR ).append( CR );
629
630 buf.append( getArgument().usage() ).append( CR );
631
632 return buf.toString();
633 }
634
635 /**
636 * こ?クラスは、main メソ?から実行できません?
637 *
638 * @param args コマンド引数配?
639 */
640 public static void main( final String[] args ) {
641 LogWriter.log( new Process_Grep().usage() );
642 }
643 }