1 7 8 package java.lang; 9 10 import java.text.BreakIterator ; 11 import java.util.HashSet ; 12 import java.util.Hashtable ; 13 import java.util.Iterator ; 14 import java.util.Locale ; 15 import sun.text.Normalizer; 16 17 18 29 final class ConditionalSpecialCasing { 30 31 final static int FINAL_CASED = 1; 33 final static int AFTER_SOFT_DOTTED = 2; 34 final static int MORE_ABOVE = 3; 35 final static int AFTER_I = 4; 36 final static int NOT_BEFORE_DOT = 5; 37 38 final static int COMBINING_CLASS_ABOVE = 230; 40 41 static Entry[] entry = { 43 new Entry(0x03A3, new char[]{0x03C2}, new char[]{0x03A3}, null, FINAL_CASED), 48 new Entry(0x0307, new char[]{0x0307}, new char[]{}, "lt", AFTER_SOFT_DOTTED), new Entry(0x0049, new char[]{0x0069, 0x0307}, new char[]{0x0049}, "lt", MORE_ABOVE), new Entry(0x004A, new char[]{0x006A, 0x0307}, new char[]{0x004A}, "lt", MORE_ABOVE), new Entry(0x012E, new char[]{0x012F, 0x0307}, new char[]{0x012E}, "lt", MORE_ABOVE), new Entry(0x00CC, new char[]{0x0069, 0x0307, 0x0300}, new char[]{0x00CC}, "lt", 0), new Entry(0x00CD, new char[]{0x0069, 0x0307, 0x0301}, new char[]{0x00CD}, "lt", 0), new Entry(0x0128, new char[]{0x0069, 0x0307, 0x0303}, new char[]{0x0128}, "lt", 0), 60 new Entry(0x0307, new char[]{}, new char[]{0x0307}, "tr", AFTER_I), new Entry(0x0307, new char[]{}, new char[]{0x0307}, "az", AFTER_I), new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "tr", NOT_BEFORE_DOT), new Entry(0x0049, new char[]{0x0131}, new char[]{0x0049}, "az", NOT_BEFORE_DOT), new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "tr", 0), new Entry(0x0069, new char[]{0x0069}, new char[]{0x0130}, "az", 0) }; 71 72 static Hashtable entryTable = new Hashtable (); 74 static { 75 for (int i = 0; i < entry.length; i ++) { 77 Entry cur = entry[i]; 78 Integer cp = new Integer (cur.getCodePoint()); 79 HashSet set = (HashSet )entryTable.get(cp); 80 if (set == null) { 81 set = new HashSet (); 82 } 83 set.add(cur); 84 entryTable.put(cp, set); 85 } 86 } 87 88 static int toLowerCaseEx(String src, int index, Locale locale) { 89 char[] result = lookUpTable(src, index, locale, true); 90 91 if (result != null) { 92 if (result.length == 1) { 93 return result[0]; 94 } else { 95 return Character.ERROR; 96 } 97 } else { 98 return Character.toLowerCase(src.codePointAt(index)); 100 } 101 } 102 103 static int toUpperCaseEx(String src, int index, Locale locale) { 104 char[] result = lookUpTable(src, index, locale, false); 105 106 if (result != null) { 107 if (result.length == 1) { 108 return result[0]; 109 } else { 110 return Character.ERROR; 111 } 112 } else { 113 return Character.toUpperCaseEx(src.codePointAt(index)); 115 } 116 } 117 118 static char[] toLowerCaseCharArray(String src, int index, Locale locale) { 119 return lookUpTable(src, index, locale, true); 120 } 121 122 static char[] toUpperCaseCharArray(String src, int index, Locale locale) { 123 char[] result = lookUpTable(src, index, locale, false); 124 if (result != null) { 125 return result; 126 } else { 127 return Character.toUpperCaseCharArray(src.codePointAt(index)); 128 } 129 } 130 131 private static char[] lookUpTable(String src, int index, Locale locale, boolean bLowerCasing) { 132 HashSet set = (HashSet )entryTable.get(new Integer (src.codePointAt(index))); 133 134 if (set != null) { 135 Iterator iter = set.iterator(); 136 String currentLang = locale.getLanguage(); 137 while (iter.hasNext()) { 138 Entry entry = (Entry)iter.next(); 139 String conditionLang= entry.getLanguage(); 140 if (((conditionLang == null) || (conditionLang.equals(currentLang))) && 141 isConditionMet(src, index, locale, entry.getCondition())) { 142 return (bLowerCasing ? entry.getLowerCase() : entry.getUpperCase()); 143 } 144 } 145 } 146 147 return null; 148 } 149 150 private static boolean isConditionMet(String src, int index, Locale locale, int condition) { 151 switch (condition) { 152 case FINAL_CASED: 153 return isFinalCased(src, index, locale); 154 155 case AFTER_SOFT_DOTTED: 156 return isAfterSoftDotted(src, index); 157 158 case MORE_ABOVE: 159 return isMoreAbove(src, index); 160 161 case AFTER_I: 162 return isAfterI(src, index); 163 164 case NOT_BEFORE_DOT: 165 return !isBeforeDot(src, index); 166 167 default: 168 return true; 169 } 170 } 171 172 182 private static boolean isFinalCased(String src, int index, Locale locale) { 183 BreakIterator wordBoundary = BreakIterator.getWordInstance(locale); 184 wordBoundary.setText(src); 185 int ch; 186 187 for (int i = index; (i >= 0) && !wordBoundary.isBoundary(i); 189 i -= Character.charCount(ch)) { 190 191 ch = src.codePointBefore(i); 192 if (isCased(ch)) { 193 194 int len = src.length(); 195 for (i = index + Character.charCount(src.codePointAt(index)); 197 (i < len) && !wordBoundary.isBoundary(i); 198 i += Character.charCount(ch)) { 199 200 ch = src.codePointAt(i); 201 if (isCased(ch)) { 202 return false; 203 } 204 } 205 206 return true; 207 } 208 } 209 210 return false; 211 } 212 213 222 private static boolean isAfterI(String src, int index) { 223 int ch; 224 int cc; 225 226 for (int i = index; i > 0; i -= Character.charCount(ch)) { 228 229 ch = src.codePointBefore(i); 230 231 if (ch == 'I') { 232 return true; 233 } else { 234 cc = Normalizer.getClass(ch); 235 if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) { 236 return false; 237 } 238 } 239 } 240 241 return false; 242 } 243 244 254 private static boolean isAfterSoftDotted(String src, int index) { 255 int ch; 256 int cc; 257 258 for (int i = index; i > 0; i -= Character.charCount(ch)) { 260 261 ch = src.codePointBefore(i); 262 263 if (isSoftDotted(ch)) { 264 return true; 265 } else { 266 cc = Normalizer.getClass(ch); 267 if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) { 268 return false; 269 } 270 } 271 } 272 273 return false; 274 } 275 276 285 private static boolean isMoreAbove(String src, int index) { 286 int ch; 287 int cc; 288 int len = src.length(); 289 290 for (int i = index + Character.charCount(src.codePointAt(index)); 292 i < len; i += Character.charCount(ch)) { 293 294 ch = src.codePointAt(i); 295 cc = Normalizer.getClass(ch); 296 297 if (cc == COMBINING_CLASS_ABOVE) { 298 return true; 299 } else if (cc == 0) { 300 return false; 301 } 302 } 303 304 return false; 305 } 306 307 318 private static boolean isBeforeDot(String src, int index) { 319 int ch; 320 int cc; 321 int len = src.length(); 322 323 for (int i = index + Character.charCount(src.codePointAt(index)); 325 i < len; i += Character.charCount(ch)) { 326 327 ch = src.codePointAt(i); 328 329 if (ch == '\u0307') { 330 return true; 331 } else { 332 cc = Normalizer.getClass(ch); 333 if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE)) { 334 return false; 335 } 336 } 337 } 338 339 return false; 340 } 341 342 352 private static boolean isCased(int ch) { 353 int type = Character.getType(ch); 354 if (type == Character.LOWERCASE_LETTER || 355 type == Character.UPPERCASE_LETTER || 356 type == Character.TITLECASE_LETTER) { 357 return true; 358 } else { 359 if ((ch >= 0x02B0) && (ch <= 0x02B8)) { 362 return true; 364 } else if ((ch >= 0x02C0) && (ch <= 0x02C1)) { 365 return true; 367 } else if ((ch >= 0x02E0) && (ch <= 0x02E4)) { 368 return true; 370 } else if (ch == 0x0345) { 371 return true; 373 } else if (ch == 0x037A) { 374 return true; 376 } else if ((ch >= 0x1D2C) && (ch <= 0x1D61)) { 377 return true; 379 } else if ((ch >= 0x2160) && (ch <= 0x217F)) { 380 return true; 383 } else if ((ch >= 0x24B6) && (ch <= 0x24E9)) { 384 return true; 387 } else { 388 return false; 389 } 390 } 391 } 392 393 private static boolean isSoftDotted(int ch) { 394 switch (ch) { 395 case 0x0069: case 0x006A: case 0x012F: case 0x0268: case 0x0456: case 0x0458: case 0x1D62: case 0x1E2D: case 0x1ECB: case 0x2071: return true; 406 default: 407 return false; 408 } 409 } 410 411 414 static class Entry { 415 int ch; 416 char [] lower; 417 char [] upper; 418 String lang; 419 int condition; 420 421 Entry(int ch, char[] lower, char[] upper, String lang, int condition) { 422 this.ch = ch; 423 this.lower = lower; 424 this.upper = upper; 425 this.lang = lang; 426 this.condition = condition; 427 } 428 429 int getCodePoint() { 430 return ch; 431 } 432 433 char[] getLowerCase() { 434 return lower; 435 } 436 437 char[] getUpperCase() { 438 return upper; 439 } 440 441 String getLanguage() { 442 return lang; 443 } 444 445 int getCondition() { 446 return condition; 447 } 448 } 449 } 450 | Popular Tags |