2 *******************************************************************************
\r
3 * Copyright (C) 2002-2008, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.text;
\r
9 import java.io.IOException;
\r
10 import java.io.InputStream;
\r
12 import java.util.Locale;
\r
13 import java.util.MissingResourceException;
\r
15 import com.ibm.icu.impl.ICUData;
\r
16 import com.ibm.icu.impl.ICULocaleService;
\r
17 import com.ibm.icu.impl.ICUResourceBundle;
\r
18 import com.ibm.icu.impl.ICUService;
\r
19 import com.ibm.icu.impl.ICUService.Factory;
\r
20 import com.ibm.icu.util.ULocale;
\r
21 import com.ibm.icu.util.UResourceBundle;
\r
22 import com.ibm.icu.impl.Assert;
\r
27 * To change this generated comment edit the template variable "typecomment":
\r
28 * Window>Preferences>Java>Templates.
\r
29 * To enable and disable the creation of type comments go to
\r
30 * Window>Preferences>Java>Code Generation.
\r
32 final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim {
\r
34 public Object registerInstance(BreakIterator iter, ULocale locale, int kind) {
\r
35 iter.setText(new java.text.StringCharacterIterator(""));
\r
36 return service.registerObject(iter, locale, kind);
\r
39 public boolean unregister(Object key) {
\r
40 if (service.isDefault()) {
\r
43 return service.unregisterFactory((Factory)key);
\r
46 public Locale[] getAvailableLocales() {
\r
47 if (service == null) {
\r
48 return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);
\r
50 return service.getAvailableLocales();
\r
54 public ULocale[] getAvailableULocales() {
\r
55 if (service == null) {
\r
56 return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);
\r
58 return service.getAvailableULocales();
\r
62 public BreakIterator createBreakIterator(ULocale locale, int kind) {
\r
63 // TODO: convert to ULocale when service switches over
\r
64 if (service.isDefault()) {
\r
65 return createBreakInstance(locale, kind);
\r
67 ULocale[] actualLoc = new ULocale[1];
\r
68 BreakIterator iter = (BreakIterator)service.get(locale, kind, actualLoc);
\r
69 iter.setLocale(actualLoc[0], actualLoc[0]); // services make no distinction between actual & valid
\r
73 private static class BFService extends ICULocaleService {
\r
75 super("BreakIterator");
\r
77 class RBBreakIteratorFactory extends ICUResourceBundleFactory {
\r
78 protected Object handleCreate(ULocale loc, int kind, ICUService srvc) {
\r
79 return createBreakInstance(loc, kind);
\r
82 registerFactory(new RBBreakIteratorFactory());
\r
87 static final ICULocaleService service = new BFService();
\r
90 /** KIND_NAMES are the resource key to be used to fetch the name of the
\r
91 * pre-compiled break rules. The resource bundle name is "boundaries".
\r
92 * The value for each key will be the rules to be used for the
\r
93 * specified locale - "word" -> "word_th" for Thai, for example.
\r
94 * DICTIONARY_POSSIBLE indexes in the same way, and indicates whether a
\r
95 * dictionary is a possibility for that type of break. This is just
\r
96 * an optimization to avoid a resource lookup where no dictionary is
\r
100 private static final String[] KIND_NAMES = {
\r
101 "grapheme", "word", "line", "sentence", "title"
\r
103 private static final boolean[] DICTIONARY_POSSIBLE = {
\r
104 false, true, true, false, false
\r
108 private static BreakIterator createBreakInstance(ULocale locale, int kind) {
\r
110 BreakIterator iter = null;
\r
111 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BRKITR_BASE_NAME, locale);
\r
114 // Get the binary rules. These are needed for both normal RulesBasedBreakIterators
\r
115 // and for Dictionary iterators.
\r
117 InputStream ruleStream = null;
\r
119 String typeKey = KIND_NAMES[kind];
\r
120 String brkfname = rb.getStringWithFallback("boundaries/" + typeKey);
\r
121 String rulesFileName = ICUResourceBundle.ICU_BUNDLE +ICUResourceBundle.ICU_BRKITR_NAME+ "/" + brkfname;
\r
122 ruleStream = ICUData.getStream(rulesFileName);
\r
124 catch (Exception e) {
\r
125 throw new MissingResourceException(e.toString(),"","");
\r
129 // Check whether a dictionary exists, and create a DBBI iterator is
\r
132 if (DICTIONARY_POSSIBLE[kind]) {
\r
133 // This type of break iterator could potentially use a dictionary.
\r
136 if (locale.getLanguage().equals("th")){
\r
137 // If the language is Thai, load the thai compact trie dictionary.
\r
138 String dictType = "Thai";
\r
139 String dictFileName = rb.getStringWithFallback("dictionaries/" + dictType);
\r
140 dictFileName = ICUResourceBundle.ICU_BUNDLE +ICUResourceBundle.ICU_BRKITR_NAME+ "/" + dictFileName;
\r
141 InputStream is = ICUData.getStream(dictFileName);
\r
142 iter = new ThaiBreakIterator(ruleStream, is);
\r
144 } catch (MissingResourceException e) {
\r
145 // Couldn't find a dictionary.
\r
146 // This is normal, and will occur whenever creating a word or line
\r
147 // break iterator for a locale that does not have a BreakDictionaryData
\r
148 // resource - meaning for all but Thai.
\r
149 // Fall through to creating a normal RulebasedBreakIterator.
\r
150 } catch (IOException e) {
\r
155 if (iter == null) {
\r
157 // Create a normal RuleBasedBreakIterator.
\r
158 // We have determined that this is not supposed to be a dictionary iterator.
\r
161 iter = RuleBasedBreakIterator.getInstanceFromCompiledRules(ruleStream);
\r
163 catch (IOException e) {
\r
164 // Shouldn't be possible to get here.
\r
165 // If it happens, the compiled rules are probably corrupted in some way.
\r
169 // TODO: Determine valid and actual locale correctly.
\r
170 ULocale uloc = ULocale.forLocale(rb.getLocale());
\r
171 iter.setLocale(uloc, uloc);
\r