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