1 7 8 20 21 package java.text; 22 23 import java.util.Vector ; 24 import sun.text.UCompactIntArray; 25 import sun.text.IntHashtable; 26 import sun.text.Normalizer; 27 import sun.text.NormalizerImpl; 28 import sun.text.ComposedCharIter; 29 import sun.text.NormalizerUtilities; 30 31 46 final class RBTableBuilder { 47 48 public RBTableBuilder(RBCollationTables.BuildAPI tables) { 49 this.tables = tables; 50 } 51 52 60 61 public void build(String pattern, int decmp) throws ParseException 62 { 63 boolean isSource = true; 64 int i = 0; 65 String expChars; 66 String groupChars; 67 if (pattern.length() == 0) 68 throw new ParseException ("Build rules empty.", 0); 69 70 mapping = new UCompactIntArray((int)RBCollationTables.UNMAPPED); 72 90 pattern = NormalizerImpl.canonicalDecomposeWithSingleQuotation(pattern); 91 92 100 mPattern = new MergeCollation (pattern); 101 102 int order = 0; 103 104 for (i = 0; i < mPattern.getCount(); ++i) 106 { 107 PatternEntry entry = mPattern.getItemAt(i); 108 if (entry != null) { 109 groupChars = entry.getChars(); 110 if (groupChars.length() > 1) { 111 switch(groupChars.charAt(groupChars.length()-1)) { 112 case '@': 113 frenchSec = true; 114 groupChars = groupChars.substring(0, groupChars.length()-1); 115 break; 116 case '!': 117 seAsianSwapping = true; 118 groupChars = groupChars.substring(0, groupChars.length()-1); 119 break; 120 } 121 } 122 123 order = increment(entry.getStrength(), order); 124 expChars = entry.getExtension(); 125 126 if (expChars.length() != 0) { 127 addExpandOrder(groupChars, expChars, order); 128 } else if (groupChars.length() > 1) { 129 char ch = groupChars.charAt(0); 130 if (Character.isHighSurrogate(ch) && groupChars.length() == 2) { 131 addOrder(Character.toCodePoint(ch, groupChars.charAt(1)), order); 132 } else { 133 addContractOrder(groupChars, order); 134 } 135 } else { 136 char ch = groupChars.charAt(0); 137 addOrder(ch, order); 138 } 139 } 140 } 141 addComposedChars(); 142 143 commit(); 144 mapping.compact(); 145 154 tables.fillInTables(frenchSec, seAsianSwapping, mapping, contractTable, expandTable, 155 contractFlags, maxSecOrder, maxTerOrder); 156 } 157 158 161 private void addComposedChars() throws ParseException { 162 ComposedCharIter iter = new ComposedCharIter(); 164 int c; 165 while ((c = iter.next()) != ComposedCharIter.DONE) { 166 if (getCharOrder(c) == RBCollationTables.UNMAPPED) { 167 String s = iter.decomposition(); 184 185 if (s.length() == 1) { 193 int order = getCharOrder(s.charAt(0)); 194 if (order != RBCollationTables.UNMAPPED) { 195 addOrder(c, order); 196 } 197 continue; 198 } else if (s.length() == 2) { 199 char ch0 = s.charAt(0); 200 if (Character.isHighSurrogate(ch0)) { 201 int order = getCharOrder(s.codePointAt(0)); 202 if (order != RBCollationTables.UNMAPPED) { 203 addOrder(c, order); 204 } 205 continue; 206 } 207 } 208 int contractOrder = getContractOrder(s); 209 if (contractOrder != RBCollationTables.UNMAPPED) { 210 addOrder(c, contractOrder); 211 } else { 212 boolean allThere = true; 219 for (int i = 0; i < s.length(); i++) { 220 if (getCharOrder(s.charAt(i)) == RBCollationTables.UNMAPPED) { 221 allThere = false; 222 break; 223 } 224 } 225 if (allThere) { 226 addExpandOrder(c, s, RBCollationTables.UNMAPPED); 227 } 228 } 229 } 230 } 231 } 232 233 245 private final void commit() 246 { 247 if (expandTable != null) { 248 for (int i = 0; i < expandTable.size(); i++) { 249 int[] valueList = (int [])expandTable.elementAt(i); 250 for (int j = 0; j < valueList.length; j++) { 251 int order = valueList[j]; 252 if (order < RBCollationTables.EXPANDCHARINDEX && order > CHARINDEX) { 253 int ch = order - CHARINDEX; 255 256 int realValue = getCharOrder(ch); 258 259 if (realValue == RBCollationTables.UNMAPPED) { 260 valueList[j] = IGNORABLEMASK & ch; 262 } else { 263 valueList[j] = realValue; 265 } 266 } 267 } 268 } 269 } 270 } 271 274 private final int increment(int aStrength, int lastValue) 275 { 276 switch(aStrength) 277 { 278 case Collator.PRIMARY: 279 lastValue += PRIMARYORDERINCREMENT; 281 lastValue &= RBCollationTables.PRIMARYORDERMASK; 282 isOverIgnore = true; 283 break; 284 case Collator.SECONDARY: 285 lastValue += SECONDARYORDERINCREMENT; 287 lastValue &= RBCollationTables.SECONDARYDIFFERENCEONLY; 288 if (!isOverIgnore) 290 maxSecOrder++; 291 break; 292 case Collator.TERTIARY: 293 lastValue += TERTIARYORDERINCREMENT; 295 if (!isOverIgnore) 297 maxTerOrder++; 298 break; 299 } 300 return lastValue; 301 } 302 303 306 private final void addOrder(int ch, int anOrder) 307 { 308 int order = mapping.elementAt(ch); 310 311 if (order >= RBCollationTables.CONTRACTCHARINDEX) { 312 int length = 1; 316 if (Character.isSupplementaryCodePoint(ch)) { 317 length = Character.toChars(ch, keyBuf, 0); 318 } else { 319 keyBuf[0] = (char)ch; 320 } 321 addContractOrder(new String (keyBuf, 0, length), anOrder); 322 } else { 323 mapping.setElementAt(ch, anOrder); 326 } 327 } 328 329 private final void addContractOrder(String groupChars, int anOrder) { 330 addContractOrder(groupChars, anOrder, true); 331 } 332 333 336 private final void addContractOrder(String groupChars, int anOrder, 337 boolean fwd) 338 { 339 if (contractTable == null) { 340 contractTable = new Vector (INITIALTABLESIZE); 341 } 342 343 int ch = groupChars.codePointAt(0); 345 350 int entry = mapping.elementAt(ch); 352 Vector entryTable = getContractValuesImpl(entry - RBCollationTables.CONTRACTCHARINDEX); 353 354 if (entryTable == null) { 355 int tableIndex = RBCollationTables.CONTRACTCHARINDEX + contractTable.size(); 357 entryTable = new Vector (INITIALTABLESIZE); 358 contractTable.addElement(entryTable); 359 360 entryTable.addElement(new EntryPair (groupChars.substring(0,Character.charCount(ch)), entry)); 363 mapping.setElementAt(ch, tableIndex); 364 } 365 366 int index = RBCollationTables.getEntry(entryTable, groupChars, fwd); 368 if (index != RBCollationTables.UNMAPPED) { 369 EntryPair pair = (EntryPair ) entryTable.elementAt(index); 370 pair.value = anOrder; 371 } else { 372 EntryPair pair = (EntryPair )entryTable.lastElement(); 373 374 if (groupChars.length() > pair.entryName.length()) { 380 entryTable.addElement(new EntryPair (groupChars, anOrder, fwd)); 381 } else { 382 entryTable.insertElementAt(new EntryPair (groupChars, anOrder, 383 fwd), entryTable.size() - 1); 384 } 385 } 386 387 if (fwd && groupChars.length() > 1) { 391 addContractFlags(groupChars); 392 addContractOrder(new StringBuffer (groupChars).reverse().toString(), 393 anOrder, false); 394 } 395 } 396 397 402 private int getContractOrder(String groupChars) 403 { 404 int result = RBCollationTables.UNMAPPED; 405 if (contractTable != null) { 406 int ch = groupChars.codePointAt(0); 407 412 Vector entryTable = getContractValues(ch); 413 if (entryTable != null) { 414 int index = RBCollationTables.getEntry(entryTable, groupChars, true); 415 if (index != RBCollationTables.UNMAPPED) { 416 EntryPair pair = (EntryPair ) entryTable.elementAt(index); 417 result = pair.value; 418 } 419 } 420 } 421 return result; 422 } 423 424 private final int getCharOrder(int ch) { 425 int order = mapping.elementAt(ch); 426 427 if (order >= RBCollationTables.CONTRACTCHARINDEX) { 428 Vector groupList = getContractValuesImpl(order - RBCollationTables.CONTRACTCHARINDEX); 429 EntryPair pair = (EntryPair )groupList.firstElement(); 430 order = pair.value; 431 } 432 return order; 433 } 434 435 440 private Vector getContractValues(int ch) 441 { 442 int index = mapping.elementAt(ch); 443 return getContractValuesImpl(index - RBCollationTables.CONTRACTCHARINDEX); 444 } 445 446 private Vector getContractValuesImpl(int index) 447 { 448 if (index >= 0) 449 { 450 return (Vector )contractTable.elementAt(index); 451 } 452 else { 454 return null; 455 } 456 } 457 458 461 private final void addExpandOrder(String contractChars, 462 String expandChars, 463 int anOrder) throws ParseException 464 { 465 int tableIndex = addExpansion(anOrder, expandChars); 467 468 if (contractChars.length() > 1) { 470 char ch = contractChars.charAt(0); 471 if (Character.isHighSurrogate(ch) && contractChars.length() == 2) { 472 char ch2 = contractChars.charAt(1); 473 if (Character.isLowSurrogate(ch2)) { 474 addOrder(Character.toCodePoint(ch, ch2), tableIndex); 476 } 477 } else { 478 addContractOrder(contractChars, tableIndex); 479 } 480 } else { 481 addOrder(contractChars.charAt(0), tableIndex); 482 } 483 } 484 485 private final void addExpandOrder(int ch, String expandChars, int anOrder) 486 throws ParseException 487 { 488 int tableIndex = addExpansion(anOrder, expandChars); 489 addOrder(ch, tableIndex); 490 } 491 492 497 private int addExpansion(int anOrder, String expandChars) { 498 if (expandTable == null) { 499 expandTable = new Vector (INITIALTABLESIZE); 500 } 501 502 int offset = (anOrder == RBCollationTables.UNMAPPED) ? 0 : 1; 504 505 int[] valueList = new int[expandChars.length() + offset]; 506 if (offset == 1) { 507 valueList[0] = anOrder; 508 } 509 510 int j = offset; 511 for (int i = 0; i < expandChars.length(); i++) { 512 char ch0 = expandChars.charAt(i); 513 char ch1; 514 int ch; 515 if (Character.isHighSurrogate(ch0)) { 516 if (++i == expandChars.length() || 517 !Character.isLowSurrogate(ch1=expandChars.charAt(i))) { 518 break; 521 } 522 ch = Character.toCodePoint(ch0, ch1); 523 524 } else { 525 ch = ch0; 526 } 527 528 int mapValue = getCharOrder(ch); 529 530 if (mapValue != RBCollationTables.UNMAPPED) { 531 valueList[j++] = mapValue; 532 } else { 533 valueList[j++] = CHARINDEX + ch; 535 } 536 } 537 if (j < valueList.length) { 538 int[] tmpBuf = new int[j]; 541 while (--j >= 0) { 542 tmpBuf[j] = valueList[j]; 543 } 544 valueList = tmpBuf; 545 } 546 int tableIndex = RBCollationTables.EXPANDCHARINDEX + expandTable.size(); 548 expandTable.addElement(valueList); 549 550 return tableIndex; 551 } 552 553 private void addContractFlags(String chars) { 554 char c0; 555 int c; 556 int len = chars.length(); 557 for (int i = 0; i < len; i++) { 558 c0 = chars.charAt(i); 559 c = Character.isHighSurrogate(c0) 560 ?Character.toCodePoint(c0, chars.charAt(++i)) 561 :c0; 562 contractFlags.put(c, 1); 563 } 564 } 565 566 final static int CHARINDEX = 0x70000000; 571 private final static int IGNORABLEMASK = 0x0000ffff; 572 private final static int PRIMARYORDERINCREMENT = 0x00010000; 573 private final static int SECONDARYORDERINCREMENT = 0x00000100; 574 private final static int TERTIARYORDERINCREMENT = 0x00000001; 575 private final static int INITIALTABLESIZE = 20; 576 private final static int MAXKEYSIZE = 5; 577 578 582 private RBCollationTables.BuildAPI tables = null; 584 private MergeCollation mPattern = null; 585 private boolean isOverIgnore = false; 586 private char[] keyBuf = new char[MAXKEYSIZE]; 587 private IntHashtable contractFlags = new IntHashtable(100); 588 589 private boolean frenchSec = false; 593 private boolean seAsianSwapping = false; 594 595 private UCompactIntArray mapping = null; 596 private Vector contractTable = null; 597 private Vector expandTable = null; 598 599 private short maxSecOrder = 0; 600 private short maxTerOrder = 0; 601 } 602 | Popular Tags |