Tworzenie usług zlokalizowanych
Wiele klas języka Java jest związana z określoną lokalizacją. Są to klasy:
- BreakIterator
- Collator
- DateFormat
- DateFormatSymbols
- DecimalFormatSymbols
- NumberFormat
- Currency
- Locale
- TimeZone
Czasami istnieje konieczność stworzenia nowej lokalizacji i dostarczenie usług dla tej lokalizacji.
Jeżeli chcemy np. stworzyć nową lokalizację musimy rozszerzyć klasę LocaleNameProvider
, która jest
pochodną klasy LocaleServiceProvider
. W klasie implementującej musimy nadpisać
cztery metody:
- getDisplayCountry()
- getDisplayLanguage()
- getDisplayVariant()
- getAvailableLocales()
Gdy chcemy stworzyć nowy zestaw symboli formatujących dla dat musimy rozszerzyć klasę DataFormatSymbolsProvider
i
nadpisać metody:
- getInstance()
- getAvailableLocales()
Każda z ww klas ma klasę ‘providera’ umieszczoną albo w pakiecie java.text.spi
albo java.util.spi
.
Poniżej pokażemy tworzenie klasy LocaleNameProviderImpl
i klasy DateFormatProviderImpl
.
Pozwolą one na prześledzenie sposobu myślenia twórców tych i innych klas co powinno pozwolić na łatwe tworzenie
nowych lokalizacji i nowych zlokalizowanych serwisów. W tej drugiej klasie pokazany jest sposób użycia klasy
DateFormatSymbols
.
Klasa LocaleNameProviderImpl
package dt13.providers; import java.util.*; import java.util.spi.*; class LocaleNameProviderImpl extends LocaleNameProvider{ private final static Locale[] locales = new Locale[]{new Locale("gd", "GD"), new Locale("pl", "PL"), Locale.US}; @Override public String getDisplayLanguage(String languageCode, Locale locale) { if(languageCode.equals("gd")){ if(locale.equals(locales[0])){ return "grhym"; } else if(locale.equals(locales[1])){ return "język smoczy"; } else if(locale.equals(locales[2])){ return "dragon language"; } } return null; } @Override public String getDisplayCountry(String countryCode, Locale locale) { if(locale.equals(locales[0])){ return "grhymnp"; } else if(locale.equals(locales[1])){ return "Smocza Jama"; } else if(locale.equals(locales[2])){ return "Dragon's Lair"; } return null; } @Override public String getDisplayVariant(String variant, Locale locale) { return null; } @Override public Locale[] getAvailableLocales() { return locales; } }
Użycie klasy
package dt13.providers; import java.util.Locale; class MainProv { public static void main(String[] args) { LocaleNameProviderImpl loc = new LocaleNameProviderImpl(); Locale[] locs = loc.getAvailableLocales(); for (Locale lo : locs) { System.out.println(lo); } System.out.println(loc.getDisplayLanguage("gd", Locale.getDefault())); System.out.println(loc.getDisplayCountry("GD", Locale.getDefault())); } }
gd_GD pl_PL en_US język smoczy Smocza Jama
Klasa DateFormatSymbolsProviderImpl
package dt13.providers; import java.text.*; import java.text.spi.*; import java.util.*; class DateFormatSymbolsProviderImpl extends DateFormatSymbolsProvider{ private final static Locale[] locales = new Locale[]{new Locale("gd", "GD"), new Locale("pl", "PL"), Locale.US}; private final String[] eragd = new String[]{"nde", "ode"}; private final String[] erapl = new String[]{ "nowa smocza era, stara smocza era"}; private final String[] eraus = new String[]{"new dragon era", "old dragon era"}; private final String[] ampmgd = new String[]{"agd", "pgd"}; private final String[] ampmpl = new String[]{"przed południem", "po południu"}; private final String[] ampmus = new String[]{"dgAM", "dgPM"}; private final String[] monthsgd = new String[]{"Pop", "Uo", "Zotz", "Zec", "Yaxkin", "Mol", "Chen", "Zec", "Ceh", "Muan", "Pax", "Kayab", "Cumku"}; private final String[] monthspl = new String[]{"Mata", "Czarne złączenie", "Nietoperz", "Czas podlewania", "Nowe Słońce", "Woda", "Czarny Deszcz", "Biały Rok", "Czerwony Rok", "Mądry Ptak", "Czas siewu", "Zółw", "Spichlerz"}; private final String[] shortmonthspl = new String[]{"Mata", "Złączenie", "Nietoperz", "Podlewanie", "Słońce", "Woda", "Deszcz", "Biały", "Czerwony", "Ptak", "Siew", "Zółw", "Spichlerz"}; private final String[] weekdaysgd = new String[]{"", "Imix", "Ik", "Akbal", "Kan", "Chicchan", "Cimi", "Manik"}; private final String[] weekdayspl = new String[]{"", "Wodny Smok", "Wiatr", "Ciemność", "Jaszczurka", "Niebiański Wąż", "Czaszka", "Smocza Łapa"}; private final String[] shortweekdayspl = new String[]{"", "Smok", "Wiatr", "Ciemność", "Jaszczurka", "Wąż", "Czaszka", "Łapa"}; private final String locPatChars = "GyYMLwWDdFEuaHkKhmsSzZX"; @Override public DateFormatSymbols getInstance(Locale locale) { DateFormatSymbols dfs = new DateFormatSymbols( Locale.getDefault(Locale.Category.FORMAT)); if(locale.equals(locales[0])){ dfs.setEras(eragd); dfs.setAmPmStrings(ampmgd); dfs.setMonths(monthsgd); dfs.setShortMonths(monthsgd); dfs.setWeekdays(weekdaysgd); dfs.setShortWeekdays(weekdaysgd); dfs.setLocalPatternChars(locPatChars); } else if(locale.equals(locales[1])){ dfs.setEras(erapl); dfs.setAmPmStrings(ampmpl); dfs.setMonths(monthspl); dfs.setShortMonths(shortmonthspl); dfs.setWeekdays(weekdayspl); dfs.setShortWeekdays(shortweekdayspl); dfs.setLocalPatternChars(locPatChars); } else if(locale.equals(locales[2])){ dfs.setEras(eraus); dfs.setAmPmStrings(ampmus); dfs.setMonths(monthsgd); dfs.setShortMonths(monthsgd); dfs.setWeekdays(weekdaysgd); dfs.setShortWeekdays(weekdaysgd); dfs.setLocalPatternChars(locPatChars); } return dfs; } @Override public Locale[] getAvailableLocales() { return locales; } }
Użycie klasy
package dt13.providers; import java.text.DateFormatSymbols; import java.util.Locale; class MainSymb { public static void main(String[] args) { DateFormatSymbolsProviderImpl imp = new DateFormatSymbolsProviderImpl(); DateFormatSymbols dfs = imp.getInstance(new Locale("gd", "GD")); String[] months = dfs.getShortMonths(); for (String m : months) { System.out.println(m); } } }
Pop Uo Zotz Zec Yaxkin Mol Chen Zec Ceh Muan Pax Kayab Cumku
Uwagi
Uwagi na temat sposobu umieszczania takich klas w plikach *.jar zawarta jest w dokumentacji Java w opisie klasy
LocaleSeviceProvider
w rozdziale Packaging of Locale Sennsitive Service Provider Implementations.