/* ****************************************************************************** * Copyright (C) 2007-2009, International Business Machines Corporation and * * others. All Rights Reserved. * ****************************************************************************** */ package com.ibm.icu.impl.duration.impl; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.MissingResourceException; import com.ibm.icu.impl.ICUData; /** * A PeriodFormatterDataService that serves PeriodFormatterData objects based on * data files stored as resources in this directory. These are text files named * after the locale, for example, 'pfd_he_IL.txt' specifies an period formatter * data file for Hebrew as spoken in Israel. Data is in a JSON-like format. */ public class ResourceBasedPeriodFormatterDataService extends PeriodFormatterDataService { private Collection availableLocales; // of String private PeriodFormatterData lastData = null; private String lastLocale = null; private Map cache = new HashMap(); // String -> PeriodFormatterData // private PeriodFormatterData fallbackFormatterData; private static final String PATH = "data/"; private static final ResourceBasedPeriodFormatterDataService singleton = new ResourceBasedPeriodFormatterDataService(); /** * Returns the singleton instance of this class. */ public static ResourceBasedPeriodFormatterDataService getInstance() { return singleton; } /** * Constructs the service. */ private ResourceBasedPeriodFormatterDataService() { List localeNames = new ArrayList(); // of String InputStream is = ICUData.getRequiredStream(getClass(), PATH + "index.txt"); try { BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String string = null; while (null != (string = br.readLine())) { string = string.trim(); if (string.startsWith("#") || string.length() == 0) { continue; } localeNames.add(string); } } catch (IOException e) { throw new IllegalStateException("IO Error reading " + PATH + "index.txt: " + e.toString()); } availableLocales = Collections.unmodifiableList(localeNames); } public PeriodFormatterData get(String localeName) { // remove tag info including calendar, we don't use the calendar int x = localeName.indexOf('@'); if (x != -1) { localeName = localeName.substring(0, x); } synchronized (this) { if (lastLocale != null && lastLocale.equals(localeName)) { return lastData; } PeriodFormatterData ld = cache.get(localeName); if (ld == null) { String ln = localeName; while (!availableLocales.contains(ln)) { int ix = ln.lastIndexOf("_"); if (ix > -1) { ln = ln.substring(0, ix); } else if (!"test".equals(ln)) { ln = "test"; } else { ln = null; break; } } if (ln != null) { String name = PATH + "pfd_" + ln + ".xml"; try { InputStream is = ICUData.getStream(getClass(), name); if (is == null) { throw new MissingResourceException( "no resource named " + name, name, ""); } else { DataRecord dr = DataRecord.read(ln, new XMLRecordReader(new InputStreamReader( is, "UTF-8"))); if (dr != null) { // debug // if (false && ln.equals("ar_EG")) { // OutputStreamWriter osw = new // OutputStreamWriter(System.out, "UTF-8"); // XMLRecordWriter xrw = new // XMLRecordWriter(osw); // dr.write(xrw); // osw.flush(); // } ld = new PeriodFormatterData(localeName, dr); } } } catch (UnsupportedEncodingException e) { throw new MissingResourceException( "Unhandled Encoding for resource " + name, name, ""); } } else { throw new MissingResourceException( "Duration data not found for " + localeName, PATH, localeName); } // if (ld == null) { // ld = getFallbackFormatterData(); // } cache.put(localeName, ld); } lastData = ld; lastLocale = localeName; return ld; } } public Collection getAvailableLocales() { return availableLocales; } // PeriodFormatterData getFallbackFormatterData() { // synchronized (this) { // if (fallbackFormatterData == null) { // DataRecord dr = new DataRecord(); // hack, no default, will die if used // fallbackFormatterData = new PeriodFormatterData(null, dr); // } // return fallbackFormatterData; // } // } }