96 import java.time.temporal.TemporalField;
97 import java.time.temporal.TemporalQueries;
98 import java.time.temporal.TemporalQuery;
99 import java.time.temporal.ValueRange;
100 import java.time.temporal.WeekFields;
101 import java.time.zone.ZoneRulesProvider;
102 import java.util.AbstractMap.SimpleImmutableEntry;
103 import java.util.ArrayList;
104 import java.util.Arrays;
105 import java.util.Collections;
106 import java.util.Comparator;
107 import java.util.HashMap;
108 import java.util.HashSet;
109 import java.util.Iterator;
110 import java.util.LinkedHashMap;
111 import java.util.List;
112 import java.util.Locale;
113 import java.util.Map;
114 import java.util.Map.Entry;
115 import java.util.Objects;
116 import java.util.Set;
117 import java.util.TimeZone;
118 import java.util.concurrent.ConcurrentHashMap;
119 import java.util.concurrent.ConcurrentMap;
120
121 import sun.text.spi.JavaTimeDateTimePatternProvider;
122 import sun.util.locale.provider.CalendarDataUtility;
123 import sun.util.locale.provider.LocaleProviderAdapter;
124 import sun.util.locale.provider.TimeZoneNameUtility;
125
126 /**
127 * Builder to create date-time formatters.
128 * <p>
129 * This allows a {@code DateTimeFormatter} to be created.
130 * All date-time formatters are created ultimately using this builder.
131 * <p>
132 * The basic elements of date-time can all be added:
133 * <ul>
134 * <li>Value - a numeric value</li>
135 * <li>Fraction - a fractional value including the decimal place. Always use this when
4106 zname = name;
4107 }
4108 }
4109 buf.append(zname);
4110 return true;
4111 }
4112
4113 // cache per instance for now
4114 private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4115 cachedTree = new HashMap<>();
4116 private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4117 cachedTreeCI = new HashMap<>();
4118
4119 @Override
4120 protected PrefixTree getTree(DateTimeParseContext context) {
4121 if (textStyle == TextStyle.NARROW) {
4122 return super.getTree(context);
4123 }
4124 Locale locale = context.getLocale();
4125 boolean isCaseSensitive = context.isCaseSensitive();
4126 Set<String> regionIds = ZoneRulesProvider.getAvailableZoneIds();
4127 int regionIdsSize = regionIds.size();
4128
4129 Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
4130 isCaseSensitive ? cachedTree : cachedTreeCI;
4131
4132 Entry<Integer, SoftReference<PrefixTree>> entry = null;
4133 PrefixTree tree = null;
4134 String[][] zoneStrings = null;
4135 if ((entry = cached.get(locale)) == null ||
4136 (entry.getKey() != regionIdsSize ||
4137 (tree = entry.getValue().get()) == null)) {
4138 tree = PrefixTree.newTree(context);
4139 zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
4140 for (String[] names : zoneStrings) {
4141 String zid = names[0];
4142 if (!regionIds.contains(zid)) {
4143 continue;
4144 }
4145 tree.add(zid, zid); // don't convert zid -> metazone
4146 zid = ZoneName.toZid(zid, locale);
4147 int i = textStyle == TextStyle.FULL ? 1 : 2;
4148 for (; i < names.length; i += 2) {
4149 tree.add(names[i], zid);
4150 }
4151 }
4152 // if we have a set of preferred zones, need a copy and
4153 // add the preferred zones again to overwrite
4154 if (preferredZones != null) {
4155 for (String[] names : zoneStrings) {
4156 String zid = names[0];
4157 if (!preferredZones.contains(zid) || !regionIds.contains(zid)) {
4158 continue;
4159 }
4160 int i = textStyle == TextStyle.FULL ? 1 : 2;
4161 for (; i < names.length; i += 2) {
4162 tree.add(names[i], zid);
4163 }
4164 }
4165 }
4166 cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
4167 }
4168 return tree;
4169 }
4170 }
4171
4172 //-----------------------------------------------------------------------
4173 /**
4174 * Prints or parses a zone ID.
4175 */
4176 static class ZoneIdPrinterParser implements DateTimePrinterParser {
4177 private final TemporalQuery<ZoneId> query;
|
96 import java.time.temporal.TemporalField;
97 import java.time.temporal.TemporalQueries;
98 import java.time.temporal.TemporalQuery;
99 import java.time.temporal.ValueRange;
100 import java.time.temporal.WeekFields;
101 import java.time.zone.ZoneRulesProvider;
102 import java.util.AbstractMap.SimpleImmutableEntry;
103 import java.util.ArrayList;
104 import java.util.Arrays;
105 import java.util.Collections;
106 import java.util.Comparator;
107 import java.util.HashMap;
108 import java.util.HashSet;
109 import java.util.Iterator;
110 import java.util.LinkedHashMap;
111 import java.util.List;
112 import java.util.Locale;
113 import java.util.Map;
114 import java.util.Map.Entry;
115 import java.util.Objects;
116 import java.util.Optional;
117 import java.util.Set;
118 import java.util.TimeZone;
119 import java.util.concurrent.ConcurrentHashMap;
120 import java.util.concurrent.ConcurrentMap;
121
122 import sun.text.spi.JavaTimeDateTimePatternProvider;
123 import sun.util.locale.provider.CalendarDataUtility;
124 import sun.util.locale.provider.LocaleProviderAdapter;
125 import sun.util.locale.provider.TimeZoneNameUtility;
126
127 /**
128 * Builder to create date-time formatters.
129 * <p>
130 * This allows a {@code DateTimeFormatter} to be created.
131 * All date-time formatters are created ultimately using this builder.
132 * <p>
133 * The basic elements of date-time can all be added:
134 * <ul>
135 * <li>Value - a numeric value</li>
136 * <li>Fraction - a fractional value including the decimal place. Always use this when
4107 zname = name;
4108 }
4109 }
4110 buf.append(zname);
4111 return true;
4112 }
4113
4114 // cache per instance for now
4115 private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4116 cachedTree = new HashMap<>();
4117 private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4118 cachedTreeCI = new HashMap<>();
4119
4120 @Override
4121 protected PrefixTree getTree(DateTimeParseContext context) {
4122 if (textStyle == TextStyle.NARROW) {
4123 return super.getTree(context);
4124 }
4125 Locale locale = context.getLocale();
4126 boolean isCaseSensitive = context.isCaseSensitive();
4127 Set<String> regionIds = new HashSet<>(ZoneRulesProvider.getAvailableZoneIds());
4128 Set<String> nonRegionIds = new HashSet<>(64);
4129 int regionIdsSize = regionIds.size();
4130
4131 Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
4132 isCaseSensitive ? cachedTree : cachedTreeCI;
4133
4134 Entry<Integer, SoftReference<PrefixTree>> entry = null;
4135 PrefixTree tree = null;
4136 String[][] zoneStrings = null;
4137 if ((entry = cached.get(locale)) == null ||
4138 (entry.getKey() != regionIdsSize ||
4139 (tree = entry.getValue().get()) == null)) {
4140 tree = PrefixTree.newTree(context);
4141 zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
4142 for (String[] names : zoneStrings) {
4143 String zid = names[0];
4144 if (!regionIds.remove(zid)) {
4145 nonRegionIds.add(zid);
4146 continue;
4147 }
4148 tree.add(zid, zid); // don't convert zid -> metazone
4149 zid = ZoneName.toZid(zid, locale);
4150 int i = textStyle == TextStyle.FULL ? 1 : 2;
4151 for (; i < names.length; i += 2) {
4152 tree.add(names[i], zid);
4153 }
4154 }
4155
4156 // add names for provider's custom ids
4157 final PrefixTree t = tree;
4158 regionIds.stream()
4159 .filter(zid -> !zid.startsWith("Etc") && !zid.startsWith("GMT"))
4160 .forEach(cid -> {
4161 String[] cidNames = TimeZoneNameUtility.retrieveDisplayNames(cid, locale);
4162 int i = textStyle == TextStyle.FULL ? 1 : 2;
4163 for (; i < cidNames.length; i += 2) {
4164 if (cidNames[i] != null && !cidNames[i].isEmpty()) {
4165 t.add(cidNames[i], cid);
4166 }
4167 }
4168 });
4169
4170 // if we have a set of preferred zones, need a copy and
4171 // add the preferred zones again to overwrite
4172 if (preferredZones != null) {
4173 for (String[] names : zoneStrings) {
4174 String zid = names[0];
4175 if (!preferredZones.contains(zid) || nonRegionIds.contains(zid)) {
4176 continue;
4177 }
4178 int i = textStyle == TextStyle.FULL ? 1 : 2;
4179 for (; i < names.length; i += 2) {
4180 tree.add(names[i], zid);
4181 }
4182 }
4183 }
4184 cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
4185 }
4186 return tree;
4187 }
4188 }
4189
4190 //-----------------------------------------------------------------------
4191 /**
4192 * Prints or parses a zone ID.
4193 */
4194 static class ZoneIdPrinterParser implements DateTimePrinterParser {
4195 private final TemporalQuery<ZoneId> query;
|