1 7 8 13 14 package com.ibm.icu.impl; 15 16 import java.io.InputStream ; 17 import java.io.InputStreamReader ; 18 import java.io.IOException ; 19 import java.io.UnsupportedEncodingException ; 20 import java.util.ArrayList ; 21 import java.util.ListResourceBundle ; 22 import java.util.Locale ; 23 import java.util.ResourceBundle ; 24 import java.util.MissingResourceException ; 25 import java.util.Hashtable ; 26 27 public class ICUListResourceBundle extends ListResourceBundle { 28 private static final String ICUDATA = "ICUDATA"; 29 private static final String ICU_BUNDLE_NAME = "LocaleElements"; 30 private static final String ICU_PACKAGE_NAME ="com.ibm.icu.impl.data"; 31 private static final String ENCODING="UTF-8"; 32 33 Locale icuLocale; 34 void setParentX(ResourceBundle b) { 35 setParent(b); 36 } 37 38 public Locale getLocale() { 39 return icuLocale; 40 } 41 42 protected ICUListResourceBundle() { 43 } 44 45 private Hashtable visited = new Hashtable (); 46 49 protected Object [][] contents; 50 51 54 private Object [][] realContents; 55 56 59 protected Object [][] getContents(){ 60 if (realContents == null) { 62 realContents = contents; 63 for (int i = 0; i < contents.length; ++i) { 64 Object newValue = getRedirectedResource((String )contents[i][0],contents[i][1], -1); 65 if (newValue != null) { 66 if (realContents == contents) { 67 realContents = (Object [][])contents.clone(); 68 } 69 realContents[i] = new Object [] { contents[i][0], newValue }; 70 } 71 } 72 } 73 return realContents; 74 } 75 76 80 private Object getRedirectedResource(String key, Object value, int index) { 81 82 if (value instanceof Object [][]) { 83 Object [][] aValue = (Object [][])value; 84 int i=0; 85 while(i < aValue.length){ 86 int j=0; 87 while(j < aValue[i].length){ 88 aValue[i][j] = getRedirectedResource((String )aValue[i][0],aValue[i][j], i); 89 j++; 90 } 91 i++; 92 } 93 }else if (value instanceof Object []){ 94 Object [] aValue = (Object []) value; 95 int i=0; 96 while( i < aValue.length){ 97 aValue[i] = getRedirectedResource(key,aValue[i], i); 98 i++; 99 } 100 }else if(value instanceof Alias){ 101 102 String cName = this.getClass().getName(); 103 visited.clear(); 104 visited.put(cName+key,""); 105 return ((Alias)value).getResource(cName,key,index, visited); 106 }else if(value instanceof RedirectedResource){ 107 return ((RedirectedResource)value).getResource(this); 108 } 109 110 return value; 111 } 112 113 private static byte[] readToEOS(InputStream stream) { 114 try { 118 ArrayList vec = new ArrayList (); 119 int count = 0; 120 int length = 0x200; final int MAXLENGTH = 0x8000; 122 int pos = -1; 123 for (;;) { 124 byte[] buffer = new byte[length]; 125 pos = 0; 126 do { 127 int n = stream.read(buffer, pos, length - pos); 128 if (n == -1) { 129 break; 130 } 131 pos += n; 132 } while (pos < length); 133 count += pos; 134 vec.add(buffer); 135 if (pos < length) { 136 break; 137 } 138 if (length < MAXLENGTH) { 139 length <<= 1; 140 } 141 } 142 143 145 byte[] data = new byte[count]; 146 pos = 0; 147 for (int i = 0; i < vec.size(); ++i) { 148 byte[] buf = (byte[])vec.get(i); 149 int len = Math.min(buf.length, count - pos); 150 System.arraycopy(buf, 0, data, pos, len); 151 pos += len; 152 } 153 return data; 155 } catch (IOException e) { 156 throw new MissingResourceException (e.getMessage(),"",""); 157 } 158 } 159 160 private static char[] readToEOS(InputStreamReader stream) { 161 try { 166 int length = 0x10000; final int MAXLENGTH = 0x40000000; 168 int n; 169 char[] buffer; 170 for (;;) { 171 buffer = new char[length]; 172 n = stream.read(buffer, 0, length); 173 if (n >= 0 && n < length) { 174 break; 175 } 176 if (length < MAXLENGTH) { 177 stream.reset(); 178 length <<= 1; 179 } else { 180 throw new IllegalStateException ("maximum input stream length exceeded"); 181 } 182 } 183 184 186 char[] data = new char[n]; 187 System.arraycopy(buffer, 0, data, 0, n); 188 return data; 189 } catch (IOException e) { 190 throw new MissingResourceException (e.getMessage(),"",""); 191 } 192 } 193 211 public static class CompressedBinary implements RedirectedResource{ 212 private byte[] expanded=null; 213 private String compressed=null; 214 public CompressedBinary(String str){ 215 compressed = str; 216 } 217 public Object getResource(Object obj){ 218 if(compressed==null){ 219 return new byte[0]; 220 } 221 222 if(expanded==null){ 223 expanded= Utility.RLEStringToByteArray(compressed); 224 } 225 return expanded ==null ? new byte[0]: expanded; 226 } 227 228 } 229 private interface RedirectedResource{ 230 public Object getResource(Object obj); 231 } 232 233 public static class ResourceBinary implements RedirectedResource{ 234 private byte[] expanded=null; 235 private String resName=null; 236 public ResourceBinary(String name){ 237 resName="data/" + name; 238 } 239 public Object getResource(Object obj) { 240 if(expanded==null){ 241 InputStream stream = ICUData.getStream(resName); 242 if(stream!=null){ 243 expanded = readToEOS(stream); 245 return expanded; 246 } 247 } 248 return ""; 249 } 250 } 251 252 public static class ResourceString implements RedirectedResource{ 253 private char[] expanded=null; 254 private String resName=null; 255 public ResourceString(String name){ 256 resName="data/"+name; 257 } 258 public Object getResource(Object obj) { 259 if(expanded==null){ 260 InputStream stream = ICUData.getStream(resName); 262 if(stream!=null){ 263 265 try{ 266 InputStreamReader reader = new InputStreamReader (stream,ENCODING); 267 expanded = readToEOS(reader); 268 }catch(UnsupportedEncodingException ex){ 269 throw new RuntimeException ("Could open converter for encoding: " +ENCODING); 270 } 271 return new String (expanded); 272 } 273 274 } 275 return ""; 276 } 277 } 278 279 private static final char RES_PATH_SEP_CHAR = '/'; 280 281 public static class Alias{ 282 public Alias(String path){ 283 pathToResource = path; 284 } 285 286 private String pathToResource; 287 288 private Object getResource(String className, String parentKey, int index, Hashtable visited){ 289 String packageName=null,bundleName=null, locale=null, keyPath=null; 290 291 if(pathToResource.indexOf(RES_PATH_SEP_CHAR)==0){ 292 int i =pathToResource.indexOf(RES_PATH_SEP_CHAR,1); 293 int j =pathToResource.indexOf(RES_PATH_SEP_CHAR,i+1); 294 bundleName=pathToResource.substring(1,i); 295 locale=pathToResource.substring(i+1); 296 if(j!=-1){ 297 locale=pathToResource.substring(i+1,j); 298 keyPath=pathToResource.substring(j+1,pathToResource.length()); 299 } 300 if(bundleName.equals(ICUDATA)){ 302 bundleName = ICU_BUNDLE_NAME; 303 packageName = ICU_PACKAGE_NAME; 304 } 305 306 }else{ 307 int i =pathToResource.indexOf(RES_PATH_SEP_CHAR); 309 int j = className.lastIndexOf("."); 313 packageName=className.substring(0,j); 314 int underScoreIndex = className.indexOf("_"); 315 if(underScoreIndex>=0){ 316 bundleName=className.substring(j+1,className.indexOf("_")); 317 }else{ 318 bundleName = className.substring(j+1,className.length()); 319 } 320 keyPath=pathToResource.substring(i+1); 321 322 if(i!=-1){ 323 locale = pathToResource.substring(0,i); 324 }else{ 325 locale=keyPath; 326 keyPath=parentKey; 327 if(locale==null || locale.equals("root")){ 328 className=packageName+"."+bundleName; 329 }else{ 330 className=packageName+"."+bundleName+"_"+ locale; 331 } 332 333 } 334 335 } 336 337 ResourceBundle bundle = null; 338 if(locale==null || locale.equals("root")){ 341 bundle = ICULocaleData.getResourceBundle(packageName,bundleName,""); 342 }else{ 343 bundle = ICULocaleData.getResourceBundle(packageName,bundleName,locale); 344 } 345 346 return findResource(bundle, className, parentKey, index, keyPath, visited); 347 348 } 349 350 private Object findResource(Object [][] contents, String key){ 351 for (int i = 0; i < contents.length; ++i) { 352 String tempKey = (String ) contents[i][0]; 354 Object value = contents[i][1]; 355 if (tempKey == null || value == null) { 356 throw new NullPointerException (); 357 } 358 if(tempKey.equals(key)){ 359 return value; 360 } 361 } 362 return null; 363 } 364 365 private Object findResource(Object o , String [] keys, int start, int index){ 366 Object obj = o; 367 if( start < keys.length && keys[start] !=null){ 368 if(obj instanceof Object [][]){ 369 obj = findResource((Object [][])obj,keys[start]); 370 }else if(obj instanceof Object [] && isIndex(keys[start])){ 371 obj = ((Object [])obj)[getIndex(keys[start])]; 372 } 373 if(start+1 < keys.length && keys[start+1] !=null){ 374 obj = findResource(obj,keys,start+1, index); 375 } 376 }else{ 377 if(index>=0){ 379 if(obj instanceof Object [][]){ 380 obj = findResource((Object [][])obj,Integer.toString(index)); 381 }else if(obj instanceof Object []){ 382 obj = ((Object [])obj)[index]; 383 } 384 } 385 } 386 return obj; 387 } 388 private Object findResource(ResourceBundle bundle, String className, String requestedKey, int index, String aliasKey, Hashtable visited){ 389 390 if(aliasKey != null && visited.get(className+aliasKey)!=null){ 391 throw new MissingResourceException ("Circular Aliases in bundle.",bundle.getClass().getName(),requestedKey); 392 } 393 if(aliasKey==null){ 394 aliasKey = requestedKey; 397 } 398 399 visited.put(className+requestedKey,""); 400 401 String [] keys = split(aliasKey,RES_PATH_SEP_CHAR); 402 Object o =null; 403 if(keys.length>0){ 404 o = bundle.getObject(keys[0]); 405 o = findResource(o, keys, 1, index); 406 } 407 o=resolveAliases(o,className,aliasKey,visited); 408 return o; 409 } 410 private Object resolveAliases(Object o,String className,String key, Hashtable visited){ 411 if(o instanceof Object [][]){ 412 o = resolveAliases((Object [][])o,className,key, visited); 413 }else if(o instanceof Object []){ 414 o = resolveAliases((Object [])o,className,key, visited); 415 }else if(o instanceof Alias){ 416 return ((Alias)o).getResource(className,key, -1, visited); 417 } 418 return o; 419 } 420 private Object resolveAliases(Object [][] o,String className, String key,Hashtable visited){ 421 int i =0; 422 while(i<o.length){ 423 o[i][1]=resolveAliases(o[i][1],className,key,visited); 424 i++; 425 } 426 return o; 427 } 428 private Object resolveAliases(Object [] o,String className, String key,Hashtable visited){ 429 int i =0; 430 while(i<o.length){ 431 o[i]=resolveAliases(o[i],className,key,visited); 432 i++; 433 } 434 return o; 435 } 436 437 438 } 439 private static String [] split(String source, char delimiter){ 440 441 char[] src = source.toCharArray(); 442 int index = 0; 443 int numdelimit=0; 444 for(int i=0;i<source.length();i++){ 446 if(src[i]==delimiter){ 447 numdelimit++; 448 } 449 } 450 String [] values =null; 451 values = new String [numdelimit+2]; 452 int old=0; 454 for(int j=0;j<src.length;j++){ 455 if(src[j]==delimiter){ 456 values[index++] = new String (src,old,j-old); 457 old=j+1; 458 } 459 } 460 if(old <src.length) 461 values[index++]=new String (src,old,src.length-old); 462 return values; 463 } 464 465 486 public final Object getObjectWithFallback(String path) 487 throws MissingResourceException { 488 String [] keys = split(path, RES_PATH_SEP_CHAR); 489 Object result = null; 490 ICUListResourceBundle actualBundle = this; 491 492 493 result = findResourceWithFallback(keys, actualBundle); 495 496 if(result == null){ 497 throw new MissingResourceException ("Could not find the resource in ",this.getClass().getName(),path); 498 } 499 return result; 500 } 501 502 503 private Object findResourceWithFallback(String [] keys, 504 ICUListResourceBundle actualBundle){ 505 506 Object obj = null; 507 508 while(actualBundle != null){ 509 obj = actualBundle.getObject(keys[0], actualBundle); 513 514 obj = findResourceWithFallback(obj, keys, 1, 0); 518 if(obj != null){ 520 break; 521 } 522 actualBundle = (ICUListResourceBundle) actualBundle.parent; 524 525 } 526 527 return obj; 528 } 529 private Object findResourceWithFallback(Object o , String [] keys, int start, 530 int index){ 531 Object obj = o; 532 533 534 if( start < keys.length && keys[start] !=null){ 535 if(obj instanceof Object [][]){ 536 obj = findResourceWithFallback((Object [][])obj,keys[start]); 537 }else if(obj instanceof Object [] && isIndex(keys[start])){ 538 obj = ((Object [])obj)[getIndex(keys[start])]; 539 } 540 if(start+1 < keys.length && keys[start+1] !=null){ 541 obj = findResourceWithFallback(obj,keys,start+1, index); 542 } 543 }else{ 544 if(index>=0){ 546 if(obj instanceof Object [][]){ 547 obj = findResourceWithFallback((Object [][])obj, 548 Integer.toString(index)); 549 }else if(obj instanceof Object []){ 550 obj = ((Object [])obj)[index]; 551 } 552 } 553 } 554 555 return obj; 556 } 557 558 private Object findResourceWithFallback(Object [][] cnts, String key){ 559 Object obj = null; 560 561 for (int i = 0; i < cnts.length; ++i) { 562 String tempKey = (String ) cnts[i][0]; 564 obj = cnts[i][1]; 565 if(tempKey != null && tempKey.equals(key)){ 566 return obj; 567 } 568 } 569 570 return null; 571 } 572 573 private final Object getObject(String key, 574 ICUListResourceBundle actualBundle) { 575 Object obj = handleGetObject(key); 576 if (obj == null) { 577 ICUListResourceBundle p = (ICUListResourceBundle) this.parent; 578 while( p!=null){ 579 obj = p.handleGetObject(key); 580 if(obj != null){ 581 actualBundle = p; 582 break; 583 } 584 p = (ICUListResourceBundle) p.parent; 585 } 586 } 587 return obj; 588 } 589 private static boolean isIndex(String s){ 590 if(s.length()==1){ 591 char c = s.charAt(0); 592 return Character.isDigit(c); 593 } 594 return false; 595 } 596 private static int getIndex(String s){ 597 if(s.length()==1){ 598 char c = s.charAt(0); 599 if(Character.isDigit(c)){ 600 return Integer.valueOf(s).intValue(); 601 } 602 } 603 return -1; 604 } 605 } 606 607 | Popular Tags |