blob: a0069645f00d4cb3237a5f9ee6f959aa10466ff6 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2002-2004, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICULocaleData;
import com.ibm.icu.impl.ICULocaleService;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.ICUService;
import com.ibm.icu.impl.ICUService.Factory;
import com.ibm.icu.util.ULocale;
/**
* @author Ram
*
* To change this generated comment edit the template variable "typecomment":
* Window>Preferences>Java>Templates.
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/
final class BreakIteratorFactory extends BreakIterator.BreakIteratorServiceShim {
public Object registerInstance(BreakIterator iter, ULocale locale, int kind) {
iter.setText(new java.text.StringCharacterIterator(""));
return service.registerObject(iter, locale, kind);
}
public boolean unregister(Object key) {
if (service.isDefault()) {
return false;
}
return service.unregisterFactory((Factory)key);
}
public Locale[] getAvailableLocales() {
if (service == null) {
return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);
} else {
return service.getAvailableLocales();
}
}
public ULocale[] getAvailableULocales() {
if (service == null) {
return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);
} else {
return service.getAvailableULocales();
}
}
public BreakIterator createBreakIterator(ULocale locale, int kind) {
// TODO: convert to ULocale when service switches over
if (service.isDefault()) {
return createBreakInstance(locale, kind);
}
ULocale[] actualLoc = new ULocale[1];
BreakIterator iter = (BreakIterator)service.get(locale, kind, actualLoc);
iter.setLocale(actualLoc[0], actualLoc[0]); // services make no distinction between actual & valid
return iter;
}
private static class BFService extends ICULocaleService {
BFService() {
super("BreakIterator");
class RBBreakIteratorFactory extends ICUResourceBundleFactory {
protected Object handleCreate(ULocale loc, int kind, ICUService service) {
return createBreakInstance(loc, kind);
}
}
registerFactory(new RBBreakIteratorFactory());
markDefault();
}
}
static final ICULocaleService service = new BFService();
// KIND_NAMES are used in synthesizing the resource name that holds the source
// break rules. For old-style (ICU 2.8 and previous) break iterators.
// The resources are com.ibm.icu.impl.data.BreakIteratorRules, and have
// names like "CharacterBreakRules", where the "Character" part of the
// name comes from here (this array).
private static final String[] KIND_NAMES = {
"Character", "Word", "Line", "Sentence", "Title"
};
/** KIND_NAMES_2 are used in synthesizing the names for
* the precompiled break rules used with the new (ICU 3.0) RBBI.
* The fully assembled names look like icudt30b_char.brk, which is the
* file name of the brk file as produced by the ICU4C build.
* @internal
*/
private static final String[] KIND_NAMES_2 = {
"char", "word", "line", "sent", "title"
};
private static BreakIterator createBreakInstance(ULocale locale, int kind) {
String prefix = KIND_NAMES[kind];
return createBreakInstance(locale, kind,
prefix + "BreakRules",
prefix + "BreakDictionary");
}
private static BreakIterator createBreakInstance(ULocale where,
int kind,
String rulesName,
String dictionaryName) {
BreakIterator iter = null;
ResourceBundle bundle = ICULocaleData.getResourceBundle("BreakIteratorRules", where);
String[] classNames = bundle.getStringArray("BreakIteratorClasses");
String rules = bundle.getString(rulesName);
if (classNames[kind].equals("RuleBasedBreakIterator")) {
// Old style (2.8 and previous) Break Iterator.
// Not used by default, but if someone wants to specify the old class
// in some locale's resources, it should still work.
iter = new RuleBasedBreakIterator_Old(rules);
}
else if (classNames[kind].equals("RuleBasedBreakIterator_New")) {
// Class for new RBBI engine.
// Open a stream to the .brk file. Path to the brk files has this form:
// data/icudt30b/line.brk (30 is version number)
try {
String rulesFileName = ICUResourceBundle.ICU_BUNDLE +"/"+ KIND_NAMES_2[kind] + ".brk";
InputStream is = ICUData.getRequiredStream(rulesFileName);
iter = RuleBasedBreakIterator_New.getInstanceFromCompiledRules(is);
}
catch (IOException e) {
throw new IllegalArgumentException(e.toString());
}
}
else if (classNames[kind].equals("DictionaryBasedBreakIterator")) {
try {
InputStream dictionary = ICUData.getStream(bundle.getString(dictionaryName));
// System.out.println("bundle: " + bundle + " dn: " + dictionaryName);
// Object t = bundle.getObject(dictionaryName);
// // System.out.println(t);
// URL url = (URL)t;
// System.out.println("url: " + url);
// InputStream dictionary = url.openStream();
// System.out.println("stream: " + dictionary);
iter = new DictionaryBasedBreakIterator(rules, dictionary);
}
catch(IOException e) {
assert false : e;
}
catch(MissingResourceException e) {
assert false : e;
}
// TODO: we don't have 'bad' resource data, so this should never happen
// in our current tests.
///CLOVER:OFF
if (iter == null) {
iter = new RuleBasedBreakIterator_Old(rules);
}
///CLOVER:ON
}
else {
// TODO: we don't have 'bad' resource data, so this should never happen
// in our current tests.
///CLOVER:OFF
throw new IllegalArgumentException("Invalid break iterator class \"" +
classNames[kind] + "\"");
///CLOVER:ON
}
// TODO: Determine valid and actual locale correctly.
ULocale uloc = ULocale.forLocale(bundle.getLocale());
iter.setLocale(uloc, uloc);
return iter;
}
}