Zielony Smok - logo witryny

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.