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.Map ;
026    import java.util.LinkedHashMap ;
027    import java.util.List ;
028    import java.util.ArrayList ;
029    import java.util.Locale ;                               // 5.7.3.2 (2014/02/28) ignoreCase ãŒå®Ÿè£?•れã¦ã?ªã‹ã£ãŸã?
030    import java.util.regex.Pattern;                 // 5.7.3.2 (2014/02/28) regexを利用ã™ã‚‹å ´å?
031    import java.util.regex.Matcher;                 // 5.7.3.2 (2014/02/28) regexを利用ã™ã‚‹å ´å?
032    
033    import java.io.File;
034    import java.io.PrintWriter;
035    import java.io.BufferedReader;
036    import java.io.IOException;
037    
038    /**
039     * Process_GrepChange ã¯ã€ä¸Šæµã‹ã‚‰å—ã‘å–ã£ã?FileLineModelã‹ã‚‰ã€èªžå¥ã‚?
040     * ç½®æ›ã™ã‚‹ã?ChainProcess インターフェースã®å®Ÿè£?‚¯ãƒ©ã‚¹ã§ã™ã?
041     *
042     * Process_Grep ã¨ã®é•ã„ã¯ã€ãƒã‚§ãƒ?‚¯ã™ã‚‹ãƒ•ァイルã®ã‚³ãƒ”ã?ã‚?キーワードãŒå­˜åœ¨
043     * ã—ãªãã¨ã‚?作æ?ã™ã‚‹ã“ã¨ã¨ã€æ¤œç´¢ã‚­ãƒ¼ã«æ­£è¦è¡¨ç¾ãŒä½¿ãˆãªã??è¤?•°è¡Œç½®ãæ›ãˆãŒ
044     * 出æ¥ãªã?“ã¨ã§ã™ã?
045     *
046     * keywordFile よりã€ç½®æ›ã™ã‚‹èªžå¥ã‚’å«ã‚?‚­ãƒ¼ã¨å€¤ã®ãƒšã‚¢ãƒ¼(タブ区åˆ?‚Š)を読å–りã€?
047     * 対象ã¨ã™ã‚‹èªžå¥ã‚’ç½®æ›ã—ã¾ã™ã?
048     * keywordFile ã«ã€ã‚¿ãƒ–ãŒå«ã¾ã‚Œãªã?¡Œã‚„ã€å?é ­ã«ã‚¿ãƒ–ãŒå­˜åœ¨ã—ã¦ã?‚‹å ´åˆã?ã€?
049     * ãã?行を読ã¿é£›ã?ã—ã¾ã™ã?ã¾ãŸã?区åˆ?‚Šã‚¿ãƒ–ã?何å?存在ã—ã¦ã‚‚æ§‹ã„ã¾ã›ã‚“ã€?
050     * ç½®æ›æ–‡å­?値)ã¯ã€\t ã®ç‰¹æ®Šæ–‡å­—ãŒä½¿ç”¨ã§ãã¾ã™ã?
051     * ã“ã? GrepChange ã§ã¯ã€èªžå¥ã«ã€æ­£è¦è¡¨ç¾ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。正è¦è¡¨ç¾ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ?
052     * ã‚?–‡å­—å?ã‚’è¤?•°è¡Œã?æ–?­—å?ã¨ç½®ãæ›ãˆã‚‹å ´åˆã?ã€Process_Grep を使用ã—ã¦ãã ã•ã„ã€?
053     * ã“ã?プログラãƒ?§ã¯ã€ä¸Šæµã‹ã‚‰å—ã‘å–ã£ã?FileLineModel ã®ãƒ•ァイルã«å¯¾ã—ã¦ã€?
054     * ç½®ãæ›ãˆãŸçµæžœã‚‚ã?åŒã˜ãƒ•ァイルã«ã‚»ãƒ¼ãƒ–ã—ã¾ã™ã?
055     * å…??ファイルをä¿å­˜ã—ãŸã„å ´åˆã?ã€äºˆã‚ãƒãƒƒã‚¯ã‚¢ãƒ??ã‚’å–å¾—ã—ã¦ãŠã„ã¦ãã ã•ã„ã€?
056     * -inEncode ã¯ã€å?力ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰æŒ‡å®šã«ãªã‚Šã¾ã™ã?
057     * -outEncode ã¯ã€å?力ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚„ã€ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒ•ァイルã®
058     * エンコード指定ã«ãªã‚Šã¾ã™ã?(keywordFile ã¯ã€å¿?š 出力ファイルã¨åŒã˜ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã§ã™ã?)
059     * ã“れらã?エンコードãŒç„¡æŒ?®šã?å ´åˆã?ã€System.getProperty("file.encoding") ã§
060     * 求ã¾ã‚‹å?を使用ã—ã¾ã™ã?
061     *
062     * 5.7.3.2 (2014/02/28)
063     * -regex=true ã§ã€?½·?°?œï½°??¾žã«æ­£è¦è¡¨ç¾ã‚’利用ã§ãã¾ã™ã?具体的ã«ã¯ã€String#replaceAll(String,String) 
064     * を利用ã—ã¦ç½®æ›ã—ã¾ã™ã?
065     * 通常ã®ç½®æ›å?ç??ã€indexOf ã§è¦‹ã¤ã‘ã¦ã€StringBuilder#replace(int,int,String) を繰り返ã—ã¦å‡¦ç?—ã¦ã?¾ã™ã?
066     * -ignoreCase=true ã§ã€æ¤œç´¢?·?°?œï½°??¾žã«å¤§æ–?­—å°æ–‡å­—を区別ã—ãªã??ç?Œå¯èƒ½ã§ã™ã?
067     *
068     * 上æµã?ロセスã§ã¯ã€Name 属æ?ã¨ã—ã¦ã€ã?Fileã€ã‚’æŒã¡ã€å?ã¯ã€Fileオブジェクãƒ?
069     * ã§ã‚ã‚‹ã€Process_FileSearch を使用ã™ã‚‹ã®ãŒã?便利ã§ã™ã?ãれ以外ã?クラスã‚?
070     * 使用ã™ã‚‹å ´åˆã§ã‚‚ã?Name属æ?ã¨ã€File オブジェクトをæŒã¤ LineModel ã‚’å—ã‘æ¸¡ã?
071     * ã§ãれã°ã€ä½¿ç”¨å¯èƒ½ã§ã™ã?
072     *
073     * 引数æ–?­—å?中ã«ã‚¹ãƒšã?スをå«ã‚??åˆã?ã€ãƒ€ãƒ–ルコーãƒ??ション("") ã§æ‹¬ã£ã¦ä¸‹ã•ã??
074     * 引数æ–?­—å?ã® ã€?ã€ã?å‰å¾Œã«ã¯ã€ã‚¹ãƒšã?ã‚¹ã¯æŒŸã‚ã¾ã›ã‚“。å¿?šã€?key=value ã®æ§˜ã«
075     * 繋ã’ã¦ãã ã•ã„ã€?
076     *
077     *  Process_GrepChange -keyword=検索æ–?­—å? -ignoreCase=true -outfile=OUTFILE -encode=UTF-8
078     *
079     *    -keywordFile=キーワーãƒ?   ?šç½®æ›ã™ã‚‹èªžå¥ã‚’å«ã‚?‚­ãƒ¼ã¨å€¤ã®ãƒšã‚¢ãƒ¼(タブ区åˆ?‚Š)
080     *   [-ignoreCase=[false/true] ] ?šæ¤œç´¢æ™‚ã«å¤§æ–?­—å°æ–‡å­—を区別ã—ãªã?true)ã‹ã©ã?‹(åˆæœŸå€¤:false[区別ã™ã‚‹])
081     *   [-regex=[false/true]      ] ?šï½·?°?œï½°??¾žã«æ­£è¦è¡¨ç¾ã‚’利用ã™ã‚‹(true)ã‹ã©ã?‹(åˆæœŸå€¤:false[利用ã—ãªã„])
082     *   [-isChange=ç½®æ›å¯å¦       ] ?šç½®æ›å?ç?‚’実施ã™ã‚‹(true)ã‹ã©ã?‹(åˆæœŸå€¤:ç½®æ›ã™ã‚‹[true])
083     *   [-inEncode=入力エンコーãƒ?] ?šå?力ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚¿ã‚¤ãƒ?
084     *   [-outEncode=出力エンコード] ?šå?力ファイルã‚?‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒ•ァイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚¿ã‚¤ãƒ?
085     *   [-display=[false/true]    ] ?šçµæžœã‚’標準å?力ã«è¡¨ç¤ºã™ã‚‹(true)ã‹ã—ãªã?false)ã?åˆæœŸå€¤:false[表示ã—ãªã„])
086     *   [-debug=[false/true]      ] ?šãƒ‡ãƒãƒƒã‚°æƒ??を標準å?力ã«è¡¨ç¤ºã™ã‚‹(true)ã‹ã—ãªã?false)ã?åˆæœŸå€¤:false[表示ã—ãªã„])
087     *
088     * @version  4.0
089     * @author   Kazuhiko Hasegawa
090     * @since    JDK5.0,
091     */
092    public class Process_GrepChange extends AbstractProcess implements ChainProcess {
093            private String[]        keyword = null;
094            private String[]        change  = null;
095            private Pattern[]       pattern = null;                 // 5.7.3.2 (2014/02/28) ?·?°?œï½°??¾žã«æ­£è¦è¡¨ç¾ã‚’利用ã™ã‚‹å ´å?
096            private boolean         ignoreCase      = false;
097            private boolean         regex           = false;        // 5.7.3.2 (2014/02/28) ?·?°?œï½°??¾žã«æ­£è¦è¡¨ç¾ã‚’利用ã™ã‚‹ã‹ã©ã?‹
098            private boolean         isChange        = true;         // 5.1.2.0 (2010/01/01) ç½®æ›ã™ã‚‹ã‹ã©ã?‹ã‚’指定å¯èƒ½ã«ã™ã‚‹
099            private String          inEncode        = null;
100            private String          outEncode       = null;
101            private boolean         display         = false;        // 表示ã—ãªã?
102            private boolean         debug           = false;        // 5.7.3.0 (2014/02/07) ãƒ?ƒãƒ?‚°æƒ??
103    
104            private int             inCount         = 0;
105            private int             findCount       = 0;
106            private int             cngCount        = 0;
107    
108            private static final Map<String,String> mustProparty   ;          // ?»ãƒ—ロパティ?½å¿??ãƒã‚§ãƒ?‚¯ç”¨ Map
109            private static final Map<String,String> usableProparty ;          // ?»ãƒ—ロパティ?½æ•´åˆæ?ãƒã‚§ãƒ?‚¯ Map
110    
111            static {
112                    mustProparty = new LinkedHashMap<String,String>();
113                    mustProparty.put( "keywordFile",        "ç½®æ›ã™ã‚‹èªžå¥ã‚’å«ã‚?‚­ãƒ¼ã¨å€¤ã®ãƒšã‚¢ãƒ¼(タブ区åˆ?‚Š)(å¿??)" );
114    
115                    usableProparty = new LinkedHashMap<String,String>();
116                    usableProparty.put( "ignoreCase",       "検索時ã«å¤§æ–?­—å°æ–‡å­—を区別ã—ãªã?true)ã‹ã©ã?‹ã€? +
117                                                                                    CR + "(åˆæœŸå€¤:区別ã™ã‚‹[false])" );
118                    usableProparty.put( "regex",            "?·?°?œï½°??¾žã«æ­£è¦è¡¨ç¾ã‚’利用ã™ã‚‹(true)ã‹ã©ã?‹ã€? +
119                                                                                    CR + "(åˆæœŸå€¤:利用ã—ãªã„[false])" );       // 5.7.3.2 (2014/02/28)
120                    usableProparty.put( "isChange",         "ç½®æ›å?ç?‚’実施ã™ã‚‹(true)ã‹ã©ã?‹" +
121                                                                                    CR + "(åˆæœŸå€¤:ç½®æ›ã™ã‚‹[true])" );
122                    usableProparty.put( "inEncode",         "入力ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚¿ã‚¤ãƒ? );
123                    usableProparty.put( "outEncode",        "出力ファイルã‚?‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒ•ァイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚¿ã‚¤ãƒ? );
124                    usableProparty.put( "display",          "çµæžœã‚’標準å?力ã«è¡¨ç¤ºã™ã‚‹(true)ã‹ã—ãªã?false)ã? +
125                                                                                    CR + "(åˆæœŸå€¤:false:表示ã—ãªã?" );
126                    usableProparty.put( "debug",    "ãƒ?ƒãƒ?‚°æƒ??を標準å?力ã«è¡¨ç¤ºã™ã‚‹(true)ã‹ã—ãªã?false)ã? +
127                                                                                    CR + "(åˆæœŸå€¤:false:表示ã—ãªã?" );                // 5.7.3.0 (2014/02/07) ãƒ?ƒãƒ?‚°æƒ??
128            }
129    
130            /**
131             * ãƒ?ƒ•ォルトコンストラクターã€?
132             * ã“ã?クラスã¯ã€å‹•çš?½œæ?ã•れã¾ã™ã?ãƒ?ƒ•ォルトコンストラクターã§ã€?
133             * super クラスã«å¯¾ã—ã¦ã€å¿?¦ãªåˆæœŸåŒ–を行ã£ã¦ãŠãã¾ã™ã?
134             *
135             */
136            public Process_GrepChange() {
137                    super( "org.opengion.fukurou.process.Process_GrepChange",mustProparty,usableProparty );
138            }
139    
140            /**
141             * プロセスã®åˆæœŸåŒ–を行ã„ã¾ã™ã?åˆã‚ã«ä¸?º¦ã?‘ã€å‘¼ã³å‡ºã•れã¾ã™ã?
142             * åˆæœŸå‡¦ç?ファイルオープンã€?¼¤?¢ã‚ªãƒ¼ãƒ—ンç­?ã«ä½¿ç”¨ã—ã¾ã™ã?
143             *
144             * @og.rev 5.1.2.0 (2010/01/01) ç½®æ›ã™ã‚‹ã‹ã©ã?‹ã‚’指定å¯èƒ½ã«ã™ã‚‹(isChange)属æ?追åŠ?
145             * @og.rev 5.7.3.2 (2014/02/28) debug ã®è¡¨ç¤ºã¨ã€?½·?°?œï½°??¾žã? \t ã®ä½¿ç”¨ã€trim() å»?­¢ã€ignoreCase ã®å®Ÿè£??regex ã®è¿½åŠ?
146             *
147             * @param   paramProcess ãƒ??タベã?ã‚¹ã®æŽ¥ç¶šå?æƒ??ãªã©ã‚’æŒã£ã¦ã?‚‹ã‚ªãƒ–ジェクãƒ?
148             */
149            public void init( final ParamProcess paramProcess ) {
150                    Argument arg = getArgument();
151    
152                    String keywordFile = arg.getProparty("keywordFile" );
153                    ignoreCase      = arg.getProparty("ignoreCase",ignoreCase);
154                    regex           = arg.getProparty("regex",regex);                               // 5.7.3.2 (2014/02/28) 
155                    isChange        = arg.getProparty("isChange",isChange);                 // 5.1.2.0 (2010/01/01)
156                    inEncode        = arg.getProparty("inEncode",System.getProperty("file.encoding"));
157                    outEncode       = arg.getProparty("outEncode",System.getProperty("file.encoding"));
158                    display         = arg.getProparty("display",display);
159                    debug           = arg.getProparty("debug",debug);                               // 5.7.3.0 (2014/02/07) ãƒ?ƒãƒ?‚°æƒ??
160    //              if( debug ) { println( arg.toString() ); }                                      // 5.7.3.0 (2014/02/07) ãƒ?ƒãƒ?‚°æƒ??
161    
162                    FileString fs = new FileString();
163                    fs.setFilename( keywordFile );
164                    fs.setEncode( outEncode );
165    //              String[] lines = fs.getValue( "\n" );
166                    String[] lines = fs.getValue( CR );                                     // 5.7.3.2 (2014/02/28) \n ã§ãªãã?CR ã¨ã—ã¾ã™ã?
167                    int len = lines.length;
168                    if( len == 0 ) {
169                            String errMsg = "keywordFile ã®å†?®¹ã?読ã¿å–れã¾ã›ã‚“ã§ã—ãŸã€?" + keywordFile + "]" ;
170                            throw new RuntimeException( errMsg );
171                    }
172    
173                    println( "keywordFile ã‚’ã?" + len + "件読ã¿å–りã¾ã—ãŸã€? );
174                    List<String> keyList = new ArrayList<String>( len );
175                    List<String> cngList = new ArrayList<String>( len );
176    
177                    for( int i=0; i<len; i++ ) {
178            //              String line = lines[i].trim();
179                            String line = lines[i];
180                            int indx = line.indexOf( '\t' );
181                            if( indx <= 0 ) { continue ; }       // TAB ãŒå?é ­ã‚??存在ã—ãªã?¡Œã?読ã¿é£›ã?ã™ã?
182                            // 5.7.3.2 (2014/02/28) debug ã®è¡¨ç¤ºã¨ã€?½·?°?œï½°??¾žã? \t ã®ä½¿ç”¨ã€trim() å»?­¢
183    //                      keyList.add( line.substring( 0,indx ).trim() );
184    //                      String cng = line.substring( indx+1 ).trim();
185                            String key = line.substring( 0,indx );
186                            String cng = line.substring( indx+1 );
187    
188                            if( ignoreCase ) { key = key.toUpperCase(Locale.JAPAN); }       // 5.7.3.2 (2014/02/28) ignoreCase ã®å®Ÿè£?¼ã‚Œ
189    
190                            if( debug ) { println( "[" + key + "]⇒[" + cng + "]" ); }
191    
192    //                      key = StringUtil.replace( key,"\\n",CR );               // 5.7.3.2 (2014/02/28) ?·?°?œï½°??¾žã« \n ã¯ä½¿ãˆãªã??
193                            key = StringUtil.replace( key,"\\t","\t" );
194    
195    //                      cng = StringUtil.replace( cng,"\\n",CR );               // 5.7.3.2 (2014/02/28) ?·?°?œï½°??¾žã« \n ã¯ä½¿ãˆãªã??
196                            cng = StringUtil.replace( cng,"\\t","\t" );
197    
198                            keyList.add( key );
199                            cngList.add( cng );
200                    }
201                    keyword = keyList.toArray( new String[keyList.size()] );
202                    change  = cngList.toArray( new String[cngList.size()] );
203    
204                    // 5.7.3.2 (2014/02/28) regex=true ã®å ´åˆã?処ç?
205                    if( regex ) {
206                            pattern = new Pattern[keyword.length];
207                            for( int i=0; i<keyword.length; i++ ) {
208                                    pattern[i] = (ignoreCase) ? Pattern.compile( keyword[i],Pattern.CASE_INSENSITIVE )
209                                                                                      : Pattern.compile( keyword[i] ) ;
210                            }
211                    }
212            }
213    
214            /**
215             * プロセスã®çµ‚äº?‚’行ã„ã¾ã™ã?æœ?¾Œã«ä¸?º¦ã?‘ã€å‘¼ã³å‡ºã•れã¾ã™ã?
216             * 終äº??ç?ファイルクローズã€?¼¤?¢ã‚¯ãƒ­ãƒ¼ã‚ºç­?ã«ä½¿ç”¨ã—ã¾ã™ã?
217             *
218             * @param   isOK トã?タルã§ã€OKã?£ãŸã‹ã©ã?‹[true:æˆåŠŸ/false:失敗]
219             */
220            public void end( final boolean isOK ) {
221                    // ã“ã“ã§ã¯å‡¦ç?‚’行ã„ã¾ã›ã‚“ã€?
222            }
223    
224            /**
225             * 引数㮠LineModel ã‚’å?ç?™ã‚‹ãƒ¡ã‚½ãƒ?ƒ‰ã§ã™ã?
226             * 変æ›å‡¦ç?¾Œã? LineModel ã‚’è¿”ã—ã¾ã™ã?
227             * 後続å?ç?‚’行ã‚ãªã??å?ãƒ??ã‚¿ã®ãƒ•ィルタリングを行ã†å ´å?ã¯ã€?
228             * null ãƒ??ã‚¿ã‚’è¿”ã—ã¾ã™ã?ã¤ã¾ã‚Šã?null ãƒ??ã‚¿ã¯ã€å¾Œç¶šå?ç?‚’行ã‚ãªã?
229             * フラグã®ä»£ã‚りã«ã‚‚使用ã—ã¦ã?¾ã™ã?
230             * ãªãŠã?変æ›å‡¦ç?¾Œã? LineModel ã¨ã€ã‚ªãƒªã‚¸ãƒŠãƒ«ã® LineModel ãŒã?
231             * åŒä¸?‹ã€ã‚³ãƒ”ã?(クローン)ã‹ã?ã€å„処ç?ƒ¡ã‚½ãƒ?ƒ‰å†?§æ±ºã‚ã¦ã?¾ã™ã?
232             * ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«æ˜Žè¨˜ã•れã¦ã?ªã??åˆã?ã€å‰¯ä½œç”¨ãŒå•題ã«ãªã‚‹å?åˆã?ã€?
233             * å??ç?”ã¨ã«è‡ªåˆ?§ã‚³ãƒ”ã?(クローン)ã—ã¦ä¸‹ã•ã??
234             *
235             * @og.rev 4.0.0.0 (2007/11/28) メソãƒ?ƒ‰ã®æˆ»ã‚Šå?ã‚’ãƒã‚§ãƒ?‚¯ã—ã¾ã™ã?
236             * @og.rev 5.1.2.0 (2010/01/01) ç½®æ›ã™ã‚‹ã‹ã©ã?‹ã‚’指定å¯èƒ½ã«ã™ã‚‹(isChange)属æ?追åŠ?
237             * @og.rev 5.7.2.2 (2014/01/24) エラー時ã«ãƒ??ã‚¿ã‚‚å?力ã—ã¾ã™ã?
238             * @og.rev 5.7.3.2 (2014/02/28) debug ã®è¡¨ç¤ºã¨ã€ignoreCase ã®å®Ÿè£?
239             *
240             * @param       data    オリジナルã®LineModel
241             *
242             * @return      処ç?¤‰æ›å¾Œã?LineModel
243             */
244            public LineModel action( final LineModel data ) {
245                    inCount++ ;
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    
256                    File org = fileData.getFile() ;
257                    String orgName = org.getPath();
258                    if( ! org.isFile() ) { return data; }
259    
260                    if( debug ) { println( "File:" + org ); }               // 5.1.2.0 (2010/01/01) display ã®æ¡ä»¶å¤‰æ›´
261    
262                    BufferedReader reader = FileUtil.getBufferedReader( org,inEncode );
263    //              File            tempFile  = new File( org.getPath() + "_temp" );
264    //              PrintWriter     tempWrt   = FileUtil.getPrintWriter( tempFile,outEncode );
265                    File            tempFile  = null;
266                    PrintWriter     tempWrt   = null;
267    
268                    // 5.1.2.0 (2010/01/01) ç½®æ›ã™ã‚‹å?åˆã?å‰å?ç?
269                    if( isChange ) {
270                            tempFile  = new File( orgName + "_temp" );
271                            tempWrt   = FileUtil.getPrintWriter( tempFile,outEncode );
272                    }
273    
274                    boolean nextFlag  = false;
275    
276                    try {
277                            String line ;
278                            int    lineNo = 0;
279                            while((line = reader.readLine()) != null) {
280                                    lineNo++ ;
281                                    // 5.7.3.2 (2014/02/28) regex 対�
282                                    if( regex ) {
283                                            for( int i=0; i<pattern.length; i++ ) {
284                                                    Matcher mt = pattern[i].matcher( line );
285                                                    nextFlag = mt.matches();
286                                                    if( nextFlag ) {
287                                                            findCount++ ;
288                                                            if( display ) { println( orgName + ":" + lineNo + ":" + keyword[i] + ":" + line ); }
289                                                            if( isChange ) {
290                                                                    line = mt.replaceAll( change[i] );
291                                                                    cngCount++ ;
292                                                            }
293                                                    }
294                                            }
295                                    }
296                                    else {
297                                            StringBuilder buf = new StringBuilder( line );
298            //                              boolean foundFlag = false;              // 行å˜ä½ã«åˆæœŸåŒ–ã™ã‚‹ã?
299                                            for( int i=0; i<keyword.length; i++ ) {
300                                                    // 5.7.3.2 (2014/02/28) ignoreCase 対応ã?
301            //                                      int indx = buf.indexOf( keyword[i] );
302                                                    int indx = (ignoreCase) ? buf.toString().toUpperCase(Locale.JAPAN).indexOf( keyword[i] )
303                                                                                                    : buf.indexOf( keyword[i] ) ;
304    
305                                                    // ç½®æ›å¯¾è±¡ç™ºè¦‹ã?行å?力用ã«è¦‹ã¤ã‹ã‚Œã°ã€true ã«ã™ã‚‹ã€?
306                                                    if( indx >= 0 ) {
307            //                                              foundFlag = true;
308                                                            nextFlag  = true;               // ?‘度ã§ã‚‚見ã¤ã‹ã‚Œã°ã€true ã«ã‚»ãƒ?ƒˆ
309                                                            if( display ) { println( orgName + ":" + lineNo + ":" + keyword[i] + ":" + line ); }
310                                                            findCount++ ;
311                                                    }
312                                                    // ç½®æ›å¯¾è±¡ãŒè¦‹ã¤ã‹ã£ã¦ã‚‚ã?isChange=true ã§ãªã‘れã°ã€ç½®æ›å?ç??行ã‚ãªã??
313                                                    if( isChange ) {
314                                                            while( indx >= 0 ) {
315                                                                    buf.replace( indx,indx+keyword[i].length(),change[i] );
316                                                                    // 5.7.3.2 (2014/02/28) ignoreCase 対応ã?
317            //                                                      indx = buf.indexOf( keyword[i],indx+change[i].length() );
318                                                                    int nxt = indx+change[i].length();
319                                                                    indx = (ignoreCase) ? buf.toString().toUpperCase(Locale.JAPAN).indexOf( keyword[i],nxt )
320                                                                                                            : buf.indexOf( keyword[i],nxt );
321    
322                    //                                              nextFlag = true;                        // キーワードãŒå­˜åœ¨ã—ãŸãƒ•ァイルã€?
323                                                                    cngCount++ ;
324    //                                                              findCount++ ;
325                                                            }
326                                                    }
327                                            }
328                                            line = buf.toString();
329                                    }
330                                    // 5.1.2.0 (2010/01/01) ç½®æ›ã™ã‚‹å?åˆã?処ç?
331                                    if( isChange ) {
332    //                                      tempWrt.println( buf.toString() );
333                                            tempWrt.println( line );                                // 5.7.3.2 (2014/02/28) regexã§å‡ºåŠ›ã‚’å…±æœ‰ã™ã‚‹ç‚ºã€?
334                                    }
335                            }
336                    }
337                    catch ( IOException ex ) {
338                            String errMsg = "処ç?¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€?" + data.getRowNo() + "]ä»¶ç›®" + CR
339    //                                              + data.toString() ;
340                                                    +       "data=[" + data.dataLine() + "]" + CR ;         // 5.7.2.2 (2014/01/24) エラー時ã«ãƒ??ã‚¿ã‚‚å?力ã—ã¾ã™ã?
341                            throw new RuntimeException( errMsg,ex );
342                    }
343                    finally {
344                            Closer.ioClose( reader );
345                            Closer.ioClose( tempWrt );
346                    }
347    
348                    // 5.1.2.0 (2010/01/01) ç½®æ›ã™ã‚‹å?åˆã?処ç?
349                    if( isChange ) {
350                            if( nextFlag ) {
351                                    if( !org.delete() ) {
352                                            String errMsg = "æ‰?®šã?ファイルを削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€?" + org + "]" + CR
353                                                            +       "data=[" + data.dataLine() + "]" + CR ;         // 5.7.2.2 (2014/01/24) エラー時ã«ãƒ??ã‚¿ã‚‚å?力ã—ã¾ã™ã?
354                                            throw new RuntimeException( errMsg );
355                                    }
356                                    if( !tempFile.renameTo( org ) ) {
357                                            String errMsg = "æ‰?®šã?ファイルをリãƒã?ãƒ?§ãã¾ã›ã‚“ã§ã—ãŸã€?" + tempFile + "]" + CR
358                                                            +       "data=[" + data.dataLine() + "]" + CR ;         // 5.7.2.2 (2014/01/24) エラー時ã«ãƒ??ã‚¿ã‚‚å?力ã—ã¾ã™ã?
359                                            throw new RuntimeException( errMsg );
360                                    }
361                            }
362                            else {
363                                    if( !tempFile.delete() ) {
364                                            String errMsg = "æ‰?®šã?ファイルを削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€?" + tempFile + "]" + CR
365                                                            +       "data=[" + data.dataLine() + "]" + CR ;         // 5.7.2.2 (2014/01/24) エラー時ã«ãƒ??ã‚¿ã‚‚å?力ã—ã¾ã™ã?
366                                            throw new RuntimeException( errMsg );
367                                    }
368                            }
369                    }
370    
371                    return (nextFlag) ? data : null ;
372            }
373    
374            /**
375             * プロセスã®å‡¦ç?µæžœã®ãƒ¬ãƒã?ト表ç¾ã‚’è¿”ã—ã¾ã™ã?
376             * 処ç??ログラãƒ?ã€å?力件数ã€å?力件数ãªã©ã®æƒ??ã§ã™ã?
377             * ã“ã?æ–?­—å?ã‚’ãã®ã¾ã¾ã€æ¨™æº–å?力ã«å‡ºã™ã“ã¨ã§ã€çµæžœãƒ¬ãƒã?トã¨å‡ºæ¥ã‚‹ã‚ˆã?ª
378             * å½¢å¼ã§å‡ºã—ã¦ãã ã•ã„ã€?
379             *
380             * @return   処ç?µæžœã®ãƒ¬ãƒã?ãƒ?
381             */
382            public String report() {
383                    String report = "[" + getClass().getName() + "]" + CR
384                                    + TAB + "Search File Count : " + inCount    + CR
385                                    + TAB + "Key Find    Count : " + findCount  + CR
386                                    + TAB + "Key Change  Count : " + cngCount ;
387    
388                    return report ;
389            }
390    
391            /**
392             * ã“ã?クラスã®ä½¿ç”¨æ–¹æ³•ã‚’è¿”ã—ã¾ã™ã?
393             *
394             * @return      ã“ã?クラスã®ä½¿ç”¨æ–¹æ³?
395             */
396            public String usage() {
397                    StringBuilder buf = new StringBuilder();
398    
399                    buf.append( "Process_GrepChange ã¯ã€ä¸Šæµã‹ã‚‰å—ã‘å–ã£ã?FileLineModelã‹ã‚‰ã€èªžå¥ã‚?                      ).append( CR );
400                    buf.append( "ç½®æ›ã™ã‚‹ã?ChainProcess インターフェースã®å®Ÿè£?‚¯ãƒ©ã‚¹ã§ã™ã?"                                              ).append( CR );
401                    buf.append( "Process_Grep ã¨ã®é•ã„ã¯ã€ãƒã‚§ãƒ?‚¯ã™ã‚‹ãƒ•ァイルã®ã‚³ãƒ”ã?ã‚?キーワードãŒå­˜åœ¨"           ).append( CR );
402                    buf.append( "ã—ãªãã¨ã‚?作æ?ã™ã‚‹ã“ã¨ã¨ã€æ¤œç´¢ã‚­ãƒ¼ã«æ­£è¦è¡¨ç¾ãŒä½¿ãˆãªã??è¤?•°è¡Œç½®ãæ›ãˆãŒ"            ).append( CR );
403                    buf.append( "出æ¥ãªã?“ã¨ã§ã™ã?"                                                                                                                  ).append( CR );
404                    buf.append( CR );
405                    buf.append( "keywordFile よりã€ç½®æ›ã™ã‚‹èªžå¥ã‚’å«ã‚?‚­ãƒ¼ã¨å€¤ã®ãƒšã‚¢ãƒ¼(タブ区åˆ?‚Š)を読å–りã€?  ).append( CR );
406                    buf.append( "対象ã¨ã™ã‚‹èªžå¥ã‚’ç½®æ›ã—ã¾ã™ã?"                                                                                                  ).append( CR );
407                    buf.append( "keywordFile ã«ã€ã‚¿ãƒ–ãŒå«ã¾ã‚Œãªã?¡Œã‚„ã€å?é ­ã«ã‚¿ãƒ–ãŒå­˜åœ¨ã—ã¦ã?‚‹å ´åˆã?ã€?               ).append( CR );
408                    buf.append( "ãã?行を読ã¿é£›ã?ã—ã¾ã™ã?ã¾ãŸã?区åˆ?‚Šã‚¿ãƒ–ã?何å?存在ã—ã¦ã‚‚æ§‹ã„ã¾ã›ã‚“ã€?                    ).append( CR );
409                    buf.append( "ãŸã ã—ã?タブã§åŒºåˆ?£ãŸå‰(キー)ã¨å¾Œã‚(値)ã¯ã€trim() ã•れã¾ã™ã?ã§ã€ã‚¹ãƒšã?ス"            ).append( CR );
410                    buf.append( "ãŒå‰å¾Œã«å­˜åœ¨ã—ã¦ã?‚‹å ´åˆã?ã€ã”注æ„ãã?•ã??"                                                                        ).append( CR );
411                    buf.append( "ç½®æ›æ–‡å­?値)ã¯ã€\t 㨠\n ã®ç‰¹æ®Šæ–‡å­—ãŒä½¿ç”¨ã§ãã¾ã™ã?"                                                      ).append( CR );
412                    buf.append( "ã“ã? GrepChange ã§ã¯ã€èªžå¥ã«ã€æ­£è¦è¡¨ç¾ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。正è¦è¡¨ç¾ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ?   ).append( CR );
413                    buf.append( "ã‚?–‡å­—å?ã‚’è¤?•°è¡Œã?æ–?­—å?ã¨ç½®ãæ›ãˆã‚‹å ´åˆã?ã€Process_Grep を使用ã—ã¦ä¸‹ã•ã??"   ).append( CR );
414                    buf.append( "ã“ã?プログラãƒ?§ã¯ã€ä¸Šæµã‹ã‚‰å—ã‘å–ã£ã?FileLineModel ã®ãƒ•ァイルã«å¯¾ã—ã¦ã€?           ).append( CR );
415                    buf.append( "ç½®ãæ›ãˆãŸçµæžœã‚‚ã?åŒã˜ãƒ•ァイルã«ã‚»ãƒ¼ãƒ–ã—ã¾ã™ã?"                                                            ).append( CR );
416                    buf.append( "å…??ファイルをä¿å­˜ã—ãŸã„å ´åˆã?ã€äºˆã‚ãƒãƒƒã‚¯ã‚¢ãƒ??ã‚’å–å¾—ã—ã¦ãŠã„ã¦ãã ã•ã„ã€?      ).append( CR );
417                    buf.append( "-inEncode ã¯ã€å?力ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰æŒ‡å®šã«ãªã‚Šã¾ã™ã?"                                          ).append( CR );
418                    buf.append( "-outEncode ã¯ã€å?力ファイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã‚„ã€ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãƒ•ァイルã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ?       ).append( CR );
419                    buf.append( "æŒ?®šã«ãªã‚Šã¾ã™ã?(keywordFile ã¯ã€å¿?š 出力ファイルã¨åŒã˜ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã§ã™ã?)"         ).append( CR );
420                    buf.append( "ã“れらã?エンコードãŒç„¡æŒ?®šã?å ´åˆã?ã€System.getProperty(\"file.encoding\") "      ).append( CR );
421                    buf.append( "ã§æ±‚ã¾ã‚‹å?を使用ã—ã¾ã™ã?"                                                                                                              ).append( CR );
422                    buf.append( CR );
423                    buf.append( "上æµã?ロセスã§ã¯ã€Name 属æ?ã¨ã—ã¦ã€ã?Fileã€ã‚’æŒã¡ã€å?ã¯ã€Fileオブジェクãƒ?            ).append( CR );
424                    buf.append( "ã§ã‚ã‚‹ã€Process_FileSearch を使用ã™ã‚‹ã®ãŒã?便利ã§ã™ã?ãれ以外ã?クラスã‚?           ).append( CR );
425                    buf.append( "使用ã™ã‚‹å ´åˆã§ã‚‚ã?Name属æ?ã¨ã€File オブジェクトをæŒã¤ LineModel ã‚’å—ã‘æ¸¡ã?  ).append( CR );
426                    buf.append( "ã§ãれã°ã€ä½¿ç”¨å¯èƒ½ã§ã™ã?"                                                                                                            ).append( CR );
427                    buf.append( CR );
428                    buf.append( "引数æ–?­—å?中ã«ç©ºç™½ã‚’å«ã‚??åˆã?ã€ãƒ€ãƒ–ルコーãƒ??ション(\"\") ã§æ‹¬ã£ã¦ä¸‹ã•ã??" ).append( CR );
429                    buf.append( "引数æ–?­—å?ã® ã€?ã€ã?å‰å¾Œã«ã¯ã€ç©ºç™½ã¯æŒŸã‚ã¾ã›ã‚“。å¿?šã€?key=value ã®æ§˜ã«"             ).append( CR );
430                    buf.append( "繋ã’ã¦ãã ã•ã„ã€?                                                                                                                              ).append( CR );
431                    buf.append( CR ).append( CR );
432    
433                    buf.append( getArgument().usage() ).append( CR );
434    
435                    return buf.toString();
436            }
437    
438            /**
439             * ã“ã?クラスã¯ã€main メソãƒ?ƒ‰ã‹ã‚‰å®Ÿè¡Œã§ãã¾ã›ã‚“ã€?
440             *
441             * @param       args    コマンド引数é…å?
442             */
443            public static void main( final String[] args ) {
444                    LogWriter.log( new Process_GrepChange().usage() );
445            }
446    }