1 7 package com.ibm.icu.text; 8 import com.ibm.icu.impl.Utility; 9 import com.ibm.icu.impl.UtilityExtensions; 10 import java.util.Vector ; 11 12 29 class CompoundTransliterator extends Transliterator { 30 31 private Transliterator[] trans; 32 33 private int numAnonymousRBTs = 0; 34 35 private static final String COPYRIGHT = 36 "\u00A9 IBM Corporation 1999-2001. All rights reserved."; 37 38 51 public CompoundTransliterator(Transliterator[] transliterators, 52 UnicodeFilter filter) { 53 super(joinIDs(transliterators), filter); 54 trans = new Transliterator[transliterators.length]; 55 System.arraycopy(transliterators, 0, trans, 0, trans.length); 56 computeMaximumContextLength(); 57 } 58 59 68 public CompoundTransliterator(Transliterator[] transliterators) { 69 this(transliterators, null); 70 } 71 72 80 public CompoundTransliterator(String ID, int direction, 81 UnicodeFilter filter) { 82 super(ID, filter); 83 init(ID, direction, true); 84 } 85 86 92 public CompoundTransliterator(String ID, int direction) { 93 this(ID, direction, null); 94 } 95 96 101 public CompoundTransliterator(String ID) { 102 this(ID, FORWARD, null); 103 } 104 105 110 CompoundTransliterator(Vector list) { 111 this(list, 0); 112 } 113 114 CompoundTransliterator(Vector list, int numAnonymousRBTs) { 115 super("", null); 116 trans = null; 117 init(list, FORWARD, false); 118 this.numAnonymousRBTs = numAnonymousRBTs; 119 } 121 122 137 private void init(String id, 138 int direction, 139 boolean fixReverseID) { 140 142 Vector list = new Vector (); 143 UnicodeSet[] compoundFilter = new UnicodeSet[1]; 144 StringBuffer regenID = new StringBuffer (); 145 if (!TransliteratorIDParser.parseCompoundID(id, direction, 146 regenID, list, compoundFilter)) { 147 throw new IllegalArgumentException ("Invalid ID " + id); 148 } 149 150 TransliteratorIDParser.instantiateList(list); 151 152 init(list, direction, fixReverseID); 153 154 if (compoundFilter[0] != null) { 155 setFilter(compoundFilter[0]); 156 } 157 } 158 159 171 private void init(Vector list, 172 int direction, 173 boolean fixReverseID) { 174 176 int count = list.size(); 178 trans = new Transliterator[count]; 179 180 int i; 183 for (i=0; i<count; ++i) { 184 int j = (direction == FORWARD) ? i : count - 1 - i; 185 trans[i] = (Transliterator) list.elementAt(j); 186 } 187 188 if (direction == REVERSE && fixReverseID) { 191 StringBuffer newID = new StringBuffer (); 192 for (i=0; i<count; ++i) { 193 if (i > 0) { 194 newID.append(ID_DELIM); 195 } 196 newID.append(trans[i].getID()); 197 } 198 setID(newID.toString()); 199 } 200 201 computeMaximumContextLength(); 202 } 203 204 209 private static String joinIDs(Transliterator[] transliterators) { 210 StringBuffer id = new StringBuffer (); 211 for (int i=0; i<transliterators.length; ++i) { 212 if (i > 0) { 213 id.append(';'); 214 } 215 id.append(transliterators[i].getID()); 216 } 217 return id.toString(); 218 } 219 220 225 public int getCount() { 226 return trans.length; 227 } 228 229 235 public Transliterator getTransliterator(int index) { 236 return trans[index]; 237 } 238 239 242 private static void _smartAppend(StringBuffer buf, char c) { 243 if (buf.length() != 0 && 244 buf.charAt(buf.length() - 1) != c) { 245 buf.append(c); 246 } 247 } 248 249 260 public String toRules(boolean escapeUnprintable) { 261 StringBuffer rulesSource = new StringBuffer (); 268 if (numAnonymousRBTs >= 1 && getFilter() != null) { 269 rulesSource.append("::").append(getFilter().toPattern(escapeUnprintable)).append(ID_DELIM); 272 } 273 for (int i=0; i<trans.length; ++i) { 274 String rule; 275 276 if (trans[i].getID().startsWith("%Pass")) { 281 rule = trans[i].toRules(escapeUnprintable); 282 if (numAnonymousRBTs > 1 && i > 0 && trans[i - 1].getID().startsWith("%Pass")) 283 rule = "::Null;" + rule; 284 285 } else if (trans[i].getID().indexOf(';') >= 0) { 290 rule = trans[i].toRules(escapeUnprintable); 291 292 } else { 294 rule = trans[i].baseToRules(escapeUnprintable); 295 } 296 _smartAppend(rulesSource, '\n'); 297 rulesSource.append(rule); 298 _smartAppend(rulesSource, ID_DELIM); 299 } 300 return rulesSource.toString(); 301 } 302 303 308 protected UnicodeSet handleGetSourceSet() { 309 UnicodeSet set = new UnicodeSet(); 310 for (int i=0; i<trans.length; ++i) { 311 set.addAll(trans[i].getSourceSet()); 312 319 if (!set.isEmpty()) { 321 break; 322 } 323 } 324 return set; 325 } 326 327 332 public UnicodeSet getTargetSet() { 333 UnicodeSet set = new UnicodeSet(); 334 for (int i=0; i<trans.length; ++i) { 335 set.addAll(trans[i].getTargetSet()); 337 } 338 return set; 339 } 340 341 345 protected void handleTransliterate(Replaceable text, 346 Position index, boolean incremental) { 347 370 371 401 402 if (trans.length < 1) { 403 index.start = index.limit; 404 return; } 406 407 int compoundLimit = index.limit; 412 413 int compoundStart = index.start; 416 417 int delta = 0; 419 StringBuffer log = null; 420 if (DEBUG) { 421 log = new StringBuffer ("CompoundTransliterator{" + getID() + 422 (incremental ? "}i: IN=" : "}: IN=")); 423 UtilityExtensions.formatInput(log, text, index); 424 System.out.println(Utility.escape(log.toString())); 425 } 426 427 for (int i=0; i<trans.length; ++i) { 430 index.start = compoundStart; int limit = index.limit; 432 433 if (index.start == index.limit) { 434 if (DEBUG) { 436 System.out.println("CompoundTransliterator[" + i + 437 ".." + (trans.length-1) + 438 (incremental ? "]i: " : "]: ") + 439 UtilityExtensions.formatInput(text, index) + 440 " (NOTHING TO DO)"); 441 } 442 break; 443 } 444 445 if (DEBUG) { 446 log.setLength(0); 447 log.append("CompoundTransliterator[" + i + "=" + 448 trans[i].getID() + 449 (incremental ? "]i: " : "]: ")); 450 UtilityExtensions.formatInput(log, text, index); 451 } 452 453 trans[i].filteredTransliterate(text, index, incremental); 454 455 if (!incremental && index.start != index.limit) { 463 throw new RuntimeException ("ERROR: Incomplete non-incremental transliteration by " + trans[i].getID()); 464 } 465 466 if (DEBUG) { 467 log.append(" => "); 468 UtilityExtensions.formatInput(log, text, index); 469 System.out.println(Utility.escape(log.toString())); 470 } 471 472 delta += index.limit - limit; 474 475 if (incremental) { 476 index.limit = index.start; 482 } 483 } 484 485 compoundLimit += delta; 486 487 index.limit = compoundLimit; 491 492 if (DEBUG) { 493 log.setLength(0); 494 log.append("CompoundTransliterator{" + getID() + 495 (incremental ? "}i: OUT=" : "}: OUT=")); 496 UtilityExtensions.formatInput(log, text, index); 497 System.out.println(Utility.escape(log.toString())); 498 } 499 } 500 501 505 private void computeMaximumContextLength() { 506 int max = 0; 507 for (int i=0; i<trans.length; ++i) { 508 int len = trans[i].getMaximumContextLength(); 509 if (len > max) { 510 max = len; 511 } 512 } 513 setMaximumContextLength(max); 514 } 515 } 516 | Popular Tags |