1 10 package com.ibm.icu.text; 11 import com.ibm.icu.lang.UScript; 12 import java.lang.Math ; 13 import java.util.Enumeration ; 14 import java.util.HashSet ; 15 import java.util.HashMap ; 16 import java.util.Map ; 17 import java.util.MissingResourceException ; 18 38 class AnyTransliterator extends Transliterator { 39 40 43 static final char TARGET_SEP = '-'; 44 static final char VARIANT_SEP = '/'; 45 static final String ANY = "Any"; 46 static final String NULL_ID = "Null"; 47 static final String LATIN_PIVOT = "-Latin;Latin-"; 48 49 52 private Map cache; 53 54 57 private String target; 58 59 62 private int targetScript; 63 64 67 protected void handleTransliterate(Replaceable text, 68 Position pos, boolean isIncremental) { 69 int allStart = pos.start; 70 int allLimit = pos.limit; 71 72 ScriptRunIterator it = 73 new ScriptRunIterator(text, pos.contextStart, pos.contextLimit); 74 75 while (it.next()) { 76 if (it.limit <= allStart) continue; 78 79 Transliterator t = getTransliterator(it.scriptCode); 82 83 if (t == null) { 84 pos.start = it.limit; 87 continue; 88 } 89 90 boolean incremental = isIncremental && (it.limit >= allLimit); 94 95 pos.start = Math.max(allStart, it.start); 96 pos.limit = Math.min(allLimit, it.limit); 97 int limit = pos.limit; 98 t.filteredTransliterate(text, pos, incremental); 99 int delta = pos.limit - limit; 100 allLimit += delta; 101 it.adjustLimit(delta); 102 103 if (it.limit >= allLimit) break; 105 } 106 107 pos.limit = allLimit; 110 } 111 112 123 private AnyTransliterator(String id, 124 String theTarget, 125 String theVariant, 126 int theTargetScript) { 127 super(id, null); 128 targetScript = theTargetScript; 129 cache = new HashMap (); 130 131 target = theTarget; 132 if (theVariant.length() > 0) { 133 target = theTarget + VARIANT_SEP + theVariant; 134 } 135 } 136 137 145 private Transliterator getTransliterator(int source) { 146 if (source == targetScript || source == UScript.INVALID_CODE) { 147 return null; 148 } 149 150 Integer key = new Integer (source); 151 Transliterator t = (Transliterator) cache.get(key); 152 if (t == null) { 153 String sourceName = UScript.getName(source); 154 String id = sourceName + TARGET_SEP + target; 155 156 try { 157 t = Transliterator.getInstance(id, FORWARD); 158 } catch (RuntimeException e) { } 159 if (t == null) { 160 161 id = sourceName + LATIN_PIVOT + target; 163 try { 164 t = Transliterator.getInstance(id, FORWARD); 165 } catch (RuntimeException e) { } 166 } 167 168 if (t != null) { 169 cache.put(key, t); 170 } 171 } 172 173 return t; 174 } 175 176 181 static void register() { 182 183 HashSet seen = new HashSet (); 184 185 for (Enumeration s=Transliterator.getAvailableSources(); s.hasMoreElements(); ) { 186 String source = (String ) s.nextElement(); 187 188 if (source.equalsIgnoreCase(ANY)) continue; 190 191 for (Enumeration t=Transliterator.getAvailableTargets(source); 192 t.hasMoreElements(); ) { 193 String target = (String ) t.nextElement(); 194 195 if (seen.contains(target)) continue; 197 seen.add(target); 198 199 int targetScript = scriptNameToCode(target); 201 if (targetScript == UScript.INVALID_CODE) continue; 202 203 for (Enumeration v=Transliterator.getAvailableVariants(source, target); 204 v.hasMoreElements(); ) { 205 String variant = (String ) v.nextElement(); 206 207 String id; 208 id = TransliteratorIDParser.STVtoID(ANY, target, variant); 209 AnyTransliterator trans = new AnyTransliterator(id, target, variant, 210 targetScript); 211 Transliterator.registerInstance(trans); 212 Transliterator.registerSpecialInverse(target, NULL_ID, false); 213 } 214 } 215 } 216 } 217 218 222 private static int scriptNameToCode(String name) { 223 try{ 224 int[] codes = UScript.getCode(name); 225 return codes != null ? codes[0] : UScript.INVALID_CODE; 226 }catch( MissingResourceException e){ 227 return UScript.INVALID_CODE; 228 } 229 } 230 231 234 246 private static class ScriptRunIterator { 247 248 private Replaceable text; 249 private int textStart; 250 private int textLimit; 251 252 257 public int scriptCode; 258 259 262 public int start; 263 264 267 public int limit; 268 269 273 public ScriptRunIterator(Replaceable text, int start, int limit) { 274 this.text = text; 275 this.textStart = start; 276 this.textLimit = limit; 277 this.limit = start; 278 } 279 280 281 286 public boolean next() { 287 int ch; 288 int s; 289 290 scriptCode = UScript.INVALID_CODE; start = limit; 292 293 if (start == textLimit) { 295 return false; 296 } 297 298 while (start > textStart) { 301 ch = text.char32At(start - 1); s = UScript.getScript(ch); 303 if (s == UScript.COMMON || s == UScript.INHERITED) { 304 --start; 305 } else { 306 break; 307 } 308 } 309 310 while (limit < textLimit) { 313 ch = text.char32At(limit); s = UScript.getScript(ch); 315 if (s != UScript.COMMON && s != UScript.INHERITED) { 316 if (scriptCode == UScript.INVALID_CODE) { 317 scriptCode = s; 318 } else if (s != scriptCode) { 319 break; 320 } 321 } 322 ++limit; 323 } 324 325 return true; 328 } 329 330 334 public void adjustLimit(int delta) { 335 limit += delta; 336 textLimit += delta; 337 } 338 } 339 } 340 341 | Popular Tags |