11package 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 ;
47import com .ibm .icu .util .GregorianCalendar ;
58import java .util .HashMap ;
69import 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