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 */ 016package org.opengion.fukurou.process; 017 018import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 019import org.opengion.fukurou.security.HybsCryptography; 020import org.opengion.fukurou.util.Argument; 021import org.opengion.fukurou.util.StringUtil; 022import org.opengion.fukurou.system.LogWriter; 023 024import java.util.Map ; 025import java.util.LinkedHashMap ; 026 027/** 028 * Process_StringUtil は、上流から受け取ったデータをStringUtilクラスの特定の 029 * メソッドでデータ変換する、CainProcess インターフェースの実装クラスです。 030 * 031 * 上流(プロセスチェインのデータは上流から下流へと渡されます。)から 032 * LineModel を元に、指定のカラムの文字を、変換します。 033 * 034 * 現時点で利用できるStringUtil のメソッドは、下記の通りです。 035 * urlEncode : UTF-8 で、URLエンコードを行う。 036 * rTrim : 文字列の後ろのスペースを削除 037 * htmlFilter : HTML上のエスケープ文字を変換 038 * code39 : CODE39 の 文字列を作成(チェックデジット付き) 039 * getUnicodeEscape : HTML のエスケープ記号(&#xZZZZ;)に変換 040 * getReplaceEscape : HTML のエスケープ記号(&#xZZZZ;)を戻す 041 * spanCut : 引数からspanタグを取り除く 042 * 043 * HybsCryptography のメソッドも呼び出せます。 044 * getMD5 : MessageDigestにより、MD5 でハッシュした文字に変換 045 * encrypt : Hybs独自の暗号化を行います(Hybs内部設定の秘密鍵) 046 * decrypt : Hybs独自の復号化を行います(Hybs内部設定の秘密鍵) 047 * 048 * 引数文字列中にスペースを含む場合は、ダブルコーテーション("") で括って下さい。 049 * 引数文字列の 『=』の前後には、スペースは挟めません。必ず、-key=value の様に 050 * 繋げてください。 051 * 052 * @og.formSample 053 * Process_StringUtil -action=getMD5|encrypt|decrypt|code39|getUnicodeEscape|getReplaceEscape|・・・ -keys=AA,BB,CC 054 * 055 * -action=ESC|REV :StringUtilクラスの特定のメソッド名を指定します(必須)。 056 * urlEncode|rTrim|htmlFilter|getMD5|code39|getUnicodeEscape|getReplaceEscape|spanCut 057 * -keys=AA,BB,CC :変換するカラムをCSV形式で複数指定できます(必須)。 058 * [ -display=[false/true]] :結果を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 059 * [ -debug=[false/true] ] :デバッグ情報を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 060 * 061 * @og.rev 5.0.0.2 (2009/09/15) 新規クラス作成 062 * 063 * @version 0.9.0 2004/02/27 064 * @author Kazuhiko Hasegawa 065 * @since JDK5.0, 066 */ 067public class Process_StringUtil extends AbstractProcess implements ChainProcess { 068 069 private static final String STR_ACTION_BASE = "org.opengion.fukurou.process.Process_StringUtil$SU_" ; 070 071 private String keys ; // 変換するカラム名配列のアドレス 072 private int[] clmNos ; // 変換するカラム名配列のアドレス 073 private boolean display ; // 表示しない 074 private boolean debug ; // 5.7.3.0 (2014/02/07) デバッグ情報 075 076 private boolean firstRow = true; // 最初の一行目 077 private int count ; 078 private StrAction stAction ; // Ver 5.0.0.2 (2009/09/15) 079 080 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 081 private static final Map<String,String> MUST_PROPARTY ; // [プロパティ]必須チェック用 Map 082 /** staticイニシャライザ後、読み取り専用にするので、ConcurrentHashMap を使用しません。 */ 083 private static final Map<String,String> USABLE_PROPARTY ; // [プロパティ]整合性チェック Map 084 085 static { 086 MUST_PROPARTY = new LinkedHashMap<>(); 087 MUST_PROPARTY.put( "action", "StringUtilの特定のメソッドを指定します(必須)" + 088 CR + "urlEncode , rTrim , htmlFilter , getMD5 , encrypt , decrypt , code39 , getUnicodeEscape , getReplaceEscape , spanCut" ); 089 090 MUST_PROPARTY.put( "keys", "変換するカラムをCSV形式で複数指定できます(必須)。" ); 091 092 USABLE_PROPARTY = new LinkedHashMap<>(); 093 USABLE_PROPARTY.put( "display", "結果を標準出力に表示する(true)かしない(false)か" + 094 CR + " (初期値:false[表示しない])" ); 095 USABLE_PROPARTY.put( "debug", "デバッグ情報を標準出力に表示する(true)かしない(false)か" + 096 CR + "(初期値:false:表示しない)" ); // 5.7.3.0 (2014/02/07) デバッグ情報 097 } 098 099 /** 100 * デフォルトコンストラクター。 101 * このクラスは、動的作成されます。デフォルトコンストラクターで、 102 * super クラスに対して、必要な初期化を行っておきます。 103 * 104 */ 105 public Process_StringUtil() { 106 super( "org.opengion.fukurou.process.Process_StringUtil",MUST_PROPARTY,USABLE_PROPARTY ); 107 } 108 109 /** 110 * プロセスの初期化を行います。初めに一度だけ、呼び出されます。 111 * 初期処理(ファイルオープン、DBオープン等)に使用します。 112 * 113 * @param paramProcess データベースの接続先情報などを持っているオブジェクト 114 */ 115 public void init( final ParamProcess paramProcess ) { 116 final Argument arg = getArgument(); 117 118 keys = arg.getProparty( "keys",keys ); 119 display = arg.getProparty( "display",display ); 120 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) デバッグ情報 121 122 final String act = arg.getProparty( "action" ); 123 124 stAction = (StrAction)StringUtil.newInstance( STR_ACTION_BASE + act ); 125 } 126 127 /** 128 * 引数の LineModel を処理するメソッドです。 129 * 変換処理後の LineModel を返します。 130 * 後続処理を行わない場合(データのフィルタリングを行う場合)は、 131 * null データを返します。つまり、null データは、後続処理を行わない 132 * フラグの代わりにも使用しています。 133 * なお、変換処理後の LineModel と、オリジナルの LineModel が、 134 * 同一か、コピー(クローン)かは、各処理メソッド内で決めています。 135 * ドキュメントに明記されていない場合は、副作用が問題になる場合は、 136 * 各処理ごとに自分でコピー(クローン)して下さい。 137 * 138 * @param data オリジナルのLineModel 139 * 140 * @return 処理変換後のLineModel 141 */ 142 public LineModel action( final LineModel data ) { 143 count++ ; 144 try { 145 if( firstRow ) { 146 makeColumnNos( data ); 147 firstRow = false; 148 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 149 } 150 151 if( debug ) { println( "Before:" + data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 152 for( int i=0; i<clmNos.length; i++ ) { 153 final String val = (String)data.getValue( clmNos[i] ) ; 154 data.setValue( clmNos[i],stAction.change( val ) ); 155 } 156 157 if( debug ) { println( "After :" + data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 158 else if( display ) { println( data.dataLine() ); } // 5.1.2.0 (2010/01/01) display の条件変更 159 } 160 catch( final Throwable ex ) { 161 final String errMsg = "row=[" + count + "]" + CR + 162 " data=[" + data + "]" + CR ; 163 throw new OgRuntimeException( errMsg,ex ); 164 } 165 return data; 166 } 167 168 /** 169 * プロセスの終了を行います。最後に一度だけ、呼び出されます。 170 * 終了処理(ファイルクローズ、DBクローズ等)に使用します。 171 * 172 * @param isOK トータルで、OKだったかどうか[true:成功/false:失敗] 173 */ 174 public void end( final boolean isOK ) { 175 keys = null; // 変換するカラム名配列のアドレス 176 clmNos = null; // 変換するカラム名配列のアドレス 177 } 178 179 /** 180 * プロセスの処理結果のレポート表現を返します。 181 * 処理プログラム名、入力件数、出力件数などの情報です。 182 * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような 183 * 形式で出してください。 184 * 185 * @return 処理結果のレポート 186 */ 187 public String report() { 188 // 7.2.9.5 (2020/11/28) PMD:Consider simply returning the value vs storing it in local variable 'XXXX' 189 return "[" + getClass().getName() + "]" + CR 190// final String report = "[" + getClass().getName() + "]" + CR 191 + TAB + "Output Count : " + count ; 192 193// return report ; 194 } 195 196 /** 197 * カラム番号配列を取得します。 198 * 繰返し処理を行う場合に、事前にアドレスでアクセスできるように処理するカラム番号を 199 * キャッシュしておきます。 200 * 201 * @param data LineModelオブジェクト 202 */ 203 private void makeColumnNos( final LineModel data ) { 204 final String[] clms = StringUtil.csv2Array( keys ); 205 final int size = clms.length; 206 clmNos = new int[size]; 207 for( int i=0; i<size; i++ ) { 208 clmNos[i] = data.getColumnNo( clms[i] ); 209 } 210 } 211 212 /** 213 * このクラスの使用方法を返します。 214 * 215 * @return このクラスの使用方法 216 * @og.rtnNotNull 217 */ 218 public String usage() { 219 final StringBuilder buf = new StringBuilder( BUFFER_LARGE ) 220 .append( "Process_StringUtil は、上流から受け取ったデータをStringUtilクラスの特定の" ).append( CR ) 221 .append( "メソッドでデータ変換する、CainProcess インターフェースの実装クラスです。" ).append( CR ) 222 .append( CR ) 223 .append( "上流(プロセスチェインのデータは上流から下流へと渡されます。)から" ).append( CR ) 224 .append( " LineModel を元に、指定のカラムの文字を、変換します。" ).append( CR ) 225 .append( CR ) 226 .append( "現時点で利用できるStringUtil のメソッドは、下記の通りです。" ).append( CR ) 227 .append( " urlEncode : UTF-8 で、URLエンコードを行う。" ).append( CR ) 228 .append( " rTrim : 文字列の後ろのスペースを削除" ).append( CR ) 229 .append( " htmlFilter : HTML上のエスケープ文字を変換" ).append( CR ) 230 .append( " code39 : CODE39 の 文字列を作成(チェックデジット付き)" ).append( CR ) 231 .append( " getUnicodeEscape : HTML のエスケープ記号(&#xZZZZ;)に変換" ).append( CR ) 232 .append( " getReplaceEscape : HTML のエスケープ記号(&#xZZZZ;)を戻す" ).append( CR ) 233 .append( " spanCut : 引数からspanタグを取り除く" ).append( CR ) 234 .append( CR ) 235 .append( "HybsCryptography のメソッドも呼び出せます。" ).append( CR ) 236 .append( " getMD5 : MessageDigestにより、MD5 でハッシュした文字に変換" ).append( CR ) 237 .append( " encrypt : Hybs独自の暗号化を行います(Hybs内部設定の秘密鍵)" ).append( CR ) 238 .append( " decrypt : Hybs独自の復号化を行います(Hybs内部設定の秘密鍵)" ).append( CR ) 239 .append( CR ) 240 .append( "引数文字列中に空白を含む場合は、ダブルコーテーション(\"\") で括って下さい。" ).append( CR ) 241 .append( "引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に" ).append( CR ) 242 .append( "繋げてください。" ).append( CR ) 243 .append( CR ).append( CR ) 244 .append( getArgument().usage() ).append( CR ); 245 246 return buf.toString(); 247 } 248 249 /** 250 * このクラスは、main メソッドから実行できません。 251 * 252 * @param args コマンド引数配列 253 */ 254 public static void main( final String[] args ) { 255 LogWriter.log( new Process_StringUtil().usage() ); 256 } 257 258 /** 259 * インナークラスとして、共通メソッドを定義します(I/Fの代わり)。 260 * 261 * ※ このクラスは継承されるため、final化しません。 262 */ 263 private static class StrAction { 264 /** 265 * 引数を変換します。 266 * 267 * @param val 引数 268 * @return 変換された文字列 269 */ 270 public String change( final String val ) { 271 return val; 272 } 273 } 274 275 /** 276 * UTF-8 で、URLエンコードを行います。 277 */ 278 private static final class SU_urlEncode extends StrAction { 279 /** 280 * 引数を変換します。 281 * 282 * @param val 引数 283 * @return 変換された文字列 284 */ 285 @Override 286 public String change( final String val ) { 287 return StringUtil.urlEncode( val ); 288 } 289 } 290 291 /** 292 * 文字列の後ろのスペースを削除します。 293 * 注意:'\u0020' (スペース文字) より小さい文字を切り取ります。 294 */ 295 private static final class SU_rTrim extends StrAction { 296 /** 297 * 引数を変換します。 298 * 299 * @param val 引数 300 * @return 変換された文字列 301 */ 302 @Override 303 public String change( final String val ) { 304 return StringUtil.rTrim( val ); 305 } 306 } 307 308 /** 309 * HTML上のエスケープ文字を変換します。 310 */ 311 private static final class SU_htmlFilter extends StrAction { 312 /** 313 * 引数を変換します。 314 * 315 * @param val 引数 316 * @return 変換された文字列 317 */ 318 @Override 319 public String change( final String val ) { 320 return StringUtil.htmlFilter( val ); 321 } 322 } 323 324 /** 325 * CODE39 の 文字列を作成します。(チェックデジット付き) 326 */ 327 private static final class SU_code39 extends StrAction { 328 /** 329 * 引数を変換します。 330 * 331 * @param val 引数 332 * @return 変換された文字列 333 */ 334 @Override 335 public String change( final String val ) { 336 return StringUtil.code39( val,true ); 337 } 338 } 339 340 /** 341 * Unicode文字列の値を HTML のエスケープ記号(&#xZZZZ;)に変換します。 342 */ 343 private static final class SU_getUnicodeEscape extends StrAction { 344 /** 345 * 引数を変換します。 346 * 347 * @param val 引数 348 * @return 変換された文字列 349 */ 350 @Override 351 public String change( final String val ) { 352 return StringUtil.getUnicodeEscape( val ); 353 } 354 } 355 356 /** 357 * HTML のエスケープ記号(&#xZZZZ;)をUnicode文字列に戻します。 358 */ 359 private static final class SU_getReplaceEscape extends StrAction { 360 /** 361 * 引数を変換します。 362 * 363 * @param val 引数 364 * @return 変換された文字列 365 */ 366 @Override 367 public String change( final String val ) { 368 return StringUtil.getReplaceEscape( val ); 369 } 370 } 371 372 /** 373 * 引数からspanタグを取り除いて返します。 374 */ 375 private static final class SU_spanCut extends StrAction { 376 /** 377 * 引数を変換します。 378 * 379 * @param val 引数 380 * @return 変換された文字列 381 */ 382 @Override 383 public String change( final String val ) { 384 return StringUtil.spanCut( val ); 385 } 386 } 387 388 /** 389 * MessageDigestにより、MD5 でハッシュした文字に変換します。 390 * 391 * @og.rev 5.2.2.0 (2010/11/01) util.StringUtil から security.HybsCryptography へ移動 392 * 393 */ 394 private static final class SU_getMD5 extends StrAction { 395 /** 396 * 引数を変換します。 397 * 398 * @param val 引数 399 * @return 変換された文字列 400 */ 401 @Override 402 public String change( final String val ) { 403 return HybsCryptography.getMD5( val ); 404 } 405 } 406 407 /** 408 * Hybs独自の暗号化を行います(Hybs内部設定の秘密鍵) 409 * 410 * @og.rev 5.2.2.0 (2010/11/01) 新規追加 411 */ 412 private static final class SU_encrypt extends StrAction { 413 private HybsCryptography crpt ; 414 415 /** 416 * 引数を変換します。 417 * 418 * @param val 引数 419 * @return 変換された文字列 420 */ 421 @Override 422 public String change( final String val ) { 423 if( crpt == null ) { 424 crpt = new HybsCryptography(); 425 } 426 return crpt.encrypt( val ); 427 } 428 } 429 430 /** 431 * Hybs独自の復号化を行います(Hybs内部設定の秘密鍵) 432 * 433 * @og.rev 5.2.2.0 (2010/11/01) 新規追加 434 */ 435 private static final class SU_decrypt extends StrAction { 436 private HybsCryptography crpt ; 437 438 /** 439 * 引数を変換します。 440 * 441 * @param val 引数 442 * @return 変換された文字列 443 */ 444 @Override 445 public String change( final String val ) { 446 if( crpt == null ) { 447 crpt = new HybsCryptography(); 448 } 449 return crpt.decrypt( val ); 450 } 451 } 452}