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.util; 017 018import java.awt.Color; 019import java.io.PrintWriter; 020import java.io.StringWriter; 021import java.io.UnsupportedEncodingException; 022import java.net.URLEncoder; 023import java.net.URLDecoder; 024import java.util.ArrayList; 025import java.util.Arrays; 026import java.util.Enumeration; 027import java.util.HashMap; 028import java.util.Iterator; 029import java.util.Map; 030import java.util.StringTokenizer; 031import java.util.Locale ; // 5.7.2.3 (2014/01/31) 032import java.nio.charset.Charset; // 5.5.2.6 (2012/05/25) 033 034 035/** 036 * StringUtil.java は、共通的に使用される String関連メソッドを集約した、クラスです。 037 * 038 * @og.group ユーティリティ 039 * 040 * @version 4.0 041 * @author Kazuhiko Hasegawa 042 * @since JDK5.0, 043 */ 044public final class StringUtil { 045 046 /** バッファの初期容量を通常より多い目に設定します。(200) */ 047 private static final int BUFFER_MIDDLE = 200; 048 049 /** システム依存の改行記号をセットします。 */ 050 private static final String CR = System.getProperty("line.separator"); 051 052 /** 053 * プラットフォーム依存のデフォルトの Charset です。 054 * プラットフォーム依存性を考慮する場合、エンコード指定で作成しておく事をお勧めします。 055 * 056 * @og.rev 5.5.2.6 (2012/05/25) findbugs対応 057 */ 058 public static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ; 059 060 /** 061 * code39 のチェックデジット計算に使用する モジュラス43 の変換表です。 062 * 063 */ 064 private static final String MODULUS_43 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" ; 065 066 /** 067 * getUnicodeEscape で使用する桁合わせ用文字列配列です。 068 * Unicodeの HexString 変換後の桁に応じて、埋め合わせします。 069 * 070 */ 071 private static final String[] UTF_STR = { "�", "�", "�", "�", "&#x" }; 072 073 // 4.0.3.0 (2007/12/26) 色コードにPURPLE を追加 074 // 5.7.8.0 (2014/07/04) 透明追加 075 private static final Map<String,Color> CLR_MAP; 076 static { 077 CLR_MAP = new HashMap<String,Color>(); 078 CLR_MAP.put( "BLACK" ,Color.BLACK ); 079 CLR_MAP.put( "BLUE" ,Color.BLUE ); 080 CLR_MAP.put( "CYAN" ,Color.CYAN ); 081 CLR_MAP.put( "DARK_GRAY" ,Color.DARK_GRAY ); 082 CLR_MAP.put( "GRAY" ,Color.GRAY ); 083 CLR_MAP.put( "GREEN" ,Color.GREEN ); 084 CLR_MAP.put( "LIGHT_GRAY" ,Color.LIGHT_GRAY ); 085 CLR_MAP.put( "MAGENTA" ,Color.MAGENTA ); 086 CLR_MAP.put( "ORANGE" ,Color.ORANGE ); 087 CLR_MAP.put( "PINK" ,Color.PINK ); 088 CLR_MAP.put( "RED" ,Color.RED ); 089 CLR_MAP.put( "WHITE" ,Color.WHITE ); 090 CLR_MAP.put( "YELLOW" ,Color.YELLOW ); 091 CLR_MAP.put( "PURPLE" ,new Color( 8388736 ) ); // #800080 092 CLR_MAP.put( "TRANSPARENT" ,new Color( 255,255,255,0 ) ); // 5.7.8.0 (2014/07/04) 透明追加 093 } 094 095 /** 096 * デフォルトコンストラクターをprivateにして、 097 * オブジェクトの生成をさせないようにする。 098 * 099 */ 100 private StringUtil() {} 101 102 /** 103 * UTF-8 で、URLエンコードを行います。 104 * このメソッドは、JDK1.4 以上でないと使用できません。 105 * 106 * @param value エンコードする文字列 107 * 108 * @return 指定の文字コードでURLエンコードされた文字列 109 */ 110 public static String urlEncode( final String value ) { 111 if( value == null ) { return ""; } 112 113 try { 114 return URLEncoder.encode( value,"UTF-8" ); 115 } 116 catch( UnsupportedEncodingException ex ) { 117 String errMsg = "UnsupportedEncodingException [UTF-8]" + CR 118 + ex.getMessage() ; 119 throw new RuntimeException( errMsg,ex ); 120 } 121 catch( RuntimeException ex2 ) { // 3.6.0.0 (2004/09/17) 122 String errMsg = "予期せぬエラー value=[" + value + "] , encode=[UTF-8]" + CR 123 + ex2.getMessage(); 124 throw new RuntimeException( errMsg,ex2 ); 125 } 126 } 127 128 /** 129 * UTF-8 でURLエンコードされた文字列をデコードします。 130 * このメソッドは、JDK1.4 以上でないと使用できません。 131 * 132 * @og.rev 5.4.5.0 追加 133 * @param value デコードする文字列 134 * 135 * @return デコードされた文字列 136 */ 137 public static String urlDecode( final String value ) { 138 try { 139 return URLDecoder.decode( value,"UTF-8" ); 140 } 141 catch( UnsupportedEncodingException ex ) { 142 String errMsg = "UnsupportedEncodingException [UTF-8]" + CR 143 + ex.getMessage() ; 144 throw new RuntimeException( errMsg,ex ); 145 } 146 catch( RuntimeException ex2 ) { // 3.6.0.0 (2004/09/17) 147 String errMsg = "予期せぬエラー value=[" + value + "] , encode=[UTF-8]" + CR 148 + ex2.getMessage(); 149 throw new RuntimeException( errMsg,ex2 ); 150 } 151 } 152 153 /** 154 * 文字列の後ろのスペースを削除します。 155 * String クラスの trim()メソッドは、文字列の両方のスペースを削除しますが、 156 * この rTrim( String ) は、後ろの半角スペースのみ、詰めます。 157 * 注意:'\u0020' (スペース文字) より小さい文字を切り取ります。 158 * 159 * @param str 元の文字列 160 * 161 * @return 後ろの半角スペースを詰めた、新しい文字列 162 */ 163 public static String rTrim( final String str ) { 164 if( str == null ) { return null; } 165 int count = str.length(); 166 167 int len = count; 168 169 while ( 0 < len && str.charAt(len-1) <= ' ' ) { 170 len--; 171 } 172 return (len < count) ? str.substring(0, len) : str; 173 } 174 175 /** 176 * 文字列の後ろから、" .0" の文字を削除した数字型文字列を返します。 177 * 数字型文字列は、入力文字列の後ろの スペース、小数点、ゼロを削除します。 178 * また、先頭が、"." で始まる場合は、"0" を追加します。 179 * 例: "123.00" ⇒ "123" , ".123" ⇒ "0.123" 180 * 181 * @og.rev 3.8.8.1 (2007/01/10) 新規作成 182 * 183 * @param str 元の文字列 184 * 185 * @return 数字文字列化された、新しい文字列 186 */ 187 public static String toNumber( final String str ) { 188 if( str == null ) { return null; } 189 190 String rtn = str.trim() ; 191 192 int adrs = rtn.indexOf( '.' ); 193 int count = rtn.length(); 194 int len = count; 195 196 if( adrs >= 0 ) { 197 while ( adrs < len && ".0".indexOf( rtn.charAt(len-1) ) >= 0 ) { 198 len--; 199 } 200 } 201 202 if( len < count ) { rtn = rtn.substring(0, len); } 203 if( adrs == 0 ) { rtn = "0" + rtn; } 204 205 return rtn ; 206 } 207 208 /** 209 * 文字列の前方のゼロ(0)を削除します。 210 * 先頭の0を削除するまえに、trim して、スペースを削除しておきます。 211 * 212 * @og.rev 3.5.4.5 (2004/01/23) 新規追加 213 * 214 * @param in 元の文字列 215 * 216 * @return 前方のゼロ(0)を削除した、新しい文字列 217 */ 218 public static String lTrim0( final String in ) { 219 if( in == null ) { return null; } 220 String str = in.trim(); 221 int count = str.length(); 222 223 int len = 0; 224 225 while ( count > len && str.charAt(len) == '0' ) { 226 len++; 227 } 228 229 if( len == 0 ) { return str; } // 先頭がゼロでない。 230 else if( len == count ) { return "0"; } // すべてがゼロ 231 else if( str.charAt(len) == '.' ) { return "0" + str.substring(len); } 232 else { return str.substring(len); } 233 } 234 235 /** 236 * 文字列配列の各要素の後ろのスペースを削除します。 237 * 個々の配列要素に対して、rTrim( String str ) を適用します。 238 * 元の文字列配列に直接作用するのではなく、新しい文字列配列に 239 * 結果をコピーして返します。 240 * ただし、元の文字列配列が、null か、length == 0 の場合は、 241 * 元の文字列配列(アドレス)を返します。 242 * 注意:'\u0020' (スペース文字) より小さい文字を切り取ります。 243 * 244 * @param str 元の文字列 245 * 246 * @return 後ろの半角スペースを詰めた、新しい文字列 247 */ 248 public static String[] rTrims( final String[] str ) { 249 if( str == null || str.length == 0 ) { return str; } 250 251 String[] rtn = new String[ str.length ]; 252 for( int i=0; i<str.length; i++ ) { 253 rtn[i] = rTrim( str[i] ); 254 } 255 return rtn ; 256 } 257 258 /** 259 * 文字列の前後のダブルクオートを取り外します。 260 * 前後にダブルクオートが入っていなければ、そのままの文字列を返します。 261 * 前後に入っていない(片方のみなど)場合も、そのままの文字列を返します。 262 * 263 * @param str 元の文字列 264 * 265 * @return ダブルクオートを取り外した新しい文字列 266 */ 267 public static String csvOutQuote( final String str ) { 268 if( str == null ) { return null; } 269 int end = str.length(); 270 271 if( end < 2 || str.charAt(0) != '"' || str.charAt( end-1 ) != '"' ) { 272 return str; 273 } 274 275 return str.substring( 1,end-1 ) ; 276 } 277 278 /** 279 * 内部で使われる byte[] から String 生成 メソッド 280 * 281 * @param byteValue 変換するバイト列 282 * @param start 変換開始アドレス 283 * @param length 変換バイト数 284 * @param encode 変換する文字エンコード 285 * 286 * @return 変換後文字列 287 */ 288 public static String makeString( final byte[] byteValue, final int start, final int length,final String encode ) { 289 290 if( encode.startsWith( "Unicode" ) ) { 291 String errMsg = "Unicode文字列は、変換できません。[" + encode + "]" + CR; 292 throw new RuntimeException( errMsg ); 293 } 294 295 String rtn = null; 296 if( byteValue != null ) { 297 try { 298 // encode コードで変換されている byte[] を、String に変換。 299 rtn = new String( byteValue,start,length,encode ); 300 } catch( UnsupportedEncodingException ex ) { // 変換コードが存在しないエラー 301 String errMsg = "文字変換コードが存在しません。[" + encode + "]" + CR 302 + ex.getMessage() ; 303 throw new RuntimeException( errMsg,ex ); 304 } 305 } 306 return rtn; 307 } 308 309 /** 310 * 指定の文字列をバイトコードに変換します。 311 * 引数の文字列が null の場合は、return は、byte[0] を返します。 312 * 313 * @param value 変換するストリング値 314 * @param encode 変換する文字エンコード 315 * 316 * @return 変換後文字列 317 */ 318 public static byte[] makeByte( final String value,final String encode ) { 319 byte[] rtnByte = new byte[0]; 320 if( value != null ) { 321 try { 322 rtnByte = value.getBytes( encode ); // byte[] に encode コードで変換。 323 } catch( UnsupportedEncodingException ex ) { // 変換コードが存在しないエラー 324 String errMsg = "文字変換コードが存在しません。[" + encode + "]" + CR 325 + ex.getMessage(); 326 throw new RuntimeException( errMsg,ex ); 327 } 328 } 329 return rtnByte; 330 } 331 332 /** 333 * 半角スペースで固定長(半角換算の数)に変換した文字列を返します。 334 * 半角スペース埋めは、文字が半角、全角混在でもかまいません。 335 * 内部にセットした文字列は、変化しません。 336 * 337 * @param str Fill埋めする文字列 338 * @param su_fill Fill埋めする文字列の長さ。(半角換算の数) 339 * 340 * @return Fill埋めした新しいStringを返す。 341 */ 342 public static String stringXFill( final String str,final int su_fill ) { 343 char[] charValue ; 344 345 if( str == null ) { charValue = new char[0]; } 346 else { charValue = str.toCharArray(); } 347 int len = charValue.length; 348 349 if( su_fill < len ) { 350 String errMsg = "元の文字数がフォームより長いです。(数字が壊れます。)" 351 + "su_fill[" + su_fill + "], len[" + len + "]" + CR 352 + "input=[" + str + "]" + CR; 353 throw new RuntimeException( errMsg ); 354 } 355 356 char[] charbuf = new char[ su_fill ]; // 移す char 配列を新規作成 357 Arrays.fill( charbuf,' ' ); 358 System.arraycopy( charValue,0,charbuf,0,len ); 359 360 return new String( charbuf ); // コピーした配列全てを文字列に変換 361 } 362 363 /** 364 * 半角スペースで固定長(半角換算の数)に変換した文字列を返します。 365 * 半角スペース埋めは、文字が半角、全角混在でもかまいません。 366 * 内部にセットした文字列は、変化しません。 367 * 368 * @param str Fill埋めする文字列 369 * @param su_fill Fill埋めする文字列の長さ。(半角換算の数) 370 * @param encode Fill埋めする文字列の文字エンコード 371 * 372 * @return Fill埋めした新しいStringを返す。 373 */ 374 public static String stringFill( final String str,final int su_fill,final String encode ) { 375 if( su_fill < 0 ) { 376 String errMsg = "指定文字数が負です。[" + su_fill + "]"; 377 throw new RuntimeException( errMsg ); 378 } 379 380 byte[] byteValue = makeByte( str,encode ); 381 int len = byteValue.length; 382 383 // 内部文字列が指定長より長い場合 384 if( len >= su_fill ) { 385 return makeString( byteValue,0,su_fill,encode ); 386 } 387 else { 388 byte[] space = makeByte( " ",encode ); 389 int spaceLen = space.length ; 390 if( spaceLen == 4 ) { // encode が、UnicodeLittle の場合の特殊処理 391 space[0] = space[2]; 392 space[1] = space[3]; 393 spaceLen = 2; 394 } 395 byte[] bytebuf = new byte[ su_fill ]; 396 for( int i=0; i<len; i++ ) { bytebuf[i] = byteValue[i]; } 397 398 int k = 0; 399 for( int j=len; j<su_fill; j++ ) { // 余った部分は、スペース埋め 400 if( k >= spaceLen ) { k = 0; } 401 bytebuf[j] = space[k++]; 402 } 403 return makeString( bytebuf,0,su_fill,encode ); // 新たに、すべての長さの部分文字列を作成する。 404 } 405 } 406 407 /** 408 * 整数のフォーム( 12 で、整数部 12桁を表す)に合った新しい文字列を作り、それを返します。 409 * 実行できるのは、整数の String に対してのみです。 410 * 内部にセットした文字列は、変化しません。 411 * 412 * String str = StringUtil.intFill( "123",10 ); 413 * 414 * 実行結果:"0000000123" 415 * 416 * @param str 整数の String 417 * @param su_fill フォームを表す数字 ( 12 で、整数部 12桁を表す) 418 * 419 * @return 整数のフォームに合った文字列 420 */ 421 public static String intFill( final String str,final int su_fill ) { 422 if( su_fill < 0 ) { 423 String errMsg = "指定文字数が負です。[" + su_fill + "]"; 424 throw new RuntimeException( errMsg ); 425 } 426 427 char[] charbuf = new char[ su_fill ]; // 移す char 配列を新規作成 428 Arrays.fill( charbuf,'0' ); 429 430 if( str == null ) { return new String( charbuf ); } 431 432 char[] charValue = str.toCharArray(); 433 int len = charValue.length; 434 435 if( su_fill < len ) { 436 String errMsg = "元の文字数がフォームより長いです。(数字が壊れます。) su_fill[" + su_fill + "], len[" + len + "]"; 437 throw new RuntimeException( errMsg ); 438 } 439 440 System.arraycopy( charValue,0,charbuf,su_fill-len,len ); 441 442 return new String( charbuf ); // コピーした配列全てを文字列に変換 443 } 444 445 /** 446 * 全角スペースで固定長(半角換算の数)に変換した文字列を返します。 447 * 448 * @param str Fill埋めする文字列 449 * @param su_fill Fill埋めする文字列の長さ。(半角換算の数) 450 * @param encode Fill埋めする文字列の文字エンコード 451 * 452 * @return 全角スペースでFill埋めした新しいStringを返す。 453 */ 454 public static String stringKFill( final String str,final int su_fill,final String encode ) { 455 if( su_fill < 0 ) { 456 String errMsg = "指定文字数が負です。[" + su_fill + "]"; 457 throw new RuntimeException( errMsg ); 458 } 459 460 byte[] byteValue = makeByte( str,encode ); 461 int len = byteValue.length; 462 463 // 内部文字列が指定長より長い場合 464 if( len >= su_fill ) { 465 return makeString( byteValue,0,su_fill,encode ); 466 } 467 else { 468 byte[] space = makeByte( " ",encode ); 469 int spaceLen = space.length ; 470 byte[] bytebuf = new byte[ su_fill ]; 471 for( int i=0; i<len; i++ ) { bytebuf[i] = byteValue[i]; } 472 int k = 0; 473 for( int j=len; j<su_fill; j++ ) { // 余った部分は、スペース埋め 474 if( k >= spaceLen ) { k = 0; } 475 bytebuf[j] = space[k++]; 476 } 477 return makeString( bytebuf,0,su_fill,encode ); // 新たに、すべての長さの部分文字列を作成する。 478 } 479 } 480 481 /** 482 * 小数点のフォームに合った新しい文字列を作り、文字列を返します。 483 * 現在は、小数点が頭に付いたり、最後に付く場合の対応はしていません。 484 * フォームは、12.4 で、 000000000010.1000 という形で、ピリオドを含みます。 485 * 486 * // 半角 整数部 10 桁 小数部 5桁で固定長の文字を得る。 487 * String str = StringUtil.realFill( "123.45" ,10.5 ) ; 488 * 489 * 実行結果:0000000123.45000 490 * 491 * @param str 整数の String 492 * @param su_fill フォームを表す実数 ( 12.4 で、整数部 12桁、小数部 4桁 計17桁 ) 493 * 494 * @return value 小数点のフォーム文字列 495 */ 496 public static String realFill( final String str,final double su_fill ) { 497 if( su_fill < 0 ) { 498 String errMsg = "指定文字数が負です。[" + su_fill + "]"; 499 throw new RuntimeException( errMsg ); 500 } 501 502 int su_seisu = (int)(su_fill); // 指定のフォームの整数部を取り出す。 503 int su_shosu = (int)(su_fill*10 - su_seisu*10); // 小数部を取り出しす。 504 char[] charbuf = new char[ su_seisu + su_shosu + 1 ]; // 移す char 配列 505 Arrays.fill( charbuf,'0' ); 506 507 if( str == null ) { 508 charbuf[su_seisu] = '.' ; 509 return new String( charbuf ); 510 } 511 512 char[] charValue = str.toCharArray(); 513 int len = charValue.length; 514 515 // 検査する文字列の加工(検査文字列は、インデックスの値とバイト数で文字数を求める。) 516 // 小数点の位置を求める。 本当は、String クラスの indexOf で求めず、byte[] で検索すべきである。 517 int valueindex = str.indexOf( '.' ); 518 if( valueindex < 0 ) { // valueform 自体が、合っていない。 519 String errMsg = "元の文字列に小数点が、含まれません。"; 520 throw new RuntimeException( errMsg ); 521 } 522 int su_valueseisu = valueindex; // 整数部の文字数は、小数点の位置と同じ 523 int su_valueshosu = len - valueindex - 1 ; // 小数部の文字数は、全文字数−整数文字数−1 524 525 // フォームの整数文字数 ー 加工文字の整数文字部 = 転送先配列位置 526 int to_index = su_seisu - su_valueseisu; 527 if( to_index < 0 ) { 528 String errMsg = "元の数字が、フォームより長いです。(数字が壊れます。) form[" + su_fill + "]"; 529 throw new RuntimeException( errMsg ); 530 } 531 int end_index; 532 // 転送先配列終了位置は、お互いの小数部の文字数により、短い方を選ぶ。 533 if( su_shosu < su_valueshosu ) { end_index = su_seisu + su_shosu + 1; } 534 else { end_index = su_seisu + su_valueshosu + 1; } 535 536 int from_index = 0; 537 while( to_index < end_index ) { 538 charbuf[to_index++] = charValue[from_index++]; // 転送(移し替え) 539 } 540 return new String( charbuf ); // コピーした配列全てを文字列に変換 541 } 542 543 /** 544 * ストリングの部分文字列を,別の文字列に置換えたストリングを返します。 545 * 例えば,リターンコードを< br />に置換えて,画面上に改行表示させるが可能です。 546 * 547 * @og.rev 5.0.0.1 (2009/08/15) 不要なオブジェクトの生成を抑制する。 548 * 549 * @param target 元の文字列 550 * @param from 置換元部分文字列 551 * @param to 置換先部分文字列 552 * 553 * @return 置換えた文字列 554 */ 555 public static String replace( final String target,final String from,final String to ) { 556 if( target == null || from == null || to == null || target.indexOf( from ) < 0 ) { return target; } 557 558 StringBuilder strBuf = new StringBuilder( target.length() ); 559 560 int start = 0; 561 int end = target.indexOf( from,start ); 562 while( end >= 0 ) { 563 strBuf.append( target.substring( start,end ) ); 564 strBuf.append( to ); 565 start = end + from.length(); 566 end = target.indexOf( from,start ); 567 } 568 569 if( start > 0 ) { 570 strBuf.append( target.substring( start ) ); 571 return strBuf.toString(); 572 } 573 else { 574 return target; // 3.4.0.2 (2003/09/05) 575 } 576 } 577 578 /** 579 * 引数の AA:01 BB:02 CC:03 … 形式の、元値:新値のスペース区切り文字列を元に、 580 * 元値を新値に置き換えます。 581 * これは、部分置換ではなく、完全一致で処理します。 582 * caseStr が null や、マッチしなかった場合は、元の値を返します。 583 * その場合、ignoreCase=true としている場合は、元の文字列 も大文字に変換されて返されます。 584 * 585 * ゼロ文字列を元値や新値で使用することは可能ですが、スペースを使用することはできません。 586 * 587 * @og.rev 5.7.2.3 (2014/01/31) 新規追加 588 * 589 * @param target 元の文字列 590 * @param caseStr 置換リスト(AA:01 BB:02 CC:03 … 形式)。null の場合は、比較しない。 591 * @param ignoreCase true:大文字として比較 / false:そのまま比較 592 * 593 * @return 元の文字列を置き換えた結果。置換リストに存在しなければ、元の文字列を返す。 594 */ 595 public static String caseReplace( final String target,final String caseStr,final boolean ignoreCase ) { 596 if( target == null ) { return target; } 597 598 String rtn = ignoreCase ? target.toUpperCase(Locale.JAPAN) : target ; 599 600 if( caseStr != null ) { 601 String caseTmp = " " + caseStr.trim() + " " ; // CASE文字列の形式をそろえる。 602 603 int adrs = caseTmp.indexOf( " " + rtn + ":" ); // 前スペースと後ろコロンで、単語を確定する。 604 if( adrs >= 0 ) { 605 int st = caseTmp.indexOf( ':' , adrs+1 ); // 最初のコロンの位置。元値:新値 の 新値 の取出 606 int ed = caseTmp.indexOf( ' ' , st+1 ); // コロンの次から、最初のスペースの位置 607 if( st >= 0 && ed >= 0 ) { 608 rtn = caseTmp.substring( st+1,ed ); // コロンの次から、スペースの前までを切り出す。 609 } 610 } 611 } 612 613 return rtn ; 614 } 615 616 /** 617 * String型の配列から、カンマ(,)で連結されたString を作成します。 618 * これは,配列を表示用に変換する為のものです。 619 * array2line( array, ",", 0 ); と同等です。 620 * 621 * @param array 元の文字列配列 622 * 623 * @return 一列に変換した文字列(引数がnullの場合は、長さ0の文字列を返す) 624 */ 625 public static String array2csv( final String[] array ) { 626 return array2line( array, ",", 0 ); 627 } 628 629 /** 630 * String型の配列から、セパレーターで連結されたString を作成します。 631 * これは,配列を表示用に変換する為のものです。 632 * 633 * @param array 元の文字列配列 634 * @param separator 区切り記号 635 * 636 * @return 一列に変換した文字列(引数がnullの場合は、長さ0の文字列を返す) 637 */ 638 public static String array2line( final String[] array,final String separator ) { 639 return array2line( array, separator,0 ); 640 } 641 642 /** 643 * String型の配列から、セパレーターで連結されたString を作成します。 644 * これは,配列を表示用に変換する為のものです。 645 * 646 * @param array 元の文字列配列 647 * @param separator 区切り記号 648 * @param start 配列の連結開始アドレス 649 * 650 * @return 一列に変換した文字列(引数がnullの場合は、長さ0の文字列を返す) 651 */ 652 public static String array2line( final String[] array,final String separator,final int start ) { 653 if( array == null || array.length <= start ) { return ""; } 654 655 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 656 657 rtn.append( valueOf( array[start] ) ); 658 for(int i=start+1; i < array.length; i++) { 659 rtn.append( separator ); 660 rtn.append( valueOf( array[i] ) ); 661 } 662 return rtn.toString(); 663 } 664 665 /** 666 * Enumerationから、オブジェクト配列データを返します。 667 * これは,Enumerationを表示用に変換する為のものです。 668 * 669 * @param enume 元のEnumeration 670 * 671 * @return オブジェクト配列 672 */ 673 public static Object[] enume2Array( final Enumeration<?> enume ) { // 4.3.3.6 (2008/11/15) Generics警告対応 674 if( enume == null || ! enume.hasMoreElements() ) { return new Object[0]; } 675 676 ArrayList<Object> obj = new ArrayList<Object>(); 677 678 while( enume.hasMoreElements() ) { 679 obj.add( enume.nextElement() ); 680 } 681 return obj.toArray(); 682 } 683 684 /** 685 * Enumerationから、オブジェクト配列データを返します。 686 * これは,Enumerationを表示用に変換する為のものです。 687 * 688 * @param enume 元のEnumeration 689 * @param objs - 配列が十分な大きさを持つ場合は、Vector の要素が格納される配列。 690 * そうでない場合は、要素を格納するために同じ実行時の型の新しい配列が割り当てられる 691 * @return オブジェクト配列 692 */ 693 public static Object[] enume2Array( final Enumeration<?> enume,final Object[] objs ) { // 4.3.3.6 (2008/11/15) Generics警告対応 694 if( enume == null || ! enume.hasMoreElements() ) { return objs ; } 695 696 ArrayList<Object> list = new ArrayList<Object>(); 697 698 while( enume.hasMoreElements() ) { 699 list.add( enume.nextElement() ); 700 } 701 return list.toArray( objs ); 702 } 703 704 /** 705 * Iteratorから、セパレーターで連結されたString を作成します。 706 * これは,Enumerationを表示用に変換する為のものです。 707 * 708 * @param ite 元のIterator 709 * @param separator 区切り記号 710 * 711 * @return 一列に変換した文字列 712 */ 713 public static String iterator2line( final Iterator<?> ite,final String separator ) { 714 if( ite == null || ! ite.hasNext() ) { return ""; } 715 716 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 717 718 rtn.append( valueOf( ite.next() ) ); 719 while( ite.hasNext() ) { 720 rtn.append( separator ); 721 rtn.append( valueOf( ite.next() ) ); 722 } 723 return rtn.toString(); 724 } 725 726 /** 727 * カンマ(,)で連結された String を、配列に分解して、その値を返します。 728 * これは,たとえば、AAA,BBB,CCC などのリソースデータを受けてから配列に入れ直して、 729 * メニューなりリストを作成するのに便利です。 730 * 要素が空の場合は、必ずカンマの間にスペースを入れて記述してください。 731 * 分割後の文字列の前後のスペースは、削除されます。 732 * 733 * @param csvData 元のデータ 734 * 735 * @return 文字列配列(引数がnull、ゼロ文字列の場合は、サイズ0の配列を返す) 736 */ 737 public static String[] csv2Array( final String csvData ) { 738 return csv2Array( csvData, ',', 0 ); 739 } 740 741 /** 742 * 区切り文字で連結された String を、配列に分解して、その値を返します。 743 * これは,たとえば、AAA,BBB,CCC などのリソースデータを受けてから配列に入れ直して、 744 * メニューなりリストを作成するのに便利です。 745 * 連続した区切り文字は、1文字に分割します。 746 * 分割後の文字列の前後のスペースは、削除されます。 747 * 748 * @param csvData 元のデータ 749 * @param separator 区切り文字 750 * 751 * @return 文字列配列(引数がnull、ゼロ文字列の場合は、サイズ0の配列を返す) 752 */ 753 public static String[] csv2Array( final String csvData,final char separator ) { 754 return csv2Array( csvData,separator,0 ); 755 } 756 757 /** 758 * 区切り文字で連結された String を、配列に分解して、その値を返します。 759 * これは,たとえば、AAA,BBB,CCC などのリソースデータを受けてから配列に入れ直して、 760 * メニューなりリストを作成するのに便利です。 761 * 連続した区切り文字は、1文字に分割します。 762 * 分割後の文字列の前後のスペースは、削除されます。 763 * 第3の引数は、リターンする配列の個数を指定します。ただし、第一引数がNULLや、ゼロ文字列 764 * などの不正な情報の場合は、通常と同じく 長さゼロの配列を返します。 765 * len=0 を指定すると分解したデータの個数分の配列を作成します。指定の長さが短い場合は、 766 * そこまで分のみ取り込みます。指定の長さが長い場合は、余分に配列を作成します。 767 * セットされる値は、"" です。 768 * 769 * @og.rev 3.8.5.1 (2006/05/08) 設定配列の数を指定できるように変更 770 * @og.rev 3.8.8.2 (2007/01/26) 分割後の値の前後のスペースは削除します。 771 * 772 * @param csvData 元のデータ 773 * @param separator 区切り文字 774 * @param len 指定の長さの配列で返します。 775 * 776 * @return 文字列配列(引数がnull、ゼロ文字列の場合は、サイズ0の配列を返す) 777 */ 778 public static String[] csv2Array( final String csvData,final char separator, final int len ) { 779 if( csvData == null || csvData.length() == 0 ) { return new String[0] ; } 780 781 CSVTokenizer token = new CSVTokenizer( csvData,separator ); 782 783 int count = (len > 0 ) ? len : token.countTokens() ; 784 String[] rtn = new String[ count ]; 785 int i = 0; 786 for( ; i<count && token.hasMoreTokens() ; i++ ) { 787 rtn[i] = token.nextToken().trim(); // 3.8.8.2 (2007/01/26) 788 } 789 for( ; i<count; i++ ) { 790 rtn[i] = "" ; 791 } 792 793 return rtn; 794 } 795 796 /** 797 * 区切り文字で連結された String を、配列に分解して、その値を返します。 798 * これは,たとえば、AAA,BBB,CCC などのリソースデータを受けてから配列に入れ直して、 799 * メニューなりリストを作成するのに便利です。 800 * csv2Array と異なり、連続した区切り文字は、分割せずにトークンのみ切り出します。 801 * トークンは、カンマ(,)のみで区切り、その後 trim() により 802 * 前後のスペースを削除します。 803 * 804 * @param csvData 元のデータ 805 * 806 * @return 文字列配列 807 */ 808 public static String[] csv2ArrayOnly( final String csvData ) { 809 if( csvData == null || csvData.length() == 0 ) { return new String[0] ; } 810 811 StringTokenizer token = new StringTokenizer( csvData,"," ); 812 813 ArrayList<String> list = new ArrayList<String>(); 814 while( token.hasMoreTokens() ) { 815 String temp = token.nextToken().trim(); 816 if( temp.length() > 0 ) { list.add( temp ); } 817 } 818 819 return list.toArray( new String[list.size()] ); 820 } 821 822 /** 823 * カンマ(,)、ハイフン(-)で連結された String を、配列に分解して、その値を返す処理のスペシャル版です。 824 * 0,1,3,5-8,10-* などの数字文字列から、必要な数字をピックアップした文字配列を返します。 825 * 引数の maxNo は、"*" が指定された場合の、最大の数値です。 826 * よって、"*" は、単独(1文字)では、0-maxNo を表し、N-* では、N-maxNo を意味します。 827 * カンマ区切りで指定される値は、基本的に数字で、重複(1,1,2,2)、逆転(3,2,1)で指定できます。 828 * 5-3 と指定した場合は、5,4,3 に分解されます。逆順に登録されます。 829 * 重複削除、昇順並べ替え等が、必要な場合は、取得後の配列を操作してください。 830 * 831 * @og.rev 5.5.7.2 (2012/10/09) 新規追加 832 * @og.rev 5.9.12.4 (2016/09/30) アルファベットの対応を廃止し、数字配列のみサポートします。 833 * 834 * @param csvData 0,1,3,5-8,10-* などのCSV-ハイフン文字列 835 * @param maxNo "*" が指定された場合の、最大数 836 * @return 文字列配列(引数がnull、ゼロ文字列の場合は、サイズ0の配列を返す) 837 */ 838 public static String[] csv2ArrayExt( final String csvData , final int maxNo ) { 839 if( csvData == null || csvData.length() == 0 ) { return new String[0] ; } 840 841 String strData = csvData.replace( "-*" , "-" + maxNo ); // まず、N-* 形式を、N-maxNo に変換します。 842 strData = strData.replace( "*" , "0-" + maxNo ); // その後、"*" 単独(1文字)を、0-maxNo に変換します。 843 844 ArrayList<String> noList = new ArrayList<String>(); 845 846 String[] nos = strData.split( "," ); // カンマで分解。N , N-M , N-* のどれか 847 for( int i=0; i<nos.length; i++ ) { 848 String sno = nos[i] ; 849 int hai = sno.indexOf( '-' ); 850 // ハイフンが含まれているときは前後に分解して、間を埋める 851 if( hai > 0 ) { 852 String st1 = sno.substring( 0,hai ); // 先頭からハイフンまで 853 String st2 = sno.substring( hai+1 ); // ハイフンから最後まで 854 // 5.9.12.4 (2016/09/30) アルファベット対応をやめる 855// if( st1.length() == 1 && st2.length() == 1 ) { // ともに1文字の場合は、char化して処理。(英数字処理) 856// char ch1 = st1.charAt(0); 857// char ch2 = st2.charAt(0); 858// if( ch1 < ch2 ) { while( ch1 <= ch2 ) { noList.add( String.valueOf(ch1++) ); } } 859// else { while( ch1 >= ch2 ) { noList.add( String.valueOf(ch1--) ); } } 860// } 861// else { 862 int ch1 = Integer.parseInt( st1 ); 863 int ch2 = Integer.parseInt( st2 ); 864 if( ch1 < ch2 ) { while( ch1 <= ch2 ) { noList.add( String.valueOf(ch1++) ); } } 865 else { while( ch1 >= ch2 ) { noList.add( String.valueOf(ch1--) ); } } 866// } 867 } 868 else { 869 noList.add( String.valueOf(sno) ); 870 } 871 } 872 return noList.toArray( new String[noList.size()] ) ; 873 } 874 875 /** 876 * Integer限定版です。 877 * V6では返り値の型変更をしていますが、V5では一旦別名にしておきます。 878 * 879 * @og.rev 5.9.0.0 (2015/09/04) 新規追加 880 * @og.rev 5.9.12.4 (2016/09/30) アルファベットの対応を廃止し、数字配列のみサポートします。 881 * 882 * @param csvData 0,1,3,5-8,10-* などのCSV-ハイフン文字列 883 * @param maxNo "*" が指定された場合の、最大数 884 * @return 文字列配列(引数がnull、ゼロ文字列の場合は、サイズ0の配列を返す) 885 */ 886 public static Integer[] csv2ArrayExt2( final String csvData , final int maxNo ) { 887 if( csvData == null || csvData.length() == 0 ) { return new Integer[0] ; } 888 889 String strData = csvData.replace( "-*" , "-" + maxNo ); // まず、N-* 形式を、N-maxNo に変換します。 890 strData = strData.replace( "*" , "0-" + maxNo ); // その後、"*" 単独(1文字)を、0-maxNo に変換します。 891 892 ArrayList<Integer> noList = new ArrayList<Integer>(); 893 894 String[] nos = strData.split( "," ); // カンマで分解。N , N-M , N-* のどれか 895 for( int i=0; i<nos.length; i++ ) { 896 String sno = nos[i] ; 897 int hai = sno.indexOf( '-' ); 898 // ハイフンが含まれているときは前後に分解して、間を埋める 899 if( hai > 0 ) { 900 String st1 = sno.substring( 0,hai ); // 先頭からハイフンまで 901 String st2 = sno.substring( hai+1 ); // ハイフンから最後まで 902 // 5.9.12.4 (2016/09/30) アルファベット対応をやめる 903// if( st1.length() == 1 && st2.length() == 1 ) { // ともに1文字の場合は、char化して処理。(英数字処理) 904// char ch1 = st1.charAt(0); 905// char ch2 = st2.charAt(0); 906// if( ch1 < ch2 ) { while( ch1 <= ch2 ) { noList.add( Integer.valueOf(ch1++) ); } } 907// else { while( ch1 >= ch2 ) { noList.add( Integer.valueOf(ch1--) ); } } 908// } 909// else { 910 int ch1 = Integer.parseInt( st1 ); 911 int ch2 = Integer.parseInt( st2 ); 912 if( ch1 < ch2 ) { while( ch1 <= ch2 ) { noList.add( Integer.valueOf(ch1++) ); } } 913 else { while( ch1 >= ch2 ) { noList.add( Integer.valueOf(ch1--) ); } } 914// } 915 } 916 else { 917 noList.add( Integer.valueOf(sno) ); 918 } 919 } 920 return noList.toArray( new Integer[noList.size()] ) ; 921 } 922 923 /** 924 * Object 引数の文字列表現を返します。 925 * これは,String.valueOf とほぼ同じ動作をしますが、引数が null の場合に、 926 * "null" という文字列を返すのではなく、なにもない文字列 "" を返します。 927 * 928 * @param obj 文字列表現すべき元のオブジェクト 929 * 930 * @return 引数が null の場合は、"" に等しい文字列。そうでない場合は、obj.toString() の値 931 */ 932 public static String valueOf( final Object obj ) { 933 if( obj == null ) { return ""; } 934 else { return obj.toString(); } 935 } 936 937 /** 938 * HTML上のエスケープ文字を変換します。 939 * 940 * HTMLで表示する場合にきちんとエスケープ文字に変換しておかないと 941 * Script を実行されたり、不要なHTMLコマンドを潜り込まされたりするため、 942 * セキュリティーホールになる可能性があるので、注意してください。 943 * 944 * @param input HTMLエスケープ前の文字列 945 * 946 * @return エスケープ文字に変換後の文字列 947 */ 948 public static String htmlFilter( final String input ) { 949 if( input == null || input.length() == 0 ) { return ""; } 950 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 951 char ch; 952 for(int i=0; i<input.length(); i++) { 953 ch = input.charAt(i); 954 switch( ch ) { 955 case '<' : rtn.append("<"); break; 956 case '>' : rtn.append(">"); break; 957 case '"' : rtn.append("""); break; 958 case '\'' : rtn.append("'"); break; 959 case '&' : rtn.append("&"); break; 960 default : rtn.append(ch); 961 } 962 } 963 return rtn.toString() ; 964 } 965 966 /** 967 * XML上のエスケープ文字を変換します。 968 * 969 * HTMLとの違いはアポストロフィです。 970 * 971 * @og.rev 5.8.2.2 (2014/12/19) 新規作成 972 * 973 * @param input XMLエスケープ前の文字列 974 * 975 * @return エスケープ文字に変換後の文字列 976 */ 977 public static String xmlFilter( final String input ) { 978 if( input == null || input.length() == 0 ) { return ""; } 979 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 980 char ch; 981 for(int i=0; i<input.length(); i++) { 982 ch = input.charAt(i); 983 switch( ch ) { 984 case '<' : rtn.append("<"); break; 985 case '>' : rtn.append(">"); break; 986 case '"' : rtn.append("""); break; 987 case '\'' : rtn.append("'"); break; 988 case '&' : rtn.append("&"); break; 989 default : rtn.append(ch); 990 } 991 } 992 return rtn.toString() ; 993 } 994 995 /** 996 * JavaScript 等の引数でのクオート文字をASCII変換します。 997 * 998 * JavaScript の引数の値に、ダブルクオート(")、シングルクオート(')が 999 * 含まれると、文字列を表す為に前後に指定しているクオートと混乱し、 1000 * データを表現できないケースがあります。その場合には、クオート文字を 1001 * ASCII文字に置き換える事で、指定の文字を渡すことが可能になります。 1002 * ここでは、引数文字列に、ダブルクオート(")、シングルクオート(')が、 1003 * 含まれると、それぞれ、ASCII コード(¥x22、¥x27)に置き換えます。 1004 * なお、null は、ゼロ文字列に変換して返します。 1005 * 1006 * @param input 入力文字列 1007 * 1008 * @return クオート文字をASCII文字に置き換えた文字列 1009 */ 1010 public static String quoteFilter( final String input ) { 1011 if( input == null || input.length() == 0 ) { return ""; } 1012 if( input.indexOf( '\'' ) < 0 && input.indexOf( '"' ) < 0 ) { return input; } 1013 1014 StringBuilder rtn = new StringBuilder(); 1015 char ch; 1016 for(int i=0; i<input.length(); i++) { 1017 ch = input.charAt(i); 1018 switch( ch ) { 1019 case '"' : rtn.append( "\\x22" ); break; 1020 case '\'' : rtn.append( "\\x27" ); break; 1021 default : rtn.append( ch ); 1022 } 1023 } 1024 return rtn.toString() ; 1025 } 1026 1027 /** 1028 * JSON形式で出力する場合のためのエスケープ処理です。 1029 * 1030 * 1031 * @og.rev 5.9.6.4(2016/03/25) 新規作成 1032 * 1033 * @param input XMLエスケープ前の文字列 1034 * 1035 * @return エスケープ文字に変換後の文字列 1036 */ 1037 public static String jsonFilter( final String input ) { 1038 if( input == null || input.length() == 0 ) { return ""; } 1039 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 1040 char ch; 1041 for(int i=0; i<input.length(); i++) { 1042 ch = input.charAt(i); 1043 switch( ch ) { 1044 case '"' : rtn.append("\\\""); break; 1045 case '\\' : rtn.append("\\\\"); break; 1046 case '/' : rtn.append("\\/"); break; 1047 case '\b' : rtn.append("\\b"); break; 1048 case '\f' : rtn.append("\\f"); break; 1049 case '\n' : rtn.append("\\n"); break; 1050 case '\r' : rtn.append("\\r"); break; 1051 case '\t' : rtn.append("\\t"); break; 1052 default : rtn.append(ch); 1053 } 1054 } 1055 return rtn.toString() ; 1056 } 1057 1058 /** 1059 * 所定のキャラクタコードを取り除いた文字列を作成します。 1060 * 1061 * 実現したい機能は、String#replace( 'x','' ) 的な表現です。 1062 * つまり、指定のキャラクタを取り除きたいのですが、上記コマンドでは、 1063 * コンパイル時にエラーが発生します。 1064 * 取り除きたいキャラクタコードが存在しない場合は、指定の文字列を 1065 * そのまま返します。 1066 * 1067 * @param value 処理対象の文字列 1068 * @param ch 取り除きたいキャラクタ 1069 * 1070 * @return 処理後の文字列 1071 */ 1072 public static String deleteChar( final String value,final char ch ) { 1073 if( value == null || value.indexOf( ch ) < 0 ) { return value; } 1074 char[] chs = value.toCharArray() ; 1075 int j=0; 1076 for( int i=0;i<chs.length; i++ ) { 1077 if( chs[i] == ch ) { continue; } 1078 chs[j] = chs[i]; 1079 j++; 1080 } 1081 return String.valueOf( chs,0,j ); 1082 } 1083 1084 /** 1085 * 文字列に含まれる、特定の文字の個数をカウントして返します。 1086 * 1087 * @og.rev 5.2.0.0 (2010/09/01) 1088 * 1089 * @param value 処理対象の文字列 1090 * @param ch カウントする文字 1091 * 1092 * @return カウント数 1093 */ 1094 public static int countChar( final String value,final char ch ) { 1095 if( value == null || value.indexOf( ch ) < 0 ) { return 0; } 1096 char[] chs = value.toCharArray() ; 1097 int cnt=0; 1098 for( int i=0;i<chs.length; i++ ) { 1099 if( chs[i] == ch ) { cnt++; } 1100 } 1101 return cnt; 1102 } 1103 1104 /** 1105 * CODE39 の 文字列を作成します。 1106 * 1107 * CODE39 は、『0〜9, A〜Z,-,・, ,$,/,+,%』のコードが使用できる 1108 * バーコードの体系です。通常 * で始まり * で終了します。 1109 * また、チェックデジット に、モジュラス43 が使われます。 1110 * ここでは、指定の文字列の前後に、* を付与し、必要であれば 1111 * チェックデジットも付与します。 1112 * 指定の入力文字列には、* を付けないでください。 1113 * 1114 * @param value 処理対象の文字列 1115 * @param checkDigit チェックデジットの付与(true:付ける/false:付けない) 1116 * 1117 * @return 処理後の文字列 1118 */ 1119 public static String code39( final String value,final boolean checkDigit ) { 1120 String rtn = ( value == null ) ? "" : value ; 1121 if( ! checkDigit ) { return "*" + rtn + "*"; } 1122 1123 int kei = 0; 1124 int cd; 1125 for( int i=0; i<rtn.length(); i++ ) { 1126 cd = MODULUS_43.indexOf( rtn.charAt(i) ); 1127 if( cd < 0 ) { 1128 String errMsg = "指定の文字中に、CODE39 規定外文字が使用されています。[" + rtn.charAt(i) + "]" ; 1129 throw new RuntimeException( errMsg ); 1130 } 1131 kei += cd ; 1132 } 1133 char digit = MODULUS_43.charAt( kei % 43 ); 1134 1135 return "*" + rtn + digit + "*" ; 1136 } 1137 1138 /** 1139 * 引数 in が、null または、ゼロ文字列の場合は、デフォルト値 def を返します。 1140 * もちろん、in も def も null の場合は、null を返します。 1141 * 1142 * @param in 基準となる文字列 1143 * @param def デフォルト文字列 1144 * 1145 * @return ( in != null ) ? in : def ; 1146 */ 1147 public static String nval( final String in,final String def ) { 1148 return ( in == null || in.length() == 0 ) ? def : in ; 1149 } 1150 1151 /** 1152 * 引数 in が、null または、ゼロ文字列の場合は、デフォルト値 def を返します。 1153 * 1154 * @param in 基準となる文字列 1155 * @param def デフォルト数字 1156 * 1157 * @return 引数 in を変換した数字。変換できない場合は デフォルト値 def 1158 */ 1159 public static int nval( final String in,final int def ) { 1160 return ( in == null || in.length() == 0 ) ? def : Integer.parseInt( in ) ; 1161 } 1162 1163 /** 1164 * 引数 in が、null または、ゼロ文字列の場合は、デフォルト値 def を返します。 1165 * 1166 * @param in 基準となる文字列 1167 * @param def デフォルト数字 1168 * 1169 * @return 引数 in を変換した数字。変換できない場合は デフォルト値 def 1170 */ 1171 public static long nval( final String in,final long def ) { 1172 return ( in == null || in.length() == 0 ) ? def : Long.parseLong( in ) ; 1173 } 1174 1175 /** 1176 * 引数 in が、null または、ゼロ文字列の場合は、デフォルト値 def を返します。 1177 * 通常は、"true" または、 "TRUE" 文字列を、論理値の true に変換します。 1178 * ただし、文字列長が 1文字の場合のみ、"0" 以外を true に変換します。 1179 * 1180 * @param in 基準となる文字列 1181 * @param def デフォルト論理値 1182 * 1183 * @return 引数 in を変換した論理値。変換できない場合は デフォルト値 def 1184 */ 1185 public static boolean nval( final String in,final boolean def ) { 1186 boolean rtn = def; 1187 if( in != null && in.length() != 0 ) { 1188 rtn = "true".equalsIgnoreCase( in ) ; 1189 if( in.length() == 1 ) { rtn = ! "0".equals( in ); } 1190 } 1191 return rtn ; 1192 } 1193 1194 /** 1195 * 引数 in が、null、"_"、ゼロ文字列の場合は、デフォルト値 def を返します。 1196 * 1197 * さらに、メモリ領域を節約する為、intern() の結果を返します。 1198 * 1199 * @og.rev 5.2.2.0 (2010/11/01) "_" の取り扱い変更 1200 * 1201 * @param in 基準となる文字列 1202 * @param def デフォルト文字列 1203 * 1204 * @return null、"_"、ゼロ文字列の場合は、デフォルト文字列を、そうでなければ、入力文字を返す。 1205 */ 1206 public static String nval2( final String in,final String def ) { 1207 return ( in == null || in.length() == 0 || "_".equals( in ) ) ? def : in.intern() ; 1208 } 1209 1210 /** 1211 * 引数 in が、null または、ゼロ文字列の場合は、デフォルト値 def を返します。 1212 * ただし、NULL代替文字(_)は デフォルト値 def2 に置き換えます。 1213 * 1214 * さらに、メモリ領域を節約する為、intern() の結果を返します。 1215 * 1216 * @og.rev 5.2.2.0 (2010/11/01) "_" の取り扱い変更 1217 * 1218 * @param in 基準となる文字列 1219 * @param def デフォルト文字列 1220 * @param def2 NULL代替文字(_)の場合のデフォルト文字列 1221 * 1222 * @return NULL文字列関係の場合は、ゼロ文字列を、そうでなければ、入力文字を返す。 1223 */ 1224 public static String nval2( final String in,final String def,final String def2 ) { 1225 return ( in == null || in.length() == 0 ) ? def : ( "_".equals( in ) ? def2 : in.intern() ) ; 1226 } 1227 1228 /** 1229 * 引数 in が、null または、ゼロ文字列、またはすべて空白文字の場合は、true を返します。 1230 * それ以外は false を返します。 1231 * 1232 * 注意は、オールスペースやタブ文字、改行文字も true になります。 1233 * 1234 * @param in 基準となる文字列 1235 * 1236 * @return NULL文字列関係の場合は、true を、そうでなければ、false を返す。 1237 */ 1238 public static boolean isNull( final String in ) { 1239 if( in == null || in.length() == 0 ) { return true; } 1240 1241 // String.trim().length()==0 の高速版 1242 for( int i=0; i<in.length(); i++ ) { 1243 if( !Character.isWhitespace( in.charAt(i) ) ) { 1244 return false; 1245 } 1246 } 1247 return true; 1248 } 1249 1250 /** 1251 * Throwable の printStackTrace() 結果を文字列に変換して返します。 1252 * 1253 * @param th printStackTraceすべき元のThrowableオブジェクト 1254 * 1255 * @return Throwableの詳細メッセージ( th.printStackTrace() ) 1256 */ 1257 public static String stringStackTrace( final Throwable th ) { 1258 if( th == null ) { return null; } 1259 1260 StringWriter sw = new StringWriter(); 1261 th.printStackTrace( new PrintWriter( sw ) ); 1262 1263 return String.valueOf( sw ); 1264 } 1265 1266 /** 1267 * Throwable の printStackTrace() 結果の内、opengion に関する箇所だけを文字列に変換して返します。 1268 * 1269 * printStackTrace() すると、膨大なメッセージが表示されるため、その中の、"org.opengion" を 1270 * 含む箇所だけを、抜粋します。 1271 * 1272 * @og.rev 5.7.2.0 (2014/01/10) 新規作成 1273 * 1274 * @param th 元のThrowableオブジェクト 1275 * 1276 * @return Throwableの詳細メッセージ( StackTraceElement の抜粋 ) 1277 */ 1278 public static String ogStackTrace( final Throwable th ) { 1279 if( th == null ) { return null; } 1280 1281 StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ); 1282 1283 StackTraceElement[] eles = th.getStackTrace(); 1284 if( eles.length > 0 ) { 1285 rtn.append( " " ).append( eles[0].toString() ).append( CR ); 1286 } 1287 1288 for( int i=1; i<eles.length; i++ ) { 1289 String cls = eles[i].getClassName(); 1290 if( cls.indexOf( "org.opengion" ) >= 0 ) { 1291 rtn.append( " at " ).append( eles[i].toString() ).append( CR ); 1292 } 1293 } 1294 1295 return rtn.toString(); 1296 } 1297 1298 /** 1299 * 大きな浮動小数点数について、カンマ編集を行います。 1300 * 1301 * このメソッドでは、1.23 E12 などの数字は扱いません。通常の 1302 * 数字とピリオドで構成された文字列のみ、変換対象になります。 1303 * (ただし、不正な文字列を与えてもエラーチェックはしていません。) 1304 * minFraction には、少数点部に与える固定値を指定します。入力文字列が 1305 * その桁数より少ない場合は、0埋めします。 1306 * 多い場合でもカットしません。 1307 * minFraction が 0 の場合は、少数点は付きません。 1308 * ".12" などの少数点は、必ず先頭に 0 が付きます。 1309 * 入力文字列が null か、ゼロ文字列時は、そのまま入力データを返します。 1310 * 1311 * <pre> 1312 * DecimalFormat format = new DecimalFormat( "#,##0.00########" ); 1313 * double dd = Double.parseDouble( val ); 1314 * return format.format( dd ); 1315 * </pre> 1316 * に対して、minFraction分の少数以下のゼロの指定と、inに ',' が 1317 * 含まれた処理を追加した感じになります。 1318 * 1319 * @og.rev 4.0.0.0 (2007/10/26) 空白のトリム処理を追加 1320 * 1321 * @param in 変換元の文字列 1322 * @param minFraction 変換時の少数点以下の固定桁数 1323 * 1324 * @return カンマ編集後の数字型文字列 1325 */ 1326 public static String numberFormat( final String in, final int minFraction ) { 1327 if( in == null || in.length() == 0 ) { return in ; } 1328 1329 // 4.0.0.0 (2007/10/26) 1330 String tmp = in.trim(); 1331 1332 if( tmp.length() == 0 ) { return tmp ; } 1333 1334 char[] chs = tmp.toCharArray(); 1335 int pos = 0; 1336 1337 // 整数部の設定 1338 boolean firstZero = true; 1339 StringBuilder buf1 = new StringBuilder(); 1340 while( pos < chs.length ) { 1341 char ch = chs[pos++]; 1342 if( ch == '.' ) { break; } 1343 else if( ch != '-' && ch != ',' && ( ch != '0' || !firstZero )) { 1344 buf1.append( ch ); 1345 firstZero = false; 1346 } 1347 } 1348 if( buf1.length() == 0 ) { 1349 buf1.append( '0' ); 1350 } 1351 1352 for( int i=buf1.length()-3; i>0; i-=3 ) { 1353 buf1.insert( i,',' ); 1354 } 1355 if( chs[0] == '-' ) { buf1.insert( 0,'-' ); } 1356 1357 // 少数部の設定 1358 // 3.6.0.3 (2004/10/05) 桁数が多い場合でもカットしない 1359 StringBuilder buf2 = new StringBuilder(); 1360 while( pos < chs.length ) { 1361 buf2.append( chs[pos++] ); 1362 } 1363 1364 while( buf2.length() < minFraction ) { 1365 buf2.append( '0' ); 1366 } 1367 1368 if( buf2.length() > 0 ) { 1369 buf1.append( '.' ).append( buf2 ); 1370 } 1371 1372 return buf1.toString(); 1373 } 1374 1375 /** 1376 * 識別id に応じた オブジェクトを作成します。 1377 * 作成するには、デフォルトコンストラクターが必要です。 1378 * 1379 * @param cls 作成するクラスのフルネーム 1380 * 1381 * @return オブジェクト 1382 * @throws RuntimeException 何らかのエラーが発生した場合 1383 */ 1384 public static Object newInstance( final String cls ) { 1385 return newInstance( cls,Thread.currentThread().getContextClassLoader() ); 1386 } 1387 1388 /** 1389 * 指定されたクラスローダを使って、識別id に応じた オブジェクトを作成します。 1390 * 作成するには、デフォルトコンストラクターが必要です。 1391 * initialize パラメータは true 相当(それまでに初期化されていない場合だけ初期化)です。 1392 * 1393 * @param cls 作成するクラスのフルネーム 1394 * @param loader 作成するクラスのクラスローダ 1395 * 1396 * @return オブジェクト 1397 * @throws RuntimeException 何らかのエラーが発生した場合 1398 */ 1399 public static Object newInstance( final String cls,final ClassLoader loader ) { 1400 try { 1401 return Class.forName( cls,true,loader ).newInstance(); 1402 } 1403 catch( ClassNotFoundException ex1 ) { 1404 String errMsg = "クラスが見つかりません。class=[" + cls + "]" + CR 1405 + ex1.getMessage() ; 1406 throw new RuntimeException( errMsg,ex1 ); 1407 } 1408 catch( LinkageError ex2 ) { 1409 String errMsg = "リンケージが失敗しました。class=[" + cls + "]" + CR 1410 + ex2.getMessage(); 1411 throw new RuntimeException( errMsg,ex2 ); 1412 } 1413 catch( InstantiationException ex3 ) { 1414 String errMsg = "インスタンスの生成が失敗しました。class=[" + cls + "]" + CR 1415 + ex3.getMessage() ; 1416 throw new RuntimeException( errMsg,ex3 ); 1417 } 1418 catch( IllegalAccessException ex4 ) { 1419 String errMsg = "クラスまたは初期化子にアクセスできません。class=[" + cls + "]" + CR 1420 + ex4.getMessage(); 1421 throw new RuntimeException( errMsg,ex4 ); 1422 } 1423 catch( RuntimeException ex5 ) { // 3.6.0.0 (2004/09/17) 1424 String errMsg = "予期せぬエラー class=[" + cls + "]" + CR 1425 + ex5.getMessage() ; 1426 throw new RuntimeException( errMsg,ex5 ); 1427 } 1428 } 1429 1430 /** 1431 * 指定のURL文字列同士を連結させます。 1432 * そのとき、後方URLが、絶対パスの場合は、連結せず 後方URLを返します。 1433 * 第2引数以降は、絶対パス判定をせず直前のURLの末尾判定のみで連結します。 1434 * 1435 * 絶対パスかどうかは、通常のファイル属性と同様に、先頭が、'/' (UNIX)または、 1436 * 2文字目が、":" (Windows)の場合、または、先頭が "\" (ネットワークパス)で 1437 * 始まる場合で判断します。 1438 * 連結時に、前方URLの末尾に "/" を付加します。 1439 * 1440 * 処理の互換性確保のため、第3引数の可変長引数を追加しています。 1441 * 1442 * @og.rev 5.0.0.1 (2009/08/15) 不要なオブジェクトの生成を抑制する。 1443 * @og.rev 5.6.5.2 (2013/06/21) 第3引数を可変長引数に変更 1444 * 1445 * @param url1 先頭URL文字列 1446 * @param url2 後方URL文字列(絶対パスの場合は、返り値) 1447 * @param urls 後方URL文字列 1448 * 1449 * @return URL文字列同士の連結結果 url1 + url2(url2が絶対パスの場合は、url2から連結開始) 1450 */ 1451 public static String urlAppend( final String url1,final String url2,final String... urls ) { 1452 StringBuilder rtnUrl = new StringBuilder( 200 ); 1453 1454 if( url2 == null || url2.length() == 0 ) { rtnUrl.append( url1 ) ; } 1455 else if( ( url1 == null || url1.length() == 0 ) || 1456 ( url2.charAt(0) == '/' ) || // 実ディレクトリが UNIX 1457 ( url2.length() > 1 && url2.charAt(1) == ':' ) || // 実ディレクトリが Windows 1458 ( url2.charAt(0) == '\\' ) ) { // 実ディレクトリが ネットワークパス 1459 rtnUrl.append( url2 ) ; 1460 } 1461 else { 1462 char ch = url1.charAt( url1.length()-1 ) ; 1463 if( ch == '/' || ch == '\\' ) { 1464 rtnUrl.append( url1 ).append( url2 ) ; 1465 } 1466 else { 1467 rtnUrl.append( url1 ).append( "/" ).append( url2 ) ; 1468 } 1469 } 1470 1471 // ここからが、追加分 1472 for( String url : urls ) { 1473 if( url != null && url.length() > 0 ) { 1474 char ch = rtnUrl.charAt( rtnUrl.length()-1 ) ; 1475 if( ch == '/' || ch == '\\' ) { 1476 rtnUrl.append( url ) ; 1477 } 1478 else { 1479 rtnUrl.append( "/" ).append( url ) ; 1480 } 1481 } 1482 } 1483 1484 return rtnUrl.toString() ; 1485 } 1486 1487 /** 1488 * Unicode文字列の値を HTML のエスケープ記号(&#xZZZZ;)に変換します。 1489 * 1490 * SJIS(JA16SJIS) で作成されたデータベースに、(NVARCHAR2)を使用して中国語等を登録するのは 1491 * 非常に複雑でかつ、リスクが大きい処理になります。 1492 * ORACLE殿でも、自信を持っては勧められない機能とのコメントを頂いています。 1493 * そこで、HTMLでのエスケープ文字を使用して、Unicodeを文字列化して登録する為の 1494 * DBType として、新規に作成します。 1495 * ここでは、入力文字を、キャラクタ(char)型に分解し、(&#xZZZZ;)に変換していきます。 1496 * よって、通常に1文字(Shift-JISで2Byte,UTF-8で3Byte)が、8Byteになります。 1497 * この変換された文字列を、HTML上でそのまま取り出すと、元のUnicode文字に戻る為、 1498 * 通常のShift-JISでは、扱えない文字(中国語など)でも表示可能になります。 1499 * ここでは、2バイト文字のみ、変換しています。 1500 * 1501 * @param value 変換前の文字列 1502 * 1503 * @return HTMLのエスケープ記号(&#xZZZZ;) 1504 */ 1505 public static String getUnicodeEscape( final String value ) { 1506 if( value == null || value.length() == 0 ) { return ""; } 1507 1508 StringBuilder rtn = new StringBuilder( value.length() * 4 ); 1509 1510 for( int i=0; i<value.length(); i++ ) { 1511 char ch = value.charAt(i); 1512 1513 if( ch > 0xff ) { 1514 String hex = Integer.toHexString( (int)ch ) ; 1515 rtn.append( UTF_STR[hex.length()] ).append( hex ).append( ";" ); 1516 } 1517 else { 1518 rtn.append( ch ); 1519 } 1520 } 1521 1522 return rtn.toString(); 1523 } 1524 1525 /** 1526 * HTML のエスケープ記号(&#xZZZZ;)をUnicode文字列に戻します。 1527 * 1528 * HTMLでのエスケープ文字を使用して登録された文字を、Unicodeに戻します。 1529 * (&#xZZZZ;)の8Byteを、もとのキャラクタコードに戻し、合成します。 1530 * ここでは、通常の文字列に混在したエスケープ文字も戻せるようにします。 1531 * 1532 * @param value HTMLのエスケープ記号(&#xZZZZ;)を含む文字列 1533 * 1534 * @og.rev 5.9.5.3 (2016/02/26) 無限ループ対応 1535 * 1536 * @return 通常のUnicode文字列 1537 */ 1538 public static String getReplaceEscape( final String value ) { 1539 if( value == null || value.length() == 0 ) { return ""; } 1540 1541 StringBuilder rtn = new StringBuilder( value ); 1542 1543 int st = rtn.indexOf( "&#" ); 1544 while( st >= 0 ) { 1545 if( st+7 < rtn.length() && rtn.charAt( st+7 ) == ';' ) { 1546 int ch = Integer.parseInt( rtn.substring( st+3,st+7 ),16 ); 1547 rtn.replace( st,st+8, Character.toString( (char)ch ) ); 1548 } 1549// st = rtn.indexOf( "&#",st ); 1550 st = rtn.indexOf( "&#",st + 1 ); // 5.9.5.3 (2016/02/26) 無限ループ対応 1551 } 1552 1553 return rtn.toString(); 1554 } 1555 1556 /** 1557 * 文字列をdoubleに変換します。 1558 * 1559 * これは、Double.parseDouble( value ) と、ほぼ同じ動作を行います。 1560 * 内部的には、引数の カンマ(,) を削除した文字列を、Double.parseDouble( value ) 1561 * に渡します。 1562 * また、引数が、null,ゼロ文字列,'_' の時には、0.0 を返します。 1563 * 1564 * @param value doubleに変換する元の文字列 1565 * 1566 * @return 変換後のdouble数値 1567 */ 1568 public static double parseDouble( final String value ) { 1569 double rtn ; 1570 1571 if( value == null || value.length() == 0 || value.equals( "_" ) ) { 1572 rtn = 0.0d; 1573 } 1574 else if( value.indexOf( ',' ) < 0 ) { 1575 rtn = Double.parseDouble( value ); 1576 } 1577 else { 1578 char[] chs = value.toCharArray() ; 1579 int j=0; 1580 for( int i=0;i<chs.length; i++ ) { 1581 if( chs[i] == ',' ) { continue; } 1582 chs[j] = chs[i]; 1583 j++; 1584 } 1585 rtn = Double.parseDouble( String.valueOf( chs,0,j ) ); 1586 } 1587 1588 return rtn ; 1589 } 1590 1591 /** 1592 * カラーキーワードより、Colorオブジェクトを作成します。 1593 * 1594 * 指定文字列は、java.awt.Color クラスのstatic フィールド名で指定します。 1595 * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY , 1596 * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , PURPLE , TRANSPARENT(透明) が指定できます。 1597 * また、先頭に、# を付ける事で、#XXXXXX形式の16bitRGB表記 でも指定可能です。 1598 * static フィールド名のMapを管理していますが、存在しない場合は、エラーになります。 1599 * 1600 * @og.rev 3.8.9.1 (2007/06/29) 新規作成 1601 * @og.rev 4.1.1.0 (2008/02/04) CLR_MAP に存在しない場合はエラーにします。 1602 * 1603 * @param value java.awt.Color フィールドを示す文字列または、#XXXXXX形式の16bitRGB表記 1604 * 1605 * @return Colorオブジェクト 1606 * @see java.awt.Color#BLACK 1607 */ 1608 public static Color getColorInstance( final String value ) { 1609 final Color clr ; 1610 1611 if( value.startsWith("#") ) { 1612 int code = Integer.parseInt( value.substring(1),16 ); 1613 clr = new Color( code ); 1614 } 1615 else { 1616 clr = CLR_MAP.get( value ); 1617 if( clr == null ) { 1618 String errMsg = "指定の色コードは使用できません Color=[" + value + "]" + CR 1619 + "ColorMap=" + CLR_MAP.keySet().toString(); 1620 throw new RuntimeException( errMsg ); 1621 } 1622 } 1623 1624 return clr; 1625 } 1626 1627 /** 1628 * 引数からspanタグを取り除いて返します。 1629 * 1630 * 引数が、<span ・・・>XXXX</span>形式の場合、XXXX のみ出力します。 1631 * 1632 * @og.rev 4.3.4.3 (2008/12/22) TableWriterで利用していたものを移動 1633 * @og.rev 5.9.11.1 (2016/08/10) spanだけでなく、pre,textareaも除外するようにしておく 1634 * 1635 * @param data 元のString文字列 1636 * 1637 * @return spanタグが取り除かれた文字列 1638 */ 1639 public static String spanCut( final String data ) { 1640 String rtn = data; 1641 if( data != null ){ 1642 if( data.startsWith( "<span" ) ) { 1643 int st = data.indexOf( '>' ); 1644 int ed = data.indexOf( "</span>",st ); 1645 rtn = data.substring( st+1,ed ); 1646 } 1647 else if( data.startsWith( "<pre" ) ) { // 5.9.11.1 本来はV6のようにするべきだが、V5は暫定的な対応にしておく 1648 int st = data.indexOf( '>' ); 1649 int ed = data.indexOf( "</pre>",st ); 1650 rtn = data.substring( st+1,ed ); 1651 } 1652 else if( data.startsWith( "<textarea" ) ) { 1653 int st = data.indexOf( '>' ); 1654 int ed = data.indexOf( "</textarea>",st ); 1655 rtn = data.substring( st+1,ed ); 1656 } 1657 } 1658 1659 return rtn ; 1660 } 1661 1662 /** 1663 * 簡易CSS形式のフォーマットを、Mapにセットします。 1664 * 1665 * 簡易CSS形式とは、セレクタのない、{ プロパティ1 : 値1 ; ・・・ } 形式とします。 1666 * これを、プロパティ1 と 値1 のMap にセットする処理を行います。 1667 * コメントは、削除されます。また、同一プロパティが記述されている場合は、後処理を採用します。 1668 * 1669 * なお、入力テキストが、null か、{…} が存在しない場合は、null を返します。 1670 * 1671 * @og.rev 5.6.5.2 (2013/06/21) 新規追加 1672 * 1673 * @param cssText 簡易CSS形式のフォーマット文字列 1674 * 1675 * @return パース結果のMap 1676 */ 1677 public static Map<String,String> cssParse( final String cssText ) { 1678 Map<String,String> map = null; 1679 1680 if( cssText != null ) { 1681 // まずコメントを削除します。 1682 StringBuilder buf = new StringBuilder( cssText ); 1683 1684 int ad1 = buf.indexOf( "/*" ); 1685 while( ad1 >= 0 ) { 1686 int ad2 = buf.indexOf( "*/" , ad1 ); 1687 if( ad2 < 0 ) { buf = buf.delete( ad1,buf.length() ); break; } // 閉じてなければ以降を全削除 1688 buf = buf.delete( ad1,ad2+2 ); 1689 ad1 = buf.indexOf( "/*" ); // コメントは削除されたので、初めから検索する。 1690 } 1691 1692 // 処理対象は、{ 〜 } の間の文字列。 1693 ad1 = buf.indexOf( "{" ); 1694 int ad2 = buf.indexOf( "}",ad1 ); 1695 if( ad1 >= 0 && ad2 > 0 ) { 1696 String tempText = buf.substring( ad1+1,ad2 ); // これが処理対象の文字列 1697 1698 String[] recode = tempText.split( ";" ); // KEY1 : VAL1; の ; で分割する。 1699 1700 for( int i=0; i<recode.length; i++ ) { 1701 int ad = recode[i].indexOf( ':' ); 1702 if( ad > 0 ) { 1703 String key = recode[i].substring( 0,ad ).trim(); 1704 String val = recode[i].substring( ad+1 ).trim(); 1705 if( key.isEmpty() || val.isEmpty() ) { continue; } 1706 1707 if( map == null ) { map = new HashMap<String,String>(); } // 対象データがある時だけMapを作りたかったので。 1708 map.put( key,val ); 1709 } 1710 } 1711 } 1712 } 1713 return map ; 1714 } 1715 1716 /** 1717 * 引数から空白文字を削除して返します。 1718 * 1719 * 1720 * @og.rev 5.6.9.4 (2013/10/31) TableWriterで利用していたものを移動 1721 * 1722 * @param data 元のString文字列 1723 * 1724 * @return 空白文字が取り除かれた文字列 1725 */ 1726 public static String deleteWhitespace( final String data ) { 1727 if( data == null || data.length() == 0 ){ 1728 return data; 1729 } 1730 return data.replaceAll( "\\s", "" ) ; 1731 } 1732 1733 /** 1734 * 引数から指定文字の分のバイト数で切った文字列を返します。 1735 * 文字列のバイト数は指定のエンコードでカウントします。 1736 * (文字の途中で切れる事はありません) 1737 * 1738 * 1739 * @og.rev 5.9.1.3 (2015/10/30) 新規作成 1740 * 1741 * @param org 元のString文字列 1742 * @param cutBytes 切るバイト数 1743 * @param enc 文字列のエンコード 1744 * 1745 * @return バイト数で切った文字列 1746 */ 1747 public static String cut( String org, int cutBytes, String enc ) { 1748 try { 1749 if ( org == null || org.length() == 0 || cutBytes <= 0 || org.getBytes(enc).length <= cutBytes ) { 1750 return org; 1751 } 1752 1753 StringBuilder cutSb = new StringBuilder(); 1754 StringBuilder tmpSb = new StringBuilder(); 1755 1756 for (int i = 0; i < org.length(); i++) { 1757 String cut = org.substring(i, i + 1); 1758 if (cutBytes < tmpSb.toString().getBytes(enc).length + cut.getBytes(enc).length) { 1759 cutSb.append(tmpSb.toString()); 1760 break; 1761 } 1762 tmpSb.append(cut); 1763 } 1764 return cutSb.toString(); 1765 1766 } 1767 catch (UnsupportedEncodingException e) { 1768 e.printStackTrace(); 1769 return org; 1770 } 1771 } 1772 1773 /** 1774 * 引数から指定文字の分のバイト数で切った文字列を返します。 1775 * バイト数のカウントはUTF-8として行います。 1776 * 1777 * 1778 * @og.rev 5.9.1.3 (2015/10/30) 新規作成 1779 * 1780 * @param org 元のString文字列 1781 * @param cutBytes 切るバイト数 1782 * 1783 * @return バイト数で切った文字列 1784 */ 1785 public static String cut( String org, int cutBytes ) { 1786 return cut( org, cutBytes, "UTF-8"); 1787 } 1788}