1 /* |
1 /* |
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package sun.util.calendar; |
26 package sun.util.calendar; |
27 |
27 |
28 import java.io.IOException; |
28 import java.security.AccessController; |
29 import java.util.ArrayList; |
|
30 import java.util.List; |
|
31 import java.util.Properties; |
|
32 import java.util.StringTokenizer; |
|
33 import java.util.TimeZone; |
29 import java.util.TimeZone; |
34 |
30 |
35 /** |
31 /** |
36 * |
32 * |
37 * @author Masayoshi Okutsu |
33 * @author Masayoshi Okutsu |
38 * @since 1.6 |
34 * @since 1.6 |
39 */ |
35 */ |
40 |
36 |
41 public class LocalGregorianCalendar extends BaseCalendar { |
37 public class LocalGregorianCalendar extends BaseCalendar { |
|
38 private static final Era[] JAPANESE_ERAS = { |
|
39 new Era("Meiji", "M", -3218832000000L, true), |
|
40 new Era("Taisho", "T", -1812153600000L, true), |
|
41 new Era("Showa", "S", -1357603200000L, true), |
|
42 new Era("Heisei", "H", 600220800000L, true), |
|
43 }; |
|
44 |
|
45 private static boolean isValidEra(Era newEra, Era[] eras) { |
|
46 Era last = eras[eras.length - 1]; |
|
47 if (last.getSinceDate().getYear() >= newEra.getSinceDate().getYear()) { |
|
48 return false; |
|
49 } |
|
50 // The new era name should be unique. Its abbr may not. |
|
51 String newName = newEra.getName(); |
|
52 for (Era era : eras) { |
|
53 if (era.getName().equals(newName)) { |
|
54 return false; |
|
55 } |
|
56 } |
|
57 return true; |
|
58 } |
|
59 |
42 private String name; |
60 private String name; |
43 private Era[] eras; |
61 private Era[] eras; |
44 |
62 |
45 public static class Date extends BaseCalendar.Date { |
63 public static class Date extends BaseCalendar.Date { |
46 |
64 |
116 return sb.toString(); |
134 return sb.toString(); |
117 } |
135 } |
118 } |
136 } |
119 |
137 |
120 static LocalGregorianCalendar getLocalGregorianCalendar(String name) { |
138 static LocalGregorianCalendar getLocalGregorianCalendar(String name) { |
121 Properties calendarProps; |
139 // Only the Japanese calendar is supported. |
122 try { |
140 if (!"japanese".equals(name)) { |
123 calendarProps = CalendarSystem.getCalendarProperties(); |
|
124 } catch (IOException | IllegalArgumentException e) { |
|
125 throw new InternalError(e); |
|
126 } |
|
127 // Parse calendar.*.eras |
|
128 String props = calendarProps.getProperty("calendar." + name + ".eras"); |
|
129 if (props == null) { |
|
130 return null; |
141 return null; |
131 } |
142 } |
132 List<Era> eras = new ArrayList<>(); |
143 |
133 StringTokenizer eraTokens = new StringTokenizer(props, ";"); |
144 // Append an era to the predefined eras if it's given by the property. |
134 while (eraTokens.hasMoreTokens()) { |
145 String prop = AccessController.doPrivileged( |
135 String items = eraTokens.nextToken().trim(); |
146 new sun.security.action.GetPropertyAction("jdk.calendar.japanese.supplemental.era")); |
136 StringTokenizer itemTokens = new StringTokenizer(items, ","); |
147 if (prop != null) { |
137 String eraName = null; |
148 Era era = parseEraEntry(prop); |
138 boolean localTime = true; |
149 if (era != null) { |
139 long since = 0; |
150 if (isValidEra(era, JAPANESE_ERAS)) { |
140 String abbr = null; |
151 int length = JAPANESE_ERAS.length; |
141 |
152 Era[] eras = new Era[length + 1]; |
142 while (itemTokens.hasMoreTokens()) { |
153 System.arraycopy(JAPANESE_ERAS, 0, eras, 0, length); |
143 String item = itemTokens.nextToken(); |
154 eras[length] = era; |
144 int index = item.indexOf('='); |
155 return new LocalGregorianCalendar(name, eras); |
145 // it must be in the key=value form. |
156 } |
146 if (index == -1) { |
157 } |
|
158 } |
|
159 return new LocalGregorianCalendar(name, JAPANESE_ERAS); |
|
160 } |
|
161 |
|
162 private static Era parseEraEntry(String entry) { |
|
163 String[] keyValuePairs = entry.split(","); |
|
164 String eraName = null; |
|
165 boolean localTime = true; |
|
166 long since = 0; |
|
167 String abbr = null; |
|
168 |
|
169 for (String item : keyValuePairs) { |
|
170 String[] keyvalue = item.split("="); |
|
171 if (keyvalue.length != 2) { |
|
172 return null; |
|
173 } |
|
174 String key = keyvalue[0].trim(); |
|
175 String value = keyvalue[1].trim(); |
|
176 switch (key) { |
|
177 case "name": |
|
178 eraName = value; |
|
179 break; |
|
180 case "since": |
|
181 if (value.endsWith("u")) { |
|
182 localTime = false; |
|
183 value = value.substring(0, value.length() - 1); |
|
184 } |
|
185 try { |
|
186 since = Long.parseLong(value); |
|
187 } catch (NumberFormatException e) { |
147 return null; |
188 return null; |
148 } |
189 } |
149 String key = item.substring(0, index); |
190 break; |
150 String value = item.substring(index + 1); |
191 case "abbr": |
151 if ("name".equals(key)) { |
192 abbr = value; |
152 eraName = value; |
193 break; |
153 } else if ("since".equals(key)) { |
194 default: |
154 if (value.endsWith("u")) { |
195 return null; |
155 localTime = false; |
196 } |
156 since = Long.parseLong(value.substring(0, value.length() - 1)); |
197 } |
157 } else { |
198 if (eraName == null || eraName.isEmpty() |
158 since = Long.parseLong(value); |
199 || abbr == null || abbr.isEmpty()) { |
159 } |
200 return null; |
160 } else if ("abbr".equals(key)) { |
201 } |
161 abbr = value; |
202 return new Era(eraName, abbr, since, localTime); |
162 } else { |
|
163 throw new RuntimeException("Unknown key word: " + key); |
|
164 } |
|
165 } |
|
166 Era era = new Era(eraName, abbr, since, localTime); |
|
167 eras.add(era); |
|
168 } |
|
169 Era[] eraArray = new Era[eras.size()]; |
|
170 eras.toArray(eraArray); |
|
171 |
|
172 return new LocalGregorianCalendar(name, eraArray); |
|
173 } |
203 } |
174 |
204 |
175 private LocalGregorianCalendar(String name, Era[] eras) { |
205 private LocalGregorianCalendar(String name, Era[] eras) { |
176 this.name = name; |
206 this.name = name; |
177 this.eras = eras; |
207 this.eras = eras; |