]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/BreakIteratorFactory.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / BreakIteratorFactory.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2002-2008, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.text;\r
8 \r
9 import java.io.IOException;\r
10 import java.io.InputStream;\r
11 \r
12 import java.util.Locale;\r
13 import java.util.MissingResourceException;\r
14 \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
23 \r
24 /**\r
25  * @author Ram\r
26  *\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
31  */\r
32 final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim {\r
33 \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
37     }\r
38 \r
39     public boolean unregister(Object key) {\r
40         if (service.isDefault()) {\r
41             return false;\r
42         }\r
43         return service.unregisterFactory((Factory)key);\r
44     }\r
45 \r
46     public Locale[] getAvailableLocales() {\r
47         if (service == null) {\r
48             return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);\r
49         } else {\r
50             return service.getAvailableLocales();\r
51         }\r
52     }\r
53 \r
54     public ULocale[] getAvailableULocales() {\r
55         if (service == null) {\r
56             return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);\r
57         } else {\r
58             return service.getAvailableULocales();\r
59         }\r
60     }\r
61 \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
66         }\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
70         return iter;\r
71     }\r
72 \r
73     private static class BFService extends ICULocaleService {\r
74         BFService() {\r
75             super("BreakIterator");\r
76 \r
77             class RBBreakIteratorFactory extends ICUResourceBundleFactory {\r
78                 protected Object handleCreate(ULocale loc, int kind, ICUService srvc) {\r
79                     return createBreakInstance(loc, kind);\r
80                 }\r
81             }\r
82             registerFactory(new RBBreakIteratorFactory());\r
83 \r
84             markDefault();\r
85         }\r
86     }\r
87     static final ICULocaleService service = new BFService();\r
88 \r
89 \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
97      *             ever possible.\r
98      *  @internal\r
99      */\r
100     private static final String[] KIND_NAMES = {\r
101             "grapheme", "word", "line", "sentence", "title"\r
102         };\r
103     private static final boolean[] DICTIONARY_POSSIBLE = {\r
104             false,      true,  true,   false,     false\r
105     };\r
106 \r
107 \r
108     private static BreakIterator createBreakInstance(ULocale locale, int kind) {\r
109 \r
110         BreakIterator    iter       = null;\r
111         ICUResourceBundle rb        = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BRKITR_BASE_NAME, locale);\r
112         \r
113         //\r
114         //  Get the binary rules.  These are needed for both normal RulesBasedBreakIterators\r
115         //                         and for Dictionary iterators.\r
116         //\r
117         InputStream      ruleStream = null;\r
118         try {\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
123         }\r
124         catch (Exception e) {\r
125             throw new MissingResourceException(e.toString(),"","");\r
126         }\r
127  \r
128         //\r
129         //  Check whether a dictionary exists, and create a DBBI iterator is\r
130         //   one does.\r
131         //\r
132         if (DICTIONARY_POSSIBLE[kind]) {\r
133             // This type of break iterator could potentially use a dictionary.\r
134             //\r
135             try {\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
143                 }\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
151                 Assert.fail(e);\r
152             }\r
153          }\r
154 \r
155         if (iter == null) {\r
156             //\r
157             // Create a normal RuleBasedBreakIterator.\r
158             //    We have determined that this is not supposed to be a dictionary iterator.\r
159             //\r
160             try {\r
161                 iter = RuleBasedBreakIterator.getInstanceFromCompiledRules(ruleStream);\r
162             }\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
166                 Assert.fail(e);\r
167            }\r
168         }\r
169         // TODO: Determine valid and actual locale correctly.\r
170         ULocale uloc = ULocale.forLocale(rb.getLocale());\r
171         iter.setLocale(uloc, uloc);\r
172         \r
173         return iter;\r
174 \r
175     }\r
176 \r
177 }\r