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