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.HybsEntry ; 020 import org.opengion.fukurou.util.LogWriter; 021 import org.opengion.fukurou.util.StringUtil; // 5.7.2.3 (2014/01/31) 022 023 import java.util.Map ; 024 import java.util.LinkedHashMap ; 025 026 /** 027 * Process_TableFilter は、上流から受け取ったデータをフィルタする? 028 * ChainProcess インターフェースの実?ラスです? 029 * 030 * 上?プロセスチェインの??タは上流から下流へと渡されます?)から 031 * 受け取ったLineModel を?に??目のフィルタリングを行います? 032 * 条件が?立した?合?、下流に流します??の条件を指定できますが? 033 * すべて AND で判定されます? 034 * (設定条件すべてを?す?合?み、下流に??タを流します?) 035 * 036 * 引数??中にスペ?スを含??合?、ダブルコー??ション("") で括って下さ?? 037 * 引数??の ?』?前後には、スペ?スは挟めません。??key=value の様に 038 * 繋げてください? 039 * 040 * @og.formSample 041 * Process_TableFilter 042 * 043 * [ -prefix_XXXX=接頭? ] ??目?XXXX)が???接頭辞で始まる?合?条件成立? 044 * [ -suffix_XXXX=接尾? ] ??目?XXXX)が???接尾辞で終わる?合?条件成立? 045 * [ -instr_XXXX=部?字? ] ??目?XXXX)が???部?字?と??する場合?条件成立? 046 * [ -equals_XXXX=?? ] ??目?XXXX)が???と??する場合?条件成立???は、大?小文字?区別しません(equalsIgnoreCase)? 047 * [ -match_XXXX=正規表現 ] ??目?XXXX)が?正規表現と??する場合?条件成立? 048 * [ -unmatch_XXXX=正規表現 ] ??目?XXXX)が?正規表現と??しな??合?条件成立? 049 * [ -const_XXXX=固定? ] ??const_FGJ=1 050 * ??XXXX)に、固定?を設定します? 051 * [ -replace_XXXX=固定? ] ??replace_BIKO="YYYY⇒ZZZZ" (????、で区?ます?) 052 * ??XXXX)の??から、YYYY と??を ZZZZ に置換します? 053 * -replace_FGJ="_:0 A:1 B:2" (??:新値 の??゚ー?区?) 054 * 区??に ?を使用しな??合?、CASE処?行います? 055 * ??XXXX)の値を??? から 新値 に置換します?(完???) 056 * [ -display=[false/true] ] ?結果を標準?力に表示する(true)かしな?false)?初期値:false[表示しない]) 057 * [ -debug=[false/true] ] ?デバッグ??を標準?力に表示する(true)かしな?false)?初期値:false[表示しない]) 058 * 059 * @version 4.0 060 * @author Kazuhiko Hasegawa 061 * @since JDK5.0, 062 */ 063 public class Process_TableFilter extends AbstractProcess implements ChainProcess { 064 /** replace_ で使用する区?記号 {@value} */ 065 public static final char REP_SEP = '? ; // 4.3.1.1 (2008/08/24) 066 067 private static final String PREFIX_KEY = "prefix_" ; 068 private static final String SUFFIX_KEY = "suffix_" ; 069 private static final String INSTR_KEY = "instr_" ; 070 private static final String EQUALS_KEY = "equals_" ; 071 private static final String MATCH_KEY = "match_" ; 072 private static final String UNMATCH_KEY = "unmatch_"; 073 private static final String CONST_KEY = "const_" ; 074 private static final String REPLACE_KEY = "replace_" ; // 4.3.1.1 (2008/08/24) 075 076 private final LineModelFilter filter = new LineModelFilter(); 077 078 private boolean display = false; // 表示しな? 079 private boolean debug = false; // 5.7.3.0 (2014/02/07) ???? 080 081 private String[] cnstClm = null; // 固定?を設定するカラ? 082 private int[] cnstClmNos = null; // 固定?を設定するカラ?号 083 private String[] constVal = null; // カラ?号に対応した固定? 084 085 // 4.3.1.1 (2008/08/24) replace 置換関係に?な??タ 086 private String[] repClm = null; // 置換を設定するカラ? 087 private int[] repClmNos = null; // 置換を設定するカラ?号 088 private String[] repValFrom = null; // カラ?号に対応した置換??? 089 private String[] repValTo = null; // カラ?号に対応した置換後文字? 090 091 // 5.7.2.3 (2014/01/31) replace 置換? case処?係に?な??タ 092 private String[] caseVals = null; // カラ?号に対応した置換後文字? 093 094 private boolean firstRow = true; // ??の?目 095 private int count = 0; 096 097 private static final Map<String,String> mustProparty ; // ?プロパティ???チェ?用 Map 098 private static final Map<String,String> usableProparty ; // ?プロパティ?整合?チェ? Map 099 100 static { 101 mustProparty = new LinkedHashMap<String,String>(); 102 103 usableProparty = new LinkedHashMap<String,String>(); 104 usableProparty.put( PREFIX_KEY , "??XXXX)が???接頭辞で始まる?合?条件成立?" ); 105 usableProparty.put( SUFFIX_KEY , "??XXXX)が???接尾辞で終わる?合?条件成立?" ); 106 usableProparty.put( INSTR_KEY , "??XXXX)が???部?字?と??する場合?条件成立?" ); 107 usableProparty.put( EQUALS_KEY , "??XXXX)が???と??する場合?条件成立?" + 108 CR + "(大?小文字?区別しな?" ); 109 usableProparty.put( MATCH_KEY , "??XXXX)が?正規表現と??する場合?条件成立?" ); 110 usableProparty.put( UNMATCH_KEY , "??XXXX)が?正規表現と??しな??合?条件成立?" ); 111 usableProparty.put( CONST_KEY , "??XXXX)に、固定?を設定します?" ); 112 // 4.3.1.1 (2008/08/24) replace 置換関? 113 usableProparty.put( REPLACE_KEY , "??XXXX)の??から、YYYY⇒ZZZZ で部?換します?" + 114 CR + "??XXXX)の??から、_:0 A:1 B:2でCASE置換します?" ); 115 usableProparty.put( "display" , "結果を標準?力に表示する(true)かしな?false)? + 116 CR + "(初期値:false:表示しな?" ); 117 usableProparty.put( "debug", "????を標準?力に表示する(true)かしな?false)? + 118 CR + "(初期値:false:表示しな?" ); // 5.7.3.0 (2014/02/07) ???? 119 } 120 121 /** 122 * ?ォルトコンストラクター? 123 * こ?クラスは、動??されます??ォルトコンストラクターで? 124 * super クラスに対して、?な初期化を行っておきます? 125 * 126 */ 127 public Process_TableFilter() { 128 super( "org.opengion.fukurou.process.Process_TableFilter",mustProparty,usableProparty ); 129 } 130 131 /** 132 * プロセスの初期化を行います?初めに??、呼び出されます? 133 * 初期処?ファイルオープン??オープン?に使用します? 134 * 135 * @og.rev 4.3.1.1 (2008/08/24) 置換関係対? 136 * @og.rev 5.7.2.3 (2014/01/31) replace 置換? case処?? 137 * 138 * @param paramProcess ??タベ?スの接続???などを持って?オブジェク? 139 */ 140 public void init( final ParamProcess paramProcess ) { 141 Argument arg = getArgument(); 142 143 display = arg.getProparty( "display",display ); 144 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) ???? 145 // if( debug ) { println( arg.toString() ); } // 5.7.3.0 (2014/02/07) ???? 146 147 HybsEntry[] entry = arg.getEntrys( PREFIX_KEY ); 148 for( int i=0; i<entry.length; i++ ) { 149 filter.add( FilterOperation.PREFIX, entry[i].getKey(), entry[i].getValue() ); 150 } 151 152 entry = arg.getEntrys( SUFFIX_KEY ); 153 for( int i=0; i<entry.length; i++ ) { 154 filter.add( FilterOperation.SUFFIX, entry[i].getKey(), entry[i].getValue() ); 155 } 156 157 entry = arg.getEntrys( INSTR_KEY ); 158 for( int i=0; i<entry.length; i++ ) { 159 filter.add( FilterOperation.INSTR, entry[i].getKey(), entry[i].getValue() ); 160 } 161 162 entry = arg.getEntrys( EQUALS_KEY ); 163 for( int i=0; i<entry.length; i++ ) { 164 filter.add( FilterOperation.EQUALS, entry[i].getKey(), entry[i].getValue() ); 165 } 166 167 entry = arg.getEntrys( MATCH_KEY ); 168 for( int i=0; i<entry.length; i++ ) { 169 filter.add( FilterOperation.MATCH, entry[i].getKey(), entry[i].getValue() ); 170 } 171 172 entry = arg.getEntrys( UNMATCH_KEY ); 173 for( int i=0; i<entry.length; i++ ) { 174 filter.add( FilterOperation.UNMATCH, entry[i].getKey(), entry[i].getValue() ); 175 } 176 177 HybsEntry[] cnstKey = arg.getEntrys( CONST_KEY ); 178 int csize = cnstKey.length; 179 cnstClm = new String[csize]; 180 constVal = new String[csize]; 181 for( int i=0; i<csize; i++ ) { 182 cnstClm[i] = cnstKey[i].getKey(); 183 constVal[i] = cnstKey[i].getValue(); 184 } 185 186 // 4.3.1.1 (2008/08/24) replace 置換関? 187 HybsEntry[] repKey = arg.getEntrys( REPLACE_KEY ); 188 int rsize = repKey.length; 189 repClm = new String[rsize]; 190 repValFrom = new String[rsize]; 191 repValTo = new String[rsize]; 192 caseVals = new String[rsize]; // 5.7.2.3 (2014/01/31) replace 置換? case処? 193 for( int i=0; i<rsize; i++ ) { 194 repClm[i] = repKey[i].getKey(); 195 String val = repKey[i].getValue(); // val は、YYYY⇒ZZZZ の形? 196 if( val != null ) { 197 int ad = val.indexOf( REP_SEP ); // REP_SEP は?? 198 if( ad >= 0 ) { 199 repValFrom[i] = val.substring( 0,ad ); 200 repValTo[i] = val.substring( ad+1 ); 201 } 202 else { 203 // 5.7.2.3 (2014/01/31) replace 置換? case処? 204 // repValFrom[i] = val; // 昔?、 が無??合?、引数をクリアする処?った? 205 // repValTo[i] = ""; // 206 caseVals[i] = val; // 5.7.2.3 (2014/01/31) replace 置換? case処? 207 } 208 } 209 } 210 } 211 212 /** 213 * 引数の LineModel を??るメソ?です? 214 * 変換処?? LineModel を返します? 215 * 後続??行わな?????タのフィルタリングを行う場?は? 216 * null ??タを返します?つまり?null ??タは、後続??行わな? 217 * フラグの代わりにも使用して?す? 218 * なお?変換処?? LineModel と、オリジナルの LineModel が? 219 * 同?、コピ?(クローン)か?、各処?ソ??決めて?す? 220 * ドキュメントに明記されて???合?、副作用が問題になる?合?? 221 * ???とに自?コピ?(クローン)して下さ?? 222 * 223 * @og.rev 4.3.1.1 (2008/08/24) 置換関係対? 224 * @og.rev 5.7.2.3 (2014/01/31) replace 置換? case処?? 225 * 226 * @param data オリジナルのLineModel 227 * 228 * @return 処?換後?LineModel 229 */ 230 public LineModel action( final LineModel data ) { 231 count++ ; 232 233 // if( display ) { println( data.dataLine() ); } 234 235 if( !filter.filter( data ) ) { 236 return null; // 不?? 237 } 238 239 if( firstRow ) { 240 int csize = cnstClm.length; 241 cnstClmNos = new int[csize]; 242 for( int i=0; i<csize; i++ ) { 243 cnstClmNos[i] = data.getColumnNo( cnstClm[i] ); 244 } 245 246 // 4.3.1.1 (2008/08/24) 置換関係対? 247 int rsize = repClm.length; 248 repClmNos = new int[rsize]; 249 for( int i=0; i<rsize; i++ ) { 250 repClmNos[i] = data.getColumnNo( repClm[i] ); 251 } 252 253 firstRow = false; 254 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) ???? 255 } 256 257 if( debug ) { println( "Before:" + data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 258 259 for( int i=0; i<cnstClm.length; i++ ) { 260 data.setValue( cnstClmNos[i],constVal[i] ); 261 } 262 263 // 4.3.1.1 (2008/08/24) 置換関係対? 264 for( int i=0; i<repClm.length; i++ ) { 265 // 5.7.2.3 (2014/01/31) Object ?null の時?処?おかしかった?で修正 266 // String val = String.valueOf( data.getValue( repClmNos[i] ) ); 267 // if( val != null ) { 268 String val = ""; 269 Object obj = data.getValue( repClmNos[i] ); 270 if( obj != null ) { val = String.valueOf( obj ); } 271 272 if( caseVals[i] == null ) { // 従来からのリプレース処? 273 val = val.replaceAll( repValFrom[i],repValTo[i] ); 274 } 275 else { 276 // 5.7.2.3 (2014/01/31) replace 置換? case処?? 277 val = StringUtil.caseReplace( val , caseVals[i] , false ); 278 } 279 data.setValue( repClmNos[i],val ); 280 } 281 282 if( debug ) { println( "After :" + data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 283 else if( display ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 284 return data; 285 } 286 287 /** 288 * プロセスの終?行います??に??、呼び出されます? 289 * 終???ファイルクローズ??クローズ?に使用します? 290 * 291 * @og.rev 4.3.1.1 (2008/08/24) 置換関係対? 292 * @og.rev 5.7.2.3 (2014/01/31) replace 置換? case処?? 293 * 294 * @param isOK ト?タルで、OK?たかど?[true:成功/false:失敗] 295 */ 296 public void end( final boolean isOK ) { 297 cnstClm = null; // 固定?を設定するカラ? 298 cnstClmNos = null; // 固定?を設定するカラ?号 299 constVal = null; // カラ?号に対応した固定? 300 301 repClm = null; // 置換を設定するカラ? 302 repClmNos = null; // 置換を設定するカラ?号 303 repValFrom = null; // カラ?号に対応した置換??? 304 repValTo = null; // カラ?号に対応した置換後文字? 305 caseVals = null; // 5.7.2.3 (2014/01/31) replace 置換? case処? 306 } 307 308 /** 309 * プロセスの処?果のレポ?ト表現を返します? 310 * 処??ログラ?、?力件数、?力件数などの??です? 311 * こ???をそのまま、標準?力に出すことで、結果レポ?トと出来るよ? 312 * 形式で出してください? 313 * 314 * @return 処?果のレポ?? 315 */ 316 public String report() { 317 String report = "[" + getClass().getName() + "]" + CR 318 + TAB + "Model Filter : " + filter + CR 319 + TAB + "Output Count : " + count ; 320 321 return report ; 322 } 323 324 /** 325 * こ?クラスの使用方法を返します? 326 * 327 * @return こ?クラスの使用方? 328 */ 329 public String usage() { 330 StringBuilder buf = new StringBuilder(); 331 332 buf.append( "Process_TableFilter は、上流から受け取ったデータをフィルタする? ).append( CR ); 333 buf.append( "ChainProcess インターフェースの実?ラスです?" ).append( CR ); 334 buf.append( CR ); 335 buf.append( "上?プロセスチェインの??タは上流から下流へと渡されます?)から" ).append( CR ); 336 buf.append( "受け取ったLineModel を?に??目のフィルタリングを行います?" ).append( CR ); 337 buf.append( "条件が?立した?合?、下流に流します??の条件を指定できますが? ).append( CR ); 338 buf.append( "すべて AND で判定されます?" ).append( CR ); 339 buf.append( "(設定条件すべてを?す?合?み、下流に??タを流します?)" ).append( CR ); 340 buf.append( CR ); 341 buf.append( "引数??中に空白を含??合?、ダブルコー??ション(\"\") で括って下さ??" ).append( CR ); 342 buf.append( "引数??の ?』?前後には、空白は挟めません。??key=value の様に" ).append( CR ); 343 buf.append( "繋げてください? ).append( CR ); 344 buf.append( CR ).append( CR ); 345 buf.append( getArgument().usage() ).append( CR ); 346 347 return buf.toString(); 348 } 349 350 /** 351 * こ?クラスは、main メソ?から実行できません? 352 * 353 * @param args コマンド引数配? 354 */ 355 public static void main( final String[] args ) { 356 LogWriter.log( new Process_TableFilter().usage() ); 357 } 358 }