1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.joda.time.chrono;
17
18 import java.lang.ref.WeakReference;
19 import java.text.DateFormatSymbols;
20 import java.util.Locale;
21 import java.util.TreeMap;
22 import java.util.WeakHashMap;
23
24 import org.joda.time.DateTimeFieldType;
25 import org.joda.time.DateTimeUtils;
26 import org.joda.time.IllegalFieldValueException;
27
28
29
30
31
32
33
34 class GJLocaleSymbols {
35 private static final int FAST_CACHE_SIZE = 64;
36
37 private static final GJLocaleSymbols[] cFastCache = new GJLocaleSymbols[FAST_CACHE_SIZE];
38
39 private static WeakHashMap<Locale, GJLocaleSymbols> cCache = new WeakHashMap<Locale, GJLocaleSymbols>();
40
41 public static GJLocaleSymbols forLocale(Locale locale) {
42 if (locale == null) {
43 locale = Locale.getDefault();
44 }
45 int index = System.identityHashCode(locale) & (FAST_CACHE_SIZE - 1);
46 GJLocaleSymbols symbols = cFastCache[index];
47 if (symbols != null && symbols.iLocale.get() == locale) {
48 return symbols;
49 }
50 synchronized (cCache) {
51 symbols = cCache.get(locale);
52 if (symbols == null) {
53 symbols = new GJLocaleSymbols(locale);
54 cCache.put(locale, symbols);
55 }
56 }
57 cFastCache[index] = symbols;
58 return symbols;
59 }
60
61 private static String[] realignMonths(String[] months) {
62 String[] a = new String[13];
63 for (int i=1; i<13; i++) {
64 a[i] = months[i - 1];
65 }
66 return a;
67 }
68
69 private static String[] realignDaysOfWeek(String[] daysOfWeek) {
70 String[] a = new String[8];
71 for (int i=1; i<8; i++) {
72 a[i] = daysOfWeek[(i < 7) ? i + 1 : 1];
73 }
74 return a;
75 }
76
77 private static void addSymbols(TreeMap<String, Integer> map, String[] symbols, Integer[] integers) {
78 for (int i=symbols.length; --i>=0; ) {
79 String symbol = symbols[i];
80 if (symbol != null) {
81 map.put(symbol, integers[i]);
82 }
83 }
84 }
85
86 private static void addNumerals(TreeMap<String, Integer> map, int start, int end, Integer[] integers) {
87 for (int i=start; i<=end; i++) {
88 map.put(String.valueOf(i).intern(), integers[i]);
89 }
90 }
91
92 private static int maxLength(String[] a) {
93 int max = 0;
94 for (int i=a.length; --i>=0; ) {
95 String s = a[i];
96 if (s != null) {
97 int len = s.length();
98 if (len > max) {
99 max = len;
100 }
101 }
102 }
103 return max;
104 }
105
106 private final WeakReference<Locale> iLocale;
107
108 private final String[] iEras;
109 private final String[] iDaysOfWeek;
110 private final String[] iShortDaysOfWeek;
111 private final String[] iMonths;
112 private final String[] iShortMonths;
113 private final String[] iHalfday;
114
115 private final TreeMap<String, Integer> iParseEras;
116 private final TreeMap<String, Integer> iParseDaysOfWeek;
117 private final TreeMap<String, Integer> iParseMonths;
118
119 private final int iMaxEraLength;
120 private final int iMaxDayOfWeekLength;
121 private final int iMaxShortDayOfWeekLength;
122 private final int iMaxMonthLength;
123 private final int iMaxShortMonthLength;
124 private final int iMaxHalfdayLength;
125
126
127
128
129 private GJLocaleSymbols(Locale locale) {
130 iLocale = new WeakReference<Locale>(locale);
131
132 DateFormatSymbols dfs = DateTimeUtils.getDateFormatSymbols(locale);
133
134 iEras = dfs.getEras();
135 iDaysOfWeek = realignDaysOfWeek(dfs.getWeekdays());
136 iShortDaysOfWeek = realignDaysOfWeek(dfs.getShortWeekdays());
137 iMonths = realignMonths(dfs.getMonths());
138 iShortMonths = realignMonths(dfs.getShortMonths());
139 iHalfday = dfs.getAmPmStrings();
140
141 Integer[] integers = new Integer[13];
142 for (int i=0; i<13; i++) {
143 integers[i] = Integer.valueOf(i);
144 }
145
146 iParseEras = new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);
147 addSymbols(iParseEras, iEras, integers);
148 if ("en".equals(locale.getLanguage())) {
149
150
151
152 iParseEras.put("BCE", integers[0]);
153 iParseEras.put("CE", integers[1]);
154 }
155
156 iParseDaysOfWeek = new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);
157 addSymbols(iParseDaysOfWeek, iDaysOfWeek, integers);
158 addSymbols(iParseDaysOfWeek, iShortDaysOfWeek, integers);
159 addNumerals(iParseDaysOfWeek, 1, 7, integers);
160
161 iParseMonths = new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);
162 addSymbols(iParseMonths, iMonths, integers);
163 addSymbols(iParseMonths, iShortMonths, integers);
164 addNumerals(iParseMonths, 1, 12, integers);
165
166 iMaxEraLength = maxLength(iEras);
167 iMaxDayOfWeekLength = maxLength(iDaysOfWeek);
168 iMaxShortDayOfWeekLength = maxLength(iShortDaysOfWeek);
169 iMaxMonthLength = maxLength(iMonths);
170 iMaxShortMonthLength = maxLength(iShortMonths);
171 iMaxHalfdayLength = maxLength(iHalfday);
172 }
173
174 public String eraValueToText(int value) {
175 return iEras[value];
176 }
177
178 public int eraTextToValue(String text) {
179 Integer era = iParseEras.get(text);
180 if (era != null) {
181 return era.intValue();
182 }
183 throw new IllegalFieldValueException(DateTimeFieldType.era(), text);
184 }
185
186 public int getEraMaxTextLength() {
187 return iMaxEraLength;
188 }
189
190 public String monthOfYearValueToText(int value) {
191 return iMonths[value];
192 }
193
194 public String monthOfYearValueToShortText(int value) {
195 return iShortMonths[value];
196 }
197
198 public int monthOfYearTextToValue(String text) {
199 Integer month = iParseMonths.get(text);
200 if (month != null) {
201 return month.intValue();
202 }
203 throw new IllegalFieldValueException(DateTimeFieldType.monthOfYear(), text);
204 }
205
206 public int getMonthMaxTextLength() {
207 return iMaxMonthLength;
208 }
209
210 public int getMonthMaxShortTextLength() {
211 return iMaxShortMonthLength;
212 }
213
214 public String dayOfWeekValueToText(int value) {
215 return iDaysOfWeek[value];
216 }
217
218 public String dayOfWeekValueToShortText(int value) {
219 return iShortDaysOfWeek[value];
220 }
221
222 public int dayOfWeekTextToValue(String text) {
223 Integer day = iParseDaysOfWeek.get(text);
224 if (day != null) {
225 return day.intValue();
226 }
227 throw new IllegalFieldValueException(DateTimeFieldType.dayOfWeek(), text);
228 }
229
230 public int getDayOfWeekMaxTextLength() {
231 return iMaxDayOfWeekLength;
232 }
233
234 public int getDayOfWeekMaxShortTextLength() {
235 return iMaxShortDayOfWeekLength;
236 }
237
238 public String halfdayValueToText(int value) {
239 return iHalfday[value];
240 }
241
242 public int halfdayTextToValue(String text) {
243 String[] halfday = iHalfday;
244 for (int i = halfday.length; --i>=0; ) {
245 if (halfday[i].equalsIgnoreCase(text)) {
246 return i;
247 }
248 }
249 throw new IllegalFieldValueException(DateTimeFieldType.halfdayOfDay(), text);
250 }
251
252 public int getHalfdayMaxTextLength() {
253 return iMaxHalfdayLength;
254 }
255 }