]> granicus.if.org Git - icu/blob
71326836deee1ab65ada42f5cb79c4627b0d56fb
[icu] /
1 /*
2  ******************************************************************************
3  * Copyright (C) 2007-2009, International Business Machines Corporation and   *
4  * others. All Rights Reserved.                                               *
5  ******************************************************************************
6  */
7
8 package com.ibm.icu.impl.duration.impl;
9
10 import java.io.BufferedReader;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.io.InputStreamReader;
14 import java.io.UnsupportedEncodingException;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.MissingResourceException;
22
23 import com.ibm.icu.impl.ICUData;
24
25 /**
26  * A PeriodFormatterDataService that serves PeriodFormatterData objects based on
27  * data files stored as resources in this directory. These are text files named
28  * after the locale, for example, 'pfd_he_IL.txt' specifies an period formatter
29  * data file for Hebrew as spoken in Israel. Data is in a JSON-like format.
30  */
31 public class ResourceBasedPeriodFormatterDataService extends
32         PeriodFormatterDataService {
33     private Collection<String> availableLocales; // of String
34
35     private PeriodFormatterData lastData = null;
36     private String lastLocale = null;
37     private Map<String, PeriodFormatterData> cache = new HashMap<String, PeriodFormatterData>(); // String -> PeriodFormatterData
38     // private PeriodFormatterData fallbackFormatterData;
39
40     private static final String PATH = "data/";
41
42     private static final ResourceBasedPeriodFormatterDataService singleton = new ResourceBasedPeriodFormatterDataService();
43
44     /**
45      * Returns the singleton instance of this class.
46      */
47     public static ResourceBasedPeriodFormatterDataService getInstance() {
48         return singleton;
49     }
50
51     /**
52      * Constructs the service.
53      */
54     private ResourceBasedPeriodFormatterDataService() {
55         List<String> localeNames = new ArrayList<String>(); // of String
56         InputStream is = ICUData.getRequiredStream(getClass(), PATH
57                 + "index.txt");
58         try {
59             BufferedReader br = new BufferedReader(new InputStreamReader(is,
60                     "UTF-8"));
61             String string = null;
62             while (null != (string = br.readLine())) {
63                 string = string.trim();
64                 if (string.startsWith("#") || string.length() == 0) {
65                     continue;
66                 }
67                 localeNames.add(string);
68             }
69         } catch (IOException e) {
70             throw new IllegalStateException("IO Error reading " + PATH
71                     + "index.txt: " + e.toString());
72         }
73         availableLocales = Collections.unmodifiableList(localeNames);
74     }
75
76     public PeriodFormatterData get(String localeName) {
77         // remove tag info including calendar, we don't use the calendar
78         int x = localeName.indexOf('@');
79         if (x != -1) {
80             localeName = localeName.substring(0, x);
81         }
82
83         synchronized (this) {
84             if (lastLocale != null && lastLocale.equals(localeName)) {
85                 return lastData;
86             }
87
88             PeriodFormatterData ld = cache.get(localeName);
89             if (ld == null) {
90                 String ln = localeName;
91                 while (!availableLocales.contains(ln)) {
92                     int ix = ln.lastIndexOf("_");
93                     if (ix > -1) {
94                         ln = ln.substring(0, ix);
95                     } else if (!"test".equals(ln)) {
96                         ln = "test";
97                     } else {
98                         ln = null;
99                         break;
100                     }
101                 }
102                 if (ln != null) {
103                     String name = PATH + "pfd_" + ln + ".xml";
104                     try {
105                         InputStream is = ICUData.getStream(getClass(), name);
106                         if (is == null) {
107                             throw new MissingResourceException(
108                                     "no resource named " + name, name, "");
109                         } else {
110                             DataRecord dr = DataRecord.read(ln,
111                                     new XMLRecordReader(new InputStreamReader(
112                                             is, "UTF-8")));
113                             if (dr != null) {
114                                 // debug
115                                 // if (false && ln.equals("ar_EG")) {
116                                 // OutputStreamWriter osw = new
117                                 // OutputStreamWriter(System.out, "UTF-8");
118                                 // XMLRecordWriter xrw = new
119                                 // XMLRecordWriter(osw);
120                                 // dr.write(xrw);
121                                 // osw.flush();
122                                 // }
123                                 ld = new PeriodFormatterData(localeName, dr);
124                             }
125                         }
126                     } catch (UnsupportedEncodingException e) {
127                         throw new MissingResourceException(
128                                 "Unhandled Encoding for resource " + name,
129                                 name, "");
130                     }
131                 } else {
132                     throw new MissingResourceException(
133                             "Duration data not found for  " + localeName, PATH,
134                             localeName);
135                 }
136
137                 // if (ld == null) {
138                 // ld = getFallbackFormatterData();
139                 // }
140                 cache.put(localeName, ld);
141             }
142             lastData = ld;
143             lastLocale = localeName;
144
145             return ld;
146         }
147     }
148
149     public Collection<String> getAvailableLocales() {
150         return availableLocales;
151     }
152
153     // PeriodFormatterData getFallbackFormatterData() {
154     // synchronized (this) {
155     // if (fallbackFormatterData == null) {
156     // DataRecord dr = new DataRecord(); // hack, no default, will die if used
157     // fallbackFormatterData = new PeriodFormatterData(null, dr);
158     // }
159     // return fallbackFormatterData;
160     // }
161     // }
162 }