1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2002-2016, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11 package android.icu.text; 12 13 import java.io.IOException; 14 import java.nio.ByteBuffer; 15 import java.util.Locale; 16 import java.util.MissingResourceException; 17 18 import android.icu.impl.Assert; 19 import android.icu.impl.ICUBinary; 20 import android.icu.impl.ICUData; 21 import android.icu.impl.ICULocaleService; 22 import android.icu.impl.ICUResourceBundle; 23 import android.icu.impl.ICUService; 24 import android.icu.impl.ICUService.Factory; 25 import android.icu.util.ULocale; 26 27 /** 28 * @author Ram 29 * 30 * To change this generated comment edit the template variable "typecomment": 31 * Window>Preferences>Java>Templates. 32 * To enable and disable the creation of type comments go to 33 * Window>Preferences>Java>Code Generation. 34 */ 35 final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim { 36 37 @Override 38 public Object registerInstance(BreakIterator iter, ULocale locale, int kind) { 39 iter.setText(new java.text.StringCharacterIterator("")); 40 return service.registerObject(iter, locale, kind); 41 } 42 43 @Override 44 public boolean unregister(Object key) { 45 if (service.isDefault()) { 46 return false; 47 } 48 return service.unregisterFactory((Factory)key); 49 } 50 51 @Override 52 public Locale[] getAvailableLocales() { 53 if (service == null) { 54 return ICUResourceBundle.getAvailableLocales(); 55 } else { 56 return service.getAvailableLocales(); 57 } 58 } 59 60 @Override 61 public ULocale[] getAvailableULocales() { 62 if (service == null) { 63 return ICUResourceBundle.getAvailableULocales(); 64 } else { 65 return service.getAvailableULocales(); 66 } 67 } 68 69 @Override 70 public BreakIterator createBreakIterator(ULocale locale, int kind) { 71 // TODO: convert to ULocale when service switches over 72 if (service.isDefault()) { 73 return createBreakInstance(locale, kind); 74 } 75 ULocale[] actualLoc = new ULocale[1]; 76 BreakIterator iter = (BreakIterator)service.get(locale, kind, actualLoc); 77 iter.setLocale(actualLoc[0], actualLoc[0]); // services make no distinction between actual & valid 78 return iter; 79 } 80 81 private static class BFService extends ICULocaleService { 82 BFService() { 83 super("BreakIterator"); 84 85 class RBBreakIteratorFactory extends ICUResourceBundleFactory { 86 @Override 87 protected Object handleCreate(ULocale loc, int kind, ICUService srvc) { 88 return createBreakInstance(loc, kind); 89 } 90 } 91 registerFactory(new RBBreakIteratorFactory()); 92 93 markDefault(); 94 } 95 96 /** 97 * createBreakInstance() returns an appropriate BreakIterator for any locale. 98 * It falls back to root if there is no specific data. 99 * 100 * <p>Without this override, the service code would fall back to the default locale 101 * which is not desirable for an algorithm with a good Unicode default, 102 * like break iteration. 103 */ 104 @Override 105 public String validateFallbackLocale() { 106 return ""; 107 } 108 } 109 static final ICULocaleService service = new BFService(); 110 111 112 /** KIND_NAMES are the resource key to be used to fetch the name of the 113 * pre-compiled break rules. The resource bundle name is "boundaries". 114 * The value for each key will be the rules to be used for the 115 * specified locale - "word" -> "word_th" for Thai, for example. 116 */ 117 private static final String[] KIND_NAMES = { 118 "grapheme", "word", "line", "sentence", "title" 119 }; 120 121 122 private static BreakIterator createBreakInstance(ULocale locale, int kind) { 123 124 RuleBasedBreakIterator iter = null; 125 ICUResourceBundle rb = ICUResourceBundle. 126 getBundleInstance(ICUData.ICU_BRKITR_BASE_NAME, locale, 127 ICUResourceBundle.OpenType.LOCALE_ROOT); 128 129 // 130 // Get the binary rules. 131 // 132 ByteBuffer bytes = null; 133 String typeKeyExt = null; 134 if (kind == BreakIterator.KIND_LINE) { 135 String lbKeyValue = locale.getKeywordValue("lb"); 136 if ( lbKeyValue != null && (lbKeyValue.equals("strict") || lbKeyValue.equals("normal") || lbKeyValue.equals("loose")) ) { 137 typeKeyExt = "_" + lbKeyValue; 138 } 139 } 140 141 try { 142 String typeKey = (typeKeyExt == null)? KIND_NAMES[kind]: KIND_NAMES[kind] + typeKeyExt; 143 String brkfname = rb.getStringWithFallback("boundaries/" + typeKey); 144 String rulesFileName = ICUData.ICU_BRKITR_NAME+ '/' + brkfname; 145 bytes = ICUBinary.getData(rulesFileName); 146 } 147 catch (Exception e) { 148 throw new MissingResourceException(e.toString(),"",""); 149 } 150 151 // 152 // Create a normal RuleBasedBreakIterator. 153 // 154 try { 155 iter = RuleBasedBreakIterator.getInstanceFromCompiledRules(bytes); 156 } 157 catch (IOException e) { 158 // Shouldn't be possible to get here. 159 // If it happens, the compiled rules are probably corrupted in some way. 160 Assert.fail(e); 161 } 162 // TODO: Determine valid and actual locale correctly. 163 ULocale uloc = ULocale.forLocale(rb.getLocale()); 164 iter.setLocale(uloc, uloc); 165 iter.setBreakType(kind); 166 167 // filtered break 168 if (kind == BreakIterator.KIND_SENTENCE) { 169 final String ssKeyword = locale.getKeywordValue("ss"); 170 if (ssKeyword != null && ssKeyword.equals("standard")) { 171 final ULocale base = new ULocale(locale.getBaseName()); 172 return FilteredBreakIteratorBuilder.getInstance(base).wrapIteratorWithFilter(iter); 173 } 174 } 175 176 return iter; 177 178 } 179 180 } 181