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