Skip to content

Commit 9f1c860

Browse files
committed
CLDR-17851 update to supplemental calendar date parser per discuss
- memoize to only parse once, make items freezable - store values in fields rather than storing XPathValue
1 parent a20ea88 commit 9f1c860

1 file changed

Lines changed: 71 additions & 31 deletions

File tree

tools/cldr-code/src/main/java/org/unicode/cldr/util/SupplementalCalendarData.java

Lines changed: 71 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package org.unicode.cldr.util;
22

3-
import com.ibm.icu.impl.locale.XCldrStub.ImmutableMap;
3+
import com.google.common.base.Suppliers;
4+
import com.google.common.collect.ComparisonChain;
5+
import com.google.common.collect.ImmutableMap;
6+
import com.ibm.icu.util.Freezable;
47
import com.ibm.icu.util.GregorianCalendar;
58
import java.util.HashMap;
69
import java.util.Iterator;
@@ -15,35 +18,48 @@ public static class EraData implements Comparable<EraData> {
1518
static final int INDEX = 4; // index of our element
1619

1720
/** the <era> xpath */
18-
private final XPathValue xpath;
21+
private final String start;
22+
23+
private final String end;
24+
private final String code;
25+
private final int type;
26+
private final String calendarType; // for comparison
27+
private final GregorianCalendar startCalendar;
28+
private final GregorianCalendar endCalendar;
1929

2030
EraData(final XPathValue xpath) {
21-
this.xpath = xpath;
22-
// TODO: validate (in unit test)
31+
calendarType = xpath.getAttributeValue(2, LDMLConstants.TYPE);
32+
type = Integer.parseInt(xpath.getAttributeValue(INDEX, LDMLConstants.TYPE));
33+
34+
start = xpath.getAttributeValue(INDEX, LDMLConstants.START);
35+
startCalendar = forDateString(start);
36+
end = xpath.getAttributeValue(INDEX, LDMLConstants.END);
37+
endCalendar = forDateString(end);
38+
code = xpath.getAttributeValue(INDEX, LDMLConstants.CODE);
2339
}
2440

2541
public int getType() {
26-
return Integer.parseInt(xpath.getAttributeValue(INDEX, LDMLConstants.TYPE));
42+
return type;
2743
}
2844

2945
public String getStart() {
30-
return xpath.getAttributeValue(INDEX, LDMLConstants.START);
46+
return start;
3147
}
3248

3349
public String getEnd() {
34-
return xpath.getAttributeValue(INDEX, LDMLConstants.END);
50+
return end;
3551
}
3652

3753
public GregorianCalendar getStartCalendar() {
38-
return forDateString(getStart());
54+
return startCalendar;
3955
}
4056

4157
public GregorianCalendar getEndCalendar() {
42-
return forDateString(getEnd());
58+
return endCalendar;
4359
}
4460

4561
public String getCode() {
46-
return xpath.getAttributeValue(INDEX, LDMLConstants.CODE);
62+
return code;
4763
}
4864

4965
public String[] getAliases() {
@@ -86,38 +102,32 @@ private GregorianCalendar getLatest() {
86102
/** only works within the same cal system */
87103
@Override
88104
public int compareTo(EraData o) {
89-
final GregorianCalendar l = getLatest();
90-
final GregorianCalendar ol = o.getLatest();
91-
if (l == null || ol == null) {
92-
// compare by id
93-
return Integer.compare(getType(), o.getType());
94-
} else {
95-
// compare by date
96-
return l.compareTo(ol);
97-
}
105+
return ComparisonChain.start()
106+
.compare(calendarType, o.calendarType)
107+
.compare(getLatest(), o.getLatest())
108+
.compare(getType(), o.getType())
109+
.result();
98110
}
99111
}
100112

101113
/** a <calendar type=> element */
102-
public static class CalendarData implements Iterable<Integer> {
114+
public static class CalendarData implements Iterable<Integer>, Freezable<CalendarData> {
103115
static final int INDEX = 3; // index of our element
104116

105117
/** the <calendarSystem> xpath */
106-
private XPathValue system = null;
118+
private String system = null;
107119

108120
/** the <inheritEras> xpath */
109-
private XPathValue inheritEras = null;
121+
private String inheritEras = null;
110122

111123
private Map<Integer, EraData> eras = new HashMap<Integer, EraData>();
112124

113125
public String getSystemType() {
114-
if (system == null) return null;
115-
return system.getAttributeValue(INDEX, LDMLConstants.TYPE);
126+
return system;
116127
}
117128

118129
public String getInheritEras() {
119-
if (inheritEras == null) return null;
120-
return inheritEras.getAttributeValue(INDEX, LDMLConstants.CALENDAR);
130+
return inheritEras;
121131
}
122132

123133
@Override
@@ -128,6 +138,32 @@ public Iterator<Integer> iterator() {
128138
public EraData get(Integer era) {
129139
return eras.get(era);
130140
}
141+
142+
@Override
143+
public CalendarData cloneAsThawed() {
144+
throw new UnsupportedOperationException("Unimplemented 'cloneAsThawed'");
145+
}
146+
147+
@Override
148+
public CalendarData freeze() {
149+
eras = ImmutableMap.copyOf(eras);
150+
return this;
151+
}
152+
153+
@Override
154+
public boolean isFrozen() {
155+
return (eras instanceof ImmutableMap);
156+
}
157+
158+
void setSystemXPath(XPathValue xpath) {
159+
if (isFrozen()) throw new UnsupportedOperationException("frozen");
160+
system = xpath.getAttributeValue(INDEX, LDMLConstants.TYPE);
161+
}
162+
163+
void setInheritEras(XPathValue xpath) {
164+
if (isFrozen()) throw new UnsupportedOperationException("frozen");
165+
inheritEras = xpath.getAttributeValue(INDEX, LDMLConstants.CALENDAR);
166+
}
131167
}
132168

133169
private Map<String, CalendarData> typeToCalendar = new HashMap<>();
@@ -194,25 +230,29 @@ private void acceptInheritEras(XPathValue x, CalendarData c) {
194230
if (c.inheritEras != null) {
195231
throw new IllegalArgumentException("Duplicate calendar inheritEras: " + x);
196232
}
197-
c.inheritEras = x;
233+
c.setInheritEras(x);
198234
}
199235

200236
private void acceptCalendarSystem(XPathValue x, CalendarData c) {
201237
if (c.system != null) {
202238
throw new IllegalArgumentException("Duplicate calendar system: " + x);
203239
}
204-
c.system = x;
240+
c.setSystemXPath(x);
205241
}
206242

243+
final Supplier<SupplementalCalendarData> supplier =
244+
Suppliers.memoize(() -> new SupplementalCalendarData(typeToCalendar));
245+
246+
/** Calling get() freezes the data, so, only call get() once all data is loaded. */
207247
@Override
208248
public SupplementalCalendarData get() {
209-
return new SupplementalCalendarData(typeToCalendar);
249+
return supplier.get();
210250
}
211251
}
212252

213253
private SupplementalCalendarData(Map<String, CalendarData> m) {
214-
// TODO: freeze all types
215-
// m.forEach(c -> c.freeze());
254+
// freeze all types
255+
m.values().forEach(c -> c.freeze());
216256
this.typeToCalendar = ImmutableMap.copyOf(m);
217257
}
218258

0 commit comments

Comments
 (0)