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.util.Argument; 019import org.opengion.fukurou.util.StringUtil; 020import org.opengion.fukurou.util.LogWriter; 021 022import java.util.Map ; 023import java.util.LinkedHashMap ; 024 025/** 026 * 【廃止】Process_UnicodeEscape は、上流から受け取ったデータをエスケープ変換する 027 * ChainProcess インターフェースの実装クラスです。 028 * 029 * ※ 5.0.0.2 (2009/09/15) このクラスは、廃止になりました。 030 * 類似機能に、Process_StringUtil を利用してください。 031 * -action 引数に、getUnicodeEscape か、getReplaceEscape を指定することで、 032 * ESCAPE(変換)/REVERSE(戻し) の指定と同一の処理を行います。 033 * 034 * 上流(プロセスチェインのデータは上流から下流へと渡されます。)から受け取った 035 * LineModel を元に、指定のカラムのUTF-8 文字コードと、HTML のエスケープ記号 036 * (&#xZZZZ;)文字との相互変換を行います。 037 * 入力文字を、キャラクタ(char)型に分解し、(&#xZZZZ;)に変換していきます。 038 * よって、通常に1文字(Shift-JISで2Byte,UTF-8で3Byte)が、8Byteになります。 039 * この変換された文字列を、HTML上でそのまま取り出すと、元のUnicode文字に戻る為、 040 * 通常のShift-JISでは、扱えない文字(中国語など)でも表示可能になります。 041 * 042 * 引数文字列中にスペースを含む場合は、ダブルコーテーション("") で括って下さい。 043 * 引数文字列の 『=』の前後には、スペースは挟めません。必ず、-key=value の様に 044 * 繋げてください。 045 * 046 * @og.formSample 047 * Process_UnicodeEscape -action=ESC|REV [-keys=AA,BB,CC] [-all=false|true] 048 * 049 * -action=ESC|REV :ESCAPE(変換)/REVERSE(戻し) を指定します。先頭文字で判定します(必須)。 050 * [ -keys=AA,BB,CC ] :変換するカラムをCSV形式で複数指定できます。 051 * [ -all=[false/true] ] :全カラムを変換する場合は、trueを設定します(初期値:false[部分指定]) 052 * [ -display=[false/true]] :結果を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 053 * [ -debug=[false/true] ] :デバッグ情報を標準出力に表示する(true)かしない(false)か(初期値:false[表示しない]) 054 * 055 * @og.rev 5.0.0.2 (2009/09/15) 廃止クラスです。 056 * @deprecated 5.0.0.2 (2009/09/15) 廃止クラスです。類似機能に、Process_StringUtil を利用してください。 057 * @version 0.9.0 2004/02/27 058 * @author Kazuhiko Hasegawa 059 * @since JDK5.0, 060 */ 061@Deprecated public class Process_UnicodeEscape extends AbstractProcess implements ChainProcess { 062 063 private boolean isEscape = true; // 変換方法(true:Escape/false:Reverse) 064 private String keys = null; // 変換するカラム名配列のアドレス 065 private int[] clmNos = null; // 変換するカラム名配列のアドレス 066 private boolean all = false; // 部分指定 067 private boolean display = false; // 表示しない 068 private boolean debug = false; // 5.7.3.0 (2014/02/07) デバッグ情報 069 070 private boolean firstRow = true; // 最初の一行目 071 private int count = 0; 072 073 private static final Map<String,String> mustProparty ; // [プロパティ]必須チェック用 Map 074 private static final Map<String,String> usableProparty ; // [プロパティ]整合性チェック Map 075 076 static { 077 mustProparty = new LinkedHashMap<String,String>(); 078 mustProparty.put( "action", "ESCAPE(変換)/REVERSE(戻し) を指定します(必須)" ); 079 080 usableProparty = new LinkedHashMap<String,String>(); 081 usableProparty.put( "keys", "変換するカラムをCSV形式で複数指定できます。" ); 082 usableProparty.put( "all", "全カラムを変換する場合は、trueを設定します。" + 083 CR + " (初期値:false:部分指定)" ); 084 usableProparty.put( "display", "結果を標準出力に表示する(true)かしない(false)か" + 085 CR + " (初期値:false:表示しない)" ); 086 usableProparty.put( "debug", "デバッグ情報を標準出力に表示する(true)かしない(false)か" + 087 CR + "(初期値:false:表示しない)" ); // 5.7.3.0 (2014/02/07) デバッグ情報 088 } 089 090 /** 091 * デフォルトコンストラクター。 092 * このクラスは、動的作成されます。デフォルトコンストラクターで、 093 * super クラスに対して、必要な初期化を行っておきます。 094 * 095 */ 096 public Process_UnicodeEscape() { 097 super( "org.opengion.fukurou.process.Process_UnicodeEscape",mustProparty,usableProparty ); 098 } 099 100 /** 101 * プロセスの初期化を行います。初めに一度だけ、呼び出されます。 102 * 初期処理(ファイルオープン、DBオープン等)に使用します。 103 * 104 * @param paramProcess データベースの接続先情報などを持っているオブジェクト 105 */ 106 public void init( final ParamProcess paramProcess ) { 107 Argument arg = getArgument(); 108 109 keys = arg.getProparty( "keys",keys ); 110 all = arg.getProparty( "all",all ); 111 display = arg.getProparty( "display",display ); 112 debug = arg.getProparty("debug",debug); // 5.7.3.0 (2014/02/07) デバッグ情報 113// if( debug ) { println( arg.toString() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 114 115 String act = arg.getProparty( "action" ); 116 117 118 if( act.charAt( 0 ) == 'E' ) { isEscape = true; } 119 else if( act.charAt( 0 ) == 'R' ) { isEscape = false; } 120 else { 121 String errMsg = "action=[" + act + "] は、E(SCAPE) か、R(EVERSE) を設定して下さい。" 122 + "先頭1文字目(大文字)で判定しています。"; 123 throw new RuntimeException( errMsg ); 124 } 125 126 if( ( keys == null || keys.length() == 0 ) && !all ) { 127 String errMsg = "keys か、all は設定して下さい。" 128 + "keys=[" + keys + "], all=[" + all + "]"; 129 throw new RuntimeException( errMsg ); 130 } 131 } 132 133 /** 134 * 引数の LineModel を処理するメソッドです。 135 * 変換処理後の LineModel を返します。 136 * 後続処理を行わない場合(データのフィルタリングを行う場合)は、 137 * null データを返します。つまり、null データは、後続処理を行わない 138 * フラグの代わりにも使用しています。 139 * なお、変換処理後の LineModel と、オリジナルの LineModel が、 140 * 同一か、コピー(クローン)かは、各処理メソッド内で決めています。 141 * ドキュメントに明記されていない場合は、副作用が問題になる場合は、 142 * 各処理ごとに自分でコピー(クローン)して下さい。 143 * 144 * @param data オリジナルのLineModel 145 * 146 * @return 処理変換後のLineModel 147 */ 148 public LineModel action( final LineModel data ) { 149 count++ ; 150 try { 151 if( firstRow ) { 152 makeColumnNos( data ); 153 firstRow = false; 154 if( display ) { println( data.nameLine() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 155 } 156 157 for( int i=0; i<clmNos.length; i++ ) { 158 String val = (String)data.getValue( clmNos[i] ) ; 159 160 if( isEscape ) { 161 val = StringUtil.getUnicodeEscape( val ) ; 162 } 163 else { 164 val = StringUtil.getReplaceEscape( val ) ; 165 } 166 data.setValue( clmNos[i],val ); 167 } 168 169// if( display ) { printKey( count,data ); } 170 if( display ) { println( data.dataLine() ); } // 5.7.3.0 (2014/02/07) デバッグ情報 171 } 172 catch( Throwable ex ) { 173 String errMsg = "row=[" + count + "]" + CR + 174 " data=[" + data + "]" + CR ; 175 throw new RuntimeException( errMsg,ex ); 176 } 177 return data; 178 } 179 180 /** 181 * プロセスの終了を行います。最後に一度だけ、呼び出されます。 182 * 終了処理(ファイルクローズ、DBクローズ等)に使用します。 183 * 184 * @param isOK トータルで、OKだったかどうか[true:成功/false:失敗] 185 */ 186 public void end( final boolean isOK ) { 187 keys = null; // 変換するカラム名配列のアドレス 188 clmNos = null; // 変換するカラム名配列のアドレス 189 } 190 191 /** 192 * プロセスの処理結果のレポート表現を返します。 193 * 処理プログラム名、入力件数、出力件数などの情報です。 194 * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような 195 * 形式で出してください。 196 * 197 * @return 処理結果のレポート 198 */ 199 public String report() { 200 String report = "[" + getClass().getName() + "]" + CR 201 + TAB + "Output Count : " + count ; 202 203 return report ; 204 } 205 206 /** 207 * カラム番号配列を取得します。 208 * 繰返し処理を行う場合に、事前にアドレスでアクセスできるように処理するカラム番号を 209 * キャッシュしておきます。 210 * 211 * @param data ラインモデル 212 */ 213 private void makeColumnNos( final LineModel data ) { 214 if( all ) { 215 String[] names = data.getNames(); 216 int size = names.length; 217 clmNos = new int[size]; 218 for( int i=0; i<size; i++ ) { 219 clmNos[i] = i; 220 } 221 } 222 else { 223 String[] clms = StringUtil.csv2Array( keys ); 224 int size = clms.length; 225 clmNos = new int[size]; 226 for( int i=0; i<size; i++ ) { 227 clmNos[i] = data.getColumnNo( clms[i] ); 228 } 229 } 230 } 231 232 /** 233 * 画面出力用のフォーマットを作成します。 234 * 235 * @og.rev 5.7.3.0 (2014/02/07) 表示方法の変更のため、廃止 236 * 237 * @param rowNo データ読み取り件数 238 * @param data ラインモデル 239 */ 240// private void printKey( final int rowNo , final LineModel data ) { 241// StringBuilder buf = new StringBuilder(); 242// 243// buf.append( "row=[" ).append( rowNo ).append( "] : " ); 244// for( int i=0; i < clmNos.length; i++ ) { 245// buf.append( data.getName( clmNos[i] ) ); 246// buf.append( " ⇒ " ); 247// buf.append( data.getValue( clmNos[i] ) ); 248// buf.append( " , " ); 249// } 250// 251// println( buf.toString() ); 252// } 253 254 /** 255 * このクラスの使用方法を返します。 256 * 257 * @return このクラスの使用方法 258 */ 259 public String usage() { 260 StringBuilder buf = new StringBuilder(); 261 262 buf.append( "Process_UnicodeEscape は、上流から受け取ったデータをエスケープ変換する" ).append( CR ); 263 buf.append( "CainProcess インターフェースの実装クラスです。" ).append( CR ); 264 buf.append( CR ); 265 buf.append( "上流(プロセスチェインのデータは上流から下流へと渡されます。)から" ).append( CR ); 266 buf.append( " LineModel を元に、指定のカラムのUTF-8 文字コードと、HTML のエスケープ" ).append( CR ); 267 buf.append( "記号(&#xZZZZ;)文字との相互変換を行います。" ).append( CR ); 268 buf.append( "入力文字を、キャラクタ(char)型に分解し、(&#xZZZZ;)に変換していきます。" ).append( CR ); 269 buf.append( "よって、通常に1文字(Shift-JISで2Byte,UTF-8で3Byte)が、8Byteになります。" ).append( CR ); 270 buf.append( "この変換された文字列を、HTML上でそのまま取り出すと、元のUnicode文字に戻る為" ).append( CR ); 271 buf.append( "通常のShift-JISでは、扱えない文字(中国語など)でも表示可能になります。" ).append( CR ); 272 buf.append( CR ); 273 buf.append( "引数文字列中に空白を含む場合は、ダブルコーテーション(\"\") で括って下さい。" ).append( CR ); 274 buf.append( "引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に" ).append( CR ); 275 buf.append( "繋げてください。" ).append( CR ); 276 buf.append( CR ).append( CR ); 277 buf.append( getArgument().usage() ).append( CR ); 278 279 return buf.toString(); 280 } 281 282 /** 283 * このクラスは、main メソッドから実行できません。 284 * 285 * @param args コマンド引数配列 286 */ 287 public static void main( final String[] args ) { 288 LogWriter.log( new Process_UnicodeEscape().usage() ); 289 } 290}