1 /* 2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.util.locale.provider; 27 28 import java.io.IOException; 29 import java.text.BreakIterator; 30 import java.text.spi.BreakIteratorProvider; 31 import java.util.Locale; 32 import java.util.MissingResourceException; 33 import java.util.Objects; 34 import java.util.Set; 35 import sun.text.DictionaryBasedBreakIterator; 36 import sun.text.RuleBasedBreakIterator; 37 38 /** 39 * Concrete implementation of the {@link java.text.spi.BreakIteratorProvider 40 * BreakIteratorProvider} class for the JRE LocaleProviderAdapter. 41 * 42 * @author Naoto Sato 43 * @author Masayoshi Okutsu 44 */ 45 public class BreakIteratorProviderImpl extends BreakIteratorProvider 46 implements AvailableLanguageTags { 47 48 private static final int CHARACTER_INDEX = 0; 49 private static final int WORD_INDEX = 1; 50 private static final int LINE_INDEX = 2; 51 private static final int SENTENCE_INDEX = 3; 52 53 private final LocaleProviderAdapter.Type type; 54 private final Set<String> langtags; 55 BreakIteratorProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags)56 public BreakIteratorProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) { 57 this.type = type; 58 this.langtags = langtags; 59 } 60 61 /** 62 * Returns an array of all locales for which this locale service provider 63 * can provide localized objects or names. 64 * 65 * @return An array of all locales for which this locale service provider 66 * can provide localized objects or names. 67 */ 68 @Override getAvailableLocales()69 public Locale[] getAvailableLocales() { 70 return LocaleProviderAdapter.toLocaleArray(langtags); 71 } 72 73 /** 74 * Returns a new <code>BreakIterator</code> instance 75 * for <a href="../BreakIterator.html#word">word breaks</a> 76 * for the given locale. 77 * @param locale the desired locale 78 * @return A break iterator for word breaks 79 * @exception NullPointerException if <code>locale</code> is null 80 * @exception IllegalArgumentException if <code>locale</code> isn't 81 * one of the locales returned from 82 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 83 * getAvailableLocales()}. 84 * @see java.text.BreakIterator#getWordInstance(java.util.Locale) 85 */ 86 @Override getWordInstance(Locale locale)87 public BreakIterator getWordInstance(Locale locale) { 88 return getBreakInstance(locale, 89 WORD_INDEX, 90 "WordData", 91 "WordDictionary"); 92 } 93 94 /** 95 * Returns a new <code>BreakIterator</code> instance 96 * for <a href="../BreakIterator.html#line">line breaks</a> 97 * for the given locale. 98 * @param locale the desired locale 99 * @return A break iterator for line breaks 100 * @exception NullPointerException if <code>locale</code> is null 101 * @exception IllegalArgumentException if <code>locale</code> isn't 102 * one of the locales returned from 103 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 104 * getAvailableLocales()}. 105 * @see java.text.BreakIterator#getLineInstance(java.util.Locale) 106 */ 107 @Override getLineInstance(Locale locale)108 public BreakIterator getLineInstance(Locale locale) { 109 return getBreakInstance(locale, 110 LINE_INDEX, 111 "LineData", 112 "LineDictionary"); 113 } 114 115 /** 116 * Returns a new <code>BreakIterator</code> instance 117 * for <a href="../BreakIterator.html#character">character breaks</a> 118 * for the given locale. 119 * @param locale the desired locale 120 * @return A break iterator for character breaks 121 * @exception NullPointerException if <code>locale</code> is null 122 * @exception IllegalArgumentException if <code>locale</code> isn't 123 * one of the locales returned from 124 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 125 * getAvailableLocales()}. 126 * @see java.text.BreakIterator#getCharacterInstance(java.util.Locale) 127 */ 128 @Override getCharacterInstance(Locale locale)129 public BreakIterator getCharacterInstance(Locale locale) { 130 return getBreakInstance(locale, 131 CHARACTER_INDEX, 132 "CharacterData", 133 "CharacterDictionary"); 134 } 135 136 /** 137 * Returns a new <code>BreakIterator</code> instance 138 * for <a href="../BreakIterator.html#sentence">sentence breaks</a> 139 * for the given locale. 140 * @param locale the desired locale 141 * @return A break iterator for sentence breaks 142 * @exception NullPointerException if <code>locale</code> is null 143 * @exception IllegalArgumentException if <code>locale</code> isn't 144 * one of the locales returned from 145 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 146 * getAvailableLocales()}. 147 * @see java.text.BreakIterator#getSentenceInstance(java.util.Locale) 148 */ 149 @Override getSentenceInstance(Locale locale)150 public BreakIterator getSentenceInstance(Locale locale) { 151 return getBreakInstance(locale, 152 SENTENCE_INDEX, 153 "SentenceData", 154 "SentenceDictionary"); 155 } 156 getBreakInstance(Locale locale, int type, String ruleName, String dictionaryName)157 private BreakIterator getBreakInstance(Locale locale, 158 int type, 159 String ruleName, 160 String dictionaryName) { 161 Objects.requireNonNull(locale); 162 163 LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale); 164 String[] classNames = (String[]) lr.getBreakIteratorInfo("BreakIteratorClasses"); 165 String ruleFile = (String) lr.getBreakIteratorInfo(ruleName); 166 byte[] ruleData = lr.getBreakIteratorResources(ruleName); 167 168 try { 169 switch (classNames[type]) { 170 case "RuleBasedBreakIterator": 171 return new RuleBasedBreakIterator(ruleFile, ruleData); 172 173 case "DictionaryBasedBreakIterator": 174 String dictionaryFile = (String) lr.getBreakIteratorInfo(dictionaryName); 175 byte[] dictionaryData = lr.getBreakIteratorResources(dictionaryName); 176 return new DictionaryBasedBreakIterator(ruleFile, ruleData, 177 dictionaryFile, dictionaryData); 178 default: 179 throw new IllegalArgumentException("Invalid break iterator class \"" + 180 classNames[type] + "\""); 181 } 182 } catch (MissingResourceException | IllegalArgumentException e) { 183 throw new InternalError(e.toString(), e); 184 } 185 } 186 187 @Override getAvailableLanguageTags()188 public Set<String> getAvailableLanguageTags() { 189 return langtags; 190 } 191 192 @Override isSupportedLocale(Locale locale)193 public boolean isSupportedLocale(Locale locale) { 194 return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags); 195 } 196 } 197