]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/text/BreakIteratorFactory.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / text / BreakIteratorFactory.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2002-2010, 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 import java.util.Locale;\r
12 import java.util.MissingResourceException;\r
13 \r
14 import com.ibm.icu.impl.Assert;\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 \r
23 /**\r
24  * @author Ram\r
25  *\r
26  * To change this generated comment edit the template variable "typecomment":\r
27  * Window>Preferences>Java>Templates.\r
28  * To enable and disable the creation of type comments go to\r
29  * Window>Preferences>Java>Code Generation.\r
30  */\r
31 final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim {\r
32 \r
33     public Object registerInstance(BreakIterator iter, ULocale locale, int kind) {\r
34         iter.setText(new java.text.StringCharacterIterator(""));\r
35         return service.registerObject(iter, locale, kind);\r
36     }\r
37 \r
38     public boolean unregister(Object key) {\r
39         if (service.isDefault()) {\r
40             return false;\r
41         }\r
42         return service.unregisterFactory((Factory)key);\r
43     }\r
44 \r
45     public Locale[] getAvailableLocales() {\r
46         if (service == null) {\r
47             return ICUResourceBundle.getAvailableLocales();\r
48         } else {\r
49             return service.getAvailableLocales();\r
50         }\r
51     }\r
52 \r
53     public ULocale[] getAvailableULocales() {\r
54         if (service == null) {\r
55             return ICUResourceBundle.getAvailableULocales();\r
56         } else {\r
57             return service.getAvailableULocales();\r
58         }\r
59     }\r
60 \r
61     public BreakIterator createBreakIterator(ULocale locale, int kind) {\r
62     // TODO: convert to ULocale when service switches over\r
63         if (service.isDefault()) {\r
64             return createBreakInstance(locale, kind);\r
65         }\r
66         ULocale[] actualLoc = new ULocale[1];\r
67         BreakIterator iter = (BreakIterator)service.get(locale, kind, actualLoc);\r
68         iter.setLocale(actualLoc[0], actualLoc[0]); // services make no distinction between actual & valid\r
69         return iter;\r
70     }\r
71 \r
72     private static class BFService extends ICULocaleService {\r
73         BFService() {\r
74             super("BreakIterator");\r
75 \r
76             class RBBreakIteratorFactory extends ICUResourceBundleFactory {\r
77                 protected Object handleCreate(ULocale loc, int kind, ICUService srvc) {\r
78                     return createBreakInstance(loc, kind);\r
79                 }\r
80             }\r
81             registerFactory(new RBBreakIteratorFactory());\r
82 \r
83             markDefault();\r
84         }\r
85     }\r
86     static final ICULocaleService service = new BFService();\r
87 \r
88 \r
89     /** KIND_NAMES are the resource key to be used to fetch the name of the\r
90      *             pre-compiled break rules.  The resource bundle name is "boundaries".\r
91      *             The value for each key will be the rules to be used for the\r
92      *             specified locale - "word" -> "word_th" for Thai, for example.\r
93      *  DICTIONARY_POSSIBLE indexes in the same way, and indicates whether a\r
94      *             dictionary is a possibility for that type of break.  This is just\r
95      *             an optimization to avoid a resource lookup where no dictionary is\r
96      *             ever possible.\r
97      */\r
98     private static final String[] KIND_NAMES = {\r
99             "grapheme", "word", "line", "sentence", "title"\r
100         };\r
101     private static final boolean[] DICTIONARY_POSSIBLE = {\r
102             false,      true,  true,   false,     false\r
103     };\r
104 \r
105 \r
106     private static BreakIterator createBreakInstance(ULocale locale, int kind) {\r
107 \r
108         BreakIterator    iter       = null;\r
109         ICUResourceBundle rb        = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BRKITR_BASE_NAME, locale);\r
110         \r
111         //\r
112         //  Get the binary rules.  These are needed for both normal RulesBasedBreakIterators\r
113         //                         and for Dictionary iterators.\r
114         //\r
115         InputStream      ruleStream = null;\r
116         try {\r
117             String         typeKey       = KIND_NAMES[kind];\r
118             String         brkfname      = rb.getStringWithFallback("boundaries/" + typeKey);\r
119             String         rulesFileName = ICUResourceBundle.ICU_BUNDLE +ICUResourceBundle.ICU_BRKITR_NAME+ "/" + brkfname;\r
120                            ruleStream    = ICUData.getStream(rulesFileName);\r
121         }\r
122         catch (Exception e) {\r
123             throw new MissingResourceException(e.toString(),"","");\r
124         }\r
125  \r
126         //\r
127         //  Check whether a dictionary exists, and create a DBBI iterator is\r
128         //   one does.\r
129         //\r
130         if (DICTIONARY_POSSIBLE[kind]) {\r
131             // This type of break iterator could potentially use a dictionary.\r
132             //\r
133             try {\r
134                 if (locale.getLanguage().equals("th")){\r
135                     // If the language is Thai, load the thai compact trie dictionary.\r
136                     String dictType = "Thai";\r
137                     String dictFileName = rb.getStringWithFallback("dictionaries/" + dictType);\r
138                     dictFileName = ICUResourceBundle.ICU_BUNDLE +ICUResourceBundle.ICU_BRKITR_NAME+ "/" + dictFileName;\r
139                     InputStream is = ICUData.getStream(dictFileName);\r
140                     iter = new ThaiBreakIterator(ruleStream, is);\r
141                 }\r
142             } catch (MissingResourceException e) {\r
143                 //  Couldn't find a dictionary.\r
144                 //  This is normal, and will occur whenever creating a word or line\r
145                 //  break iterator for a locale that does not have a BreakDictionaryData\r
146                 //  resource - meaning for all but Thai.\r
147                 //  Fall through to creating a normal RulebasedBreakIterator.\r
148             } catch (IOException e) {\r
149                 Assert.fail(e);\r
150             }\r
151          }\r
152 \r
153         if (iter == null) {\r
154             //\r
155             // Create a normal RuleBasedBreakIterator.\r
156             //    We have determined that this is not supposed to be a dictionary iterator.\r
157             //\r
158             try {\r
159                 iter = RuleBasedBreakIterator.getInstanceFromCompiledRules(ruleStream);\r
160             }\r
161             catch (IOException e) {\r
162                 // Shouldn't be possible to get here.\r
163                 // If it happens, the compiled rules are probably corrupted in some way.\r
164                 Assert.fail(e);\r
165            }\r
166         }\r
167         // TODO: Determine valid and actual locale correctly.\r
168         ULocale uloc = ULocale.forLocale(rb.getLocale());\r
169         iter.setLocale(uloc, uloc);\r
170         \r
171         return iter;\r
172 \r
173     }\r
174 \r
175 }\r