| /* |
| ****************************************************************************** |
| * 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<String> availableLocales; // of String |
| |
| private PeriodFormatterData lastData = null; |
| private String lastLocale = null; |
| private Map<String, PeriodFormatterData> cache = new HashMap<String, PeriodFormatterData>(); // 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<String> localeNames = new ArrayList<String>(); // 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<String> 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; |
| // } |
| // } |
| } |