提交 421115af 编写于 作者: L lana

Merge

...@@ -189,7 +189,6 @@ JAVA_JAVA_java = \ ...@@ -189,7 +189,6 @@ JAVA_JAVA_java = \
java/util/ListResourceBundle.java \ java/util/ListResourceBundle.java \
sun/util/EmptyListResourceBundle.java \ sun/util/EmptyListResourceBundle.java \
java/util/Locale.java \ java/util/Locale.java \
sun/util/locale/AsciiUtil.java \
sun/util/locale/BaseLocale.java \ sun/util/locale/BaseLocale.java \
sun/util/locale/Extension.java \ sun/util/locale/Extension.java \
sun/util/locale/InternalLocaleBuilder.java \ sun/util/locale/InternalLocaleBuilder.java \
...@@ -197,6 +196,7 @@ JAVA_JAVA_java = \ ...@@ -197,6 +196,7 @@ JAVA_JAVA_java = \
sun/util/locale/LocaleExtensions.java \ sun/util/locale/LocaleExtensions.java \
sun/util/locale/LocaleObjectCache.java \ sun/util/locale/LocaleObjectCache.java \
sun/util/locale/LocaleSyntaxException.java \ sun/util/locale/LocaleSyntaxException.java \
sun/util/locale/LocaleUtils.java \
sun/util/locale/ParseStatus.java \ sun/util/locale/ParseStatus.java \
sun/util/locale/StringTokenIterator.java \ sun/util/locale/StringTokenIterator.java \
sun/util/locale/UnicodeLocaleExtension.java \ sun/util/locale/UnicodeLocaleExtension.java \
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package com.sun.media.sound; package com.sun.media.sound;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -439,10 +440,10 @@ public class DLSInstrument extends ModelInstrument { ...@@ -439,10 +440,10 @@ public class DLSInstrument extends ModelInstrument {
} }
public byte[] getGuid() { public byte[] getGuid() {
return guid; return guid == null ? null : Arrays.copyOf(guid, guid.length);
} }
public void setGuid(byte[] guid) { public void setGuid(byte[] guid) {
this.guid = guid; this.guid = guid == null ? null : Arrays.copyOf(guid, guid.length);
} }
} }
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package com.sun.media.sound; package com.sun.media.sound;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import javax.sound.midi.Soundbank; import javax.sound.midi.Soundbank;
import javax.sound.midi.SoundbankResource; import javax.sound.midi.SoundbankResource;
import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFormat;
...@@ -113,10 +114,10 @@ public class DLSSample extends SoundbankResource { ...@@ -113,10 +114,10 @@ public class DLSSample extends SoundbankResource {
} }
public byte[] getGuid() { public byte[] getGuid() {
return guid; return guid == null ? null : Arrays.copyOf(guid, guid.length);
} }
public void setGuid(byte[] guid) { public void setGuid(byte[] guid) {
this.guid = guid; this.guid = guid == null ? null : Arrays.copyOf(guid, guid.length);
} }
} }
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
*/ */
package com.sun.media.sound; package com.sun.media.sound;
import java.util.Arrays;
/** /**
* Connection blocks are used to connect source variable * Connection blocks are used to connect source variable
* to a destination variable. * to a destination variable.
...@@ -117,19 +119,17 @@ public class ModelConnectionBlock { ...@@ -117,19 +119,17 @@ public class ModelConnectionBlock {
} }
public ModelSource[] getSources() { public ModelSource[] getSources() {
return sources; return Arrays.copyOf(sources, sources.length);
} }
public void setSources(ModelSource[] source) { public void setSources(ModelSource[] source) {
this.sources = source; this.sources = source == null ? no_sources : Arrays.copyOf(source, source.length);
} }
public void addSource(ModelSource source) { public void addSource(ModelSource source) {
ModelSource[] oldsources = sources; ModelSource[] oldsources = sources;
sources = new ModelSource[oldsources.length + 1]; sources = new ModelSource[oldsources.length + 1];
for (int i = 0; i < oldsources.length; i++) { System.arraycopy(oldsources, 0, sources, 0, oldsources.length);
sources[i] = oldsources[i];
}
sources[sources.length - 1] = source; sources[sources.length - 1] = source;
} }
} }
...@@ -503,7 +503,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer { ...@@ -503,7 +503,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
firstVoice = true; firstVoice = true;
voiceNo = 0; voiceNo = 0;
int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0)); int tunedKey = (int)(Math.round(tuning.getTuning(noteNumber)/100.0));
play_noteNumber = noteNumber; play_noteNumber = noteNumber;
play_velocity = velocity; play_velocity = velocity;
play_delay = delay; play_delay = delay;
...@@ -607,7 +607,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer { ...@@ -607,7 +607,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
firstVoice = true; firstVoice = true;
voiceNo = 0; voiceNo = 0;
int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0)); int tunedKey = (int)(Math.round(tuning.getTuning(noteNumber)/100.0));
play_noteNumber = noteNumber; play_noteNumber = noteNumber;
play_velocity = lastVelocity[noteNumber]; play_velocity = lastVelocity[noteNumber];
play_releasetriggered = true; play_releasetriggered = true;
...@@ -632,7 +632,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer { ...@@ -632,7 +632,7 @@ public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
int delay = play_delay; int delay = play_delay;
boolean releasetriggered = play_releasetriggered; boolean releasetriggered = play_releasetriggered;
SoftPerformer p = current_instrument.getPerformers()[performerIndex]; SoftPerformer p = current_instrument.getPerformer(performerIndex);
if (firstVoice) { if (firstVoice) {
firstVoice = false; firstVoice = false;
......
...@@ -76,7 +76,12 @@ public class SoftInstrument extends Instrument { ...@@ -76,7 +76,12 @@ public class SoftInstrument extends Instrument {
return data; return data;
} }
/* am: currently getPerformers() is not used (replaced with getPerformer(int))
public SoftPerformer[] getPerformers() { public SoftPerformer[] getPerformers() {
return performers; return performers;
} }
*/
public SoftPerformer getPerformer(int index) {
return performers[index];
}
} }
...@@ -505,7 +505,7 @@ public abstract class SoftMixingDataLine implements DataLine { ...@@ -505,7 +505,7 @@ public abstract class SoftMixingDataLine implements DataLine {
} }
public Control[] getControls() { public Control[] getControls() {
return controls; return Arrays.copyOf(controls, controls.length);
} }
public boolean isControlSupported(Type control) { public boolean isControlSupported(Type control) {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
package com.sun.media.sound; package com.sun.media.sound;
import java.util.Arrays;
import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiDevice.Info; import javax.sound.midi.MidiDevice.Info;
import javax.sound.midi.spi.MidiDeviceProvider; import javax.sound.midi.spi.MidiDeviceProvider;
...@@ -39,7 +40,7 @@ public class SoftProvider extends MidiDeviceProvider { ...@@ -39,7 +40,7 @@ public class SoftProvider extends MidiDeviceProvider {
private static Info[] softinfos = {softinfo}; private static Info[] softinfos = {softinfo};
public MidiDevice.Info[] getDeviceInfo() { public MidiDevice.Info[] getDeviceInfo() {
return softinfos; return Arrays.copyOf(softinfos, softinfos.length);
} }
public MidiDevice getDevice(MidiDevice.Info info) { public MidiDevice getDevice(MidiDevice.Info info) {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package com.sun.media.sound; package com.sun.media.sound;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import javax.sound.midi.Patch; import javax.sound.midi.Patch;
...@@ -234,8 +235,10 @@ public class SoftTuning { ...@@ -234,8 +235,10 @@ public class SoftTuning {
} }
} }
// am: getTuning(int) is more effective.
// currently getTuning() is used only by tests
public double[] getTuning() { public double[] getTuning() {
return tuning; return Arrays.copyOf(tuning, tuning.length);
} }
public double getTuning(int noteNumber) { public double getTuning(int noteNumber) {
......
...@@ -136,8 +136,8 @@ import java.util.Arrays; ...@@ -136,8 +136,8 @@ import java.util.Arrays;
* </pre> * </pre>
* </blockquote> * </blockquote>
* And the output result would be like the following: * And the output result would be like the following:
* <pre>
* <blockquote> * <blockquote>
* <pre>
* Format with -INF : is negative * Format with -INF : is negative
* Format with -1.0 : is negative * Format with -1.0 : is negative
* Format with 0 : is zero or fraction * Format with 0 : is zero or fraction
......
...@@ -51,13 +51,13 @@ import java.util.spi.LocaleNameProvider; ...@@ -51,13 +51,13 @@ import java.util.spi.LocaleNameProvider;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.util.LocaleServiceProviderPool; import sun.util.LocaleServiceProviderPool;
import sun.util.locale.AsciiUtil;
import sun.util.locale.BaseLocale; import sun.util.locale.BaseLocale;
import sun.util.locale.InternalLocaleBuilder; import sun.util.locale.InternalLocaleBuilder;
import sun.util.locale.LanguageTag; import sun.util.locale.LanguageTag;
import sun.util.locale.LocaleExtensions; import sun.util.locale.LocaleExtensions;
import sun.util.locale.LocaleObjectCache; import sun.util.locale.LocaleObjectCache;
import sun.util.locale.LocaleSyntaxException; import sun.util.locale.LocaleSyntaxException;
import sun.util.locale.LocaleUtils;
import sun.util.locale.ParseStatus; import sun.util.locale.ParseStatus;
import sun.util.locale.UnicodeLocaleExtension; import sun.util.locale.UnicodeLocaleExtension;
import sun.util.resources.LocaleData; import sun.util.resources.LocaleData;
...@@ -412,59 +412,59 @@ public final class Locale implements Cloneable, Serializable { ...@@ -412,59 +412,59 @@ public final class Locale implements Cloneable, Serializable {
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale ENGLISH = getInstance("en", "", ""); static public final Locale ENGLISH = createConstant("en", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale FRENCH = getInstance("fr", "", ""); static public final Locale FRENCH = createConstant("fr", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale GERMAN = getInstance("de", "", ""); static public final Locale GERMAN = createConstant("de", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale ITALIAN = getInstance("it", "", ""); static public final Locale ITALIAN = createConstant("it", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale JAPANESE = getInstance("ja", "", ""); static public final Locale JAPANESE = createConstant("ja", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale KOREAN = getInstance("ko", "", ""); static public final Locale KOREAN = createConstant("ko", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale CHINESE = getInstance("zh", "", ""); static public final Locale CHINESE = createConstant("zh", "");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale SIMPLIFIED_CHINESE = getInstance("zh", "CN", ""); static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
/** Useful constant for language. /** Useful constant for language.
*/ */
static public final Locale TRADITIONAL_CHINESE = getInstance("zh", "TW", ""); static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale FRANCE = getInstance("fr", "FR", ""); static public final Locale FRANCE = createConstant("fr", "FR");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale GERMANY = getInstance("de", "DE", ""); static public final Locale GERMANY = createConstant("de", "DE");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale ITALY = getInstance("it", "IT", ""); static public final Locale ITALY = createConstant("it", "IT");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale JAPAN = getInstance("ja", "JP", ""); static public final Locale JAPAN = createConstant("ja", "JP");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale KOREA = getInstance("ko", "KR", ""); static public final Locale KOREA = createConstant("ko", "KR");
/** Useful constant for country. /** Useful constant for country.
*/ */
...@@ -480,19 +480,19 @@ public final class Locale implements Cloneable, Serializable { ...@@ -480,19 +480,19 @@ public final class Locale implements Cloneable, Serializable {
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale UK = getInstance("en", "GB", ""); static public final Locale UK = createConstant("en", "GB");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale US = getInstance("en", "US", ""); static public final Locale US = createConstant("en", "US");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale CANADA = getInstance("en", "CA", ""); static public final Locale CANADA = createConstant("en", "CA");
/** Useful constant for country. /** Useful constant for country.
*/ */
static public final Locale CANADA_FRENCH = getInstance("fr", "CA", ""); static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
/** /**
* Useful constant for the root locale. The root locale is the locale whose * Useful constant for the root locale. The root locale is the locale whose
...@@ -502,7 +502,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -502,7 +502,7 @@ public final class Locale implements Cloneable, Serializable {
* *
* @since 1.6 * @since 1.6
*/ */
static public final Locale ROOT = getInstance("", "", ""); static public final Locale ROOT = createConstant("", "");
/** /**
* The key for the private use extension ('x'). * The key for the private use extension ('x').
...@@ -532,14 +532,14 @@ public final class Locale implements Cloneable, Serializable { ...@@ -532,14 +532,14 @@ public final class Locale implements Cloneable, Serializable {
private static final int DISPLAY_LANGUAGE = 0; private static final int DISPLAY_LANGUAGE = 0;
private static final int DISPLAY_COUNTRY = 1; private static final int DISPLAY_COUNTRY = 1;
private static final int DISPLAY_VARIANT = 2; private static final int DISPLAY_VARIANT = 2;
private static final int DISPLAY_SCRIPT = 3; private static final int DISPLAY_SCRIPT = 3;
/** /**
* Private constructor used by getInstance method * Private constructor used by getInstance method
*/ */
private Locale(BaseLocale baseLocale, LocaleExtensions extensions) { private Locale(BaseLocale baseLocale, LocaleExtensions extensions) {
_baseLocale = baseLocale; this.baseLocale = baseLocale;
_extensions = extensions; this.localeExtensions = extensions;
} }
/** /**
...@@ -572,8 +572,8 @@ public final class Locale implements Cloneable, Serializable { ...@@ -572,8 +572,8 @@ public final class Locale implements Cloneable, Serializable {
if (language== null || country == null || variant == null) { if (language== null || country == null || variant == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
_baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant); baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
_extensions = getCompatibilityExtensions(language, "", country, variant); localeExtensions = getCompatibilityExtensions(language, "", country, variant);
} }
/** /**
...@@ -626,6 +626,15 @@ public final class Locale implements Cloneable, Serializable { ...@@ -626,6 +626,15 @@ public final class Locale implements Cloneable, Serializable {
this(language, "", ""); this(language, "", "");
} }
/**
* This method must be called only for creating the Locale.*
* constants due to making shortcuts.
*/
private static Locale createConstant(String lang, String country) {
BaseLocale base = BaseLocale.createInstance(lang, country);
return getInstance(base, null);
}
/** /**
* Returns a <code>Locale</code> constructed from the given * Returns a <code>Locale</code> constructed from the given
* <code>language</code>, <code>country</code> and * <code>language</code>, <code>country</code> and
...@@ -641,7 +650,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -641,7 +650,7 @@ public final class Locale implements Cloneable, Serializable {
* @exception NullPointerException if any argument is null. * @exception NullPointerException if any argument is null.
*/ */
static Locale getInstance(String language, String country, String variant) { static Locale getInstance(String language, String country, String variant) {
return getInstance(language, "", country, variant, LocaleExtensions.EMPTY_EXTENSIONS); return getInstance(language, "", country, variant, null);
} }
static Locale getInstance(String language, String script, String country, static Locale getInstance(String language, String script, String country,
...@@ -651,10 +660,6 @@ public final class Locale implements Cloneable, Serializable { ...@@ -651,10 +660,6 @@ public final class Locale implements Cloneable, Serializable {
} }
if (extensions == null) { if (extensions == null) {
extensions = LocaleExtensions.EMPTY_EXTENSIONS;
}
if (extensions.equals(LocaleExtensions.EMPTY_EXTENSIONS)) {
extensions = getCompatibilityExtensions(language, script, country, variant); extensions = getCompatibilityExtensions(language, script, country, variant);
} }
...@@ -668,22 +673,33 @@ public final class Locale implements Cloneable, Serializable { ...@@ -668,22 +673,33 @@ public final class Locale implements Cloneable, Serializable {
} }
private static class Cache extends LocaleObjectCache<LocaleKey, Locale> { private static class Cache extends LocaleObjectCache<LocaleKey, Locale> {
public Cache() { private Cache() {
} }
@Override
protected Locale createObject(LocaleKey key) { protected Locale createObject(LocaleKey key) {
return new Locale(key._base, key._exts); return new Locale(key.base, key.exts);
} }
} }
private static class LocaleKey { private static final class LocaleKey {
private BaseLocale _base; private final BaseLocale base;
private LocaleExtensions _exts; private final LocaleExtensions exts;
private final int hash;
private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) { private LocaleKey(BaseLocale baseLocale, LocaleExtensions extensions) {
_base = baseLocale; base = baseLocale;
_exts = extensions; exts = extensions;
// Calculate the hash value here because it's always used.
int h = base.hashCode();
if (exts != null) {
h ^= exts.hashCode();
}
hash = h;
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
...@@ -692,11 +708,18 @@ public final class Locale implements Cloneable, Serializable { ...@@ -692,11 +708,18 @@ public final class Locale implements Cloneable, Serializable {
return false; return false;
} }
LocaleKey other = (LocaleKey)obj; LocaleKey other = (LocaleKey)obj;
return _base.equals(other._base) && _exts.equals(other._exts); if (hash != other.hash || !base.equals(other.base)) {
return false;
}
if (exts == null) {
return other.exts == null;
}
return exts.equals(other.exts);
} }
@Override
public int hashCode() { public int hashCode() {
return _base.hashCode() ^ _exts.hashCode(); return hash;
} }
} }
...@@ -981,7 +1004,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -981,7 +1004,7 @@ public final class Locale implements Cloneable, Serializable {
* @see #getDisplayLanguage * @see #getDisplayLanguage
*/ */
public String getLanguage() { public String getLanguage() {
return _baseLocale.getLanguage(); return baseLocale.getLanguage();
} }
/** /**
...@@ -995,7 +1018,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -995,7 +1018,7 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public String getScript() { public String getScript() {
return _baseLocale.getScript(); return baseLocale.getScript();
} }
/** /**
...@@ -1007,7 +1030,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1007,7 +1030,7 @@ public final class Locale implements Cloneable, Serializable {
* @see #getDisplayCountry * @see #getDisplayCountry
*/ */
public String getCountry() { public String getCountry() {
return _baseLocale.getRegion(); return baseLocale.getRegion();
} }
/** /**
...@@ -1017,7 +1040,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1017,7 +1040,7 @@ public final class Locale implements Cloneable, Serializable {
* @see #getDisplayVariant * @see #getDisplayVariant
*/ */
public String getVariant() { public String getVariant() {
return _baseLocale.getVariant(); return baseLocale.getVariant();
} }
/** /**
...@@ -1039,7 +1062,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1039,7 +1062,7 @@ public final class Locale implements Cloneable, Serializable {
if (!LocaleExtensions.isValidKey(key)) { if (!LocaleExtensions.isValidKey(key)) {
throw new IllegalArgumentException("Ill-formed extension key: " + key); throw new IllegalArgumentException("Ill-formed extension key: " + key);
} }
return _extensions.getExtensionValue(key); return (localeExtensions == null) ? null : localeExtensions.getExtensionValue(key);
} }
/** /**
...@@ -1052,7 +1075,10 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1052,7 +1075,10 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public Set<Character> getExtensionKeys() { public Set<Character> getExtensionKeys() {
return _extensions.getKeys(); if (localeExtensions == null) {
return Collections.emptySet();
}
return localeExtensions.getKeys();
} }
/** /**
...@@ -1064,7 +1090,10 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1064,7 +1090,10 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public Set<String> getUnicodeLocaleAttributes() { public Set<String> getUnicodeLocaleAttributes() {
return _extensions.getUnicodeLocaleAttributes(); if (localeExtensions == null) {
return Collections.emptySet();
}
return localeExtensions.getUnicodeLocaleAttributes();
} }
/** /**
...@@ -1085,7 +1114,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1085,7 +1114,7 @@ public final class Locale implements Cloneable, Serializable {
if (!UnicodeLocaleExtension.isKey(key)) { if (!UnicodeLocaleExtension.isKey(key)) {
throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key); throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key);
} }
return _extensions.getUnicodeLocaleType(key); return (localeExtensions == null) ? null : localeExtensions.getUnicodeLocaleType(key);
} }
/** /**
...@@ -1097,7 +1126,10 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1097,7 +1126,10 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public Set<String> getUnicodeLocaleKeys() { public Set<String> getUnicodeLocaleKeys() {
return _extensions.getUnicodeLocaleKeys(); if (localeExtensions == null) {
return Collections.emptySet();
}
return localeExtensions.getUnicodeLocaleKeys();
} }
/** /**
...@@ -1106,16 +1138,17 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1106,16 +1138,17 @@ public final class Locale implements Cloneable, Serializable {
* @return base locale of this Locale * @return base locale of this Locale
*/ */
BaseLocale getBaseLocale() { BaseLocale getBaseLocale() {
return _baseLocale; return baseLocale;
} }
/** /**
* Package local method returning the Locale's LocaleExtensions, * Package private method returning the Locale's LocaleExtensions,
* used by ResourceBundle * used by ResourceBundle.
* @return locale exnteions of this Locale * @return locale exnteions of this Locale,
* or {@code null} if no extensions are defined
*/ */
LocaleExtensions getLocaleExtensions() { LocaleExtensions getLocaleExtensions() {
return _extensions; return localeExtensions;
} }
/** /**
...@@ -1160,26 +1193,27 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1160,26 +1193,27 @@ public final class Locale implements Cloneable, Serializable {
* @see #getDisplayName * @see #getDisplayName
* @see #toLanguageTag * @see #toLanguageTag
*/ */
@Override
public final String toString() { public final String toString() {
boolean l = (_baseLocale.getLanguage().length() != 0); boolean l = (baseLocale.getLanguage().length() != 0);
boolean s = (_baseLocale.getScript().length() != 0); boolean s = (baseLocale.getScript().length() != 0);
boolean r = (_baseLocale.getRegion().length() != 0); boolean r = (baseLocale.getRegion().length() != 0);
boolean v = (_baseLocale.getVariant().length() != 0); boolean v = (baseLocale.getVariant().length() != 0);
boolean e = (_extensions.getID().length() != 0); boolean e = (localeExtensions != null && localeExtensions.getID().length() != 0);
StringBuilder result = new StringBuilder(_baseLocale.getLanguage()); StringBuilder result = new StringBuilder(baseLocale.getLanguage());
if (r || (l && (v || s || e))) { if (r || (l && (v || s || e))) {
result.append('_') result.append('_')
.append(_baseLocale.getRegion()); // This may just append '_' .append(baseLocale.getRegion()); // This may just append '_'
} }
if (v && (l || r)) { if (v && (l || r)) {
result.append('_') result.append('_')
.append(_baseLocale.getVariant()); .append(baseLocale.getVariant());
} }
if (s && (l || r)) { if (s && (l || r)) {
result.append("_#") result.append("_#")
.append(_baseLocale.getScript()); .append(baseLocale.getScript());
} }
if (e && (l || r)) { if (e && (l || r)) {
...@@ -1187,7 +1221,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1187,7 +1221,7 @@ public final class Locale implements Cloneable, Serializable {
if (!s) { if (!s) {
result.append('#'); result.append('#');
} }
result.append(_extensions.getID()); result.append(localeExtensions.getID());
} }
return result.toString(); return result.toString();
...@@ -1261,7 +1295,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1261,7 +1295,7 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public String toLanguageTag() { public String toLanguageTag() {
LanguageTag tag = LanguageTag.parseLocale(_baseLocale, _extensions); LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
String subtag = tag.getLanguage(); String subtag = tag.getLanguage();
...@@ -1433,8 +1467,9 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1433,8 +1467,9 @@ public final class Locale implements Cloneable, Serializable {
bldr.setLanguageTag(tag); bldr.setLanguageTag(tag);
BaseLocale base = bldr.getBaseLocale(); BaseLocale base = bldr.getBaseLocale();
LocaleExtensions exts = bldr.getLocaleExtensions(); LocaleExtensions exts = bldr.getLocaleExtensions();
if (exts.isEmpty() && base.getVariant().length() > 0) { if (exts == null && base.getVariant().length() > 0) {
exts = getCompatibilityExtensions(base.getLanguage(), base.getScript(), base.getRegion(), base.getVariant()); exts = getCompatibilityExtensions(base.getLanguage(), base.getScript(),
base.getRegion(), base.getVariant());
} }
return getInstance(base, exts); return getInstance(base, exts);
} }
...@@ -1454,7 +1489,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1454,7 +1489,7 @@ public final class Locale implements Cloneable, Serializable {
* three-letter language abbreviation is not available for this locale. * three-letter language abbreviation is not available for this locale.
*/ */
public String getISO3Language() throws MissingResourceException { public String getISO3Language() throws MissingResourceException {
String lang = _baseLocale.getLanguage(); String lang = baseLocale.getLanguage();
if (lang.length() == 3) { if (lang.length() == 3) {
return lang; return lang;
} }
...@@ -1481,10 +1516,10 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1481,10 +1516,10 @@ public final class Locale implements Cloneable, Serializable {
* three-letter country abbreviation is not available for this locale. * three-letter country abbreviation is not available for this locale.
*/ */
public String getISO3Country() throws MissingResourceException { public String getISO3Country() throws MissingResourceException {
String country3 = getISO3Code(_baseLocale.getRegion(), LocaleISOData.isoCountryTable); String country3 = getISO3Code(baseLocale.getRegion(), LocaleISOData.isoCountryTable);
if (country3 == null) { if (country3 == null) {
throw new MissingResourceException("Couldn't find 3-letter country code for " throw new MissingResourceException("Couldn't find 3-letter country code for "
+ _baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry"); + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
} }
return country3; return country3;
} }
...@@ -1542,7 +1577,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1542,7 +1577,7 @@ public final class Locale implements Cloneable, Serializable {
* @exception NullPointerException if <code>inLocale</code> is <code>null</code> * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
*/ */
public String getDisplayLanguage(Locale inLocale) { public String getDisplayLanguage(Locale inLocale) {
return getDisplayString(_baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE); return getDisplayString(baseLocale.getLanguage(), inLocale, DISPLAY_LANGUAGE);
} }
/** /**
...@@ -1568,7 +1603,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1568,7 +1603,7 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public String getDisplayScript(Locale inLocale) { public String getDisplayScript(Locale inLocale) {
return getDisplayString(_baseLocale.getScript(), inLocale, DISPLAY_SCRIPT); return getDisplayString(baseLocale.getScript(), inLocale, DISPLAY_SCRIPT);
} }
/** /**
...@@ -1603,7 +1638,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1603,7 +1638,7 @@ public final class Locale implements Cloneable, Serializable {
* @exception NullPointerException if <code>inLocale</code> is <code>null</code> * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
*/ */
public String getDisplayCountry(Locale inLocale) { public String getDisplayCountry(Locale inLocale) {
return getDisplayString(_baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY); return getDisplayString(baseLocale.getRegion(), inLocale, DISPLAY_COUNTRY);
} }
private String getDisplayString(String code, Locale inLocale, int type) { private String getDisplayString(String code, Locale inLocale, int type) {
...@@ -1662,7 +1697,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1662,7 +1697,7 @@ public final class Locale implements Cloneable, Serializable {
* @exception NullPointerException if <code>inLocale</code> is <code>null</code> * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
*/ */
public String getDisplayVariant(Locale inLocale) { public String getDisplayVariant(Locale inLocale) {
if (_baseLocale.getVariant().length() == 0) if (baseLocale.getVariant().length() == 0)
return ""; return "";
OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale); OpenListResourceBundle bundle = LocaleData.getLocaleNames(inLocale);
...@@ -1758,7 +1793,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1758,7 +1793,7 @@ public final class Locale implements Cloneable, Serializable {
return formatList(variantNames, listPattern, listCompositionPattern); return formatList(variantNames, listPattern, listCompositionPattern);
} }
} }
ArrayList<String> names = new ArrayList<String>(4); ArrayList<String> names = new ArrayList<>(4);
if (languageName.length() != 0) { if (languageName.length() != 0) {
names.add(languageName); names.add(languageName);
} }
...@@ -1833,10 +1868,14 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1833,10 +1868,14 @@ public final class Locale implements Cloneable, Serializable {
* Since Locales are often used in hashtables, caches the value * Since Locales are often used in hashtables, caches the value
* for speed. * for speed.
*/ */
@Override
public int hashCode() { public int hashCode() {
int hc = hashCodeValue; int hc = hashCodeValue;
if (hc == 0) { if (hc == 0) {
hc = _baseLocale.hashCode() ^ _extensions.hashCode(); hc = baseLocale.hashCode();
if (localeExtensions != null) {
hc ^= localeExtensions.hashCode();
}
hashCodeValue = hc; hashCodeValue = hc;
} }
return hc; return hc;
...@@ -1851,21 +1890,26 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1851,21 +1890,26 @@ public final class Locale implements Cloneable, Serializable {
* *
* @return true if this Locale is equal to the specified object. * @return true if this Locale is equal to the specified object.
*/ */
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) // quick check if (this == obj) // quick check
return true; return true;
if (!(obj instanceof Locale)) if (!(obj instanceof Locale))
return false; return false;
BaseLocale otherBase = ((Locale)obj)._baseLocale; BaseLocale otherBase = ((Locale)obj).baseLocale;
LocaleExtensions otherExt = ((Locale)obj)._extensions; if (!baseLocale.equals(otherBase)) {
return _baseLocale.equals(otherBase) && _extensions.equals(otherExt); return false;
}
if (localeExtensions == null) {
return ((Locale)obj).localeExtensions == null;
}
return localeExtensions.equals(((Locale)obj).localeExtensions);
} }
// ================= privates ===================================== // ================= privates =====================================
private transient BaseLocale _baseLocale; private transient BaseLocale baseLocale;
private transient LocaleExtensions _extensions; private transient LocaleExtensions localeExtensions;
/** /**
* Calculated hashcode * Calculated hashcode
...@@ -1883,7 +1927,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1883,7 +1927,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
private String[] getDisplayVariantArray(OpenListResourceBundle bundle, Locale inLocale) { private String[] getDisplayVariantArray(OpenListResourceBundle bundle, Locale inLocale) {
// Split the variant name into tokens separated by '_'. // Split the variant name into tokens separated by '_'.
StringTokenizer tokenizer = new StringTokenizer(_baseLocale.getVariant(), "_"); StringTokenizer tokenizer = new StringTokenizer(baseLocale.getVariant(), "_");
String[] names = new String[tokenizer.countTokens()]; String[] names = new String[tokenizer.countTokens()];
// For each variant token, lookup the display name. If // For each variant token, lookup the display name. If
...@@ -1996,11 +2040,11 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1996,11 +2040,11 @@ public final class Locale implements Cloneable, Serializable {
*/ */
private void writeObject(ObjectOutputStream out) throws IOException { private void writeObject(ObjectOutputStream out) throws IOException {
ObjectOutputStream.PutField fields = out.putFields(); ObjectOutputStream.PutField fields = out.putFields();
fields.put("language", _baseLocale.getLanguage()); fields.put("language", baseLocale.getLanguage());
fields.put("script", _baseLocale.getScript()); fields.put("script", baseLocale.getScript());
fields.put("country", _baseLocale.getRegion()); fields.put("country", baseLocale.getRegion());
fields.put("variant", _baseLocale.getVariant()); fields.put("variant", baseLocale.getVariant());
fields.put("extensions", _extensions.getID()); fields.put("extensions", localeExtensions == null ? "" : localeExtensions.getID());
fields.put("hashcode", -1); // place holder just for backward support fields.put("hashcode", -1); // place holder just for backward support
out.writeFields(); out.writeFields();
} }
...@@ -2020,13 +2064,17 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2020,13 +2064,17 @@ public final class Locale implements Cloneable, Serializable {
String country = (String)fields.get("country", ""); String country = (String)fields.get("country", "");
String variant = (String)fields.get("variant", ""); String variant = (String)fields.get("variant", "");
String extStr = (String)fields.get("extensions", ""); String extStr = (String)fields.get("extensions", "");
_baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant); baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
try { if (extStr.length() > 0) {
InternalLocaleBuilder bldr = new InternalLocaleBuilder(); try {
bldr.setExtensions(extStr); InternalLocaleBuilder bldr = new InternalLocaleBuilder();
_extensions = bldr.getLocaleExtensions(); bldr.setExtensions(extStr);
} catch (LocaleSyntaxException e) { localeExtensions = bldr.getLocaleExtensions();
throw new IllformedLocaleException(e.getMessage()); } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage());
}
} else {
localeExtensions = null;
} }
} }
...@@ -2045,8 +2093,8 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2045,8 +2093,8 @@ public final class Locale implements Cloneable, Serializable {
* @throws java.io.ObjectStreamException * @throws java.io.ObjectStreamException
*/ */
private Object readResolve() throws java.io.ObjectStreamException { private Object readResolve() throws java.io.ObjectStreamException {
return getInstance(_baseLocale.getLanguage(), _baseLocale.getScript(), return getInstance(baseLocale.getLanguage(), baseLocale.getScript(),
_baseLocale.getRegion(), _baseLocale.getVariant(), _extensions); baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
} }
private static volatile String[] isoLanguages = null; private static volatile String[] isoLanguages = null;
...@@ -2056,7 +2104,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2056,7 +2104,7 @@ public final class Locale implements Cloneable, Serializable {
private static String convertOldISOCodes(String language) { private static String convertOldISOCodes(String language) {
// we accept both the old and the new ISO codes for the languages whose ISO // we accept both the old and the new ISO codes for the languages whose ISO
// codes have changed, but we always store the OLD code, for backward compatibility // codes have changed, but we always store the OLD code, for backward compatibility
language = AsciiUtil.toLowerString(language).intern(); language = LocaleUtils.toLowerString(language).intern();
if (language == "he") { if (language == "he") {
return "iw"; return "iw";
} else if (language == "yi") { } else if (language == "yi") {
...@@ -2068,19 +2116,22 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2068,19 +2116,22 @@ public final class Locale implements Cloneable, Serializable {
} }
} }
private static LocaleExtensions getCompatibilityExtensions(String language, String script, String country, String variant) { private static LocaleExtensions getCompatibilityExtensions(String language,
LocaleExtensions extensions = LocaleExtensions.EMPTY_EXTENSIONS; String script,
String country,
String variant) {
LocaleExtensions extensions = null;
// Special cases for backward compatibility support // Special cases for backward compatibility support
if (AsciiUtil.caseIgnoreMatch(language, "ja") if (LocaleUtils.caseIgnoreMatch(language, "ja")
&& script.length() == 0 && script.length() == 0
&& AsciiUtil.caseIgnoreMatch(country, "JP") && LocaleUtils.caseIgnoreMatch(country, "jp")
&& AsciiUtil.caseIgnoreMatch(variant, "JP")) { && "JP".equals(variant)) {
// ja_JP_JP -> u-ca-japanese (calendar = japanese) // ja_JP_JP -> u-ca-japanese (calendar = japanese)
extensions = LocaleExtensions.CALENDAR_JAPANESE; extensions = LocaleExtensions.CALENDAR_JAPANESE;
} else if (AsciiUtil.caseIgnoreMatch(language, "th") } else if (LocaleUtils.caseIgnoreMatch(language, "th")
&& script.length() == 0 && script.length() == 0
&& AsciiUtil.caseIgnoreMatch(country, "TH") && LocaleUtils.caseIgnoreMatch(country, "th")
&& AsciiUtil.caseIgnoreMatch(variant, "TH")) { && "TH".equals(variant)) {
// th_TH_TH -> u-nu-thai (numbersystem = thai) // th_TH_TH -> u-nu-thai (numbersystem = thai)
extensions = LocaleExtensions.NUMBER_THAI; extensions = LocaleExtensions.NUMBER_THAI;
} }
...@@ -2196,7 +2247,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2196,7 +2247,7 @@ public final class Locale implements Cloneable, Serializable {
* @since 1.7 * @since 1.7
*/ */
public static final class Builder { public static final class Builder {
private InternalLocaleBuilder _locbld; private final InternalLocaleBuilder localeBuilder;
/** /**
* Constructs an empty Builder. The default value of all * Constructs an empty Builder. The default value of all
...@@ -2204,7 +2255,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2204,7 +2255,7 @@ public final class Locale implements Cloneable, Serializable {
* empty string. * empty string.
*/ */
public Builder() { public Builder() {
_locbld = new InternalLocaleBuilder(); localeBuilder = new InternalLocaleBuilder();
} }
/** /**
...@@ -2229,7 +2280,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2229,7 +2280,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setLocale(Locale locale) { public Builder setLocale(Locale locale) {
try { try {
_locbld.setLocale(locale._baseLocale, locale._extensions); localeBuilder.setLocale(locale.baseLocale, locale.localeExtensions);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2259,8 +2310,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2259,8 +2310,7 @@ public final class Locale implements Cloneable, Serializable {
if (sts.isError()) { if (sts.isError()) {
throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex()); throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
} }
_locbld.setLanguageTag(tag); localeBuilder.setLanguageTag(tag);
return this; return this;
} }
...@@ -2279,7 +2329,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2279,7 +2329,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setLanguage(String language) { public Builder setLanguage(String language) {
try { try {
_locbld.setLanguage(language); localeBuilder.setLanguage(language);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2300,7 +2350,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2300,7 +2350,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setScript(String script) { public Builder setScript(String script) {
try { try {
_locbld.setScript(script); localeBuilder.setScript(script);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2325,7 +2375,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2325,7 +2375,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setRegion(String region) { public Builder setRegion(String region) {
try { try {
_locbld.setRegion(region); localeBuilder.setRegion(region);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2352,7 +2402,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2352,7 +2402,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setVariant(String variant) { public Builder setVariant(String variant) {
try { try {
_locbld.setVariant(variant); localeBuilder.setVariant(variant);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2384,7 +2434,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2384,7 +2434,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setExtension(char key, String value) { public Builder setExtension(char key, String value) {
try { try {
_locbld.setExtension(key, value); localeBuilder.setExtension(key, value);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2414,7 +2464,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2414,7 +2464,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder setUnicodeLocaleKeyword(String key, String type) { public Builder setUnicodeLocaleKeyword(String key, String type) {
try { try {
_locbld.setUnicodeLocaleKeyword(key, type); localeBuilder.setUnicodeLocaleKeyword(key, type);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2435,7 +2485,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2435,7 +2485,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder addUnicodeLocaleAttribute(String attribute) { public Builder addUnicodeLocaleAttribute(String attribute) {
try { try {
_locbld.addUnicodeLocaleAttribute(attribute); localeBuilder.addUnicodeLocaleAttribute(attribute);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2458,7 +2508,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2458,7 +2508,7 @@ public final class Locale implements Cloneable, Serializable {
*/ */
public Builder removeUnicodeLocaleAttribute(String attribute) { public Builder removeUnicodeLocaleAttribute(String attribute) {
try { try {
_locbld.removeUnicodeLocaleAttribute(attribute); localeBuilder.removeUnicodeLocaleAttribute(attribute);
} catch (LocaleSyntaxException e) { } catch (LocaleSyntaxException e) {
throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex()); throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
} }
...@@ -2471,7 +2521,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2471,7 +2521,7 @@ public final class Locale implements Cloneable, Serializable {
* @return This builder. * @return This builder.
*/ */
public Builder clear() { public Builder clear() {
_locbld.clear(); localeBuilder.clear();
return this; return this;
} }
...@@ -2483,7 +2533,7 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2483,7 +2533,7 @@ public final class Locale implements Cloneable, Serializable {
* @see #setExtension(char, String) * @see #setExtension(char, String)
*/ */
public Builder clearExtensions() { public Builder clearExtensions() {
_locbld.clearExtensions(); localeBuilder.clearExtensions();
return this; return this;
} }
...@@ -2498,9 +2548,9 @@ public final class Locale implements Cloneable, Serializable { ...@@ -2498,9 +2548,9 @@ public final class Locale implements Cloneable, Serializable {
* @return A Locale. * @return A Locale.
*/ */
public Locale build() { public Locale build() {
BaseLocale baseloc = _locbld.getBaseLocale(); BaseLocale baseloc = localeBuilder.getBaseLocale();
LocaleExtensions extensions = _locbld.getLocaleExtensions(); LocaleExtensions extensions = localeBuilder.getLocaleExtensions();
if (extensions.isEmpty() && baseloc.getVariant().length() > 0) { if (extensions == null && baseloc.getVariant().length() > 0) {
extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(), extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(),
baseloc.getRegion(), baseloc.getVariant()); baseloc.getRegion(), baseloc.getVariant());
} }
......
/* /*
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -57,7 +57,6 @@ import java.util.concurrent.ConcurrentMap; ...@@ -57,7 +57,6 @@ import java.util.concurrent.ConcurrentMap;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import sun.util.locale.BaseLocale; import sun.util.locale.BaseLocale;
import sun.util.locale.LocaleExtensions;
import sun.util.locale.LocaleObjectCache; import sun.util.locale.LocaleObjectCache;
...@@ -290,7 +289,7 @@ public abstract class ResourceBundle { ...@@ -290,7 +289,7 @@ public abstract class ResourceBundle {
* name for compatibility with some workarounds for bug 4212439. * name for compatibility with some workarounds for bug 4212439.
*/ */
private static final ConcurrentMap<CacheKey, BundleReference> cacheList private static final ConcurrentMap<CacheKey, BundleReference> cacheList
= new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE); = new ConcurrentHashMap<>(INITIAL_CACHE_SIZE);
/** /**
* Queue for reference objects referring to class loaders or bundles. * Queue for reference objects referring to class loaders or bundles.
...@@ -1755,7 +1754,7 @@ public abstract class ResourceBundle { ...@@ -1755,7 +1754,7 @@ public abstract class ResourceBundle {
* @since 1.6 * @since 1.6
*/ */
public Set<String> keySet() { public Set<String> keySet() {
Set<String> keys = new HashSet<String>(); Set<String> keys = new HashSet<>();
for (ResourceBundle rb = this; rb != null; rb = rb.parent) { for (ResourceBundle rb = this; rb != null; rb = rb.parent) {
keys.addAll(rb.handleKeySet()); keys.addAll(rb.handleKeySet());
} }
...@@ -1783,7 +1782,7 @@ public abstract class ResourceBundle { ...@@ -1783,7 +1782,7 @@ public abstract class ResourceBundle {
if (keySet == null) { if (keySet == null) {
synchronized (this) { synchronized (this) {
if (keySet == null) { if (keySet == null) {
Set<String> keys = new HashSet<String>(); Set<String> keys = new HashSet<>();
Enumeration<String> enumKeys = getKeys(); Enumeration<String> enumKeys = getKeys();
while (enumKeys.hasMoreElements()) { while (enumKeys.hasMoreElements()) {
String key = enumKeys.nextElement(); String key = enumKeys.nextElement();
...@@ -2301,7 +2300,7 @@ public abstract class ResourceBundle { ...@@ -2301,7 +2300,7 @@ public abstract class ResourceBundle {
if (baseName == null) { if (baseName == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
return new ArrayList<Locale>(CANDIDATES_CACHE.get(locale.getBaseLocale())); return new ArrayList<>(CANDIDATES_CACHE.get(locale.getBaseLocale()));
} }
private static final CandidateListCache CANDIDATES_CACHE = new CandidateListCache(); private static final CandidateListCache CANDIDATES_CACHE = new CandidateListCache();
...@@ -2327,14 +2326,14 @@ public abstract class ResourceBundle { ...@@ -2327,14 +2326,14 @@ public abstract class ResourceBundle {
if (language.equals("nb") || isNorwegianBokmal) { if (language.equals("nb") || isNorwegianBokmal) {
List<Locale> tmpList = getDefaultList("nb", script, region, variant); List<Locale> tmpList = getDefaultList("nb", script, region, variant);
// Insert a locale replacing "nb" with "no" for every list entry // Insert a locale replacing "nb" with "no" for every list entry
List<Locale> bokmalList = new LinkedList<Locale>(); List<Locale> bokmalList = new LinkedList<>();
for (Locale l : tmpList) { for (Locale l : tmpList) {
bokmalList.add(l); bokmalList.add(l);
if (l.getLanguage().length() == 0) { if (l.getLanguage().length() == 0) {
break; break;
} }
bokmalList.add(Locale.getInstance("no", l.getScript(), l.getCountry(), bokmalList.add(Locale.getInstance("no", l.getScript(), l.getCountry(),
l.getVariant(), LocaleExtensions.EMPTY_EXTENSIONS)); l.getVariant(), null));
} }
return bokmalList; return bokmalList;
} else if (language.equals("nn") || isNorwegianNynorsk) { } else if (language.equals("nn") || isNorwegianNynorsk) {
...@@ -2374,7 +2373,7 @@ public abstract class ResourceBundle { ...@@ -2374,7 +2373,7 @@ public abstract class ResourceBundle {
List<String> variants = null; List<String> variants = null;
if (variant.length() > 0) { if (variant.length() > 0) {
variants = new LinkedList<String>(); variants = new LinkedList<>();
int idx = variant.length(); int idx = variant.length();
while (idx != -1) { while (idx != -1) {
variants.add(variant.substring(0, idx)); variants.add(variant.substring(0, idx));
...@@ -2382,32 +2381,32 @@ public abstract class ResourceBundle { ...@@ -2382,32 +2381,32 @@ public abstract class ResourceBundle {
} }
} }
LinkedList<Locale> list = new LinkedList<Locale>(); List<Locale> list = new LinkedList<>();
if (variants != null) { if (variants != null) {
for (String v : variants) { for (String v : variants) {
list.add(Locale.getInstance(language, script, region, v, LocaleExtensions.EMPTY_EXTENSIONS)); list.add(Locale.getInstance(language, script, region, v, null));
} }
} }
if (region.length() > 0) { if (region.length() > 0) {
list.add(Locale.getInstance(language, script, region, "", LocaleExtensions.EMPTY_EXTENSIONS)); list.add(Locale.getInstance(language, script, region, "", null));
} }
if (script.length() > 0) { if (script.length() > 0) {
list.add(Locale.getInstance(language, script, "", "", LocaleExtensions.EMPTY_EXTENSIONS)); list.add(Locale.getInstance(language, script, "", "", null));
// With script, after truncating variant, region and script, // With script, after truncating variant, region and script,
// start over without script. // start over without script.
if (variants != null) { if (variants != null) {
for (String v : variants) { for (String v : variants) {
list.add(Locale.getInstance(language, "", region, v, LocaleExtensions.EMPTY_EXTENSIONS)); list.add(Locale.getInstance(language, "", region, v, null));
} }
} }
if (region.length() > 0) { if (region.length() > 0) {
list.add(Locale.getInstance(language, "", region, "", LocaleExtensions.EMPTY_EXTENSIONS)); list.add(Locale.getInstance(language, "", region, "", null));
} }
} }
if (language.length() > 0) { if (language.length() > 0) {
list.add(Locale.getInstance(language, "", "", "", LocaleExtensions.EMPTY_EXTENSIONS)); list.add(Locale.getInstance(language, "", "", "", null));
} }
// Add root locale at the end // Add root locale at the end
list.add(Locale.ROOT); list.add(Locale.ROOT);
......
...@@ -239,6 +239,12 @@ public class MidiSystem { ...@@ -239,6 +239,12 @@ public class MidiSystem {
* If a suitable MIDI port is not available, the Receiver is * If a suitable MIDI port is not available, the Receiver is
* retrieved from an installed synthesizer. * retrieved from an installed synthesizer.
* *
* <p>If a native receiver provided by the default device does not implement
* the {@code MidiDeviceReceiver} interface, it will be wrapped in a
* wrapper class that implements the {@code MidiDeviceReceiver} interface.
* The corresponding {@code Receiver} method calls will be forwarded
* to the native receiver.
*
* <p>If this method returns successfully, the {@link * <p>If this method returns successfully, the {@link
* javax.sound.midi.MidiDevice MidiDevice} the * javax.sound.midi.MidiDevice MidiDevice} the
* <code>Receiver</code> belongs to is opened implicitly, if it is * <code>Receiver</code> belongs to is opened implicitly, if it is
...@@ -284,7 +290,13 @@ public class MidiSystem { ...@@ -284,7 +290,13 @@ public class MidiSystem {
* it is used to identify the device that provides the default transmitter. * it is used to identify the device that provides the default transmitter.
* For details, refer to the {@link MidiSystem class description}. * For details, refer to the {@link MidiSystem class description}.
* *
* If this method returns successfully, the {@link * <p>If a native transmitter provided by the default device does not implement
* the {@code MidiDeviceTransmitter} interface, it will be wrapped in a
* wrapper class that implements the {@code MidiDeviceTransmitter} interface.
* The corresponding {@code Transmitter} method calls will be forwarded
* to the native transmitter.
*
* <p>If this method returns successfully, the {@link
* javax.sound.midi.MidiDevice MidiDevice} the * javax.sound.midi.MidiDevice MidiDevice} the
* <code>Transmitter</code> belongs to is opened implicitly, if it * <code>Transmitter</code> belongs to is opened implicitly, if it
* is not already open. It is possible to close an implicitly * is not already open. It is possible to close an implicitly
......
...@@ -45,14 +45,16 @@ import java.awt.Graphics2D; ...@@ -45,14 +45,16 @@ import java.awt.Graphics2D;
* <code>Painter</code> that only works with subclasses of {@link java.awt.Component}. * <code>Painter</code> that only works with subclasses of {@link java.awt.Component}.
* In that case, when the <code>Painter</code> is declared, you may declare that * In that case, when the <code>Painter</code> is declared, you may declare that
* it requires a <code>Component</code>, allowing the paint method to be type safe. Ex: * it requires a <code>Component</code>, allowing the paint method to be type safe. Ex:
* <pre><code> * <pre>
* Painter<Component> p = new Painter<Component>() { * {@code
* public void paint(Graphics2D g, Component c, int width, int height) { * Painter<Component> p = new Painter<Component>() {
* g.setColor(c.getBackground()); * public void paint(Graphics2D g, Component c, int width, int height) {
* //and so forth * g.setColor(c.getBackground());
* } * //and so forth
* } * }
* </code></pre></p> * }
* }
* </pre></p>
* *
* <p>This interface makes no guarantees of threadsafety.</p> * <p>This interface makes no guarantees of threadsafety.</p>
* *
......
...@@ -240,9 +240,7 @@ public class TitledBorder extends AbstractBorder ...@@ -240,9 +240,7 @@ public class TitledBorder extends AbstractBorder
int edge = (border instanceof TitledBorder) ? 0 : EDGE_SPACING; int edge = (border instanceof TitledBorder) ? 0 : EDGE_SPACING;
JLabel label = getLabel(c); JLabel label = getLabel(c);
Dimension size = label.getPreferredSize(); Dimension size = label.getPreferredSize();
Insets insets = (border != null) Insets insets = getBorderInsets(border, c, new Insets(0, 0, 0, 0));
? border.getBorderInsets(c)
: new Insets(0, 0, 0, 0);
int borderX = x + edge; int borderX = x + edge;
int borderY = y + edge; int borderY = y + edge;
...@@ -348,17 +346,8 @@ public class TitledBorder extends AbstractBorder ...@@ -348,17 +346,8 @@ public class TitledBorder extends AbstractBorder
*/ */
public Insets getBorderInsets(Component c, Insets insets) { public Insets getBorderInsets(Component c, Insets insets) {
Border border = getBorder(); Border border = getBorder();
if (border == null) { insets = getBorderInsets(border, c, insets);
insets.set(0, 0, 0, 0);
}
else if (border instanceof AbstractBorder) {
AbstractBorder ab = (AbstractBorder) border;
insets = ab.getBorderInsets(c, insets);
}
else {
Insets i = border.getBorderInsets(c);
insets.set(i.top, i.left, i.bottom, i.right);
}
String title = getTitle(); String title = getTitle();
if ((title != null) && !title.isEmpty()) { if ((title != null) && !title.isEmpty()) {
int edge = (border instanceof TitledBorder) ? 0 : EDGE_SPACING; int edge = (border instanceof TitledBorder) ? 0 : EDGE_SPACING;
...@@ -588,9 +577,7 @@ public class TitledBorder extends AbstractBorder ...@@ -588,9 +577,7 @@ public class TitledBorder extends AbstractBorder
int edge = (border instanceof TitledBorder) ? 0 : EDGE_SPACING; int edge = (border instanceof TitledBorder) ? 0 : EDGE_SPACING;
JLabel label = getLabel(c); JLabel label = getLabel(c);
Dimension size = label.getPreferredSize(); Dimension size = label.getPreferredSize();
Insets insets = (border != null) Insets insets = getBorderInsets(border, c, new Insets(0, 0, 0, 0));
? border.getBorderInsets(c)
: new Insets(0, 0, 0, 0);
int baseline = label.getBaseline(size.width, size.height); int baseline = label.getBaseline(size.width, size.height);
switch (getPosition()) { switch (getPosition()) {
...@@ -728,4 +715,19 @@ public class TitledBorder extends AbstractBorder ...@@ -728,4 +715,19 @@ public class TitledBorder extends AbstractBorder
this.label.setEnabled(c.isEnabled()); this.label.setEnabled(c.isEnabled());
return this.label; return this.label;
} }
private static Insets getBorderInsets(Border border, Component c, Insets insets) {
if (border == null) {
insets.set(0, 0, 0, 0);
}
else if (border instanceof AbstractBorder) {
AbstractBorder ab = (AbstractBorder) border;
insets = ab.getBorderInsets(c, insets);
}
else {
Insets i = border.getBorderInsets(c);
insets.set(i.top, i.left, i.bottom, i.right);
}
return insets;
}
} }
...@@ -335,9 +335,8 @@ public class BasicColorChooserUI extends ColorChooserUI ...@@ -335,9 +335,8 @@ public class BasicColorChooserUI extends ColorChooserUI
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <Foo>. * Instantiate it only within subclasses of {@code BasicColorChooserUI}.
*/ */
public class PropertyHandler implements PropertyChangeListener { public class PropertyHandler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) { public void propertyChange(PropertyChangeEvent e) {
......
...@@ -186,9 +186,8 @@ public class BasicDesktopIconUI extends DesktopIconUI { ...@@ -186,9 +186,8 @@ public class BasicDesktopIconUI extends DesktopIconUI {
/** /**
* Listens for mouse movements and acts on them. * Listens for mouse movements and acts on them.
* *
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <Foo>. * Instantiate it only within subclasses of {@code BasicDesktopIconUI}.
*/ */
public class MouseInputHandler extends MouseInputAdapter public class MouseInputHandler extends MouseInputAdapter
{ {
......
...@@ -455,6 +455,8 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -455,6 +455,8 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
} }
int dka = label.getDisplayedMnemonic(); int dka = label.getDisplayedMnemonic();
inputMap.put(KeyStroke.getKeyStroke(dka, ActionEvent.ALT_MASK, true), RELEASE); inputMap.put(KeyStroke.getKeyStroke(dka, ActionEvent.ALT_MASK, true), RELEASE);
// Need this when the sticky keys are enabled
inputMap.put(KeyStroke.getKeyStroke(dka, 0, true), RELEASE);
// Need this if ALT is released before the accelerator // Need this if ALT is released before the accelerator
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true), RELEASE); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true), RELEASE);
label.requestFocus(); label.requestFocus();
...@@ -467,7 +469,9 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener ...@@ -467,7 +469,9 @@ public class BasicLabelUI extends LabelUI implements PropertyChangeListener
InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED); InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED);
if (inputMap != null) { if (inputMap != null) {
// inputMap should never be null. // inputMap should never be null.
inputMap.remove(KeyStroke.getKeyStroke(label.getDisplayedMnemonic(), ActionEvent.ALT_MASK, true)); int dka = label.getDisplayedMnemonic();
inputMap.remove(KeyStroke.getKeyStroke(dka, ActionEvent.ALT_MASK, true));
inputMap.remove(KeyStroke.getKeyStroke(dka, 0, true));
inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true)); inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true));
} }
if (labelFor instanceof Container && if (labelFor instanceof Container &&
......
...@@ -1555,9 +1555,8 @@ public class BasicListUI extends ListUI ...@@ -1555,9 +1555,8 @@ public class BasicListUI extends ListUI
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicTableUI. * Instantiate it only within subclasses of {@code BasicListUI}.
*/ */
public class FocusHandler implements FocusListener public class FocusHandler implements FocusListener
{ {
......
...@@ -911,9 +911,8 @@ public class BasicOptionPaneUI extends OptionPaneUI { ...@@ -911,9 +911,8 @@ public class BasicOptionPaneUI extends OptionPaneUI {
* right. If <code>syncAllWidths</code> is true, the widths of each * right. If <code>syncAllWidths</code> is true, the widths of each
* component will be set to the largest preferred size width. * component will be set to the largest preferred size width.
* *
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicOptionPaneUI. * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
*/ */
public static class ButtonAreaLayout implements LayoutManager { public static class ButtonAreaLayout implements LayoutManager {
protected boolean syncAllWidths; protected boolean syncAllWidths;
...@@ -1115,9 +1114,8 @@ public class BasicOptionPaneUI extends OptionPaneUI { ...@@ -1115,9 +1114,8 @@ public class BasicOptionPaneUI extends OptionPaneUI {
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicOptionPaneUI. * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
*/ */
public class PropertyChangeHandler implements PropertyChangeListener { public class PropertyChangeHandler implements PropertyChangeListener {
/** /**
...@@ -1161,9 +1159,8 @@ public class BasicOptionPaneUI extends OptionPaneUI { ...@@ -1161,9 +1159,8 @@ public class BasicOptionPaneUI extends OptionPaneUI {
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicOptionPaneUI. * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
*/ */
public class ButtonActionListener implements ActionListener { public class ButtonActionListener implements ActionListener {
protected int buttonIndex; protected int buttonIndex;
......
...@@ -1211,9 +1211,8 @@ public class BasicProgressBarUI extends ProgressBarUI { ...@@ -1211,9 +1211,8 @@ public class BasicProgressBarUI extends ProgressBarUI {
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicProgressBarUI. * Instantiate it only within subclasses of {@code BasicProgressBarUI}.
*/ */
public class ChangeHandler implements ChangeListener { public class ChangeHandler implements ChangeListener {
// NOTE: This class exists only for backward compatability. All // NOTE: This class exists only for backward compatability. All
......
...@@ -88,9 +88,8 @@ public class BasicTableHeaderUI extends TableHeaderUI { ...@@ -88,9 +88,8 @@ public class BasicTableHeaderUI extends TableHeaderUI {
}; };
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicTableUI. * Instantiate it only within subclasses of {@code BasicTableHeaderUI}.
*/ */
public class MouseInputHandler implements MouseInputListener { public class MouseInputHandler implements MouseInputListener {
......
...@@ -730,9 +730,8 @@ public class BasicTableUI extends TableUI ...@@ -730,9 +730,8 @@ public class BasicTableUI extends TableUI
// //
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicTableUI. * Instantiate it only within subclasses of {@code BasicTableUI}.
* <p>As of Java 2 platform v1.3 this class is no longer used. * <p>As of Java 2 platform v1.3 this class is no longer used.
* Instead <code>JTable</code> * Instead <code>JTable</code>
* overrides <code>processKeyBinding</code> to dispatch the event to * overrides <code>processKeyBinding</code> to dispatch the event to
...@@ -761,9 +760,8 @@ public class BasicTableUI extends TableUI ...@@ -761,9 +760,8 @@ public class BasicTableUI extends TableUI
// //
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicTableUI. * Instantiate it only within subclasses of {@code BasicTableUI}.
*/ */
public class FocusHandler implements FocusListener { public class FocusHandler implements FocusListener {
// NOTE: This class exists only for backward compatability. All // NOTE: This class exists only for backward compatability. All
...@@ -784,7 +782,6 @@ public class BasicTableUI extends TableUI ...@@ -784,7 +782,6 @@ public class BasicTableUI extends TableUI
// //
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of BasicTableUI. * Instantiate it only within subclasses of BasicTableUI.
*/ */
......
...@@ -199,9 +199,8 @@ public class MetalComboBoxUI extends BasicComboBoxUI { ...@@ -199,9 +199,8 @@ public class MetalComboBoxUI extends BasicComboBoxUI {
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <FooUI>. * Instantiate it only within subclasses of {@code MetalComboBoxUI}.
*/ */
public class MetalPropertyChangeListener extends BasicComboBoxUI.PropertyChangeHandler { public class MetalPropertyChangeListener extends BasicComboBoxUI.PropertyChangeHandler {
public void propertyChange(PropertyChangeEvent e) { public void propertyChange(PropertyChangeEvent e) {
...@@ -244,9 +243,8 @@ public class MetalComboBoxUI extends BasicComboBoxUI { ...@@ -244,9 +243,8 @@ public class MetalComboBoxUI extends BasicComboBoxUI {
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <FooUI>. * Instantiate it only within subclasses of {@code MetalComboBoxUI}.
*/ */
public class MetalComboBoxLayoutManager extends BasicComboBoxUI.ComboBoxLayoutManager { public class MetalComboBoxLayoutManager extends BasicComboBoxUI.ComboBoxLayoutManager {
public void layoutContainer( Container parent ) { public void layoutContainer( Container parent ) {
...@@ -356,9 +354,8 @@ public class MetalComboBoxUI extends BasicComboBoxUI { ...@@ -356,9 +354,8 @@ public class MetalComboBoxUI extends BasicComboBoxUI {
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of <FooUI>. * Instantiate it only within subclasses of {@code MetalComboBoxUI}.
* *
* This class is now obsolete and doesn't do anything and * This class is now obsolete and doesn't do anything and
* is only included for backwards API compatibility. Do not call or * is only included for backwards API compatibility. Do not call or
......
...@@ -1196,9 +1196,8 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI { ...@@ -1196,9 +1196,8 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI {
} }
/** /**
* This inner class is marked &quot;public&quot; due to a compiler bug.
* This class should be treated as a &quot;protected&quot; inner class. * This class should be treated as a &quot;protected&quot; inner class.
* Instantiate it only within subclasses of MetalTabbedPaneUI. * Instantiate it only within subclasses of {@code MetalTabbedPaneUI}.
*/ */
public class TabbedPaneLayout extends BasicTabbedPaneUI.TabbedPaneLayout { public class TabbedPaneLayout extends BasicTabbedPaneUI.TabbedPaneLayout {
......
...@@ -172,6 +172,11 @@ class GlyphPainter2 extends GlyphView.GlyphPainter { ...@@ -172,6 +172,11 @@ class GlyphPainter2 extends GlyphView.GlyphPainter {
//italic carets and we do not. //italic carets and we do not.
TextHitInfo hit = layout.hitTestChar(x - (float)alloc.getX(), 0); TextHitInfo hit = layout.hitTestChar(x - (float)alloc.getX(), 0);
int pos = hit.getInsertionIndex(); int pos = hit.getInsertionIndex();
if (pos == v.getEndOffset()) {
pos--;
}
biasReturn[0] = hit.isLeadingEdge() ? Position.Bias.Forward : Position.Bias.Backward; biasReturn[0] = hit.isLeadingEdge() ? Position.Bias.Forward : Position.Bias.Backward;
return pos + v.getStartOffset(); return pos + v.getStartOffset();
} }
......
...@@ -541,7 +541,30 @@ public class GlyphView extends View implements TabableView, Cloneable { ...@@ -541,7 +541,30 @@ public class GlyphView extends View implements TabableView, Cloneable {
*/ */
@Override @Override
public float getMinimumSpan(int axis) { public float getMinimumSpan(int axis) {
return super.getMinimumSpan(axis); switch (axis) {
case View.X_AXIS:
if (minimumSpan < 0) {
minimumSpan = 0;
int p0 = getStartOffset();
int p1 = getEndOffset();
while (p1 > p0) {
int breakSpot = getBreakSpot(p0, p1);
if (breakSpot == BreakIterator.DONE) {
// the rest of the view is non-breakable
breakSpot = p0;
}
minimumSpan = Math.max(minimumSpan,
getPartialSpan(breakSpot, p1));
// Note: getBreakSpot returns the *last* breakspot
p1 = breakSpot - 1;
}
}
return minimumSpan;
case View.Y_AXIS:
return super.getMinimumSpan(axis);
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
} }
/** /**
......
...@@ -721,7 +721,34 @@ public class ParagraphView extends FlowView implements TabExpander { ...@@ -721,7 +721,34 @@ public class ParagraphView extends FlowView implements TabExpander {
@Override @Override
protected SizeRequirements calculateMinorAxisRequirements(int axis, protected SizeRequirements calculateMinorAxisRequirements(int axis,
SizeRequirements r) { SizeRequirements r) {
return super.calculateMinorAxisRequirements(axis, r); r = super.calculateMinorAxisRequirements(axis, r);
float min = 0;
float glue = 0;
int n = getLayoutViewCount();
for (int i = 0; i < n; i++) {
View v = getLayoutView(i);
float span = v.getMinimumSpan(axis);
if (v.getBreakWeight(axis, 0, v.getMaximumSpan(axis)) > View.BadBreakWeight) {
// find the longest non-breakable fragments at the view edges
int p0 = v.getStartOffset();
int p1 = v.getEndOffset();
float start = findEdgeSpan(v, axis, p0, p0, p1);
float end = findEdgeSpan(v, axis, p1, p0, p1);
glue += start;
min = Math.max(min, Math.max(span, glue));
glue = end;
} else {
// non-breakable view
glue += span;
min = Math.max(min, glue);
}
}
r.minimum = Math.max(r.minimum, (int) min);
r.preferred = Math.max(r.minimum, r.preferred);
r.maximum = Math.max(r.preferred, r.maximum);
return r;
} }
/** /**
......
...@@ -395,10 +395,10 @@ public class Utilities { ...@@ -395,10 +395,10 @@ public class Utilities {
// the length of the string measured as a whole may differ from // the length of the string measured as a whole may differ from
// the sum of individual character lengths, for example if // the sum of individual character lengths, for example if
// fractional metrics are enabled; and we must guard from this. // fractional metrics are enabled; and we must guard from this.
while (metrics.charsWidth(txt, txtOffset, offset + 1) > (x - x0)) { while (offset > 0 && metrics.charsWidth(txt, txtOffset, offset) > (x - x0)) {
offset--; offset--;
} }
return (offset < 0 ? 0 : offset); return offset;
} }
currX = nextX; currX = nextX;
} }
......
...@@ -62,7 +62,6 @@ import javax.swing.text.*; ...@@ -62,7 +62,6 @@ import javax.swing.text.*;
* <li>background-repeat * <li>background-repeat
* <li>background-position * <li>background-position
* <li>background * <li>background
* <li>background-repeat
* <li>text-decoration (with the exception of blink and overline) * <li>text-decoration (with the exception of blink and overline)
* <li>vertical-align (only sup and super) * <li>vertical-align (only sup and super)
* <li>text-align (justify is treated as center) * <li>text-align (justify is treated as center)
...@@ -75,7 +74,18 @@ import javax.swing.text.*; ...@@ -75,7 +74,18 @@ import javax.swing.text.*;
* <li>padding-right * <li>padding-right
* <li>padding-bottom * <li>padding-bottom
* <li>padding-left * <li>padding-left
* <li>padding
* <li>border-top-style
* <li>border-right-style
* <li>border-bottom-style
* <li>border-left-style
* <li>border-style (only supports inset, outset and none) * <li>border-style (only supports inset, outset and none)
* <li>border-top-color
* <li>border-right-color
* <li>border-bottom-color
* <li>border-left-color
* <li>border-color
* <li>list-style-image
* <li>list-style-type * <li>list-style-type
* <li>list-style-position * <li>list-style-position
* </ul> * </ul>
......
...@@ -966,6 +966,9 @@ class Parser implements DTDConstants { ...@@ -966,6 +966,9 @@ class Parser implements DTDConstants {
char data[] = {'&'}; char data[] = {'&'};
return data; return data;
} }
boolean semicolon = false;
switch (ch) { switch (ch) {
case '\n': case '\n':
ln++; ln++;
...@@ -985,6 +988,8 @@ class Parser implements DTDConstants { ...@@ -985,6 +988,8 @@ class Parser implements DTDConstants {
break; break;
case ';': case ';':
semicolon = true;
ch = readCh(); ch = readCh();
break; break;
} }
...@@ -1006,7 +1011,7 @@ class Parser implements DTDConstants { ...@@ -1006,7 +1011,7 @@ class Parser implements DTDConstants {
return new char[0]; return new char[0];
} }
/* given that there is not a match restore the entity reference */ /* given that there is not a match restore the entity reference */
String str = "&" + nm + ";"; String str = "&" + nm + (semicolon ? ";" : "");
char b[] = new char[str.length()]; char b[] = new char[str.length()];
str.getChars(0, b.length, b, 0); str.getChars(0, b.length, b, 0);
......
...@@ -270,11 +270,10 @@ public class SwingUtilities2 { ...@@ -270,11 +270,10 @@ public class SwingUtilities2 {
*/ */
public static int getLeftSideBearing(JComponent c, FontMetrics fm, public static int getLeftSideBearing(JComponent c, FontMetrics fm,
String string) { String string) {
int res = 0; if ((string == null) || (string.length() == 0)) {
if (!string.isEmpty()) { return 0;
res = getLeftSideBearing(c, fm, string.charAt(0));
} }
return res; return getLeftSideBearing(c, fm, string.charAt(0));
} }
/** /**
......
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -38,38 +38,46 @@ public final class BaseLocale { ...@@ -38,38 +38,46 @@ public final class BaseLocale {
public static final String SEP = "_"; public static final String SEP = "_";
private static final Cache CACHE = new Cache(); private static final Cache CACHE = new Cache();
public static final BaseLocale ROOT = BaseLocale.getInstance("", "", "", "");
private String _language = ""; private final String language;
private String _script = ""; private final String script;
private String _region = ""; private final String region;
private String _variant = ""; private final String variant;
private transient volatile int _hash = 0; private volatile int hash = 0;
// This method must be called only when creating the Locale.* constants.
private BaseLocale(String language, String region) {
this.language = language;
this.script = "";
this.region = region;
this.variant = "";
}
private BaseLocale(String language, String script, String region, String variant) { private BaseLocale(String language, String script, String region, String variant) {
if (language != null) { this.language = (language != null) ? LocaleUtils.toLowerString(language).intern() : "";
_language = AsciiUtil.toLowerString(language).intern(); this.script = (script != null) ? LocaleUtils.toTitleString(script).intern() : "";
} this.region = (region != null) ? LocaleUtils.toUpperString(region).intern() : "";
if (script != null) { this.variant = (variant != null) ? variant.intern() : "";
_script = AsciiUtil.toTitleString(script).intern(); }
}
if (region != null) { // Called for creating the Locale.* constants. No argument
_region = AsciiUtil.toUpperString(region).intern(); // validation is performed.
} public static BaseLocale createInstance(String language, String region) {
if (variant != null) { BaseLocale base = new BaseLocale(language, region);
_variant = variant.intern(); CACHE.put(new Key(language, region), base);
} return base;
} }
public static BaseLocale getInstance(String language, String script, String region, String variant) { public static BaseLocale getInstance(String language, String script,
String region, String variant) {
// JDK uses deprecated ISO639.1 language codes for he, yi and id // JDK uses deprecated ISO639.1 language codes for he, yi and id
if (language != null) { if (language != null) {
if (AsciiUtil.caseIgnoreMatch(language, "he")) { if (LocaleUtils.caseIgnoreMatch(language, "he")) {
language = "iw"; language = "iw";
} else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { } else if (LocaleUtils.caseIgnoreMatch(language, "yi")) {
language = "ji"; language = "ji";
} else if (AsciiUtil.caseIgnoreMatch(language, "id")) { } else if (LocaleUtils.caseIgnoreMatch(language, "id")) {
language = "in"; language = "in";
} }
} }
...@@ -80,21 +88,22 @@ public final class BaseLocale { ...@@ -80,21 +88,22 @@ public final class BaseLocale {
} }
public String getLanguage() { public String getLanguage() {
return _language; return language;
} }
public String getScript() { public String getScript() {
return _script; return script;
} }
public String getRegion() { public String getRegion() {
return _region; return region;
} }
public String getVariant() { public String getVariant() {
return _variant; return variant;
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
...@@ -103,138 +112,178 @@ public final class BaseLocale { ...@@ -103,138 +112,178 @@ public final class BaseLocale {
return false; return false;
} }
BaseLocale other = (BaseLocale)obj; BaseLocale other = (BaseLocale)obj;
return hashCode() == other.hashCode() return language == other.language
&& _language.equals(other._language) && script == other.script
&& _script.equals(other._script) && region == other.region
&& _region.equals(other._region) && variant == other.variant;
&& _variant.equals(other._variant);
} }
@Override
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
if (_language.length() > 0) { if (language.length() > 0) {
buf.append("language="); buf.append("language=");
buf.append(_language); buf.append(language);
} }
if (_script.length() > 0) { if (script.length() > 0) {
if (buf.length() > 0) { if (buf.length() > 0) {
buf.append(", "); buf.append(", ");
} }
buf.append("script="); buf.append("script=");
buf.append(_script); buf.append(script);
} }
if (_region.length() > 0) { if (region.length() > 0) {
if (buf.length() > 0) { if (buf.length() > 0) {
buf.append(", "); buf.append(", ");
} }
buf.append("region="); buf.append("region=");
buf.append(_region); buf.append(region);
} }
if (_variant.length() > 0) { if (variant.length() > 0) {
if (buf.length() > 0) { if (buf.length() > 0) {
buf.append(", "); buf.append(", ");
} }
buf.append("variant="); buf.append("variant=");
buf.append(_variant); buf.append(variant);
} }
return buf.toString(); return buf.toString();
} }
@Override
public int hashCode() { public int hashCode() {
int h = _hash; int h = hash;
if (h == 0) { if (h == 0) {
// Generating a hash value from language, script, region and variant // Generating a hash value from language, script, region and variant
for (int i = 0; i < _language.length(); i++) { h = language.hashCode();
h = 31*h + _language.charAt(i); h = 31 * h + script.hashCode();
} h = 31 * h + region.hashCode();
for (int i = 0; i < _script.length(); i++) { h = 31 * h + variant.hashCode();
h = 31*h + _script.charAt(i); hash = h;
}
for (int i = 0; i < _region.length(); i++) {
h = 31*h + _region.charAt(i);
}
for (int i = 0; i < _variant.length(); i++) {
h = 31*h + _variant.charAt(i);
}
_hash = h;
} }
return h; return h;
} }
private static class Key implements Comparable<Key> { private static final class Key implements Comparable<Key> {
private String _lang = ""; private final String lang;
private String _scrt = ""; private final String scrt;
private String _regn = ""; private final String regn;
private String _vart = ""; private final String vart;
private final boolean normalized;
private final int hash;
/**
* Creates a Key. language and region must be normalized
* (intern'ed in the proper case).
*/
private Key(String language, String region) {
assert language.intern() == language
&& region.intern() == region;
private volatile int _hash; // Default to 0 lang = language;
scrt = "";
regn = region;
vart = "";
this.normalized = true;
int h = language.hashCode();
if (region != "") {
int len = region.length();
for (int i = 0; i < len; i++) {
h = 31 * h + LocaleUtils.toLower(region.charAt(i));
}
}
hash = h;
}
public Key(String language, String script, String region, String variant) { public Key(String language, String script, String region, String variant) {
this(language, script, region, variant, false);
}
private Key(String language, String script, String region,
String variant, boolean normalized) {
int h = 0;
if (language != null) { if (language != null) {
_lang = language; lang = language;
int len = language.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(language.charAt(i));
}
} else {
lang = "";
} }
if (script != null) { if (script != null) {
_scrt = script; scrt = script;
int len = script.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(script.charAt(i));
}
} else {
scrt = "";
} }
if (region != null) { if (region != null) {
_regn = region; regn = region;
int len = region.length();
for (int i = 0; i < len; i++) {
h = 31*h + LocaleUtils.toLower(region.charAt(i));
}
} else {
regn = "";
} }
if (variant != null) { if (variant != null) {
_vart = variant; vart = variant;
int len = variant.length();
for (int i = 0; i < len; i++) {
h = 31*h + variant.charAt(i);
}
} else {
vart = "";
} }
hash = h;
this.normalized = normalized;
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return (this == obj) || return (this == obj) ||
(obj instanceof Key) (obj instanceof Key)
&& AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang) && this.hash == ((Key)obj).hash
&& AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt) && LocaleUtils.caseIgnoreMatch(((Key)obj).lang, this.lang)
&& AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn) && LocaleUtils.caseIgnoreMatch(((Key)obj).scrt, this.scrt)
&& ((Key)obj)._vart.equals(_vart); // variant is case sensitive in JDK! && LocaleUtils.caseIgnoreMatch(((Key)obj).regn, this.regn)
&& ((Key)obj).vart.equals(vart); // variant is case sensitive in JDK!
} }
@Override
public int compareTo(Key other) { public int compareTo(Key other) {
int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang); int res = LocaleUtils.caseIgnoreCompare(this.lang, other.lang);
if (res == 0) { if (res == 0) {
res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt); res = LocaleUtils.caseIgnoreCompare(this.scrt, other.scrt);
if (res == 0) { if (res == 0) {
res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn); res = LocaleUtils.caseIgnoreCompare(this.regn, other.regn);
if (res == 0) { if (res == 0) {
res = this._vart.compareTo(other._vart); res = this.vart.compareTo(other.vart);
} }
} }
} }
return res; return res;
} }
@Override
public int hashCode() { public int hashCode() {
int h = _hash; return hash;
if (h == 0) {
// Generating a hash value from language, script, region and variant
for (int i = 0; i < _lang.length(); i++) {
h = 31*h + AsciiUtil.toLower(_lang.charAt(i));
}
for (int i = 0; i < _scrt.length(); i++) {
h = 31*h + AsciiUtil.toLower(_scrt.charAt(i));
}
for (int i = 0; i < _regn.length(); i++) {
h = 31*h + AsciiUtil.toLower(_regn.charAt(i));
}
for (int i = 0; i < _vart.length(); i++) {
h = 31*h + _vart.charAt(i);
}
_hash = h;
}
return h;
} }
public static Key normalize(Key key) { public static Key normalize(Key key) {
String lang = AsciiUtil.toLowerString(key._lang).intern(); if (key.normalized) {
String scrt = AsciiUtil.toTitleString(key._scrt).intern(); return key;
String regn = AsciiUtil.toUpperString(key._regn).intern(); }
String vart = key._vart.intern(); // preserve upper/lower cases
return new Key(lang, scrt, regn, vart); String lang = LocaleUtils.toLowerString(key.lang).intern();
String scrt = LocaleUtils.toTitleString(key.scrt).intern();
String regn = LocaleUtils.toUpperString(key.regn).intern();
String vart = key.vart.intern(); // preserve upper/lower cases
return new Key(lang, scrt, regn, vart, true);
} }
} }
...@@ -243,13 +292,14 @@ public final class BaseLocale { ...@@ -243,13 +292,14 @@ public final class BaseLocale {
public Cache() { public Cache() {
} }
@Override
protected Key normalizeKey(Key key) { protected Key normalizeKey(Key key) {
return Key.normalize(key); return Key.normalize(key);
} }
@Override
protected BaseLocale createObject(Key key) { protected BaseLocale createObject(Key key) {
return new BaseLocale(key._lang, key._scrt, key._regn, key._vart); return new BaseLocale(key.lang, key.scrt, key.regn, key.vart);
} }
} }
} }
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,29 +32,34 @@ ...@@ -32,29 +32,34 @@
package sun.util.locale; package sun.util.locale;
public class Extension { class Extension {
private char _key; private final char key;
protected String _value; private String value, id;
protected Extension(char key) { protected Extension(char key) {
_key = key; this.key = key;
} }
Extension(char key, String value) { Extension(char key, String value) {
_key = key; this.key = key;
_value = value; setValue(value);
}
protected void setValue(String value) {
this.value = value;
this.id = key + LanguageTag.SEP + value;
} }
public char getKey() { public char getKey() {
return _key; return key;
} }
public String getValue() { public String getValue() {
return _value; return value;
} }
public String getID() { public String getID() {
return _key + LanguageTag.SEP + _value; return id;
} }
public String toString() { public String toString() {
......
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,64 +35,66 @@ import java.util.ArrayList; ...@@ -35,64 +35,66 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
public final class InternalLocaleBuilder { public final class InternalLocaleBuilder {
private String _language = ""; private static final CaseInsensitiveChar PRIVATEUSE_KEY
private String _script = ""; = new CaseInsensitiveChar(LanguageTag.PRIVATEUSE);
private String _region = "";
private String _variant = "";
private static final CaseInsensitiveChar PRIVUSE_KEY = new CaseInsensitiveChar(LanguageTag.PRIVATEUSE.charAt(0)); private String language = "";
private String script = "";
private String region = "";
private String variant = "";
private HashMap<CaseInsensitiveChar, String> _extensions; private Map<CaseInsensitiveChar, String> extensions;
private HashSet<CaseInsensitiveString> _uattributes; private Set<CaseInsensitiveString> uattributes;
private HashMap<CaseInsensitiveString, String> _ukeywords; private Map<CaseInsensitiveString, String> ukeywords;
public InternalLocaleBuilder() { public InternalLocaleBuilder() {
} }
public InternalLocaleBuilder setLanguage(String language) throws LocaleSyntaxException { public InternalLocaleBuilder setLanguage(String language) throws LocaleSyntaxException {
if (language == null || language.length() == 0) { if (LocaleUtils.isEmpty(language)) {
_language = ""; this.language = "";
} else { } else {
if (!LanguageTag.isLanguage(language)) { if (!LanguageTag.isLanguage(language)) {
throw new LocaleSyntaxException("Ill-formed language: " + language, 0); throw new LocaleSyntaxException("Ill-formed language: " + language, 0);
} }
_language = language; this.language = language;
} }
return this; return this;
} }
public InternalLocaleBuilder setScript(String script) throws LocaleSyntaxException { public InternalLocaleBuilder setScript(String script) throws LocaleSyntaxException {
if (script == null || script.length() == 0) { if (LocaleUtils.isEmpty(script)) {
_script = ""; this.script = "";
} else { } else {
if (!LanguageTag.isScript(script)) { if (!LanguageTag.isScript(script)) {
throw new LocaleSyntaxException("Ill-formed script: " + script, 0); throw new LocaleSyntaxException("Ill-formed script: " + script, 0);
} }
_script = script; this.script = script;
} }
return this; return this;
} }
public InternalLocaleBuilder setRegion(String region) throws LocaleSyntaxException { public InternalLocaleBuilder setRegion(String region) throws LocaleSyntaxException {
if (region == null || region.length() == 0) { if (LocaleUtils.isEmpty(region)) {
_region = ""; this.region = "";
} else { } else {
if (!LanguageTag.isRegion(region)) { if (!LanguageTag.isRegion(region)) {
throw new LocaleSyntaxException("Ill-formed region: " + region, 0); throw new LocaleSyntaxException("Ill-formed region: " + region, 0);
} }
_region = region; this.region = region;
} }
return this; return this;
} }
public InternalLocaleBuilder setVariant(String variant) throws LocaleSyntaxException { public InternalLocaleBuilder setVariant(String variant) throws LocaleSyntaxException {
if (variant == null || variant.length() == 0) { if (LocaleUtils.isEmpty(variant)) {
_variant = ""; this.variant = "";
} else { } else {
// normalize separators to "_" // normalize separators to "_"
String var = variant.replaceAll(LanguageTag.SEP, BaseLocale.SEP); String var = variant.replaceAll(LanguageTag.SEP, BaseLocale.SEP);
...@@ -100,7 +102,7 @@ public final class InternalLocaleBuilder { ...@@ -100,7 +102,7 @@ public final class InternalLocaleBuilder {
if (errIdx != -1) { if (errIdx != -1) {
throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx); throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx);
} }
_variant = var; this.variant = var;
} }
return this; return this;
} }
...@@ -110,10 +112,10 @@ public final class InternalLocaleBuilder { ...@@ -110,10 +112,10 @@ public final class InternalLocaleBuilder {
throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute); throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute);
} }
// Use case insensitive string to prevent duplication // Use case insensitive string to prevent duplication
if (_uattributes == null) { if (uattributes == null) {
_uattributes = new HashSet<CaseInsensitiveString>(4); uattributes = new HashSet<>(4);
} }
_uattributes.add(new CaseInsensitiveString(attribute)); uattributes.add(new CaseInsensitiveString(attribute));
return this; return this;
} }
...@@ -121,8 +123,8 @@ public final class InternalLocaleBuilder { ...@@ -121,8 +123,8 @@ public final class InternalLocaleBuilder {
if (attribute == null || !UnicodeLocaleExtension.isAttribute(attribute)) { if (attribute == null || !UnicodeLocaleExtension.isAttribute(attribute)) {
throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute); throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute);
} }
if (_uattributes != null) { if (uattributes != null) {
_uattributes.remove(new CaseInsensitiveString(attribute)); uattributes.remove(new CaseInsensitiveString(attribute));
} }
return this; return this;
} }
...@@ -134,9 +136,9 @@ public final class InternalLocaleBuilder { ...@@ -134,9 +136,9 @@ public final class InternalLocaleBuilder {
CaseInsensitiveString cikey = new CaseInsensitiveString(key); CaseInsensitiveString cikey = new CaseInsensitiveString(key);
if (type == null) { if (type == null) {
if (_ukeywords != null) { if (ukeywords != null) {
// null type is used for remove the key // null type is used for remove the key
_ukeywords.remove(cikey); ukeywords.remove(cikey);
} }
} else { } else {
if (type.length() != 0) { if (type.length() != 0) {
...@@ -147,15 +149,17 @@ public final class InternalLocaleBuilder { ...@@ -147,15 +149,17 @@ public final class InternalLocaleBuilder {
while (!itr.isDone()) { while (!itr.isDone()) {
String s = itr.current(); String s = itr.current();
if (!UnicodeLocaleExtension.isTypeSubtag(s)) { if (!UnicodeLocaleExtension.isTypeSubtag(s)) {
throw new LocaleSyntaxException("Ill-formed Unicode locale keyword type: " + type, itr.currentStart()); throw new LocaleSyntaxException("Ill-formed Unicode locale keyword type: "
+ type,
itr.currentStart());
} }
itr.next(); itr.next();
} }
} }
if (_ukeywords == null) { if (ukeywords == null) {
_ukeywords = new HashMap<CaseInsensitiveString, String>(4); ukeywords = new HashMap<>(4);
} }
_ukeywords.put(cikey, type); ukeywords.put(cikey, type);
} }
return this; return this;
} }
...@@ -167,21 +171,21 @@ public final class InternalLocaleBuilder { ...@@ -167,21 +171,21 @@ public final class InternalLocaleBuilder {
throw new LocaleSyntaxException("Ill-formed extension key: " + singleton); throw new LocaleSyntaxException("Ill-formed extension key: " + singleton);
} }
boolean remove = (value == null || value.length() == 0); boolean remove = LocaleUtils.isEmpty(value);
CaseInsensitiveChar key = new CaseInsensitiveChar(singleton); CaseInsensitiveChar key = new CaseInsensitiveChar(singleton);
if (remove) { if (remove) {
if (UnicodeLocaleExtension.isSingletonChar(key.value())) { if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
// clear entire Unicode locale extension // clear entire Unicode locale extension
if (_uattributes != null) { if (uattributes != null) {
_uattributes.clear(); uattributes.clear();
} }
if (_ukeywords != null) { if (ukeywords != null) {
_ukeywords.clear(); ukeywords.clear();
} }
} else { } else {
if (_extensions != null && _extensions.containsKey(key)) { if (extensions != null && extensions.containsKey(key)) {
_extensions.remove(key); extensions.remove(key);
} }
} }
} else { } else {
...@@ -197,7 +201,8 @@ public final class InternalLocaleBuilder { ...@@ -197,7 +201,8 @@ public final class InternalLocaleBuilder {
validSubtag = LanguageTag.isExtensionSubtag(s); validSubtag = LanguageTag.isExtensionSubtag(s);
} }
if (!validSubtag) { if (!validSubtag) {
throw new LocaleSyntaxException("Ill-formed extension value: " + s, itr.currentStart()); throw new LocaleSyntaxException("Ill-formed extension value: " + s,
itr.currentStart());
} }
itr.next(); itr.next();
} }
...@@ -205,10 +210,10 @@ public final class InternalLocaleBuilder { ...@@ -205,10 +210,10 @@ public final class InternalLocaleBuilder {
if (UnicodeLocaleExtension.isSingletonChar(key.value())) { if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
setUnicodeLocaleExtension(val); setUnicodeLocaleExtension(val);
} else { } else {
if (_extensions == null) { if (extensions == null) {
_extensions = new HashMap<CaseInsensitiveChar, String>(4); extensions = new HashMap<>(4);
} }
_extensions.put(key, val); extensions.put(key, val);
} }
} }
return this; return this;
...@@ -218,7 +223,7 @@ public final class InternalLocaleBuilder { ...@@ -218,7 +223,7 @@ public final class InternalLocaleBuilder {
* Set extension/private subtags in a single string representation * Set extension/private subtags in a single string representation
*/ */
public InternalLocaleBuilder setExtensions(String subtags) throws LocaleSyntaxException { public InternalLocaleBuilder setExtensions(String subtags) throws LocaleSyntaxException {
if (subtags == null || subtags.length() == 0) { if (LocaleUtils.isEmpty(subtags)) {
clearExtensions(); clearExtensions();
return this; return this;
} }
...@@ -252,11 +257,12 @@ public final class InternalLocaleBuilder { ...@@ -252,11 +257,12 @@ public final class InternalLocaleBuilder {
} }
if (parsed < start) { if (parsed < start) {
throw new LocaleSyntaxException("Incomplete extension '" + singleton + "'", start); throw new LocaleSyntaxException("Incomplete extension '" + singleton + "'",
start);
} }
if (extensions == null) { if (extensions == null) {
extensions = new ArrayList<String>(4); extensions = new ArrayList<>(4);
} }
extensions.add(sb.toString()); extensions.add(sb.toString());
} else { } else {
...@@ -281,7 +287,9 @@ public final class InternalLocaleBuilder { ...@@ -281,7 +287,9 @@ public final class InternalLocaleBuilder {
itr.next(); itr.next();
} }
if (parsed <= start) { if (parsed <= start) {
throw new LocaleSyntaxException("Incomplete privateuse:" + subtags.substring(start), start); throw new LocaleSyntaxException("Incomplete privateuse:"
+ subtags.substring(start),
start);
} else { } else {
privateuse = sb.toString(); privateuse = sb.toString();
} }
...@@ -289,7 +297,9 @@ public final class InternalLocaleBuilder { ...@@ -289,7 +297,9 @@ public final class InternalLocaleBuilder {
} }
if (!itr.isDone()) { if (!itr.isDone()) {
throw new LocaleSyntaxException("Ill-formed extension subtags:" + subtags.substring(itr.currentStart()), itr.currentStart()); throw new LocaleSyntaxException("Ill-formed extension subtags:"
+ subtags.substring(itr.currentStart()),
itr.currentStart());
} }
return setExtensions(extensions, privateuse); return setExtensions(extensions, privateuse);
...@@ -302,30 +312,31 @@ public final class InternalLocaleBuilder { ...@@ -302,30 +312,31 @@ public final class InternalLocaleBuilder {
private InternalLocaleBuilder setExtensions(List<String> bcpExtensions, String privateuse) { private InternalLocaleBuilder setExtensions(List<String> bcpExtensions, String privateuse) {
clearExtensions(); clearExtensions();
if (bcpExtensions != null && bcpExtensions.size() > 0) { if (!LocaleUtils.isEmpty(bcpExtensions)) {
HashSet<CaseInsensitiveChar> processedExntensions = new HashSet<CaseInsensitiveChar>(bcpExtensions.size()); Set<CaseInsensitiveChar> done = new HashSet<>(bcpExtensions.size());
for (String bcpExt : bcpExtensions) { for (String bcpExt : bcpExtensions) {
CaseInsensitiveChar key = new CaseInsensitiveChar(bcpExt.charAt(0)); CaseInsensitiveChar key = new CaseInsensitiveChar(bcpExt);
// ignore duplicates // ignore duplicates
if (!processedExntensions.contains(key)) { if (!done.contains(key)) {
// each extension string contains singleton, e.g. "a-abc-def" // each extension string contains singleton, e.g. "a-abc-def"
if (UnicodeLocaleExtension.isSingletonChar(key.value())) { if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
setUnicodeLocaleExtension(bcpExt.substring(2)); setUnicodeLocaleExtension(bcpExt.substring(2));
} else { } else {
if (_extensions == null) { if (extensions == null) {
_extensions = new HashMap<CaseInsensitiveChar, String>(4); extensions = new HashMap<>(4);
} }
_extensions.put(key, bcpExt.substring(2)); extensions.put(key, bcpExt.substring(2));
} }
} }
done.add(key);
} }
} }
if (privateuse != null && privateuse.length() > 0) { if (privateuse != null && privateuse.length() > 0) {
// privateuse string contains prefix, e.g. "x-abc-def" // privateuse string contains prefix, e.g. "x-abc-def"
if (_extensions == null) { if (extensions == null) {
_extensions = new HashMap<CaseInsensitiveChar, String>(1); extensions = new HashMap<>(1);
} }
_extensions.put(new CaseInsensitiveChar(privateuse.charAt(0)), privateuse.substring(2)); extensions.put(new CaseInsensitiveChar(privateuse), privateuse.substring(2));
} }
return this; return this;
...@@ -336,24 +347,25 @@ public final class InternalLocaleBuilder { ...@@ -336,24 +347,25 @@ public final class InternalLocaleBuilder {
*/ */
public InternalLocaleBuilder setLanguageTag(LanguageTag langtag) { public InternalLocaleBuilder setLanguageTag(LanguageTag langtag) {
clear(); clear();
if (langtag.getExtlangs().size() > 0) { if (!langtag.getExtlangs().isEmpty()) {
_language = langtag.getExtlangs().get(0); language = langtag.getExtlangs().get(0);
} else { } else {
String language = langtag.getLanguage(); String lang = langtag.getLanguage();
if (!language.equals(LanguageTag.UNDETERMINED)) { if (!lang.equals(LanguageTag.UNDETERMINED)) {
_language = language; language = lang;
} }
} }
_script = langtag.getScript(); script = langtag.getScript();
_region = langtag.getRegion(); region = langtag.getRegion();
List<String> bcpVariants = langtag.getVariants(); List<String> bcpVariants = langtag.getVariants();
if (bcpVariants.size() > 0) { if (!bcpVariants.isEmpty()) {
StringBuilder var = new StringBuilder(bcpVariants.get(0)); StringBuilder var = new StringBuilder(bcpVariants.get(0));
for (int i = 1; i < bcpVariants.size(); i++) { int size = bcpVariants.size();
for (int i = 1; i < size; i++) {
var.append(BaseLocale.SEP).append(bcpVariants.get(i)); var.append(BaseLocale.SEP).append(bcpVariants.get(i));
} }
_variant = var.toString(); variant = var.toString();
} }
setExtensions(langtag.getExtensions(), langtag.getPrivateuse()); setExtensions(langtag.getExtensions(), langtag.getPrivateuse());
...@@ -361,7 +373,7 @@ public final class InternalLocaleBuilder { ...@@ -361,7 +373,7 @@ public final class InternalLocaleBuilder {
return this; return this;
} }
public InternalLocaleBuilder setLocale(BaseLocale base, LocaleExtensions extensions) throws LocaleSyntaxException { public InternalLocaleBuilder setLocale(BaseLocale base, LocaleExtensions localeExtensions) throws LocaleSyntaxException {
String language = base.getLanguage(); String language = base.getLanguage();
String script = base.getScript(); String script = base.getScript();
String region = base.getRegion(); String region = base.getRegion();
...@@ -373,14 +385,14 @@ public final class InternalLocaleBuilder { ...@@ -373,14 +385,14 @@ public final class InternalLocaleBuilder {
if (language.equals("ja") && region.equals("JP") && variant.equals("JP")) { if (language.equals("ja") && region.equals("JP") && variant.equals("JP")) {
// When locale ja_JP_JP is created, ca-japanese is always there. // When locale ja_JP_JP is created, ca-japanese is always there.
// The builder ignores the variant "JP" // The builder ignores the variant "JP"
assert("japanese".equals(extensions.getUnicodeLocaleType("ca"))); assert("japanese".equals(localeExtensions.getUnicodeLocaleType("ca")));
variant = ""; variant = "";
} }
// Exception 2 - th_TH_TH // Exception 2 - th_TH_TH
else if (language.equals("th") && region.equals("TH") && variant.equals("TH")) { else if (language.equals("th") && region.equals("TH") && variant.equals("TH")) {
// When locale th_TH_TH is created, nu-thai is always there. // When locale th_TH_TH is created, nu-thai is always there.
// The builder ignores the variant "TH" // The builder ignores the variant "TH"
assert("thai".equals(extensions.getUnicodeLocaleType("nu"))); assert("thai".equals(localeExtensions.getUnicodeLocaleType("nu")));
variant = ""; variant = "";
} }
// Exception 3 - no_NO_NY // Exception 3 - no_NO_NY
...@@ -415,36 +427,36 @@ public final class InternalLocaleBuilder { ...@@ -415,36 +427,36 @@ public final class InternalLocaleBuilder {
// The input locale is validated at this point. // The input locale is validated at this point.
// Now, updating builder's internal fields. // Now, updating builder's internal fields.
_language = language; this.language = language;
_script = script; this.script = script;
_region = region; this.region = region;
_variant = variant; this.variant = variant;
clearExtensions(); clearExtensions();
Set<Character> extKeys = (extensions == null) ? null : extensions.getKeys(); Set<Character> extKeys = (localeExtensions == null) ? null : localeExtensions.getKeys();
if (extKeys != null) { if (extKeys != null) {
// map extensions back to builder's internal format // map localeExtensions back to builder's internal format
for (Character key : extKeys) { for (Character key : extKeys) {
Extension e = extensions.getExtension(key); Extension e = localeExtensions.getExtension(key);
if (e instanceof UnicodeLocaleExtension) { if (e instanceof UnicodeLocaleExtension) {
UnicodeLocaleExtension ue = (UnicodeLocaleExtension)e; UnicodeLocaleExtension ue = (UnicodeLocaleExtension)e;
for (String uatr : ue.getUnicodeLocaleAttributes()) { for (String uatr : ue.getUnicodeLocaleAttributes()) {
if (_uattributes == null) { if (uattributes == null) {
_uattributes = new HashSet<CaseInsensitiveString>(4); uattributes = new HashSet<>(4);
} }
_uattributes.add(new CaseInsensitiveString(uatr)); uattributes.add(new CaseInsensitiveString(uatr));
} }
for (String ukey : ue.getUnicodeLocaleKeys()) { for (String ukey : ue.getUnicodeLocaleKeys()) {
if (_ukeywords == null) { if (ukeywords == null) {
_ukeywords = new HashMap<CaseInsensitiveString, String>(4); ukeywords = new HashMap<>(4);
} }
_ukeywords.put(new CaseInsensitiveString(ukey), ue.getUnicodeLocaleType(ukey)); ukeywords.put(new CaseInsensitiveString(ukey), ue.getUnicodeLocaleType(ukey));
} }
} else { } else {
if (_extensions == null) { if (extensions == null) {
_extensions = new HashMap<CaseInsensitiveChar, String>(4); extensions = new HashMap<>(4);
} }
_extensions.put(new CaseInsensitiveChar(key.charValue()), e.getValue()); extensions.put(new CaseInsensitiveChar(key), e.getValue());
} }
} }
} }
...@@ -452,37 +464,37 @@ public final class InternalLocaleBuilder { ...@@ -452,37 +464,37 @@ public final class InternalLocaleBuilder {
} }
public InternalLocaleBuilder clear() { public InternalLocaleBuilder clear() {
_language = ""; language = "";
_script = ""; script = "";
_region = ""; region = "";
_variant = ""; variant = "";
clearExtensions(); clearExtensions();
return this; return this;
} }
public InternalLocaleBuilder clearExtensions() { public InternalLocaleBuilder clearExtensions() {
if (_extensions != null) { if (extensions != null) {
_extensions.clear(); extensions.clear();
} }
if (_uattributes != null) { if (uattributes != null) {
_uattributes.clear(); uattributes.clear();
} }
if (_ukeywords != null) { if (ukeywords != null) {
_ukeywords.clear(); ukeywords.clear();
} }
return this; return this;
} }
public BaseLocale getBaseLocale() { public BaseLocale getBaseLocale() {
String language = _language; String language = this.language;
String script = _script; String script = this.script;
String region = _region; String region = this.region;
String variant = _variant; String variant = this.variant;
// Special private use subtag sequence identified by "lvariant" will be // Special private use subtag sequence identified by "lvariant" will be
// interpreted as Java variant. // interpreted as Java variant.
if (_extensions != null) { if (extensions != null) {
String privuse = _extensions.get(PRIVUSE_KEY); String privuse = extensions.get(PRIVATEUSE_KEY);
if (privuse != null) { if (privuse != null) {
StringTokenIterator itr = new StringTokenIterator(privuse, LanguageTag.SEP); StringTokenIterator itr = new StringTokenIterator(privuse, LanguageTag.SEP);
boolean sawPrefix = false; boolean sawPrefix = false;
...@@ -492,7 +504,7 @@ public final class InternalLocaleBuilder { ...@@ -492,7 +504,7 @@ public final class InternalLocaleBuilder {
privVarStart = itr.currentStart(); privVarStart = itr.currentStart();
break; break;
} }
if (AsciiUtil.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) { if (LocaleUtils.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) {
sawPrefix = true; sawPrefix = true;
} }
itr.next(); itr.next();
...@@ -502,7 +514,8 @@ public final class InternalLocaleBuilder { ...@@ -502,7 +514,8 @@ public final class InternalLocaleBuilder {
if (sb.length() != 0) { if (sb.length() != 0) {
sb.append(BaseLocale.SEP); sb.append(BaseLocale.SEP);
} }
sb.append(privuse.substring(privVarStart).replaceAll(LanguageTag.SEP, BaseLocale.SEP)); sb.append(privuse.substring(privVarStart).replaceAll(LanguageTag.SEP,
BaseLocale.SEP));
variant = sb.toString(); variant = sb.toString();
} }
} }
...@@ -512,13 +525,13 @@ public final class InternalLocaleBuilder { ...@@ -512,13 +525,13 @@ public final class InternalLocaleBuilder {
} }
public LocaleExtensions getLocaleExtensions() { public LocaleExtensions getLocaleExtensions() {
if ((_extensions == null || _extensions.size() == 0) if (LocaleUtils.isEmpty(extensions) && LocaleUtils.isEmpty(uattributes)
&& (_uattributes == null || _uattributes.size() == 0) && LocaleUtils.isEmpty(ukeywords)) {
&& (_ukeywords == null || _ukeywords.size() == 0)) { return null;
return LocaleExtensions.EMPTY_EXTENSIONS;
} }
return new LocaleExtensions(_extensions, _uattributes, _ukeywords); LocaleExtensions lext = new LocaleExtensions(extensions, uattributes, ukeywords);
return lext.isEmpty() ? null : lext;
} }
/* /*
...@@ -540,7 +553,7 @@ public final class InternalLocaleBuilder { ...@@ -540,7 +553,7 @@ public final class InternalLocaleBuilder {
sawPrivuseVar = true; sawPrivuseVar = true;
break; break;
} }
if (AsciiUtil.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) { if (LocaleUtils.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) {
prefixStart = itr.currentStart(); prefixStart = itr.currentStart();
} }
itr.next(); itr.next();
...@@ -576,11 +589,11 @@ public final class InternalLocaleBuilder { ...@@ -576,11 +589,11 @@ public final class InternalLocaleBuilder {
*/ */
private void setUnicodeLocaleExtension(String subtags) { private void setUnicodeLocaleExtension(String subtags) {
// wipe out existing attributes/keywords // wipe out existing attributes/keywords
if (_uattributes != null) { if (uattributes != null) {
_uattributes.clear(); uattributes.clear();
} }
if (_ukeywords != null) { if (ukeywords != null) {
_ukeywords.clear(); ukeywords.clear();
} }
StringTokenIterator itr = new StringTokenIterator(subtags, LanguageTag.SEP); StringTokenIterator itr = new StringTokenIterator(subtags, LanguageTag.SEP);
...@@ -590,10 +603,10 @@ public final class InternalLocaleBuilder { ...@@ -590,10 +603,10 @@ public final class InternalLocaleBuilder {
if (!UnicodeLocaleExtension.isAttribute(itr.current())) { if (!UnicodeLocaleExtension.isAttribute(itr.current())) {
break; break;
} }
if (_uattributes == null) { if (uattributes == null) {
_uattributes = new HashSet<CaseInsensitiveString>(4); uattributes = new HashSet<>(4);
} }
_uattributes.add(new CaseInsensitiveString(itr.current())); uattributes.add(new CaseInsensitiveString(itr.current()));
itr.next(); itr.next();
} }
...@@ -608,14 +621,14 @@ public final class InternalLocaleBuilder { ...@@ -608,14 +621,14 @@ public final class InternalLocaleBuilder {
// next keyword - emit previous one // next keyword - emit previous one
assert(typeStart == -1 || typeEnd != -1); assert(typeStart == -1 || typeEnd != -1);
type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd); type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd);
if (_ukeywords == null) { if (ukeywords == null) {
_ukeywords = new HashMap<CaseInsensitiveString, String>(4); ukeywords = new HashMap<>(4);
} }
_ukeywords.put(key, type); ukeywords.put(key, type);
// reset keyword info // reset keyword info
CaseInsensitiveString tmpKey = new CaseInsensitiveString(itr.current()); CaseInsensitiveString tmpKey = new CaseInsensitiveString(itr.current());
key = _ukeywords.containsKey(tmpKey) ? null : tmpKey; key = ukeywords.containsKey(tmpKey) ? null : tmpKey;
typeStart = typeEnd = -1; typeStart = typeEnd = -1;
} else { } else {
if (typeStart == -1) { if (typeStart == -1) {
...@@ -627,7 +640,7 @@ public final class InternalLocaleBuilder { ...@@ -627,7 +640,7 @@ public final class InternalLocaleBuilder {
// 1. first keyword or // 1. first keyword or
// 2. next keyword, but previous one was duplicate // 2. next keyword, but previous one was duplicate
key = new CaseInsensitiveString(itr.current()); key = new CaseInsensitiveString(itr.current());
if (_ukeywords != null && _ukeywords.containsKey(key)) { if (ukeywords != null && ukeywords.containsKey(key)) {
// duplicate // duplicate
key = null; key = null;
} }
...@@ -638,10 +651,10 @@ public final class InternalLocaleBuilder { ...@@ -638,10 +651,10 @@ public final class InternalLocaleBuilder {
// last keyword // last keyword
assert(typeStart == -1 || typeEnd != -1); assert(typeStart == -1 || typeEnd != -1);
type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd); type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd);
if (_ukeywords == null) { if (ukeywords == null) {
_ukeywords = new HashMap<CaseInsensitiveString, String>(4); ukeywords = new HashMap<>(4);
} }
_ukeywords.put(key, type); ukeywords.put(key, type);
} }
break; break;
} }
...@@ -650,21 +663,24 @@ public final class InternalLocaleBuilder { ...@@ -650,21 +663,24 @@ public final class InternalLocaleBuilder {
} }
} }
static class CaseInsensitiveString { static final class CaseInsensitiveString {
private String _s; private final String str, lowerStr;
CaseInsensitiveString(String s) { CaseInsensitiveString(String s) {
_s = s; str = s;
lowerStr = LocaleUtils.toLowerString(s);
} }
public String value() { public String value() {
return _s; return str;
} }
@Override
public int hashCode() { public int hashCode() {
return AsciiUtil.toLowerString(_s).hashCode(); return lowerStr.hashCode();
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
...@@ -672,25 +688,36 @@ public final class InternalLocaleBuilder { ...@@ -672,25 +688,36 @@ public final class InternalLocaleBuilder {
if (!(obj instanceof CaseInsensitiveString)) { if (!(obj instanceof CaseInsensitiveString)) {
return false; return false;
} }
return AsciiUtil.caseIgnoreMatch(_s, ((CaseInsensitiveString)obj).value()); return lowerStr.equals(((CaseInsensitiveString)obj).lowerStr);
} }
} }
static class CaseInsensitiveChar { static final class CaseInsensitiveChar {
private char _c; private final char ch, lowerCh;
/**
* Constructs a CaseInsensitiveChar with the first char of the
* given s.
*/
private CaseInsensitiveChar(String s) {
this(s.charAt(0));
}
CaseInsensitiveChar(char c) { CaseInsensitiveChar(char c) {
_c = c; ch = c;
lowerCh = LocaleUtils.toLower(ch);
} }
public char value() { public char value() {
return _c; return ch;
} }
@Override
public int hashCode() { public int hashCode() {
return AsciiUtil.toLower(_c); return lowerCh;
} }
@Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
return true; return true;
...@@ -698,8 +725,7 @@ public final class InternalLocaleBuilder { ...@@ -698,8 +725,7 @@ public final class InternalLocaleBuilder {
if (!(obj instanceof CaseInsensitiveChar)) { if (!(obj instanceof CaseInsensitiveChar)) {
return false; return false;
} }
return _c == AsciiUtil.toLower(((CaseInsensitiveChar)obj).value()); return lowerCh == ((CaseInsensitiveChar)obj).lowerCh;
} }
} }
} }
...@@ -44,25 +44,25 @@ public class LanguageTag { ...@@ -44,25 +44,25 @@ public class LanguageTag {
// //
public static final String SEP = "-"; public static final String SEP = "-";
public static final String PRIVATEUSE = "x"; public static final String PRIVATEUSE = "x";
public static String UNDETERMINED = "und"; public static final String UNDETERMINED = "und";
public static final String PRIVUSE_VARIANT_PREFIX = "lvariant"; public static final String PRIVUSE_VARIANT_PREFIX = "lvariant";
// //
// Language subtag fields // Language subtag fields
// //
private String _language = ""; // language subtag private String language = ""; // language subtag
private String _script = ""; // script subtag private String script = ""; // script subtag
private String _region = ""; // region subtag private String region = ""; // region subtag
private String _privateuse = ""; // privateuse private String privateuse = ""; // privateuse
private List<String> _extlangs = Collections.emptyList(); // extlang subtags private List<String> extlangs = Collections.emptyList(); // extlang subtags
private List<String> _variants = Collections.emptyList(); // variant subtags private List<String> variants = Collections.emptyList(); // variant subtags
private List<String> _extensions = Collections.emptyList(); // extensions private List<String> extensions = Collections.emptyList(); // extensions
// Map contains grandfathered tags and its preferred mappings from // Map contains grandfathered tags and its preferred mappings from
// http://www.ietf.org/rfc/rfc5646.txt // http://www.ietf.org/rfc/rfc5646.txt
private static final Map<AsciiUtil.CaseInsensitiveKey, String[]> GRANDFATHERED = // Keys are lower-case strings.
new HashMap<AsciiUtil.CaseInsensitiveKey, String[]>(); private static final Map<String, String[]> GRANDFATHERED = new HashMap<>();
static { static {
// grandfathered = irregular ; non-redundant tags registered // grandfathered = irregular ; non-redundant tags registered
...@@ -126,7 +126,7 @@ public class LanguageTag { ...@@ -126,7 +126,7 @@ public class LanguageTag {
{"zh-xiang", "hsn"}, {"zh-xiang", "hsn"},
}; };
for (String[] e : entries) { for (String[] e : entries) {
GRANDFATHERED.put(new AsciiUtil.CaseInsensitiveKey(e[0]), e); GRANDFATHERED.put(LocaleUtils.toLowerString(e[0]), e);
} }
} }
...@@ -188,7 +188,7 @@ public class LanguageTag { ...@@ -188,7 +188,7 @@ public class LanguageTag {
StringTokenIterator itr; StringTokenIterator itr;
// Check if the tag is grandfathered // Check if the tag is grandfathered
String[] gfmap = GRANDFATHERED.get(new AsciiUtil.CaseInsensitiveKey(languageTag)); String[] gfmap = GRANDFATHERED.get(LocaleUtils.toLowerString(languageTag));
if (gfmap != null) { if (gfmap != null) {
// use preferred mapping // use preferred mapping
itr = new StringTokenIterator(gfmap[1], SEP); itr = new StringTokenIterator(gfmap[1], SEP);
...@@ -210,11 +210,11 @@ public class LanguageTag { ...@@ -210,11 +210,11 @@ public class LanguageTag {
if (!itr.isDone() && !sts.isError()) { if (!itr.isDone() && !sts.isError()) {
String s = itr.current(); String s = itr.current();
sts._errorIndex = itr.currentStart(); sts.errorIndex = itr.currentStart();
if (s.length() == 0) { if (s.length() == 0) {
sts._errorMsg = "Empty subtag"; sts.errorMsg = "Empty subtag";
} else { } else {
sts._errorMsg = "Invalid subtag: " + s; sts.errorMsg = "Invalid subtag: " + s;
} }
} }
...@@ -235,8 +235,8 @@ public class LanguageTag { ...@@ -235,8 +235,8 @@ public class LanguageTag {
String s = itr.current(); String s = itr.current();
if (isLanguage(s)) { if (isLanguage(s)) {
found = true; found = true;
_language = s; language = s;
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
itr.next(); itr.next();
} }
...@@ -256,14 +256,14 @@ public class LanguageTag { ...@@ -256,14 +256,14 @@ public class LanguageTag {
break; break;
} }
found = true; found = true;
if (_extlangs.isEmpty()) { if (extlangs.isEmpty()) {
_extlangs = new ArrayList<String>(3); extlangs = new ArrayList<>(3);
} }
_extlangs.add(s); extlangs.add(s);
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
itr.next(); itr.next();
if (_extlangs.size() == 3) { if (extlangs.size() == 3) {
// Maximum 3 extlangs // Maximum 3 extlangs
break; break;
} }
...@@ -282,8 +282,8 @@ public class LanguageTag { ...@@ -282,8 +282,8 @@ public class LanguageTag {
String s = itr.current(); String s = itr.current();
if (isScript(s)) { if (isScript(s)) {
found = true; found = true;
_script = s; script = s;
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
itr.next(); itr.next();
} }
...@@ -300,8 +300,8 @@ public class LanguageTag { ...@@ -300,8 +300,8 @@ public class LanguageTag {
String s = itr.current(); String s = itr.current();
if (isRegion(s)) { if (isRegion(s)) {
found = true; found = true;
_region = s; region = s;
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
itr.next(); itr.next();
} }
...@@ -321,11 +321,11 @@ public class LanguageTag { ...@@ -321,11 +321,11 @@ public class LanguageTag {
break; break;
} }
found = true; found = true;
if (_variants.isEmpty()) { if (variants.isEmpty()) {
_variants = new ArrayList<String>(3); variants = new ArrayList<>(3);
} }
_variants.add(s); variants.add(s);
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
itr.next(); itr.next();
} }
...@@ -351,23 +351,23 @@ public class LanguageTag { ...@@ -351,23 +351,23 @@ public class LanguageTag {
s = itr.current(); s = itr.current();
if (isExtensionSubtag(s)) { if (isExtensionSubtag(s)) {
sb.append(SEP).append(s); sb.append(SEP).append(s);
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
} else { } else {
break; break;
} }
itr.next(); itr.next();
} }
if (sts._parseLength <= start) { if (sts.parseLength <= start) {
sts._errorIndex = start; sts.errorIndex = start;
sts._errorMsg = "Incomplete extension '" + singleton + "'"; sts.errorMsg = "Incomplete extension '" + singleton + "'";
break; break;
} }
if (_extensions.size() == 0) { if (extensions.isEmpty()) {
_extensions = new ArrayList<String>(4); extensions = new ArrayList<>(4);
} }
_extensions.add(sb.toString()); extensions.add(sb.toString());
found = true; found = true;
} else { } else {
break; break;
...@@ -395,17 +395,17 @@ public class LanguageTag { ...@@ -395,17 +395,17 @@ public class LanguageTag {
break; break;
} }
sb.append(SEP).append(s); sb.append(SEP).append(s);
sts._parseLength = itr.currentEnd(); sts.parseLength = itr.currentEnd();
itr.next(); itr.next();
} }
if (sts._parseLength <= start) { if (sts.parseLength <= start) {
// need at least 1 private subtag // need at least 1 private subtag
sts._errorIndex = start; sts.errorIndex = start;
sts._errorMsg = "Incomplete privateuse"; sts.errorMsg = "Incomplete privateuse";
} else { } else {
_privateuse = sb.toString(); privateuse = sb.toString();
found = true; found = true;
} }
} }
...@@ -425,9 +425,8 @@ public class LanguageTag { ...@@ -425,9 +425,8 @@ public class LanguageTag {
String privuseVar = null; // store ill-formed variant subtags String privuseVar = null; // store ill-formed variant subtags
if (language.length() > 0 && isLanguage(language)) { if (isLanguage(language)) {
// Convert a deprecated language code used by Java to // Convert a deprecated language code to its new code
// a new code
if (language.equals("iw")) { if (language.equals("iw")) {
language = "he"; language = "he";
} else if (language.equals("ji")) { } else if (language.equals("ji")) {
...@@ -435,22 +434,22 @@ public class LanguageTag { ...@@ -435,22 +434,22 @@ public class LanguageTag {
} else if (language.equals("in")) { } else if (language.equals("in")) {
language = "id"; language = "id";
} }
tag._language = language; tag.language = language;
} }
if (script.length() > 0 && isScript(script)) { if (isScript(script)) {
tag._script = canonicalizeScript(script); tag.script = canonicalizeScript(script);
hasSubtag = true; hasSubtag = true;
} }
if (region.length() > 0 && isRegion(region)) { if (isRegion(region)) {
tag._region = canonicalizeRegion(region); tag.region = canonicalizeRegion(region);
hasSubtag = true; hasSubtag = true;
} }
// Special handling for no_NO_NY - use nn_NO for language tag // Special handling for no_NO_NY - use nn_NO for language tag
if (tag._language.equals("no") && tag._region.equals("NO") && variant.equals("NY")) { if (tag.language.equals("no") && tag.region.equals("NO") && variant.equals("NY")) {
tag._language = "nn"; tag.language = "nn";
variant = ""; variant = "";
} }
...@@ -463,13 +462,13 @@ public class LanguageTag { ...@@ -463,13 +462,13 @@ public class LanguageTag {
break; break;
} }
if (variants == null) { if (variants == null) {
variants = new ArrayList<String>(); variants = new ArrayList<>();
} }
variants.add(var); // Do not canonicalize! variants.add(var); // Do not canonicalize!
varitr.next(); varitr.next();
} }
if (variants != null) { if (variants != null) {
tag._variants = variants; tag.variants = variants;
hasSubtag = true; hasSubtag = true;
} }
if (!varitr.isDone()) { if (!varitr.isDone()) {
...@@ -496,21 +495,23 @@ public class LanguageTag { ...@@ -496,21 +495,23 @@ public class LanguageTag {
List<String> extensions = null; List<String> extensions = null;
String privateuse = null; String privateuse = null;
Set<Character> locextKeys = localeExtensions.getKeys(); if (localeExtensions != null) {
for (Character locextKey : locextKeys) { Set<Character> locextKeys = localeExtensions.getKeys();
Extension ext = localeExtensions.getExtension(locextKey); for (Character locextKey : locextKeys) {
if (isPrivateusePrefixChar(locextKey.charValue())) { Extension ext = localeExtensions.getExtension(locextKey);
privateuse = ext.getValue(); if (isPrivateusePrefixChar(locextKey)) {
} else { privateuse = ext.getValue();
if (extensions == null) { } else {
extensions = new ArrayList<String>(); if (extensions == null) {
extensions = new ArrayList<>();
}
extensions.add(locextKey.toString() + SEP + ext.getValue());
} }
extensions.add(locextKey.toString() + SEP + ext.getValue());
} }
} }
if (extensions != null) { if (extensions != null) {
tag._extensions = extensions; tag.extensions = extensions;
hasSubtag = true; hasSubtag = true;
} }
...@@ -519,19 +520,20 @@ public class LanguageTag { ...@@ -519,19 +520,20 @@ public class LanguageTag {
if (privateuse == null) { if (privateuse == null) {
privateuse = PRIVUSE_VARIANT_PREFIX + SEP + privuseVar; privateuse = PRIVUSE_VARIANT_PREFIX + SEP + privuseVar;
} else { } else {
privateuse = privateuse + SEP + PRIVUSE_VARIANT_PREFIX + SEP + privuseVar.replace(BaseLocale.SEP, SEP); privateuse = privateuse + SEP + PRIVUSE_VARIANT_PREFIX
+ SEP + privuseVar.replace(BaseLocale.SEP, SEP);
} }
} }
if (privateuse != null) { if (privateuse != null) {
tag._privateuse = privateuse; tag.privateuse = privateuse;
} }
if (tag._language.length() == 0 && (hasSubtag || privateuse == null)) { if (tag.language.length() == 0 && (hasSubtag || privateuse == null)) {
// use lang "und" when 1) no language is available AND // use lang "und" when 1) no language is available AND
// 2) any of other subtags other than private use are available or // 2) any of other subtags other than private use are available or
// no private use tag is available // no private use tag is available
tag._language = UNDETERMINED; tag.language = UNDETERMINED;
} }
return tag; return tag;
...@@ -542,31 +544,40 @@ public class LanguageTag { ...@@ -542,31 +544,40 @@ public class LanguageTag {
// //
public String getLanguage() { public String getLanguage() {
return _language; return language;
} }
public List<String> getExtlangs() { public List<String> getExtlangs() {
return Collections.unmodifiableList(_extlangs); if (extlangs.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(extlangs);
} }
public String getScript() { public String getScript() {
return _script; return script;
} }
public String getRegion() { public String getRegion() {
return _region; return region;
} }
public List<String> getVariants() { public List<String> getVariants() {
return Collections.unmodifiableList(_variants); if (variants.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(variants);
} }
public List<String> getExtensions() { public List<String> getExtensions() {
return Collections.unmodifiableList(_extensions); if (extensions.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(extensions);
} }
public String getPrivateuse() { public String getPrivateuse() {
return _privateuse; return privateuse;
} }
// //
...@@ -579,25 +590,26 @@ public class LanguageTag { ...@@ -579,25 +590,26 @@ public class LanguageTag {
// ; extended language subtags // ; extended language subtags
// / 4ALPHA ; or reserved for future use // / 4ALPHA ; or reserved for future use
// / 5*8ALPHA ; or registered language subtag // / 5*8ALPHA ; or registered language subtag
return (s.length() >= 2) && (s.length() <= 8) && AsciiUtil.isAlphaString(s); int len = s.length();
return (len >= 2) && (len <= 8) && LocaleUtils.isAlphaString(s);
} }
public static boolean isExtlang(String s) { public static boolean isExtlang(String s) {
// extlang = 3ALPHA ; selected ISO 639 codes // extlang = 3ALPHA ; selected ISO 639 codes
// *2("-" 3ALPHA) ; permanently reserved // *2("-" 3ALPHA) ; permanently reserved
return (s.length() == 3) && AsciiUtil.isAlphaString(s); return (s.length() == 3) && LocaleUtils.isAlphaString(s);
} }
public static boolean isScript(String s) { public static boolean isScript(String s) {
// script = 4ALPHA ; ISO 15924 code // script = 4ALPHA ; ISO 15924 code
return (s.length() == 4) && AsciiUtil.isAlphaString(s); return (s.length() == 4) && LocaleUtils.isAlphaString(s);
} }
public static boolean isRegion(String s) { public static boolean isRegion(String s) {
// region = 2ALPHA ; ISO 3166-1 code // region = 2ALPHA ; ISO 3166-1 code
// / 3DIGIT ; UN M.49 code // / 3DIGIT ; UN M.49 code
return ((s.length() == 2) && AsciiUtil.isAlphaString(s)) return ((s.length() == 2) && LocaleUtils.isAlphaString(s))
|| ((s.length() == 3) && AsciiUtil.isNumericString(s)); || ((s.length() == 3) && LocaleUtils.isNumericString(s));
} }
public static boolean isVariant(String s) { public static boolean isVariant(String s) {
...@@ -605,13 +617,13 @@ public class LanguageTag { ...@@ -605,13 +617,13 @@ public class LanguageTag {
// / (DIGIT 3alphanum) // / (DIGIT 3alphanum)
int len = s.length(); int len = s.length();
if (len >= 5 && len <= 8) { if (len >= 5 && len <= 8) {
return AsciiUtil.isAlphaNumericString(s); return LocaleUtils.isAlphaNumericString(s);
} }
if (len == 4) { if (len == 4) {
return AsciiUtil.isNumeric(s.charAt(0)) return LocaleUtils.isNumeric(s.charAt(0))
&& AsciiUtil.isAlphaNumeric(s.charAt(1)) && LocaleUtils.isAlphaNumeric(s.charAt(1))
&& AsciiUtil.isAlphaNumeric(s.charAt(2)) && LocaleUtils.isAlphaNumeric(s.charAt(2))
&& AsciiUtil.isAlphaNumeric(s.charAt(3)); && LocaleUtils.isAlphaNumeric(s.charAt(3));
} }
return false; return false;
} }
...@@ -624,8 +636,8 @@ public class LanguageTag { ...@@ -624,8 +636,8 @@ public class LanguageTag {
// / %x79-7A ; y - z // / %x79-7A ; y - z
return (s.length() == 1) return (s.length() == 1)
&& AsciiUtil.isAlphaString(s) && LocaleUtils.isAlphaString(s)
&& !AsciiUtil.caseIgnoreMatch(PRIVATEUSE, s); && !LocaleUtils.caseIgnoreMatch(PRIVATEUSE, s);
} }
public static boolean isExtensionSingletonChar(char c) { public static boolean isExtensionSingletonChar(char c) {
...@@ -634,22 +646,24 @@ public class LanguageTag { ...@@ -634,22 +646,24 @@ public class LanguageTag {
public static boolean isExtensionSubtag(String s) { public static boolean isExtensionSubtag(String s) {
// extension = singleton 1*("-" (2*8alphanum)) // extension = singleton 1*("-" (2*8alphanum))
return (s.length() >= 2) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s); int len = s.length();
return (len >= 2) && (len <= 8) && LocaleUtils.isAlphaNumericString(s);
} }
public static boolean isPrivateusePrefix(String s) { public static boolean isPrivateusePrefix(String s) {
// privateuse = "x" 1*("-" (1*8alphanum)) // privateuse = "x" 1*("-" (1*8alphanum))
return (s.length() == 1) return (s.length() == 1)
&& AsciiUtil.caseIgnoreMatch(PRIVATEUSE, s); && LocaleUtils.caseIgnoreMatch(PRIVATEUSE, s);
} }
public static boolean isPrivateusePrefixChar(char c) { public static boolean isPrivateusePrefixChar(char c) {
return (AsciiUtil.caseIgnoreMatch(PRIVATEUSE, String.valueOf(c))); return (LocaleUtils.caseIgnoreMatch(PRIVATEUSE, String.valueOf(c)));
} }
public static boolean isPrivateuseSubtag(String s) { public static boolean isPrivateuseSubtag(String s) {
// privateuse = "x" 1*("-" (1*8alphanum)) // privateuse = "x" 1*("-" (1*8alphanum))
return (s.length() >= 1) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s); int len = s.length();
return (len >= 1) && (len <= 8) && LocaleUtils.isAlphaNumericString(s);
} }
// //
...@@ -657,76 +671,77 @@ public class LanguageTag { ...@@ -657,76 +671,77 @@ public class LanguageTag {
// //
public static String canonicalizeLanguage(String s) { public static String canonicalizeLanguage(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizeExtlang(String s) { public static String canonicalizeExtlang(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizeScript(String s) { public static String canonicalizeScript(String s) {
return AsciiUtil.toTitleString(s); return LocaleUtils.toTitleString(s);
} }
public static String canonicalizeRegion(String s) { public static String canonicalizeRegion(String s) {
return AsciiUtil.toUpperString(s); return LocaleUtils.toUpperString(s);
} }
public static String canonicalizeVariant(String s) { public static String canonicalizeVariant(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizeExtension(String s) { public static String canonicalizeExtension(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizeExtensionSingleton(String s) { public static String canonicalizeExtensionSingleton(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizeExtensionSubtag(String s) { public static String canonicalizeExtensionSubtag(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizePrivateuse(String s) { public static String canonicalizePrivateuse(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
public static String canonicalizePrivateuseSubtag(String s) { public static String canonicalizePrivateuseSubtag(String s) {
return AsciiUtil.toLowerString(s); return LocaleUtils.toLowerString(s);
} }
@Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (_language.length() > 0) { if (language.length() > 0) {
sb.append(_language); sb.append(language);
for (String extlang : _extlangs) { for (String extlang : extlangs) {
sb.append(SEP).append(extlang); sb.append(SEP).append(extlang);
} }
if (_script.length() > 0) { if (script.length() > 0) {
sb.append(SEP).append(_script); sb.append(SEP).append(script);
} }
if (_region.length() > 0) { if (region.length() > 0) {
sb.append(SEP).append(_region); sb.append(SEP).append(region);
} }
for (String variant : _extlangs) { for (String variant : variants) {
sb.append(SEP).append(variant); sb.append(SEP).append(variant);
} }
for (String extension : _extensions) { for (String extension : extensions) {
sb.append(SEP).append(extension); sb.append(SEP).append(extension);
} }
} }
if (_privateuse.length() > 0) { if (privateuse.length() > 0) {
if (sb.length() > 0) { if (sb.length() > 0) {
sb.append(SEP); sb.append(SEP);
} }
sb.append(_privateuse); sb.append(privateuse);
} }
return sb.toString(); return sb.toString();
......
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -36,6 +36,7 @@ import java.util.Map; ...@@ -36,6 +36,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.TreeSet; import java.util.TreeSet;
...@@ -45,55 +46,45 @@ import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveString; ...@@ -45,55 +46,45 @@ import sun.util.locale.InternalLocaleBuilder.CaseInsensitiveString;
public class LocaleExtensions { public class LocaleExtensions {
private SortedMap<Character, Extension> _map; private final Map<Character, Extension> extensionMap;
private String _id; private final String id;
private static final SortedMap<Character, Extension> EMPTY_MAP = public static final LocaleExtensions CALENDAR_JAPANESE
Collections.unmodifiableSortedMap(new TreeMap<Character, Extension>()); = new LocaleExtensions("u-ca-japanese",
UnicodeLocaleExtension.SINGLETON,
UnicodeLocaleExtension.CA_JAPANESE);
public static final LocaleExtensions EMPTY_EXTENSIONS; public static final LocaleExtensions NUMBER_THAI
public static final LocaleExtensions CALENDAR_JAPANESE; = new LocaleExtensions("u-nu-thai",
public static final LocaleExtensions NUMBER_THAI; UnicodeLocaleExtension.SINGLETON,
UnicodeLocaleExtension.NU_THAI);
static { private LocaleExtensions(String id, Character key, Extension value) {
EMPTY_EXTENSIONS = new LocaleExtensions(); this.id = id;
EMPTY_EXTENSIONS._id = ""; this.extensionMap = Collections.singletonMap(key, value);
EMPTY_EXTENSIONS._map = EMPTY_MAP;
CALENDAR_JAPANESE = new LocaleExtensions();
CALENDAR_JAPANESE._id = "u-ca-japanese";
CALENDAR_JAPANESE._map = new TreeMap<Character, Extension>();
CALENDAR_JAPANESE._map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), UnicodeLocaleExtension.CA_JAPANESE);
NUMBER_THAI = new LocaleExtensions();
NUMBER_THAI._id = "u-nu-thai";
NUMBER_THAI._map = new TreeMap<Character, Extension>();
NUMBER_THAI._map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), UnicodeLocaleExtension.NU_THAI);
}
private LocaleExtensions() {
} }
/* /*
* Package local constructor, only used by InternalLocaleBuilder. * Package private constructor, only used by InternalLocaleBuilder.
*/ */
LocaleExtensions(Map<CaseInsensitiveChar, String> extensions, LocaleExtensions(Map<CaseInsensitiveChar, String> extensions,
Set<CaseInsensitiveString> uattributes, Map<CaseInsensitiveString, String> ukeywords) { Set<CaseInsensitiveString> uattributes,
boolean hasExtension = (extensions != null && extensions.size() > 0); Map<CaseInsensitiveString, String> ukeywords) {
boolean hasUAttributes = (uattributes != null && uattributes.size() > 0); boolean hasExtension = !LocaleUtils.isEmpty(extensions);
boolean hasUKeywords = (ukeywords != null && ukeywords.size() > 0); boolean hasUAttributes = !LocaleUtils.isEmpty(uattributes);
boolean hasUKeywords = !LocaleUtils.isEmpty(ukeywords);
if (!hasExtension && !hasUAttributes && !hasUKeywords) { if (!hasExtension && !hasUAttributes && !hasUKeywords) {
_map = EMPTY_MAP; id = "";
_id = ""; extensionMap = Collections.emptyMap();
return; return;
} }
// Build extension map // Build extension map
_map = new TreeMap<Character, Extension>(); SortedMap<Character, Extension> map = new TreeMap<>();
if (hasExtension) { if (hasExtension) {
for (Entry<CaseInsensitiveChar, String> ext : extensions.entrySet()) { for (Entry<CaseInsensitiveChar, String> ext : extensions.entrySet()) {
char key = AsciiUtil.toLower(ext.getKey().value()); char key = LocaleUtils.toLower(ext.getKey().value());
String value = ext.getValue(); String value = ext.getValue();
if (LanguageTag.isPrivateusePrefixChar(key)) { if (LanguageTag.isPrivateusePrefixChar(key)) {
...@@ -104,54 +95,57 @@ public class LocaleExtensions { ...@@ -104,54 +95,57 @@ public class LocaleExtensions {
} }
} }
Extension e = new Extension(key, AsciiUtil.toLowerString(value)); map.put(key, new Extension(key, LocaleUtils.toLowerString(value)));
_map.put(Character.valueOf(key), e);
} }
} }
if (hasUAttributes || hasUKeywords) { if (hasUAttributes || hasUKeywords) {
TreeSet<String> uaset = null; SortedSet<String> uaset = null;
TreeMap<String, String> ukmap = null; SortedMap<String, String> ukmap = null;
if (hasUAttributes) { if (hasUAttributes) {
uaset = new TreeSet<String>(); uaset = new TreeSet<>();
for (CaseInsensitiveString cis : uattributes) { for (CaseInsensitiveString cis : uattributes) {
uaset.add(AsciiUtil.toLowerString(cis.value())); uaset.add(LocaleUtils.toLowerString(cis.value()));
} }
} }
if (hasUKeywords) { if (hasUKeywords) {
ukmap = new TreeMap<String, String>(); ukmap = new TreeMap<>();
for (Entry<CaseInsensitiveString, String> kwd : ukeywords.entrySet()) { for (Entry<CaseInsensitiveString, String> kwd : ukeywords.entrySet()) {
String key = AsciiUtil.toLowerString(kwd.getKey().value()); String key = LocaleUtils.toLowerString(kwd.getKey().value());
String type = AsciiUtil.toLowerString(kwd.getValue()); String type = LocaleUtils.toLowerString(kwd.getValue());
ukmap.put(key, type); ukmap.put(key, type);
} }
} }
UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap); UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap);
_map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), ule); map.put(UnicodeLocaleExtension.SINGLETON, ule);
} }
if (_map.size() == 0) { if (map.isEmpty()) {
// this could happen when only privuateuse with special variant // this could happen when only privuateuse with special variant
_map = EMPTY_MAP; id = "";
_id = ""; extensionMap = Collections.emptyMap();
} else { } else {
_id = toID(_map); id = toID(map);
extensionMap = map;
} }
} }
public Set<Character> getKeys() { public Set<Character> getKeys() {
return Collections.unmodifiableSet(_map.keySet()); if (extensionMap.isEmpty()) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(extensionMap.keySet());
} }
public Extension getExtension(Character key) { public Extension getExtension(Character key) {
return _map.get(Character.valueOf(AsciiUtil.toLower(key.charValue()))); return extensionMap.get(LocaleUtils.toLower(key));
} }
public String getExtensionValue(Character key) { public String getExtensionValue(Character key) {
Extension ext = _map.get(Character.valueOf(AsciiUtil.toLower(key.charValue()))); Extension ext = extensionMap.get(LocaleUtils.toLower(key));
if (ext == null) { if (ext == null) {
return null; return null;
} }
...@@ -159,7 +153,7 @@ public class LocaleExtensions { ...@@ -159,7 +153,7 @@ public class LocaleExtensions {
} }
public Set<String> getUnicodeLocaleAttributes() { public Set<String> getUnicodeLocaleAttributes() {
Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON)); Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON);
if (ext == null) { if (ext == null) {
return Collections.emptySet(); return Collections.emptySet();
} }
...@@ -168,7 +162,7 @@ public class LocaleExtensions { ...@@ -168,7 +162,7 @@ public class LocaleExtensions {
} }
public Set<String> getUnicodeLocaleKeys() { public Set<String> getUnicodeLocaleKeys() {
Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON)); Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON);
if (ext == null) { if (ext == null) {
return Collections.emptySet(); return Collections.emptySet();
} }
...@@ -177,16 +171,16 @@ public class LocaleExtensions { ...@@ -177,16 +171,16 @@ public class LocaleExtensions {
} }
public String getUnicodeLocaleType(String unicodeLocaleKey) { public String getUnicodeLocaleType(String unicodeLocaleKey) {
Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON)); Extension ext = extensionMap.get(UnicodeLocaleExtension.SINGLETON);
if (ext == null) { if (ext == null) {
return null; return null;
} }
assert (ext instanceof UnicodeLocaleExtension); assert (ext instanceof UnicodeLocaleExtension);
return ((UnicodeLocaleExtension)ext).getUnicodeLocaleType(AsciiUtil.toLowerString(unicodeLocaleKey)); return ((UnicodeLocaleExtension)ext).getUnicodeLocaleType(LocaleUtils.toLowerString(unicodeLocaleKey));
} }
public boolean isEmpty() { public boolean isEmpty() {
return _map.isEmpty(); return extensionMap.isEmpty();
} }
public static boolean isValidKey(char c) { public static boolean isValidKey(char c) {
...@@ -201,7 +195,7 @@ public class LocaleExtensions { ...@@ -201,7 +195,7 @@ public class LocaleExtensions {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
Extension privuse = null; Extension privuse = null;
for (Entry<Character, Extension> entry : map.entrySet()) { for (Entry<Character, Extension> entry : map.entrySet()) {
char singleton = entry.getKey().charValue(); char singleton = entry.getKey();
Extension extension = entry.getValue(); Extension extension = entry.getValue();
if (LanguageTag.isPrivateusePrefixChar(singleton)) { if (LanguageTag.isPrivateusePrefixChar(singleton)) {
privuse = extension; privuse = extension;
...@@ -221,19 +215,21 @@ public class LocaleExtensions { ...@@ -221,19 +215,21 @@ public class LocaleExtensions {
return buf.toString(); return buf.toString();
} }
@Override
public String toString() { public String toString() {
return _id; return id;
} }
public String getID() { public String getID() {
return _id; return id;
} }
@Override
public int hashCode() { public int hashCode() {
return _id.hashCode(); return id.hashCode();
} }
@Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (this == other) { if (this == other) {
return true; return true;
...@@ -241,6 +237,6 @@ public class LocaleExtensions { ...@@ -241,6 +237,6 @@ public class LocaleExtensions {
if (!(other instanceof LocaleExtensions)) { if (!(other instanceof LocaleExtensions)) {
return false; return false;
} }
return this._id.equals(((LocaleExtensions)other)._id); return id.equals(((LocaleExtensions)other).id);
} }
} }
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,24 +34,25 @@ package sun.util.locale; ...@@ -34,24 +34,25 @@ package sun.util.locale;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public abstract class LocaleObjectCache<K, V> { public abstract class LocaleObjectCache<K, V> {
private ConcurrentHashMap<K, CacheEntry<K, V>> _map; private ConcurrentMap<K, CacheEntry<K, V>> map;
private ReferenceQueue<V> _queue = new ReferenceQueue<V>(); private ReferenceQueue<V> queue = new ReferenceQueue<>();
public LocaleObjectCache() { public LocaleObjectCache() {
this(16, 0.75f, 16); this(16, 0.75f, 16);
} }
public LocaleObjectCache(int initialCapacity, float loadFactor, int concurrencyLevel) { public LocaleObjectCache(int initialCapacity, float loadFactor, int concurrencyLevel) {
_map = new ConcurrentHashMap<K, CacheEntry<K, V>>(initialCapacity, loadFactor, concurrencyLevel); map = new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel);
} }
public V get(K key) { public V get(K key) {
V value = null; V value = null;
cleanStaleEntries(); cleanStaleEntries();
CacheEntry<K, V> entry = _map.get(key); CacheEntry<K, V> entry = map.get(key);
if (entry != null) { if (entry != null) {
value = entry.get(); value = entry.get();
} }
...@@ -63,11 +64,11 @@ public abstract class LocaleObjectCache<K, V> { ...@@ -63,11 +64,11 @@ public abstract class LocaleObjectCache<K, V> {
return null; return null;
} }
CacheEntry<K, V> newEntry = new CacheEntry<K, V>(key, newVal, _queue); CacheEntry<K, V> newEntry = new CacheEntry<>(key, newVal, queue);
while (value == null) { while (value == null) {
cleanStaleEntries(); cleanStaleEntries();
entry = _map.putIfAbsent(key, newEntry); entry = map.putIfAbsent(key, newEntry);
if (entry == null) { if (entry == null) {
value = newVal; value = newVal;
break; break;
...@@ -79,11 +80,17 @@ public abstract class LocaleObjectCache<K, V> { ...@@ -79,11 +80,17 @@ public abstract class LocaleObjectCache<K, V> {
return value; return value;
} }
protected V put(K key, V value) {
CacheEntry<K, V> entry = new CacheEntry<>(key, value, queue);
CacheEntry<K, V> oldEntry = map.put(key, entry);
return (oldEntry == null) ? null : oldEntry.get();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void cleanStaleEntries() { private void cleanStaleEntries() {
CacheEntry<K, V> entry; CacheEntry<K, V> entry;
while ((entry = (CacheEntry<K, V>)_queue.poll()) != null) { while ((entry = (CacheEntry<K, V>)queue.poll()) != null) {
_map.remove(entry.getKey()); map.remove(entry.getKey());
} }
} }
...@@ -94,15 +101,15 @@ public abstract class LocaleObjectCache<K, V> { ...@@ -94,15 +101,15 @@ public abstract class LocaleObjectCache<K, V> {
} }
private static class CacheEntry<K, V> extends SoftReference<V> { private static class CacheEntry<K, V> extends SoftReference<V> {
private K _key; private K key;
CacheEntry(K key, V value, ReferenceQueue<V> queue) { CacheEntry(K key, V value, ReferenceQueue<V> queue) {
super(value, queue); super(value, queue);
_key = key; this.key = key;
} }
K getKey() { K getKey() {
return _key; return key;
} }
} }
} }
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,7 +35,7 @@ public class LocaleSyntaxException extends Exception { ...@@ -35,7 +35,7 @@ public class LocaleSyntaxException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private int _index = -1; private int index = -1;
public LocaleSyntaxException(String msg) { public LocaleSyntaxException(String msg) {
this(msg, 0); this(msg, 0);
...@@ -43,10 +43,10 @@ public class LocaleSyntaxException extends Exception { ...@@ -43,10 +43,10 @@ public class LocaleSyntaxException extends Exception {
public LocaleSyntaxException(String msg, int errorIndex) { public LocaleSyntaxException(String msg, int errorIndex) {
super(msg); super(msg);
_index = errorIndex; index = errorIndex;
} }
public int getErrorIndex() { public int getErrorIndex() {
return _index; return index;
} }
} }
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*******************************************************************************
* Copyright (C) 2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package sun.util.locale;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Collection of static utility methods for Locale support. The
* methods which manipulate characters or strings support ASCII only.
*/
public final class LocaleUtils {
private LocaleUtils() {
}
/**
* Compares two ASCII Strings s1 and s2, ignoring case.
*/
public static boolean caseIgnoreMatch(String s1, String s2) {
if (s1 == s2) {
return true;
}
int len = s1.length();
if (len != s2.length()) {
return false;
}
for (int i = 0; i < len; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2 && toLower(c1) != toLower(c2)) {
return false;
}
}
return true;
}
static int caseIgnoreCompare(String s1, String s2) {
if (s1 == s2) {
return 0;
}
return toLowerString(s1).compareTo(toLowerString(s2));
}
static char toUpper(char c) {
return isLower(c) ? (char)(c - 0x20) : c;
}
static char toLower(char c) {
return isUpper(c) ? (char)(c + 0x20) : c;
}
/**
* Converts the given ASCII String to lower-case.
*/
public static String toLowerString(String s) {
int len = s.length();
int idx = 0;
for (; idx < len; idx++) {
if (isUpper(s.charAt(idx))) {
break;
}
}
if (idx == len) {
return s;
}
char[] buf = new char[len];
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
buf[i] = (i < idx) ? c : toLower(c);
}
return new String(buf);
}
static String toUpperString(String s) {
int len = s.length();
int idx = 0;
for (; idx < len; idx++) {
if (isLower(s.charAt(idx))) {
break;
}
}
if (idx == len) {
return s;
}
char[] buf = new char[len];
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
buf[i] = (i < idx) ? c : toUpper(c);
}
return new String(buf);
}
static String toTitleString(String s) {
int len;
if ((len = s.length()) == 0) {
return s;
}
int idx = 0;
if (!isLower(s.charAt(idx))) {
for (idx = 1; idx < len; idx++) {
if (isUpper(s.charAt(idx))) {
break;
}
}
}
if (idx == len) {
return s;
}
char[] buf = new char[len];
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if (i == 0 && idx == 0) {
buf[i] = toUpper(c);
} else if (i < idx) {
buf[i] = c;
} else {
buf[i] = toLower(c);
}
}
return new String(buf);
}
private static boolean isUpper(char c) {
return c >= 'A' && c <= 'Z';
}
private static boolean isLower(char c) {
return c >= 'a' && c <= 'z';
}
static boolean isAlpha(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
static boolean isAlphaString(String s) {
int len = s.length();
for (int i = 0; i < len; i++) {
if (!isAlpha(s.charAt(i))) {
return false;
}
}
return true;
}
static boolean isNumeric(char c) {
return (c >= '0' && c <= '9');
}
static boolean isNumericString(String s) {
int len = s.length();
for (int i = 0; i < len; i++) {
if (!isNumeric(s.charAt(i))) {
return false;
}
}
return true;
}
static boolean isAlphaNumeric(char c) {
return isAlpha(c) || isNumeric(c);
}
static boolean isAlphaNumericString(String s) {
int len = s.length();
for (int i = 0; i < len; i++) {
if (!isAlphaNumeric(s.charAt(i))) {
return false;
}
}
return true;
}
static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
static boolean isEmpty(Set<?> set) {
return set == null || set.isEmpty();
}
static boolean isEmpty(Map<?, ?> map) {
return map == null || map.isEmpty();
}
static boolean isEmpty(List<?> list) {
return list == null || list.isEmpty();
}
}
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,29 +32,33 @@ ...@@ -32,29 +32,33 @@
package sun.util.locale; package sun.util.locale;
public class ParseStatus { public class ParseStatus {
int _parseLength = 0; int parseLength;
int _errorIndex = -1; int errorIndex;
String _errorMsg = null; String errorMsg;
public ParseStatus() {
reset();
}
public void reset() { public void reset() {
_parseLength = 0; parseLength = 0;
_errorIndex = -1; errorIndex = -1;
_errorMsg = null; errorMsg = null;
} }
public boolean isError() { public boolean isError() {
return (_errorIndex >= 0); return (errorIndex >= 0);
} }
public int getErrorIndex() { public int getErrorIndex() {
return _errorIndex; return errorIndex;
} }
public int getParseLength() { public int getParseLength() {
return _parseLength; return parseLength;
} }
public String getErrorMessage() { public String getErrorMessage() {
return _errorMsg; return errorMsg;
} }
} }
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,87 +31,99 @@ ...@@ -31,87 +31,99 @@
package sun.util.locale; package sun.util.locale;
public class StringTokenIterator { public class StringTokenIterator {
private String _text; private String text;
private String _dlms; private String dlms; // null if a single char delimiter
private char delimiterChar; // delimiter if a single char delimiter
private String _token; private String token;
private int _start; private int start;
private int _end; private int end;
private boolean _done; private boolean done;
public StringTokenIterator(String text, String dlms) { public StringTokenIterator(String text, String dlms) {
_text = text; this.text = text;
_dlms = dlms; if (dlms.length() == 1) {
delimiterChar = dlms.charAt(0);
} else {
this.dlms = dlms;
}
setStart(0); setStart(0);
} }
public String first() { public String first() {
setStart(0); setStart(0);
return _token; return token;
} }
public String current() { public String current() {
return _token; return token;
} }
public int currentStart() { public int currentStart() {
return _start; return start;
} }
public int currentEnd() { public int currentEnd() {
return _end; return end;
} }
public boolean isDone() { public boolean isDone() {
return _done; return done;
} }
public String next() { public String next() {
if (hasNext()) { if (hasNext()) {
_start = _end + 1; start = end + 1;
_end = nextDelimiter(_start); end = nextDelimiter(start);
_token = _text.substring(_start, _end); token = text.substring(start, end);
} else { } else {
_start = _end; start = end;
_token = null; token = null;
_done = true; done = true;
} }
return _token; return token;
} }
public boolean hasNext() { public boolean hasNext() {
return (_end < _text.length()); return (end < text.length());
} }
public StringTokenIterator setStart(int offset) { public StringTokenIterator setStart(int offset) {
if (offset > _text.length()) { if (offset > text.length()) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
_start = offset; start = offset;
_end = nextDelimiter(_start); end = nextDelimiter(start);
_token = _text.substring(_start, _end); token = text.substring(start, end);
_done = false; done = false;
return this; return this;
} }
public StringTokenIterator setText(String text) { public StringTokenIterator setText(String text) {
_text = text; this.text = text;
setStart(0); setStart(0);
return this; return this;
} }
private int nextDelimiter(int start) { private int nextDelimiter(int start) {
int idx = start; int textlen = this.text.length();
outer: while (idx < _text.length()) { if (dlms == null) {
char c = _text.charAt(idx); for (int idx = start; idx < textlen; idx++) {
for (int i = 0; i < _dlms.length(); i++) { if (text.charAt(idx) == delimiterChar) {
if (c == _dlms.charAt(i)) { return idx;
break outer; }
}
} else {
int dlmslen = dlms.length();
for (int idx = start; idx < textlen; idx++) {
char c = text.charAt(idx);
for (int i = 0; i < dlmslen; i++) {
if (c == dlms.charAt(i)) {
return idx;
}
} }
} }
idx++;
} }
return idx; return textlen;
} }
} }
/* /*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,56 +33,48 @@ ...@@ -32,56 +33,48 @@
package sun.util.locale; package sun.util.locale;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
public class UnicodeLocaleExtension extends Extension { public class UnicodeLocaleExtension extends Extension {
public static final char SINGLETON = 'u'; public static final char SINGLETON = 'u';
private static final SortedSet<String> EMPTY_SORTED_SET = new TreeSet<String>(); private final Set<String> attributes;
private static final SortedMap<String, String> EMPTY_SORTED_MAP = new TreeMap<String, String>(); private final Map<String, String> keywords;
private SortedSet<String> _attributes = EMPTY_SORTED_SET;
private SortedMap<String, String> _keywords = EMPTY_SORTED_MAP;
public static final UnicodeLocaleExtension CA_JAPANESE;
public static final UnicodeLocaleExtension NU_THAI;
static { public static final UnicodeLocaleExtension CA_JAPANESE
CA_JAPANESE = new UnicodeLocaleExtension(); = new UnicodeLocaleExtension("ca", "japanese");
CA_JAPANESE._keywords = new TreeMap<String, String>(); public static final UnicodeLocaleExtension NU_THAI
CA_JAPANESE._keywords.put("ca", "japanese"); = new UnicodeLocaleExtension("nu", "thai");
CA_JAPANESE._value = "ca-japanese";
NU_THAI = new UnicodeLocaleExtension(); private UnicodeLocaleExtension(String key, String value) {
NU_THAI._keywords = new TreeMap<String, String>(); super(SINGLETON, key + "-" + value);
NU_THAI._keywords.put("nu", "thai"); attributes = Collections.emptySet();
NU_THAI._value = "nu-thai"; keywords = Collections.singletonMap(key, value);
}
private UnicodeLocaleExtension() {
super(SINGLETON);
} }
UnicodeLocaleExtension(SortedSet<String> attributes, SortedMap<String, String> keywords) { UnicodeLocaleExtension(SortedSet<String> attributes, SortedMap<String, String> keywords) {
this(); super(SINGLETON);
if (attributes != null && attributes.size() > 0) { if (attributes != null) {
_attributes = attributes; this.attributes = attributes;
} else {
this.attributes = Collections.emptySet();
} }
if (keywords != null && keywords.size() > 0) { if (keywords != null) {
_keywords = keywords; this.keywords = keywords;
} else {
this.keywords = Collections.emptyMap();
} }
if (_attributes.size() > 0 || _keywords.size() > 0) { if (!this.attributes.isEmpty() || !this.keywords.isEmpty()) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (String attribute : _attributes) { for (String attribute : this.attributes) {
sb.append(LanguageTag.SEP).append(attribute); sb.append(LanguageTag.SEP).append(attribute);
} }
for (Entry<String, String> keyword : _keywords.entrySet()) { for (Entry<String, String> keyword : this.keywords.entrySet()) {
String key = keyword.getKey(); String key = keyword.getKey();
String value = keyword.getValue(); String value = keyword.getValue();
...@@ -90,38 +83,46 @@ public class UnicodeLocaleExtension extends Extension { ...@@ -90,38 +83,46 @@ public class UnicodeLocaleExtension extends Extension {
sb.append(LanguageTag.SEP).append(value); sb.append(LanguageTag.SEP).append(value);
} }
} }
_value = sb.substring(1); // skip leading '-' setValue(sb.substring(1)); // skip leading '-'
} }
} }
public Set<String> getUnicodeLocaleAttributes() { public Set<String> getUnicodeLocaleAttributes() {
return Collections.unmodifiableSet(_attributes); if (attributes == Collections.EMPTY_SET) {
return attributes;
}
return Collections.unmodifiableSet(attributes);
} }
public Set<String> getUnicodeLocaleKeys() { public Set<String> getUnicodeLocaleKeys() {
return Collections.unmodifiableSet(_keywords.keySet()); if (keywords == Collections.EMPTY_MAP) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(keywords.keySet());
} }
public String getUnicodeLocaleType(String unicodeLocaleKey) { public String getUnicodeLocaleType(String unicodeLocaleKey) {
return _keywords.get(unicodeLocaleKey); return keywords.get(unicodeLocaleKey);
} }
public static boolean isSingletonChar(char c) { public static boolean isSingletonChar(char c) {
return (SINGLETON == AsciiUtil.toLower(c)); return (SINGLETON == LocaleUtils.toLower(c));
} }
public static boolean isAttribute(String s) { public static boolean isAttribute(String s) {
// 3*8alphanum // 3*8alphanum
return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s); int len = s.length();
return (len >= 3) && (len <= 8) && LocaleUtils.isAlphaNumericString(s);
} }
public static boolean isKey(String s) { public static boolean isKey(String s) {
// 2alphanum // 2alphanum
return (s.length() == 2) && AsciiUtil.isAlphaNumericString(s); return (s.length() == 2) && LocaleUtils.isAlphaNumericString(s);
} }
public static boolean isTypeSubtag(String s) { public static boolean isTypeSubtag(String s) {
// 3*8alphanum // 3*8alphanum
return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s); int len = s.length();
return (len >= 3) && (len <= 8) && LocaleUtils.isAlphaNumericString(s);
} }
} }
...@@ -43,822 +43,824 @@ package sun.util.resources; ...@@ -43,822 +43,824 @@ package sun.util.resources;
public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle {
protected final Object[][] getContents() { protected final Object[][] getContents() {
String ACT[] = new String[] {"Fuso hor\u00e1rio do Acre", "ACT", String ACT[] = new String[] {"Fuso hor\u00e1rio do Acre", "ACT",
"Fuso hor\u00e1rio de ver\u00e3o do Acre", "ACST"}; "Fuso hor\u00e1rio de ver\u00e3o do Acre", "ACST"};
String ADELAIDE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central (Austr\u00e1lia do Sul)", "CST", String ADELAIDE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central (Austr\u00e1lia do Sul)", "CST",
"Fuso hor\u00e1rio de ver\u00e3o central (Austr\u00e1lia do Sul)", "CST"}; "Fuso hor\u00e1rio de ver\u00e3o central (Austr\u00e1lia do Sul)", "CST"};
String AGT[] = new String[] {"Fuso hor\u00e1rio da Argentina", "ART", String AGT[] = new String[] {"Fuso hor\u00e1rio da Argentina", "ART",
"Fuso hor\u00e1rio de ver\u00e3o da Argentina", "ARST"}; "Fuso hor\u00e1rio de ver\u00e3o da Argentina", "ARST"};
String AKST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Alaska", "AKST", String AKST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Alaska", "AKST",
"Hor\u00e1rio de luz natural do Alaska", "AKDT"}; "Hor\u00e1rio de luz natural do Alaska", "AKDT"};
String AMT[] = new String[] {"Fuso hor\u00e1rio do Amazonas", "AMT", String AMT[] = new String[] {"Fuso hor\u00e1rio do Amazonas", "AMT",
"Fuso hor\u00e1rio de ver\u00e3o do Amazonas", "AMST"}; "Fuso hor\u00e1rio de ver\u00e3o do Amazonas", "AMST"};
String ARAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Ar\u00e1bia", "AST", String ARAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Ar\u00e1bia", "AST",
"Hor\u00e1rio de luz natural da Ar\u00e1bia", "ADT"}; "Hor\u00e1rio de luz natural da Ar\u00e1bia", "ADT"};
String ARMT[] = new String[] {"Fuso hor\u00e1rio da Arm\u00eania", "AMT", String ARMT[] = new String[] {"Fuso hor\u00e1rio da Arm\u00eania", "AMT",
"Fuso hor\u00e1rio de ver\u00e3o da Arm\u00eania", "AMST"}; "Fuso hor\u00e1rio de ver\u00e3o da Arm\u00eania", "AMST"};
String AST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Atl\u00e2ntico", "AST", String AST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Atl\u00e2ntico", "AST",
"Hor\u00e1rio de luz natural do Atl\u00e2ntico", "ADT"}; "Hor\u00e1rio de luz natural do Atl\u00e2ntico", "ADT"};
String BDT[] = new String[] {"Fuso hor\u00e1rio de Bangladesh", "BDT", String BDT[] = new String[] {"Fuso hor\u00e1rio de Bangladesh", "BDT",
"Fuso hor\u00e1rio de ver\u00e3o de Bangladesh", "BDST"}; "Fuso hor\u00e1rio de ver\u00e3o de Bangladesh", "BDST"};
String BRISBANE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Queensland)", "EST", String BRISBANE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Queensland)", "EST",
"Fuso hor\u00e1rio de ver\u00e3o oriental (Queensland)", "EST"}; "Fuso hor\u00e1rio de ver\u00e3o oriental (Queensland)", "EST"};
String BROKEN_HILL[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central (Austr\u00e1lia do Sul/Nova Gales do Sul)", "CST", String BROKEN_HILL[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central (Austr\u00e1lia do Sul/Nova Gales do Sul)", "CST",
"Fuso hor\u00e1rio de ver\u00e3o central (Austr\u00e1lia do Sul/Nova Gales do Sul)", "CST"}; "Fuso hor\u00e1rio de ver\u00e3o central (Austr\u00e1lia do Sul/Nova Gales do Sul)", "CST"};
String BRT[] = new String[] {"Fuso hor\u00e1rio de Bras\u00edlia", "BRT", String BRT[] = new String[] {"Fuso hor\u00e1rio de Bras\u00edlia", "BRT",
"Fuso hor\u00e1rio de ver\u00e3o de Bras\u00edlia", "BRST"}; "Fuso hor\u00e1rio de ver\u00e3o de Bras\u00edlia", "BRST"};
String BTT[] = new String[] {"Fuso hor\u00e1rio de But\u00e3o", "BTT", String BTT[] = new String[] {"Fuso hor\u00e1rio de But\u00e3o", "BTT",
"Fuso hor\u00e1rio de ver\u00e3o de But\u00e3o", "BTST"}; "Fuso hor\u00e1rio de ver\u00e3o de But\u00e3o", "BTST"};
String CAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Central", "CAT", String CAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Central", "CAT",
"Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica Central", "CAST"}; "Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica Central", "CAST"};
String CET[] = new String[] {"Fuso hor\u00e1rio da Europa Central", "CET", String CET[] = new String[] {"Fuso hor\u00e1rio da Europa Central", "CET",
"Fuso hor\u00e1rio de ver\u00e3o da Europa Central", "CEST"}; "Fuso hor\u00e1rio de ver\u00e3o da Europa Central", "CEST"};
String CHAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Chatham", "CHAST", String CHAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Chatham", "CHAST",
"Hor\u00e1rio de luz natural de Chatham", "CHADT"}; "Hor\u00e1rio de luz natural de Chatham", "CHADT"};
String CIT[] = new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Central", "CIT", String CIT[] = new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Central", "CIT",
"Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Central", "CIST"}; "Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Central", "CIST"};
String CLT[] = new String[] {"Fuso hor\u00e1rio do Chile", "CLT", String CLT[] = new String[] {"Fuso hor\u00e1rio do Chile", "CLT",
"Fuso hor\u00e1rio de ver\u00e3o do Chile", "CLST"}; "Fuso hor\u00e1rio de ver\u00e3o do Chile", "CLST"};
String CST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central", "CST", String CST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central", "CST",
"Hor\u00e1rio de luz natural central", "CDT"}; "Hor\u00e1rio de luz natural central", "CDT"};
String CTT[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da China", "CST", String CTT[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da China", "CST",
"Hor\u00e1rio de luz natural da China", "CDT"}; "Hor\u00e1rio de luz natural da China", "CDT"};
String CUBA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Cuba", "CST", String CUBA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Cuba", "CST",
"Hor\u00e1rio de luz natural de Cuba", "CDT"}; "Hor\u00e1rio de luz natural de Cuba", "CDT"};
String DARWIN[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central (Territ\u00f3rio do Norte)", "CST", String DARWIN[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o central (Territ\u00f3rio do Norte)", "CST",
"Fuso hor\u00e1rio de ver\u00e3o central (Territ\u00f3rio do Norte)", "CST"}; "Fuso hor\u00e1rio de ver\u00e3o central (Territ\u00f3rio do Norte)", "CST"};
String DUBLIN[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", String DUBLIN[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT",
"Fuso hor\u00e1rio de ver\u00e3o da Irlanda", "IST"}; "Fuso hor\u00e1rio de ver\u00e3o da Irlanda", "IST"};
String EAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Oriental", "EAT", String EAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Oriental", "EAT",
"Fuso hor\u00e1rio padr\u00e3o da \u00c1frica Oriental", "EAST"}; "Fuso hor\u00e1rio padr\u00e3o da \u00c1frica Oriental", "EAST"};
String EASTER[] = new String[] {"Fuso hor\u00e1rio da Ilha de P\u00e1scoa", "EAST", String EASTER[] = new String[] {"Fuso hor\u00e1rio da Ilha de P\u00e1scoa", "EAST",
"Fuso hor\u00e1rio de ver\u00e3o da Ilha de P\u00e1scoa", "EASST"}; "Fuso hor\u00e1rio de ver\u00e3o da Ilha de P\u00e1scoa", "EASST"};
String EET[] = new String[] {"Fuso hor\u00e1rio da Europa Oriental", "EET", String EET[] = new String[] {"Fuso hor\u00e1rio da Europa Oriental", "EET",
"Fuso hor\u00e1rio de ver\u00e3o da Europa Oriental", "EEST"}; "Fuso hor\u00e1rio de ver\u00e3o da Europa Oriental", "EEST"};
String EGT[] = new String[] {"Fuso hor\u00e1rio da Groenl\u00e2ndia Oriental", "EGT", String EGT[] = new String[] {"Fuso hor\u00e1rio da Groenl\u00e2ndia Oriental", "EGT",
"Fuso hor\u00e1rio de ver\u00e3o da Groenl\u00e2ndia Oriental", "EGST"}; "Fuso hor\u00e1rio de ver\u00e3o da Groenl\u00e2ndia Oriental", "EGST"};
String EST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental", "EST", String EST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental", "EST",
"Hor\u00e1rio de luz natural oriental", "EDT"}; "Hor\u00e1rio de luz natural oriental", "EDT"};
String EST_NSW[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Nova Gales do Sul)", "EST", String EST_NSW[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Nova Gales do Sul)", "EST",
"Fuso hor\u00e1rio de ver\u00e3o oriental (Nova Gales do Sul)", "EST"}; "Fuso hor\u00e1rio de ver\u00e3o oriental (Nova Gales do Sul)", "EST"};
String GHMT[] = new String[] {"Fuso hor\u00e1rio do meridiano de Gana", "GMT", String GHMT[] = new String[] {"Fuso hor\u00e1rio do meridiano de Gana", "GMT",
"Fuso hor\u00e1rio de ver\u00e3o de Gana", "GHST"}; "Fuso hor\u00e1rio de ver\u00e3o de Gana", "GHST"};
String GAMBIER[] = new String[] {"Fuso hor\u00e1rio de Gambier", "GAMT", String GAMBIER[] = new String[] {"Fuso hor\u00e1rio de Gambier", "GAMT",
"Fuso hor\u00e1rio de ver\u00e3o de Gambier", "GAMST"}; "Fuso hor\u00e1rio de ver\u00e3o de Gambier", "GAMST"};
String GMT[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", String GMT[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT",
"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT"}; "Fuso hor\u00e1rio do meridiano de Greenwich", "GMT"};
String GMTBST[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", String GMTBST[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT",
"Fuso hor\u00e1rio de ver\u00e3o da Gr\u00e3-Bretanha", "BST"}; "Fuso hor\u00e1rio de ver\u00e3o da Gr\u00e3-Bretanha", "BST"};
String GST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do golfo", "GST", String GST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do golfo", "GST",
"Hor\u00e1rio de luz natural do golfo", "GDT"}; "Hor\u00e1rio de luz natural do golfo", "GDT"};
String HAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Hava\u00ed-Aleutian", "HAST", String HAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Hava\u00ed-Aleutian", "HAST",
"Hor\u00e1rio de luz natural do Hava\u00ed-Aleutian", "HADT"}; "Hor\u00e1rio de luz natural do Hava\u00ed-Aleutian", "HADT"};
String HKT[] = new String[] {"Fuso hor\u00e1rio de Hong Kong", "HKT", String HKT[] = new String[] {"Fuso hor\u00e1rio de Hong Kong", "HKT",
"Fuso hor\u00e1rio de ver\u00e3o de Hong Kong", "HKST"}; "Fuso hor\u00e1rio de ver\u00e3o de Hong Kong", "HKST"};
String HST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Hava\u00ed", "HST", String HST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Hava\u00ed", "HST",
"Hor\u00e1rio de luz natural do Hava\u00ed", "HDT"}; "Hor\u00e1rio de luz natural do Hava\u00ed", "HDT"};
String ICT[] = new String[] {"Fuso hor\u00e1rio da Indochina", "ICT", String ICT[] = new String[] {"Fuso hor\u00e1rio da Indochina", "ICT",
"Fuso hor\u00e1rio de ver\u00e3o da Indochina", "ICST"}; "Fuso hor\u00e1rio de ver\u00e3o da Indochina", "ICST"};
String IRT[] = new String[] {"Fuso hor\u00e1rio do Ir\u00e3", "IRST", String IRT[] = new String[] {"Fuso hor\u00e1rio do Ir\u00e3", "IRST",
"Hor\u00e1rio de luz natural do Ir\u00e3", "IRDT"}; "Hor\u00e1rio de luz natural do Ir\u00e3", "IRDT"};
String ISRAEL[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Israel", "IST", String ISRAEL[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Israel", "IST",
"Hor\u00e1rio de luz natural de Israel", "IDT"}; "Hor\u00e1rio de luz natural de Israel", "IDT"};
String IST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da \u00cdndia", "IST", String IST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da \u00cdndia", "IST",
"Hor\u00e1rio de luz natural da \u00cdndia", "IDT"}; "Hor\u00e1rio de luz natural da \u00cdndia", "IDT"};
String JST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Jap\u00e3o", "JST", String JST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Jap\u00e3o", "JST",
"Hor\u00e1rio de luz natural do Jap\u00e3o", "JDT"}; "Hor\u00e1rio de luz natural do Jap\u00e3o", "JDT"};
String KST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Coreia", "KST", String KST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Coreia", "KST",
"Hor\u00e1rio de luz natural da Coreia", "KDT"}; "Hor\u00e1rio de luz natural da Coreia", "KDT"};
String LORD_HOWE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Lord Howe", "LHST", String LORD_HOWE[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Lord Howe", "LHST",
"Fuso hor\u00e1rio de ver\u00e3o de Lord Howe", "LHST"}; "Fuso hor\u00e1rio de ver\u00e3o de Lord Howe", "LHST"};
String MHT[] = new String[] {"Fuso hor\u00e1rio das Ilhas Marshall", "MHT", String MHT[] = new String[] {"Fuso hor\u00e1rio das Ilhas Marshall", "MHT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Marshall", "MHST"}; "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Marshall", "MHST"};
String MSK[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Moscou", "MSK", String MSK[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Moscou", "MSK",
"Hor\u00e1rio de luz natural de Moscou", "MSD"}; "Hor\u00e1rio de luz natural de Moscou", "MSD"};
String MST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o das montanhas", "MST", String MST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o das montanhas", "MST",
"Hor\u00e1rio de luz natural das montanhas", "MDT"}; "Hor\u00e1rio de luz natural das montanhas", "MDT"};
String MYT[] = new String[] {"Fuso hor\u00e1rio da Mal\u00e1sia", "MYT", String MYT[] = new String[] {"Fuso hor\u00e1rio da Mal\u00e1sia", "MYT",
"Fuso hor\u00e1rio de ver\u00e3o da Mal\u00e1sia", "MYST"}; "Fuso hor\u00e1rio de ver\u00e3o da Mal\u00e1sia", "MYST"};
String NORONHA[] = new String[] {"Fuso hor\u00e1rio de Fernando de Noronha", "FNT", String NORONHA[] = new String[] {"Fuso hor\u00e1rio de Fernando de Noronha", "FNT",
"Fuso hor\u00e1rio de ver\u00e3o de Fernando de Noronha", "FNST"}; "Fuso hor\u00e1rio de ver\u00e3o de Fernando de Noronha", "FNST"};
String NOVT[] = new String[] {"Fuso hor\u00e1rio de Novosibirsk", "NOVT", String NOVT[] = new String[] {"Fuso hor\u00e1rio de Novosibirsk", "NOVT",
"Fuso hor\u00e1rio de ver\u00e3o de Novosibirsk", "NOVST"}; "Fuso hor\u00e1rio de ver\u00e3o de Novosibirsk", "NOVST"};
String NPT[] = new String[] {"Fuso hor\u00e1rio do Nepal", "NPT", String NPT[] = new String[] {"Fuso hor\u00e1rio do Nepal", "NPT",
"Fuso hor\u00e1rio de ver\u00e3o do Nepal", "NPST"}; "Fuso hor\u00e1rio de ver\u00e3o do Nepal", "NPST"};
String NST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Terra Nova", "NST", String NST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Terra Nova", "NST",
"Hor\u00e1rio de luz natural de Terra Nova", "NDT"}; "Hor\u00e1rio de luz natural de Terra Nova", "NDT"};
String NZST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Nova Zel\u00e2ndia", "NZST", String NZST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da Nova Zel\u00e2ndia", "NZST",
"Hor\u00e1rio de luz natural da Nova Zel\u00e2ndia", "NZDT"}; "Hor\u00e1rio de luz natural da Nova Zel\u00e2ndia", "NZDT"};
String PITCAIRN[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Pitcairn", "PST", String PITCAIRN[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Pitcairn", "PST",
"Hor\u00e1rio de luz natural de Pitcairn", "PDT"}; "Hor\u00e1rio de luz natural de Pitcairn", "PDT"};
String PKT[] = new String[] {"Fuso hor\u00e1rio do Paquist\u00e3o", "PKT", String PKT[] = new String[] {"Fuso hor\u00e1rio do Paquist\u00e3o", "PKT",
"Fuso hor\u00e1rio de ver\u00e3o do Paquist\u00e3o", "PKST"}; "Fuso hor\u00e1rio de ver\u00e3o do Paquist\u00e3o", "PKST"};
String PONT[] = new String[] {"Fuso hor\u00e1rio de Pohnpei", "PONT", String PONT[] = new String[] {"Fuso hor\u00e1rio de Pohnpei", "PONT",
"Fuso hor\u00e1rio de ver\u00e3o de Pohnpei", "PONST"}; "Fuso hor\u00e1rio de ver\u00e3o de Pohnpei", "PONST"};
String PST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Pac\u00edfico", "PST", String PST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o do Pac\u00edfico", "PST",
"Hor\u00e1rio de luz natural do Pac\u00edfico", "PDT"}; "Hor\u00e1rio de luz natural do Pac\u00edfico", "PDT"};
String RST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental", "EST", String RST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental", "EST",
"Hor\u00e1rio de luz natural central", "CDT"}; "Hor\u00e1rio de luz natural central", "CDT"};
String SAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da \u00c1frica do Sul", "SAST", String SAST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o da \u00c1frica do Sul", "SAST",
"Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica do Sul", "SAST"}; "Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica do Sul", "SAST"};
String SBT[] = new String[] {"Fuso hor\u00e1rio das Ilhas Salom\u00e3o", "SBT", String SBT[] = new String[] {"Fuso hor\u00e1rio das Ilhas Salom\u00e3o", "SBT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Salom\u00e3o", "SBST"}; "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Salom\u00e3o", "SBST"};
String SGT[] = new String[] {"Fuso hor\u00e1rio de Cingapura", "SGT", String SGT[] = new String[] {"Fuso hor\u00e1rio de Cingapura", "SGT",
"Fuso hor\u00e1rio de ver\u00e1 de Cingapura", "SGST"}; "Fuso hor\u00e1rio de ver\u00e1 de Cingapura", "SGST"};
String SLST[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT", String SLST[] = new String[] {"Fuso hor\u00e1rio do meridiano de Greenwich", "GMT",
"Fuso hor\u00e1rio de ver\u00e3o de Serra Leoa", "SLST"}; "Fuso hor\u00e1rio de ver\u00e3o de Serra Leoa", "SLST"};
String TASMANIA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Tasm\u00e2nia)", "EST", String TASMANIA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Tasm\u00e2nia)", "EST",
"Fuso hor\u00e1rio de ver\u00e3o oriental (Tasm\u00e2nia)", "EST"}; "Fuso hor\u00e1rio de ver\u00e3o oriental (Tasm\u00e2nia)", "EST"};
String TMT[] = new String[] {"Fuso hor\u00e1rio do Turcomenist\u00e3o", "TMT", String TMT[] = new String[] {"Fuso hor\u00e1rio do Turcomenist\u00e3o", "TMT",
"Fuso hor\u00e1rio de ver\u00e3o do Turcomenist\u00e3o", "TMST"}; "Fuso hor\u00e1rio de ver\u00e3o do Turcomenist\u00e3o", "TMST"};
String TRUT[] = new String[] {"Fuso hor\u00e1rio de Chuuk", "CHUT", String TRUT[] = new String[] {"Fuso hor\u00e1rio de Chuuk", "CHUT",
"Fuso hor\u00e1rio de ver\u00e3o de Chuuk", "CHUST"}; "Fuso hor\u00e1rio de ver\u00e3o de Chuuk", "CHUST"};
String ULAT[]= new String[] {"Fuso hor\u00e1rio de Ulan Bator", "ULAT", String ULAT[]= new String[] {"Fuso hor\u00e1rio de Ulan Bator", "ULAT",
"Fuso hor\u00e1rio de ver\u00e3o de Ulan Bator", "ULAST"}; "Fuso hor\u00e1rio de ver\u00e3o de Ulan Bator", "ULAST"};
String WAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Ocidental", "WAT", String WAT[] = new String[] {"Fuso hor\u00e1rio da \u00c1frica Ocidental", "WAT",
"Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica Ocidental", "WAST"}; "Fuso hor\u00e1rio de ver\u00e3o da \u00c1frica Ocidental", "WAST"};
String WET[] = new String[] {"Fuso hor\u00e1rio da Europa Ocidental", "WET", String WET[] = new String[] {"Fuso hor\u00e1rio da Europa Ocidental", "WET",
"Fuso hor\u00e1rio de ver\u00e3o da Europa Ocidental", "WEST"}; "Fuso hor\u00e1rio de ver\u00e3o da Europa Ocidental", "WEST"};
String WIT[] = new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Ocidental", "WIT", String WIT[] = new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Ocidental", "WIT",
"Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Ocidental", "WIST"}; "Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Ocidental", "WIST"};
String WST_AUS[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o ocidental (Austr\u00e1lia)", "WST", String WST_AUS[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o ocidental (Austr\u00e1lia)", "WST",
"Fuso hor\u00e1rio de ver\u00e3o ocidental (Austr\u00e1lia)", "WST"}; "Fuso hor\u00e1rio de ver\u00e3o ocidental (Austr\u00e1lia)", "WST"};
String SAMOA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Samoa", "SST", String SAMOA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Samoa", "SST",
"Hor\u00e1rio de luz natural de Samoa", "SDT"}; "Hor\u00e1rio de luz natural de Samoa", "SDT"};
String WST_SAMOA[] = new String[] {"Fuso hor\u00e1rio de Samoa Ocidental", "WST", String WST_SAMOA[] = new String[] {"Fuso hor\u00e1rio de Samoa Ocidental", "WST",
"Fuso hor\u00e1rio de ver\u00e3o de Samoa Ocidental", "WSST"}; "Fuso hor\u00e1rio de ver\u00e3o de Samoa Ocidental", "WSST"};
String ChST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Chamorro", "ChST", String ChST[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o de Chamorro", "ChST",
"Hor\u00e1rio de luz natural de Chamorro", "ChDT"}; "Hor\u00e1rio de luz natural de Chamorro", "ChDT"};
String VICTORIA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Victoria)", "EST", String VICTORIA[] = new String[] {"Fuso hor\u00e1rio padr\u00e3o oriental (Victoria)", "EST",
"Fuso hor\u00e1rio de ver\u00e3o oriental (Victoria)", "EST"}; "Fuso hor\u00e1rio de ver\u00e3o oriental (Victoria)", "EST"};
String UTC[] = new String[] {"Tempo universal coordenado", "UTC", String UTC[] = new String[] {"Tempo universal coordenado", "UTC",
"Tempo universal coordenado", "UTC"}; "Tempo universal coordenado", "UTC"};
String UZT[] = new String[] {"Fuso hor\u00e1rio do Uzbequist\u00e3o", "UZT", String UZT[] = new String[] {"Fuso hor\u00e1rio do Uzbequist\u00e3o", "UZT",
"Fuso hor\u00e1rio de ver\u00e3o do Uzbequist\u00e3o", "UZST"}; "Fuso hor\u00e1rio de ver\u00e3o do Uzbequist\u00e3o", "UZST"};
String WART[] = new String[] {"Fuso hor\u00e1rio da Argentina Ocidental", "WART", String WART[] = new String[] {"Fuso hor\u00e1rio da Argentina Ocidental", "WART",
"Fuso hor\u00e1rio de ver\u00e3o da Argentina Ocidental", "WARST"}; "Fuso hor\u00e1rio de ver\u00e3o da Argentina Ocidental", "WARST"};
return new Object[][] { return new Object[][] {
{"America/Los_Angeles", PST}, {"America/Los_Angeles", PST},
{"PST", PST}, {"PST", PST},
{"America/Denver", MST}, {"America/Denver", MST},
{"MST", MST}, {"MST", MST},
{"America/Phoenix", MST}, {"America/Phoenix", MST},
{"PNT", MST}, {"PNT", MST},
{"America/Chicago", CST}, {"America/Chicago", CST},
{"CST", CST}, {"CST", CST},
{"America/New_York", EST}, {"America/New_York", EST},
{"EST", EST}, {"EST", EST},
{"America/Indianapolis", EST}, {"America/Indianapolis", EST},
{"IET", EST}, {"IET", EST},
{"Pacific/Honolulu", HST}, {"Pacific/Honolulu", HST},
{"HST", HST}, {"HST", HST},
{"America/Anchorage", AKST}, {"America/Anchorage", AKST},
{"AST", AKST}, {"AST", AKST},
{"America/Halifax", AST}, {"America/Halifax", AST},
{"America/Sitka", AKST}, {"America/Sitka", AKST},
{"America/St_Johns", NST}, {"America/St_Johns", NST},
{"CNT", NST}, {"CNT", NST},
{"Europe/Paris", CET}, {"Europe/Paris", CET},
{"ECT", CET}, {"ECT", CET},
{"GMT", GMT}, {"GMT", GMT},
{"Africa/Casablanca", WET}, {"Africa/Casablanca", WET},
{"Asia/Jerusalem", ISRAEL}, {"Asia/Jerusalem", ISRAEL},
{"Asia/Tokyo", JST}, {"Asia/Tokyo", JST},
{"JST", JST}, {"JST", JST},
{"Europe/Bucharest", EET}, {"Europe/Bucharest", EET},
{"Asia/Shanghai", CTT}, {"Asia/Shanghai", CTT},
{"CTT", CTT}, {"CTT", CTT},
/* Don't change the order of the above zones /* Don't change the order of the above zones
* to keep compatibility with the previous version. * to keep compatibility with the previous version.
*/ */
{"ACT", DARWIN}, {"ACT", DARWIN},
{"AET", EST_NSW}, {"AET", EST_NSW},
{"AGT", AGT}, {"AGT", AGT},
{"ART", EET}, {"ART", EET},
{"Africa/Abidjan", GMT}, {"Africa/Abidjan", GMT},
{"Africa/Accra", GHMT}, {"Africa/Accra", GHMT},
{"Africa/Addis_Ababa", EAT}, {"Africa/Addis_Ababa", EAT},
{"Africa/Algiers", CET}, {"Africa/Algiers", CET},
{"Africa/Asmara", EAT}, {"Africa/Asmara", EAT},
{"Africa/Asmera", EAT}, {"Africa/Asmera", EAT},
{"Africa/Bamako", GMT}, {"Africa/Bamako", GMT},
{"Africa/Bangui", WAT}, {"Africa/Bangui", WAT},
{"Africa/Banjul", GMT}, {"Africa/Banjul", GMT},
{"Africa/Bissau", GMT}, {"Africa/Bissau", GMT},
{"Africa/Blantyre", CAT}, {"Africa/Blantyre", CAT},
{"Africa/Brazzaville", WAT}, {"Africa/Brazzaville", WAT},
{"Africa/Bujumbura", CAT}, {"Africa/Bujumbura", CAT},
{"Africa/Cairo", EET}, {"Africa/Cairo", EET},
{"Africa/Ceuta", CET}, {"Africa/Ceuta", CET},
{"Africa/Conakry", GMT}, {"Africa/Conakry", GMT},
{"Africa/Dakar", GMT}, {"Africa/Dakar", GMT},
{"Africa/Dar_es_Salaam", EAT}, {"Africa/Dar_es_Salaam", EAT},
{"Africa/Djibouti", EAT}, {"Africa/Djibouti", EAT},
{"Africa/Douala", WAT}, {"Africa/Douala", WAT},
{"Africa/El_Aaiun", WET}, {"Africa/El_Aaiun", WET},
{"Africa/Freetown", SLST}, {"Africa/Freetown", SLST},
{"Africa/Gaborone", CAT}, {"Africa/Gaborone", CAT},
{"Africa/Harare", CAT}, {"Africa/Harare", CAT},
{"Africa/Johannesburg", SAST}, {"Africa/Johannesburg", SAST},
{"Africa/Kampala", EAT}, {"Africa/Kampala", EAT},
{"Africa/Khartoum", EAT}, {"Africa/Khartoum", EAT},
{"Africa/Kigali", CAT}, {"Africa/Kigali", CAT},
{"Africa/Kinshasa", WAT}, {"Africa/Kinshasa", WAT},
{"Africa/Lagos", WAT}, {"Africa/Lagos", WAT},
{"Africa/Libreville", WAT}, {"Africa/Libreville", WAT},
{"Africa/Lome", GMT}, {"Africa/Lome", GMT},
{"Africa/Luanda", WAT}, {"Africa/Luanda", WAT},
{"Africa/Lubumbashi", CAT}, {"Africa/Lubumbashi", CAT},
{"Africa/Lusaka", CAT}, {"Africa/Lusaka", CAT},
{"Africa/Malabo", WAT}, {"Africa/Malabo", WAT},
{"Africa/Maputo", CAT}, {"Africa/Maputo", CAT},
{"Africa/Maseru", SAST}, {"Africa/Maseru", SAST},
{"Africa/Mbabane", SAST}, {"Africa/Mbabane", SAST},
{"Africa/Mogadishu", EAT}, {"Africa/Mogadishu", EAT},
{"Africa/Monrovia", GMT}, {"Africa/Monrovia", GMT},
{"Africa/Nairobi", EAT}, {"Africa/Nairobi", EAT},
{"Africa/Ndjamena", WAT}, {"Africa/Ndjamena", WAT},
{"Africa/Niamey", WAT}, {"Africa/Niamey", WAT},
{"Africa/Nouakchott", GMT}, {"Africa/Nouakchott", GMT},
{"Africa/Ouagadougou", GMT}, {"Africa/Ouagadougou", GMT},
{"Africa/Porto-Novo", WAT}, {"Africa/Porto-Novo", WAT},
{"Africa/Sao_Tome", GMT}, {"Africa/Sao_Tome", GMT},
{"Africa/Timbuktu", GMT}, {"Africa/Timbuktu", GMT},
{"Africa/Tripoli", EET}, {"Africa/Tripoli", EET},
{"Africa/Tunis", CET}, {"Africa/Tunis", CET},
{"Africa/Windhoek", WAT}, {"Africa/Windhoek", WAT},
{"America/Adak", HAST}, {"America/Adak", HAST},
{"America/Anguilla", AST}, {"America/Anguilla", AST},
{"America/Antigua", AST}, {"America/Antigua", AST},
{"America/Araguaina", BRT}, {"America/Araguaina", BRT},
{"America/Argentina/Buenos_Aires", AGT}, {"America/Argentina/Buenos_Aires", AGT},
{"America/Argentina/Catamarca", AGT}, {"America/Argentina/Catamarca", AGT},
{"America/Argentina/ComodRivadavia", AGT}, {"America/Argentina/ComodRivadavia", AGT},
{"America/Argentina/Cordoba", AGT}, {"America/Argentina/Cordoba", AGT},
{"America/Argentina/Jujuy", AGT}, {"America/Argentina/Jujuy", AGT},
{"America/Argentina/La_Rioja", AGT}, {"America/Argentina/La_Rioja", AGT},
{"America/Argentina/Mendoza", AGT}, {"America/Argentina/Mendoza", AGT},
{"America/Argentina/Rio_Gallegos", AGT}, {"America/Argentina/Rio_Gallegos", AGT},
{"America/Argentina/Salta", AGT}, {"America/Argentina/Salta", AGT},
{"America/Argentina/San_Juan", AGT}, {"America/Argentina/San_Juan", AGT},
{"America/Argentina/San_Luis", WART}, {"America/Argentina/San_Luis", WART},
{"America/Argentina/Tucuman", AGT}, {"America/Argentina/Tucuman", AGT},
{"America/Argentina/Ushuaia", AGT}, {"America/Argentina/Ushuaia", AGT},
{"America/Aruba", AST}, {"America/Aruba", AST},
{"America/Asuncion", new String[] {"Fuso hor\u00e1rio do Paraguai", "PYT", {"America/Asuncion", new String[] {"Fuso hor\u00e1rio do Paraguai", "PYT",
"Fuso hor\u00e1rio de ver\u00e3o do Paraguai", "PYST"}}, "Fuso hor\u00e1rio de ver\u00e3o do Paraguai", "PYST"}},
{"America/Atikokan", EST}, {"America/Atikokan", EST},
{"America/Atka", HAST}, {"America/Atka", HAST},
{"America/Bahia", BRT}, {"America/Bahia", BRT},
{"America/Bahia_Banderas", CST}, {"America/Bahia_Banderas", CST},
{"America/Barbados", AST}, {"America/Barbados", AST},
{"America/Belem", BRT}, {"America/Belem", BRT},
{"America/Belize", CST}, {"America/Belize", CST},
{"America/Blanc-Sablon", AST}, {"America/Blanc-Sablon", AST},
{"America/Boa_Vista", AMT}, {"America/Boa_Vista", AMT},
{"America/Bogota", new String[] {"Fuso hor\u00e1rio da Col\u00f4mbia", "COT", {"America/Bogota", new String[] {"Fuso hor\u00e1rio da Col\u00f4mbia", "COT",
"Fuso hor\u00e1rio de ver\u00e3o da Col\u00f4mbia", "COST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Col\u00f4mbia", "COST"}},
{"America/Boise", MST}, {"America/Boise", MST},
{"America/Buenos_Aires", AGT}, {"America/Buenos_Aires", AGT},
{"America/Cambridge_Bay", MST}, {"America/Cambridge_Bay", MST},
{"America/Campo_Grande", AMT}, {"America/Campo_Grande", AMT},
{"America/Cancun", CST}, {"America/Cancun", CST},
{"America/Caracas", new String[] {"Fuso hor\u00e1rio da Venezuela", "VET", {"America/Caracas", new String[] {"Fuso hor\u00e1rio da Venezuela", "VET",
"Fuso hor\u00e1rio de ver\u00e3o da Venezuela", "VEST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Venezuela", "VEST"}},
{"America/Catamarca", AGT}, {"America/Catamarca", AGT},
{"America/Cayenne", new String[] {"Fuso hor\u00e1rio da Guiana Francesa", "GFT", {"America/Cayenne", new String[] {"Fuso hor\u00e1rio da Guiana Francesa", "GFT",
"Fuso hor\u00e1rio de ver\u00e3o da Guiana Francesa", "GFST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Guiana Francesa", "GFST"}},
{"America/Cayman", EST}, {"America/Cayman", EST},
{"America/Chihuahua", MST}, {"America/Chihuahua", MST},
{"America/Coral_Harbour", EST}, {"America/Coral_Harbour", EST},
{"America/Cordoba", AGT}, {"America/Cordoba", AGT},
{"America/Costa_Rica", CST}, {"America/Costa_Rica", CST},
{"America/Cuiaba", AMT}, {"America/Cuiaba", AMT},
{"America/Curacao", AST}, {"America/Curacao", AST},
{"America/Danmarkshavn", GMT}, {"America/Danmarkshavn", GMT},
{"America/Dawson", PST}, {"America/Dawson", PST},
{"America/Dawson_Creek", MST}, {"America/Dawson_Creek", MST},
{"America/Detroit", EST}, {"America/Detroit", EST},
{"America/Dominica", AST}, {"America/Dominica", AST},
{"America/Edmonton", MST}, {"America/Edmonton", MST},
{"America/Eirunepe", AMT}, {"America/Eirunepe", AMT},
{"America/El_Salvador", CST}, {"America/El_Salvador", CST},
{"America/Ensenada", PST}, {"America/Ensenada", PST},
{"America/Fort_Wayne", EST}, {"America/Fort_Wayne", EST},
{"America/Fortaleza", BRT}, {"America/Fortaleza", BRT},
{"America/Glace_Bay", AST}, {"America/Glace_Bay", AST},
{"America/Godthab", new String[] {"Fuso hor\u00e1rio da Groenl\u00e2ndia Ocidental", "WGT", {"America/Godthab", new String[] {"Fuso hor\u00e1rio da Groenl\u00e2ndia Ocidental", "WGT",
"Fuso hor\u00e1rio de ver\u00e3o da Groenl\u00e2ndia Ocidental", "WGST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Groenl\u00e2ndia Ocidental", "WGST"}},
{"America/Goose_Bay", AST}, {"America/Goose_Bay", AST},
{"America/Grand_Turk", EST}, {"America/Grand_Turk", EST},
{"America/Grenada", AST}, {"America/Grenada", AST},
{"America/Guadeloupe", AST}, {"America/Guadeloupe", AST},
{"America/Guatemala", CST}, {"America/Guatemala", CST},
{"America/Guayaquil", new String[] {"Fuso hor\u00e1rio do Equador", "ECT", {"America/Guayaquil", new String[] {"Fuso hor\u00e1rio do Equador", "ECT",
"Fuso hor\u00e1rio de ver\u00e3o do Equador", "ECST"}}, "Fuso hor\u00e1rio de ver\u00e3o do Equador", "ECST"}},
{"America/Guyana", new String[] {"Fuso hor\u00e1rio da Guiana", "GYT", {"America/Guyana", new String[] {"Fuso hor\u00e1rio da Guiana", "GYT",
"Fuso hor\u00e1rio de ver\u00e3o da Guiana", "GYST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Guiana", "GYST"}},
{"America/Havana", CUBA}, {"America/Havana", CUBA},
{"America/Hermosillo", MST}, {"America/Hermosillo", MST},
{"America/Indiana/Indianapolis", EST}, {"America/Indiana/Indianapolis", EST},
{"America/Indiana/Knox", CST}, {"America/Indiana/Knox", CST},
{"America/Indiana/Marengo", EST}, {"America/Indiana/Marengo", EST},
{"America/Indiana/Petersburg", EST}, {"America/Indiana/Petersburg", EST},
{"America/Indiana/Tell_City", CST}, {"America/Indiana/Tell_City", CST},
{"America/Indiana/Vevay", EST}, {"America/Indiana/Vevay", EST},
{"America/Indiana/Vincennes", EST}, {"America/Indiana/Vincennes", EST},
{"America/Indiana/Winamac", EST}, {"America/Indiana/Winamac", EST},
{"America/Inuvik", MST}, {"America/Inuvik", MST},
{"America/Iqaluit", EST}, {"America/Iqaluit", EST},
{"America/Jamaica", EST}, {"America/Jamaica", EST},
{"America/Jujuy", AGT}, {"America/Jujuy", AGT},
{"America/Juneau", AKST}, {"America/Juneau", AKST},
{"America/Kentucky/Louisville", EST}, {"America/Kentucky/Louisville", EST},
{"America/Kentucky/Monticello", EST}, {"America/Kentucky/Monticello", EST},
{"America/Knox_IN", CST}, {"America/Knox_IN", CST},
{"America/La_Paz", new String[] {"Fuso hor\u00e1rio da Bol\u00edvia", "BOT", {"America/La_Paz", new String[] {"Fuso hor\u00e1rio da Bol\u00edvia", "BOT",
"Fuso hor\u00e1rio de ver\u00e3o da Bol\u00edvia", "BOST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Bol\u00edvia", "BOST"}},
{"America/Lima", new String[] {"Fuso hor\u00e1rio do Peru", "PET", {"America/Lima", new String[] {"Fuso hor\u00e1rio do Peru", "PET",
"Fuso hor\u00e1rio de ver\u00e3o do Peru", "PEST"}}, "Fuso hor\u00e1rio de ver\u00e3o do Peru", "PEST"}},
{"America/Louisville", EST}, {"America/Louisville", EST},
{"America/Maceio", BRT}, {"America/Maceio", BRT},
{"America/Managua", CST}, {"America/Managua", CST},
{"America/Manaus", AMT}, {"America/Manaus", AMT},
{"America/Marigot", AST}, {"America/Marigot", AST},
{"America/Martinique", AST}, {"America/Martinique", AST},
{"America/Mazatlan", MST}, {"America/Matamoros", CST},
{"America/Mendoza", AGT}, {"America/Mazatlan", MST},
{"America/Menominee", CST}, {"America/Mendoza", AGT},
{"America/Merida", CST}, {"America/Menominee", CST},
{"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST", {"America/Merida", CST},
"Metlakatla Daylight Time", "MeDT"}}, {"America/Metlakatla", new String[] {"Metlakatla Standard Time", "MeST",
{"America/Mexico_City", CST}, "Metlakatla Daylight Time", "MeDT"}},
{"America/Miquelon", new String[] {"Fuso hor\u00e1rio padr\u00e3o de S\u00e3o Pedro e Miquelon", "PMST", {"America/Mexico_City", CST},
"Hor\u00e1rio de luz natural de S\u00e3o Pedro e Miquelon", "PMDT"}}, {"America/Miquelon", new String[] {"Fuso hor\u00e1rio padr\u00e3o de S\u00e3o Pedro e Miquelon", "PMST",
{"America/Moncton", AST}, "Hor\u00e1rio de luz natural de S\u00e3o Pedro e Miquelon", "PMDT"}},
{"America/Montevideo", new String[] {"Fuso hor\u00e1rio do Uruguai", "UYT", {"America/Moncton", AST},
"Fuso hor\u00e1rio de ver\u00e3o do Uruguai", "UYST"}}, {"America/Montevideo", new String[] {"Fuso hor\u00e1rio do Uruguai", "UYT",
{"America/Monterrey", CST}, "Fuso hor\u00e1rio de ver\u00e3o do Uruguai", "UYST"}},
{"America/Montreal", EST}, {"America/Monterrey", CST},
{"America/Montserrat", AST}, {"America/Montreal", EST},
{"America/Nassau", EST}, {"America/Montserrat", AST},
{"America/Nipigon", EST}, {"America/Nassau", EST},
{"America/Nome", AKST}, {"America/Nipigon", EST},
{"America/Noronha", NORONHA}, {"America/Nome", AKST},
{"America/Noronha", NORONHA},
{"America/North_Dakota/Beulah", CST}, {"America/North_Dakota/Beulah", CST},
{"America/North_Dakota/Center", CST}, {"America/North_Dakota/Center", CST},
{"America/North_Dakota/New_Salem", CST}, {"America/North_Dakota/New_Salem", CST},
{"America/Panama", EST}, {"America/Ojinaga", MST},
{"America/Pangnirtung", EST}, {"America/Panama", EST},
{"America/Paramaribo", new String[] {"Fuso hor\u00e1rio do Suriname", "SRT", {"America/Pangnirtung", EST},
"Fuso hor\u00e1rio de ver\u00e3o do Suriname", "SRST"}}, {"America/Paramaribo", new String[] {"Fuso hor\u00e1rio do Suriname", "SRT",
{"America/Port-au-Prince", EST}, "Fuso hor\u00e1rio de ver\u00e3o do Suriname", "SRST"}},
{"America/Port_of_Spain", AST}, {"America/Port-au-Prince", EST},
{"America/Porto_Acre", AMT}, {"America/Port_of_Spain", AST},
{"America/Porto_Velho", AMT}, {"America/Porto_Acre", AMT},
{"America/Puerto_Rico", AST}, {"America/Porto_Velho", AMT},
{"America/Rainy_River", CST}, {"America/Puerto_Rico", AST},
{"America/Rankin_Inlet", CST}, {"America/Rainy_River", CST},
{"America/Recife", BRT}, {"America/Rankin_Inlet", CST},
{"America/Regina", CST}, {"America/Recife", BRT},
{"America/Resolute", RST}, {"America/Regina", CST},
{"America/Rio_Branco", AMT}, {"America/Resolute", RST},
{"America/Rosario", AGT}, {"America/Rio_Branco", AMT},
{"America/Santarem", BRT}, {"America/Rosario", AGT},
{"America/Santiago", CLT}, {"America/Santa_Isabel", PST},
{"America/Santo_Domingo", AST}, {"America/Santarem", BRT},
{"America/Sao_Paulo", BRT}, {"America/Santiago", CLT},
{"America/Scoresbysund", EGT}, {"America/Santo_Domingo", AST},
{"America/Shiprock", MST}, {"America/Sao_Paulo", BRT},
{"America/St_Barthelemy", AST}, {"America/Scoresbysund", EGT},
{"America/St_Kitts", AST}, {"America/Shiprock", MST},
{"America/St_Lucia", AST}, {"America/St_Barthelemy", AST},
{"America/St_Thomas", AST}, {"America/St_Kitts", AST},
{"America/St_Vincent", AST}, {"America/St_Lucia", AST},
{"America/Swift_Current", CST}, {"America/St_Thomas", AST},
{"America/Tegucigalpa", CST}, {"America/St_Vincent", AST},
{"America/Thule", AST}, {"America/Swift_Current", CST},
{"America/Thunder_Bay", EST}, {"America/Tegucigalpa", CST},
{"America/Tijuana", PST}, {"America/Thule", AST},
{"America/Toronto", EST}, {"America/Thunder_Bay", EST},
{"America/Tortola", AST}, {"America/Tijuana", PST},
{"America/Vancouver", PST}, {"America/Toronto", EST},
{"America/Virgin", AST}, {"America/Tortola", AST},
{"America/Whitehorse", PST}, {"America/Vancouver", PST},
{"America/Winnipeg", CST}, {"America/Virgin", AST},
{"America/Yakutat", AKST}, {"America/Whitehorse", PST},
{"America/Yellowknife", MST}, {"America/Winnipeg", CST},
{"Antarctica/Casey", WST_AUS}, {"America/Yakutat", AKST},
{"Antarctica/Davis", new String[] {"Fuso hor\u00e1rio de Davis", "DAVT", {"America/Yellowknife", MST},
"Fuso hor\u00e1rio de ver\u00e3o de Davis", "DAVST"}}, {"Antarctica/Casey", WST_AUS},
{"Antarctica/DumontDUrville", new String[] {"Fuso hor\u00e1rio de Dumont-d'Urville", "DDUT", {"Antarctica/Davis", new String[] {"Fuso hor\u00e1rio de Davis", "DAVT",
"Fuso hor\u00e1rio de ver\u00e3o de Dumont-d'Urville", "DDUST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Davis", "DAVST"}},
{"Antarctica/Mawson", new String[] {"Fuso hor\u00e1rio de Mawson", "MAWT", {"Antarctica/DumontDUrville", new String[] {"Fuso hor\u00e1rio de Dumont-d'Urville", "DDUT",
"Fuso hor\u00e1rio de ver\u00e3o de Mawson", "MAWST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Dumont-d'Urville", "DDUST"}},
{"Antarctica/McMurdo", NZST}, {"Antarctica/Macquarie", new String[] {"Macquarie Island Time", "MIST",
{"Antarctica/Palmer", CLT}, "Macquarie Island Summer Time", "MIST"}},
{"Antarctica/Rothera", new String[] {"Fuso hor\u00e1rio de Rothera", "ROTT", {"Antarctica/Mawson", new String[] {"Fuso hor\u00e1rio de Mawson", "MAWT",
"Fuso hor\u00e1rio de ver\u00e3o de Rothera", "ROTST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Mawson", "MAWST"}},
{"Antarctica/South_Pole", NZST}, {"Antarctica/McMurdo", NZST},
{"Antarctica/Syowa", new String[] {"Fuso hor\u00e1rio de Syowa", "SYOT", {"Antarctica/Palmer", CLT},
"Fuso hor\u00e1rio de ver\u00e3o de Syowa", "SYOST"}}, {"Antarctica/Rothera", new String[] {"Fuso hor\u00e1rio de Rothera", "ROTT",
{"Antarctica/Vostok", new String[] {"Fuso hor\u00e1rio de Vostok", "VOST", "Fuso hor\u00e1rio de ver\u00e3o de Rothera", "ROTST"}},
"Fuso hor\u00e1rio de ver\u00e3o de Vostok", "VOSST"}}, {"Antarctica/South_Pole", NZST},
{"Arctic/Longyearbyen", CET}, {"Antarctica/Syowa", new String[] {"Fuso hor\u00e1rio de Syowa", "SYOT",
{"Asia/Aden", ARAST}, "Fuso hor\u00e1rio de ver\u00e3o de Syowa", "SYOST"}},
{"Asia/Almaty", new String[] {"Fuso hor\u00e1rio de Alma-Ata", "ALMT", {"Antarctica/Vostok", new String[] {"Fuso hor\u00e1rio de Vostok", "VOST",
"Fuso hor\u00e1rio de ver\u00e3o de Alma-Ata", "ALMST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Vostok", "VOSST"}},
{"Asia/Amman", EET}, {"Arctic/Longyearbyen", CET},
{"Asia/Anadyr", new String[] {"Fuso hor\u00e1rio de Anadyr", "ANAT", {"Asia/Aden", ARAST},
"Fuso hor\u00e1rio de ver\u00e3o de Anadyr", "ANAST"}}, {"Asia/Almaty", new String[] {"Fuso hor\u00e1rio de Alma-Ata", "ALMT",
{"Asia/Aqtau", new String[] {"Fuso hor\u00e1rio de Aqtau", "AQTT", "Fuso hor\u00e1rio de ver\u00e3o de Alma-Ata", "ALMST"}},
"Fuso hor\u00e1rio de ver\u00e3o de Aqtau", "AQTST"}}, {"Asia/Amman", EET},
{"Asia/Aqtobe", new String[] {"Fuso hor\u00e1rio de Aqtobe", "AQTT", {"Asia/Anadyr", new String[] {"Fuso hor\u00e1rio de Anadyr", "ANAT",
"Fuso hor\u00e1rio de ver\u00e3o de Aqtobe", "AQTST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Anadyr", "ANAST"}},
{"Asia/Ashgabat", TMT}, {"Asia/Aqtau", new String[] {"Fuso hor\u00e1rio de Aqtau", "AQTT",
{"Asia/Ashkhabad", TMT}, "Fuso hor\u00e1rio de ver\u00e3o de Aqtau", "AQTST"}},
{"Asia/Baghdad", ARAST}, {"Asia/Aqtobe", new String[] {"Fuso hor\u00e1rio de Aqtobe", "AQTT",
{"Asia/Bahrain", ARAST}, "Fuso hor\u00e1rio de ver\u00e3o de Aqtobe", "AQTST"}},
{"Asia/Baku", new String[] {"Fuso hor\u00e1rio do Azerbaij\u00e3o", "AZT", {"Asia/Ashgabat", TMT},
"Fuso hor\u00e1rio de ver\u00e3o do Azerbaij\u00e3o", "AZST"}}, {"Asia/Ashkhabad", TMT},
{"Asia/Bangkok", ICT}, {"Asia/Baghdad", ARAST},
{"Asia/Beirut", EET}, {"Asia/Bahrain", ARAST},
{"Asia/Bishkek", new String[] {"Fuso hor\u00e1rio do Quirguist\u00e3o", "KGT", {"Asia/Baku", new String[] {"Fuso hor\u00e1rio do Azerbaij\u00e3o", "AZT",
"Fuso hor\u00e1rio de ver\u00e3o do Quirguist\u00e3o", "KGST"}}, "Fuso hor\u00e1rio de ver\u00e3o do Azerbaij\u00e3o", "AZST"}},
{"Asia/Brunei", new String[] {"Fuso hor\u00e1rio de Brunei", "BNT", {"Asia/Bangkok", ICT},
"Fuso hor\u00e1rio de ver\u00e3o de Brunei", "BNST"}}, {"Asia/Beirut", EET},
{"Asia/Calcutta", IST}, {"Asia/Bishkek", new String[] {"Fuso hor\u00e1rio do Quirguist\u00e3o", "KGT",
{"Asia/Choibalsan", new String[] {"Fuso hor\u00e1rio de Choibalsan", "CHOT", "Fuso hor\u00e1rio de ver\u00e3o do Quirguist\u00e3o", "KGST"}},
"Fuso hor\u00e1rio de ver\u00e3o de Choibalsan", "CHOST"}}, {"Asia/Brunei", new String[] {"Fuso hor\u00e1rio de Brunei", "BNT",
{"Asia/Chongqing", CTT}, "Fuso hor\u00e1rio de ver\u00e3o de Brunei", "BNST"}},
{"Asia/Chungking", CTT}, {"Asia/Calcutta", IST},
{"Asia/Colombo", IST}, {"Asia/Choibalsan", new String[] {"Fuso hor\u00e1rio de Choibalsan", "CHOT",
{"Asia/Dacca", BDT}, "Fuso hor\u00e1rio de ver\u00e3o de Choibalsan", "CHOST"}},
{"Asia/Dhaka", BDT}, {"Asia/Chongqing", CTT},
{"Asia/Dili", new String[] {"Fuso hor\u00e1rio do Timor-Leste", "TLT", {"Asia/Chungking", CTT},
"Fuso hor\u00e1rio de ver\u00e3o do Timor-Leste", "TLST"}}, {"Asia/Colombo", IST},
{"Asia/Damascus", EET}, {"Asia/Dacca", BDT},
{"Asia/Dubai", GST}, {"Asia/Dhaka", BDT},
{"Asia/Dushanbe", new String[] {"Fuso hor\u00e1rio do Tadjiquist\u00e3o", "TJT", {"Asia/Dili", new String[] {"Fuso hor\u00e1rio do Timor-Leste", "TLT",
"Fuso hor\u00e1rio de ver\u00e3o do Tadjiquist\u00e3o", "TJST"}}, "Fuso hor\u00e1rio de ver\u00e3o do Timor-Leste", "TLST"}},
{"Asia/Gaza", EET}, {"Asia/Damascus", EET},
{"Asia/Harbin", CTT}, {"Asia/Dubai", GST},
{"Asia/Ho_Chi_Minh", ICT}, {"Asia/Dushanbe", new String[] {"Fuso hor\u00e1rio do Tadjiquist\u00e3o", "TJT",
{"Asia/Hong_Kong", HKT}, "Fuso hor\u00e1rio de ver\u00e3o do Tadjiquist\u00e3o", "TJST"}},
{"Asia/Hovd", new String[] {"Fuso hor\u00e1rio de Hovd", "HOVT", {"Asia/Gaza", EET},
"Fuso hor\u00e1rio de ver\u00e3o de Hovd", "HOVST"}}, {"Asia/Harbin", CTT},
{"Asia/Irkutsk", new String[] {"Fuso hor\u00e1rio de Irkutsk", "IRKT", {"Asia/Ho_Chi_Minh", ICT},
"Fuso hor\u00e1rio de ver\u00e3o de Irkutsk", "IRKST"}}, {"Asia/Hong_Kong", HKT},
{"Asia/Istanbul", EET}, {"Asia/Hovd", new String[] {"Fuso hor\u00e1rio de Hovd", "HOVT",
{"Asia/Jakarta", WIT}, "Fuso hor\u00e1rio de ver\u00e3o de Hovd", "HOVST"}},
{"Asia/Jayapura", new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Oriental", "EIT", {"Asia/Irkutsk", new String[] {"Fuso hor\u00e1rio de Irkutsk", "IRKT",
"Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Oriental", "EIST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Irkutsk", "IRKST"}},
{"Asia/Kabul", new String[] {"Fuso hor\u00e1rio do Afeganist\u00e3o", "AFT", {"Asia/Istanbul", EET},
"Fuso hor\u00e1rio de ver\u00e3o do Afeganist\u00e3o", "AFST"}}, {"Asia/Jakarta", WIT},
{"Asia/Kamchatka", new String[] {"Fuso hor\u00e1rio de Petropavlovsk-Kamchatski", "PETT", {"Asia/Jayapura", new String[] {"Fuso hor\u00e1rio da Indon\u00e9sia Oriental", "EIT",
"Fuso hor\u00e1rio de ver\u00e3o de Petropavlovsk-Kamchatski", "PETST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Indon\u00e9sia Oriental", "EIST"}},
{"Asia/Karachi", PKT}, {"Asia/Kabul", new String[] {"Fuso hor\u00e1rio do Afeganist\u00e3o", "AFT",
{"Asia/Kashgar", CTT}, "Fuso hor\u00e1rio de ver\u00e3o do Afeganist\u00e3o", "AFST"}},
{"Asia/Kathmandu", NPT}, {"Asia/Kamchatka", new String[] {"Fuso hor\u00e1rio de Petropavlovsk-Kamchatski", "PETT",
{"Asia/Katmandu", NPT}, "Fuso hor\u00e1rio de ver\u00e3o de Petropavlovsk-Kamchatski", "PETST"}},
{"Asia/Kolkata", IST}, {"Asia/Karachi", PKT},
{"Asia/Krasnoyarsk", new String[] {"Fuso hor\u00e1rio de Krasnoyarsk", "KRAT", {"Asia/Kashgar", CTT},
"Fuso hor\u00e1rio de ver\u00e3o de Krasnoyarsk", "KRAST"}}, {"Asia/Kathmandu", NPT},
{"Asia/Kuala_Lumpur", MYT}, {"Asia/Katmandu", NPT},
{"Asia/Kuching", MYT}, {"Asia/Kolkata", IST},
{"Asia/Kuwait", ARAST}, {"Asia/Krasnoyarsk", new String[] {"Fuso hor\u00e1rio de Krasnoyarsk", "KRAT",
{"Asia/Macao", CTT}, "Fuso hor\u00e1rio de ver\u00e3o de Krasnoyarsk", "KRAST"}},
{"Asia/Macau", CTT}, {"Asia/Kuala_Lumpur", MYT},
{"Asia/Magadan", new String[] {"Fuso hor\u00e1rio de Magadan", "MAGT", {"Asia/Kuching", MYT},
"Fuso hor\u00e1rio de ver\u00e3o de Magadan", "MAGST"}}, {"Asia/Kuwait", ARAST},
{"Asia/Makassar", CIT}, {"Asia/Macao", CTT},
{"Asia/Manila", new String[] {"Fuso hor\u00e1rio das Filipinas", "PHT", {"Asia/Macau", CTT},
"Fuso hor\u00e1rio de ver\u00e3o das Filipinas", "PHST"}}, {"Asia/Magadan", new String[] {"Fuso hor\u00e1rio de Magadan", "MAGT",
{"Asia/Muscat", GST}, "Fuso hor\u00e1rio de ver\u00e3o de Magadan", "MAGST"}},
{"Asia/Nicosia", EET}, {"Asia/Makassar", CIT},
{"Asia/Novokuznetsk", NOVT}, {"Asia/Manila", new String[] {"Fuso hor\u00e1rio das Filipinas", "PHT",
{"Asia/Novosibirsk", NOVT}, "Fuso hor\u00e1rio de ver\u00e3o das Filipinas", "PHST"}},
{"Asia/Oral", new String[] {"Fuso hor\u00e1rio de Uralsk", "ORAT", {"Asia/Muscat", GST},
"Fuso hor\u00e1rio de ver\u00e3o de Uralsk", "ORAST"}}, {"Asia/Nicosia", EET},
{"Asia/Omsk", new String[] {"Fuso hor\u00e1rio de Omsk", "OMST", {"Asia/Novokuznetsk", NOVT},
"Fuso hor\u00e1rio de ver\u00e3o de Omsk", "OMSST"}}, {"Asia/Novosibirsk", NOVT},
{"Asia/Phnom_Penh", ICT}, {"Asia/Oral", new String[] {"Fuso hor\u00e1rio de Uralsk", "ORAT",
{"Asia/Pontianak", WIT}, "Fuso hor\u00e1rio de ver\u00e3o de Uralsk", "ORAST"}},
{"Asia/Pyongyang", KST}, {"Asia/Omsk", new String[] {"Fuso hor\u00e1rio de Omsk", "OMST",
{"Asia/Qatar", ARAST}, "Fuso hor\u00e1rio de ver\u00e3o de Omsk", "OMSST"}},
{"Asia/Qyzylorda", new String[] {"Fuso hor\u00e1rio de Kizil-Orda", "QYZT", {"Asia/Phnom_Penh", ICT},
"Fuso hor\u00e1rio de ver\u00e3o de Kizil-Orda", "QYZST"}}, {"Asia/Pontianak", WIT},
{"Asia/Rangoon", new String[] {"Fuso hor\u00e1rio de Mianmar", "MMT", {"Asia/Pyongyang", KST},
"Fuso hor\u00e1rio de ver\u00e3o de Mianmar", "MMST"}}, {"Asia/Qatar", ARAST},
{"Asia/Riyadh", ARAST}, {"Asia/Qyzylorda", new String[] {"Fuso hor\u00e1rio de Kizil-Orda", "QYZT",
{"Asia/Saigon", ICT}, "Fuso hor\u00e1rio de ver\u00e3o de Kizil-Orda", "QYZST"}},
{"Asia/Sakhalin", new String[] {"Fuso hor\u00e1rio de Sakhalina", "SAKT", {"Asia/Rangoon", new String[] {"Fuso hor\u00e1rio de Mianmar", "MMT",
"Fuso hor\u00e1rio de ver\u00e3o de Sakhalina", "SAKST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Mianmar", "MMST"}},
{"Asia/Samarkand", UZT}, {"Asia/Riyadh", ARAST},
{"Asia/Seoul", KST}, {"Asia/Saigon", ICT},
{"Asia/Singapore", SGT}, {"Asia/Sakhalin", new String[] {"Fuso hor\u00e1rio de Sakhalina", "SAKT",
{"Asia/Taipei", CTT}, "Fuso hor\u00e1rio de ver\u00e3o de Sakhalina", "SAKST"}},
{"Asia/Tel_Aviv", ISRAEL}, {"Asia/Samarkand", UZT},
{"Asia/Tashkent", UZT}, {"Asia/Seoul", KST},
{"Asia/Tbilisi", new String[] {"Fuso hor\u00e1rio da Ge\u00f3rgia", "GET", {"Asia/Singapore", SGT},
"Fuso hor\u00e1rio de ver\u00e3o da Ge\u00f3rgia", "GEST"}}, {"Asia/Taipei", CTT},
{"Asia/Tehran", IRT}, {"Asia/Tel_Aviv", ISRAEL},
{"Asia/Thimbu", BTT}, {"Asia/Tashkent", UZT},
{"Asia/Thimphu", BTT}, {"Asia/Tbilisi", new String[] {"Fuso hor\u00e1rio da Ge\u00f3rgia", "GET",
{"Asia/Ujung_Pandang", CIT}, "Fuso hor\u00e1rio de ver\u00e3o da Ge\u00f3rgia", "GEST"}},
{"Asia/Ulaanbaatar", ULAT}, {"Asia/Tehran", IRT},
{"Asia/Ulan_Bator", ULAT}, {"Asia/Thimbu", BTT},
{"Asia/Urumqi", CTT}, {"Asia/Thimphu", BTT},
{"Asia/Vientiane", ICT}, {"Asia/Ujung_Pandang", CIT},
{"Asia/Vladivostok", new String[] {"Fuso hor\u00e1rio de Vladivostok", "VLAT", {"Asia/Ulaanbaatar", ULAT},
"Fuso hor\u00e1rio de ver\u00e3o de Vladivostok", "VLAST"}}, {"Asia/Ulan_Bator", ULAT},
{"Asia/Yakutsk", new String[] {"Fuso hor\u00e1rio de Yakutsk", "YAKT", {"Asia/Urumqi", CTT},
"Fuso hor\u00e1rio de ver\u00e3o de Yakutsk", "YAKST"}}, {"Asia/Vientiane", ICT},
{"Asia/Yekaterinburg", new String[] {"Fuso hor\u00e1rio de Yekaterinburgo", "YEKT", {"Asia/Vladivostok", new String[] {"Fuso hor\u00e1rio de Vladivostok", "VLAT",
"Fuso hor\u00e1rio de ver\u00e3o de Yekaterinburgo", "YEKST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Vladivostok", "VLAST"}},
{"Asia/Yerevan", ARMT}, {"Asia/Yakutsk", new String[] {"Fuso hor\u00e1rio de Yakutsk", "YAKT",
{"Atlantic/Azores", new String[] {"Fuso hor\u00e1rio das A\u00e7ores", "AZOT", "Fuso hor\u00e1rio de ver\u00e3o de Yakutsk", "YAKST"}},
"Fuso hor\u00e1rio de ver\u00e3o das A\u00e7ores", "AZOST"}}, {"Asia/Yekaterinburg", new String[] {"Fuso hor\u00e1rio de Yekaterinburgo", "YEKT",
{"Atlantic/Bermuda", AST}, "Fuso hor\u00e1rio de ver\u00e3o de Yekaterinburgo", "YEKST"}},
{"Atlantic/Canary", WET}, {"Asia/Yerevan", ARMT},
{"Atlantic/Cape_Verde", new String[] {"Fuso hor\u00e1rio de Cabo Verde", "CVT", {"Atlantic/Azores", new String[] {"Fuso hor\u00e1rio das A\u00e7ores", "AZOT",
"Fuso hor\u00e1rio de ver\u00e3o de Cabo Verde", "CVST"}}, "Fuso hor\u00e1rio de ver\u00e3o das A\u00e7ores", "AZOST"}},
{"Atlantic/Faeroe", WET}, {"Atlantic/Bermuda", AST},
{"Atlantic/Faroe", WET}, {"Atlantic/Canary", WET},
{"Atlantic/Jan_Mayen", CET}, {"Atlantic/Cape_Verde", new String[] {"Fuso hor\u00e1rio de Cabo Verde", "CVT",
{"Atlantic/Madeira", WET}, "Fuso hor\u00e1rio de ver\u00e3o de Cabo Verde", "CVST"}},
{"Atlantic/Reykjavik", GMT}, {"Atlantic/Faeroe", WET},
{"Atlantic/South_Georgia", new String[] {"Fuso hor\u00e1rio padr\u00e3o da Ge\u00f3rgia do Sul", "GST", {"Atlantic/Faroe", WET},
"Hor\u00e1rio de luz natural da Ge\u00f3rgia do Sul", "GDT"}}, {"Atlantic/Jan_Mayen", CET},
{"Atlantic/St_Helena", GMT}, {"Atlantic/Madeira", WET},
{"Atlantic/Stanley", new String[] {"Fuso hor\u00e1rio das Ilhas Falkland", "FKT", {"Atlantic/Reykjavik", GMT},
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Falkland", "FKST"}}, {"Atlantic/South_Georgia", new String[] {"Fuso hor\u00e1rio padr\u00e3o da Ge\u00f3rgia do Sul", "GST",
{"Australia/ACT", EST_NSW}, "Hor\u00e1rio de luz natural da Ge\u00f3rgia do Sul", "GDT"}},
{"Australia/Adelaide", ADELAIDE}, {"Atlantic/St_Helena", GMT},
{"Australia/Brisbane", BRISBANE}, {"Atlantic/Stanley", new String[] {"Fuso hor\u00e1rio das Ilhas Falkland", "FKT",
{"Australia/Broken_Hill", BROKEN_HILL}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Falkland", "FKST"}},
{"Australia/Canberra", EST_NSW}, {"Australia/ACT", EST_NSW},
{"Australia/Currie", EST_NSW}, {"Australia/Adelaide", ADELAIDE},
{"Australia/Darwin", DARWIN}, {"Australia/Brisbane", BRISBANE},
{"Australia/Eucla", new String[] {"Fuso hor\u00e1rio ocidental central (Austr\u00e1lia)", "CWST", {"Australia/Broken_Hill", BROKEN_HILL},
"Fuso hor\u00e1rio de ver\u00e3o ocidental central (Austr\u00e1lia)", "CWST"}}, {"Australia/Canberra", EST_NSW},
{"Australia/Hobart", TASMANIA}, {"Australia/Currie", EST_NSW},
{"Australia/LHI", LORD_HOWE}, {"Australia/Darwin", DARWIN},
{"Australia/Lindeman", BRISBANE}, {"Australia/Eucla", new String[] {"Fuso hor\u00e1rio ocidental central (Austr\u00e1lia)", "CWST",
{"Australia/Lord_Howe", LORD_HOWE}, "Fuso hor\u00e1rio de ver\u00e3o ocidental central (Austr\u00e1lia)", "CWST"}},
{"Australia/Melbourne", VICTORIA}, {"Australia/Hobart", TASMANIA},
{"Australia/North", DARWIN}, {"Australia/LHI", LORD_HOWE},
{"Australia/NSW", EST_NSW}, {"Australia/Lindeman", BRISBANE},
{"Australia/Perth", WST_AUS}, {"Australia/Lord_Howe", LORD_HOWE},
{"Australia/Queensland", BRISBANE}, {"Australia/Melbourne", VICTORIA},
{"Australia/South", ADELAIDE}, {"Australia/North", DARWIN},
{"Australia/Sydney", EST_NSW}, {"Australia/NSW", EST_NSW},
{"Australia/Tasmania", TASMANIA}, {"Australia/Perth", WST_AUS},
{"Australia/Victoria", VICTORIA}, {"Australia/Queensland", BRISBANE},
{"Australia/West", WST_AUS}, {"Australia/South", ADELAIDE},
{"Australia/Yancowinna", BROKEN_HILL}, {"Australia/Sydney", EST_NSW},
{"BET", BRT}, {"Australia/Tasmania", TASMANIA},
{"BST", BDT}, {"Australia/Victoria", VICTORIA},
{"Brazil/Acre", AMT}, {"Australia/West", WST_AUS},
{"Brazil/DeNoronha", NORONHA}, {"Australia/Yancowinna", BROKEN_HILL},
{"Brazil/East", BRT}, {"BET", BRT},
{"Brazil/West", AMT}, {"BST", BDT},
{"Canada/Atlantic", AST}, {"Brazil/Acre", AMT},
{"Canada/Central", CST}, {"Brazil/DeNoronha", NORONHA},
{"Canada/East-Saskatchewan", CST}, {"Brazil/East", BRT},
{"Canada/Eastern", EST}, {"Brazil/West", AMT},
{"Canada/Mountain", MST}, {"Canada/Atlantic", AST},
{"Canada/Newfoundland", NST}, {"Canada/Central", CST},
{"Canada/Pacific", PST}, {"Canada/East-Saskatchewan", CST},
{"Canada/Yukon", PST}, {"Canada/Eastern", EST},
{"Canada/Saskatchewan", CST}, {"Canada/Mountain", MST},
{"CAT", CAT}, {"Canada/Newfoundland", NST},
{"CET", CET}, {"Canada/Pacific", PST},
{"Chile/Continental", CLT}, {"Canada/Yukon", PST},
{"Chile/EasterIsland", EASTER}, {"Canada/Saskatchewan", CST},
{"CST6CDT", CST}, {"CAT", CAT},
{"Cuba", CUBA}, {"CET", CET},
{"EAT", EAT}, {"Chile/Continental", CLT},
{"EET", EET}, {"Chile/EasterIsland", EASTER},
{"Egypt", EET}, {"CST6CDT", CST},
{"Eire", DUBLIN}, {"Cuba", CUBA},
{"EST5EDT", EST}, {"EAT", EAT},
{"Etc/Greenwich", GMT}, {"EET", EET},
{"Etc/UCT", UTC}, {"Egypt", EET},
{"Etc/Universal", UTC}, {"Eire", DUBLIN},
{"Etc/UTC", UTC}, {"EST5EDT", EST},
{"Etc/Zulu", UTC}, {"Etc/Greenwich", GMT},
{"Europe/Amsterdam", CET}, {"Etc/UCT", UTC},
{"Europe/Andorra", CET}, {"Etc/Universal", UTC},
{"Europe/Athens", EET}, {"Etc/UTC", UTC},
{"Europe/Belfast", GMTBST}, {"Etc/Zulu", UTC},
{"Europe/Belgrade", CET}, {"Europe/Amsterdam", CET},
{"Europe/Berlin", CET}, {"Europe/Andorra", CET},
{"Europe/Bratislava", CET}, {"Europe/Athens", EET},
{"Europe/Brussels", CET}, {"Europe/Belfast", GMTBST},
{"Europe/Budapest", CET}, {"Europe/Belgrade", CET},
{"Europe/Chisinau", EET}, {"Europe/Berlin", CET},
{"Europe/Copenhagen", CET}, {"Europe/Bratislava", CET},
{"Europe/Dublin", DUBLIN}, {"Europe/Brussels", CET},
{"Europe/Gibraltar", CET}, {"Europe/Budapest", CET},
{"Europe/Chisinau", EET},
{"Europe/Copenhagen", CET},
{"Europe/Dublin", DUBLIN},
{"Europe/Gibraltar", CET},
{"Europe/Guernsey", GMTBST}, {"Europe/Guernsey", GMTBST},
{"Europe/Helsinki", EET}, {"Europe/Helsinki", EET},
{"Europe/Isle_of_Man", GMTBST}, {"Europe/Isle_of_Man", GMTBST},
{"Europe/Istanbul", EET}, {"Europe/Istanbul", EET},
{"Europe/Jersey", GMTBST}, {"Europe/Jersey", GMTBST},
{"Europe/Kaliningrad", EET}, {"Europe/Kaliningrad", EET},
{"Europe/Kiev", EET}, {"Europe/Kiev", EET},
{"Europe/Lisbon", WET}, {"Europe/Lisbon", WET},
{"Europe/Ljubljana", CET}, {"Europe/Ljubljana", CET},
{"Europe/London", GMTBST}, {"Europe/London", GMTBST},
{"Europe/Luxembourg", CET}, {"Europe/Luxembourg", CET},
{"Europe/Madrid", CET}, {"Europe/Madrid", CET},
{"Europe/Malta", CET}, {"Europe/Malta", CET},
{"Europe/Mariehamn", EET}, {"Europe/Mariehamn", EET},
{"Europe/Minsk", EET}, {"Europe/Minsk", EET},
{"Europe/Monaco", CET}, {"Europe/Monaco", CET},
{"Europe/Moscow", MSK}, {"Europe/Moscow", MSK},
{"Europe/Nicosia", EET}, {"Europe/Nicosia", EET},
{"Europe/Oslo", CET}, {"Europe/Oslo", CET},
{"Europe/Podgorica", CET}, {"Europe/Podgorica", CET},
{"Europe/Prague", CET}, {"Europe/Prague", CET},
{"Europe/Riga", EET}, {"Europe/Riga", EET},
{"Europe/Rome", CET}, {"Europe/Rome", CET},
{"Europe/Samara", new String[] {"Fuso hor\u00e1rio de Samara", "SAMT", {"Europe/Samara", new String[] {"Fuso hor\u00e1rio de Samara", "SAMT",
"Fuso hor\u00e1rio de ver\u00e3o de Samara", "SAMST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Samara", "SAMST"}},
{"Europe/San_Marino", CET}, {"Europe/San_Marino", CET},
{"Europe/Sarajevo", CET}, {"Europe/Sarajevo", CET},
{"Europe/Simferopol", EET}, {"Europe/Simferopol", EET},
{"Europe/Skopje", CET}, {"Europe/Skopje", CET},
{"Europe/Sofia", EET}, {"Europe/Sofia", EET},
{"Europe/Stockholm", CET}, {"Europe/Stockholm", CET},
{"Europe/Tallinn", EET}, {"Europe/Tallinn", EET},
{"Europe/Tirane", CET}, {"Europe/Tirane", CET},
{"Europe/Tiraspol", EET}, {"Europe/Tiraspol", EET},
{"Europe/Uzhgorod", EET}, {"Europe/Uzhgorod", EET},
{"Europe/Vaduz", CET}, {"Europe/Vaduz", CET},
{"Europe/Vatican", CET}, {"Europe/Vatican", CET},
{"Europe/Vienna", CET}, {"Europe/Vienna", CET},
{"Europe/Vilnius", EET}, {"Europe/Vilnius", EET},
{"Europe/Volgograd", new String[] {"Fuso hor\u00e1rio de Volgogrado", "VOLT", {"Europe/Volgograd", new String[] {"Fuso hor\u00e1rio de Volgogrado", "VOLT",
"Fuso hor\u00e1rio de ver\u00e3o de Volgogrado", "VOLST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Volgogrado", "VOLST"}},
{"Europe/Warsaw", CET}, {"Europe/Warsaw", CET},
{"Europe/Zagreb", CET}, {"Europe/Zagreb", CET},
{"Europe/Zaporozhye", EET}, {"Europe/Zaporozhye", EET},
{"Europe/Zurich", CET}, {"Europe/Zurich", CET},
{"GB", GMTBST}, {"GB", GMTBST},
{"GB-Eire", GMTBST}, {"GB-Eire", GMTBST},
{"Greenwich", GMT}, {"Greenwich", GMT},
{"Hongkong", HKT}, {"Hongkong", HKT},
{"Iceland", GMT}, {"Iceland", GMT},
{"Iran", IRT}, {"Iran", IRT},
{"IST", IST}, {"IST", IST},
{"Indian/Antananarivo", EAT}, {"Indian/Antananarivo", EAT},
{"Indian/Chagos", new String[] {"Fuso hor\u00e1rio dos territ\u00f3rios do Oceano \u00cdndico", "IOT", {"Indian/Chagos", new String[] {"Fuso hor\u00e1rio dos territ\u00f3rios do Oceano \u00cdndico", "IOT",
"Fuso hor\u00e1rio de ver\u00e3o dos territ\u00f3rios do Oceano \u00cdndico", "IOST"}}, "Fuso hor\u00e1rio de ver\u00e3o dos territ\u00f3rios do Oceano \u00cdndico", "IOST"}},
{"Indian/Christmas", new String[] {"Fuso hor\u00e1rio das Ilhas Christmas", "CXT", {"Indian/Christmas", new String[] {"Fuso hor\u00e1rio das Ilhas Christmas", "CXT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Christmas", "CXST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Christmas", "CXST"}},
{"Indian/Cocos", new String[] {"Fuso hor\u00e1rio das Ilhas Cocos", "CCT", {"Indian/Cocos", new String[] {"Fuso hor\u00e1rio das Ilhas Cocos", "CCT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Cocos", "CCST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Cocos", "CCST"}},
{"Indian/Comoro", EAT}, {"Indian/Comoro", EAT},
{"Indian/Kerguelen", new String[] {"Fuso hor\u00e1rio das Terras Austrais e Ant\u00e1rticas Francesas", "TFT", {"Indian/Kerguelen", new String[] {"Fuso hor\u00e1rio das Terras Austrais e Ant\u00e1rticas Francesas", "TFT",
"Fuso hor\u00e1rio de ver\u00e3o das Terras Austrais e Ant\u00e1rticas Francesas", "TFST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Terras Austrais e Ant\u00e1rticas Francesas", "TFST"}},
{"Indian/Mahe", new String[] {"Fuso hor\u00e1rio das Seychelles", "SCT", {"Indian/Mahe", new String[] {"Fuso hor\u00e1rio das Seychelles", "SCT",
"Fuso hor\u00e1rio de ver\u00e3o das Seychelles", "SCST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Seychelles", "SCST"}},
{"Indian/Maldives", new String[] {"Fuso hor\u00e1rio das Maldivas", "MVT", {"Indian/Maldives", new String[] {"Fuso hor\u00e1rio das Maldivas", "MVT",
"Fuso hor\u00e1rio de ver\u00e3o das Maldivas", "MVST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Maldivas", "MVST"}},
{"Indian/Mauritius", new String[] {"Fuso hor\u00e1rio das Ilhas Maur\u00edcio", "MUT", {"Indian/Mauritius", new String[] {"Fuso hor\u00e1rio das Ilhas Maur\u00edcio", "MUT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Maur\u00edcio", "MUST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Maur\u00edcio", "MUST"}},
{"Indian/Mayotte", EAT}, {"Indian/Mayotte", EAT},
{"Indian/Reunion", new String[] {"Fuso hor\u00e1rio de Reuni\u00e3o", "RET", {"Indian/Reunion", new String[] {"Fuso hor\u00e1rio de Reuni\u00e3o", "RET",
"Fuso hor\u00e1rio de ver\u00e3o de Reuni\u00e3o", "REST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Reuni\u00e3o", "REST"}},
{"Israel", ISRAEL}, {"Israel", ISRAEL},
{"Jamaica", EST}, {"Jamaica", EST},
{"Japan", JST}, {"Japan", JST},
{"Kwajalein", MHT}, {"Kwajalein", MHT},
{"Libya", EET}, {"Libya", EET},
{"MET", new String[] {"Fuso hor\u00e1rio da Europa M\u00e9dia", "MET", {"MET", new String[] {"Fuso hor\u00e1rio da Europa M\u00e9dia", "MET",
"Fuso hor\u00e1rio de ver\u00e3o da Europa M\u00e9dia", "MEST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Europa M\u00e9dia", "MEST"}},
{"Mexico/BajaNorte", PST}, {"Mexico/BajaNorte", PST},
{"Mexico/BajaSur", MST}, {"Mexico/BajaSur", MST},
{"Mexico/General", CST}, {"Mexico/General", CST},
{"MIT", WST_SAMOA}, {"MIT", WST_SAMOA},
{"MST7MDT", MST}, {"MST7MDT", MST},
{"Navajo", MST}, {"Navajo", MST},
{"NET", ARMT}, {"NET", ARMT},
{"NST", NZST}, {"NST", NZST},
{"NZ", NZST}, {"NZ", NZST},
{"NZ-CHAT", CHAST}, {"NZ-CHAT", CHAST},
{"PLT", PKT}, {"PLT", PKT},
{"Portugal", WET}, {"Portugal", WET},
{"PRT", AST}, {"PRT", AST},
{"Pacific/Apia", WST_SAMOA}, {"Pacific/Apia", WST_SAMOA},
{"Pacific/Auckland", NZST}, {"Pacific/Auckland", NZST},
{"Pacific/Chatham", CHAST}, {"Pacific/Chatham", CHAST},
{"Pacific/Chuuk", TRUT}, {"Pacific/Chuuk", TRUT},
{"Pacific/Easter", EASTER}, {"Pacific/Easter", EASTER},
{"Pacific/Efate", new String[] {"Fuso hor\u00e1rio de Vanuatu", "VUT", {"Pacific/Efate", new String[] {"Fuso hor\u00e1rio de Vanuatu", "VUT",
"Fuso hor\u00e1rio de ver\u00e3o de Vanuatu", "VUST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Vanuatu", "VUST"}},
{"Pacific/Enderbury", new String[] {"Fuso hor\u00e1rio das Ilhas F\u00e9nix", "PHOT", {"Pacific/Enderbury", new String[] {"Fuso hor\u00e1rio das Ilhas F\u00e9nix", "PHOT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas F\u00e9nix", "PHOST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas F\u00e9nix", "PHOST"}},
{"Pacific/Fakaofo", new String[] {"Fuso hor\u00e1rio de Tokelau", "TKT", {"Pacific/Fakaofo", new String[] {"Fuso hor\u00e1rio de Tokelau", "TKT",
"Fuso hor\u00e1rio de ver\u00e3o de Tokelau", "TKST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Tokelau", "TKST"}},
{"Pacific/Fiji", new String[] {"Fuso hor\u00e1rio de Fiji", "FJT", {"Pacific/Fiji", new String[] {"Fuso hor\u00e1rio de Fiji", "FJT",
"Fuso hor\u00e1rio de ver\u00e3o de Fiji", "FJST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Fiji", "FJST"}},
{"Pacific/Funafuti", new String[] {"Fuso hor\u00e1rio de Tuvalu", "TVT", {"Pacific/Funafuti", new String[] {"Fuso hor\u00e1rio de Tuvalu", "TVT",
"Fuso hor\u00e1rio de ver\u00e3o de Tuvalu", "TVST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Tuvalu", "TVST"}},
{"Pacific/Galapagos", new String[] {"Fuso hor\u00e1rio das Ilhas Gal\u00e1pagos", "GALT", {"Pacific/Galapagos", new String[] {"Fuso hor\u00e1rio das Ilhas Gal\u00e1pagos", "GALT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Gal\u00e1pagos", "GALST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Gal\u00e1pagos", "GALST"}},
{"Pacific/Gambier", GAMBIER}, {"Pacific/Gambier", GAMBIER},
{"Pacific/Guadalcanal", SBT}, {"Pacific/Guadalcanal", SBT},
{"Pacific/Guam", ChST}, {"Pacific/Guam", ChST},
{"Pacific/Johnston", HST}, {"Pacific/Johnston", HST},
{"Pacific/Kiritimati", new String[] {"Fuso hor\u00e1rio das Esp\u00f3rades Equatoriais", "LINT", {"Pacific/Kiritimati", new String[] {"Fuso hor\u00e1rio das Esp\u00f3rades Equatoriais", "LINT",
"Fuso hor\u00e1rio de ver\u00e3o das Esp\u00f3rades Equatoriais", "LINST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Esp\u00f3rades Equatoriais", "LINST"}},
{"Pacific/Kosrae", new String[] {"Fuso hor\u00e1rio de Kosrae", "KOST", {"Pacific/Kosrae", new String[] {"Fuso hor\u00e1rio de Kosrae", "KOST",
"Fuso hor\u00e1rio de ver\u00e3o de Kosrae", "KOSST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Kosrae", "KOSST"}},
{"Pacific/Kwajalein", MHT}, {"Pacific/Kwajalein", MHT},
{"Pacific/Majuro", MHT}, {"Pacific/Majuro", MHT},
{"Pacific/Marquesas", new String[] {"Fuso hor\u00e1rio das Ilhas Marquesas", "MART", {"Pacific/Marquesas", new String[] {"Fuso hor\u00e1rio das Ilhas Marquesas", "MART",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Marquesas", "MARST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Marquesas", "MARST"}},
{"Pacific/Midway", SAMOA}, {"Pacific/Midway", SAMOA},
{"Pacific/Nauru", new String[] {"Fuso hor\u00e1rio de Nauru", "NRT", {"Pacific/Nauru", new String[] {"Fuso hor\u00e1rio de Nauru", "NRT",
"Fuso hor\u00e1rio de ver\u00e3o de Nauru", "NRST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Nauru", "NRST"}},
{"Pacific/Niue", new String[] {"Fuso hor\u00e1rio de Niue", "NUT", {"Pacific/Niue", new String[] {"Fuso hor\u00e1rio de Niue", "NUT",
"Fuso hor\u00e1rio de ver\u00e3o de Niue", "NUST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Niue", "NUST"}},
{"Pacific/Norfolk", new String[] {"Fuso hor\u00e1rio da Ilha de Norfolk", "NFT", {"Pacific/Norfolk", new String[] {"Fuso hor\u00e1rio da Ilha de Norfolk", "NFT",
"Fuso hor\u00e1rio de ver\u00e3o da Ilha de Norfolk", "NFST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Ilha de Norfolk", "NFST"}},
{"Pacific/Noumea", new String[] {"Fuso hor\u00e1rio da Nova Caled\u00f4nia", "NCT", {"Pacific/Noumea", new String[] {"Fuso hor\u00e1rio da Nova Caled\u00f4nia", "NCT",
"Fuso hor\u00e1rio de ver\u00e3o da Nova Caled\u00f4nia", "NCST"}}, "Fuso hor\u00e1rio de ver\u00e3o da Nova Caled\u00f4nia", "NCST"}},
{"Pacific/Pago_Pago", SAMOA}, {"Pacific/Pago_Pago", SAMOA},
{"Pacific/Palau", new String[] {"Fuso hor\u00e1rio de Palau", "PWT", {"Pacific/Palau", new String[] {"Fuso hor\u00e1rio de Palau", "PWT",
"Fuso hor\u00e1rio de ver\u00e3o de Palau", "PWST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Palau", "PWST"}},
{"Pacific/Pitcairn", PITCAIRN}, {"Pacific/Pitcairn", PITCAIRN},
{"Pacific/Pohnpei", PONT}, {"Pacific/Pohnpei", PONT},
{"Pacific/Ponape", PONT}, {"Pacific/Ponape", PONT},
{"Pacific/Port_Moresby", new String[] {"Fuso hor\u00e1rio de Papua-Nova Guin\u00e9", "PGT", {"Pacific/Port_Moresby", new String[] {"Fuso hor\u00e1rio de Papua-Nova Guin\u00e9", "PGT",
"Fuso hor\u00e1rio de ver\u00e3o de Papua-Nova Guin\u00e9", "PGST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Papua-Nova Guin\u00e9", "PGST"}},
{"Pacific/Rarotonga", new String[] {"Fuso hor\u00e1rio das Ilhas Cook", "CKT", {"Pacific/Rarotonga", new String[] {"Fuso hor\u00e1rio das Ilhas Cook", "CKT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Cook", "CKHST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Cook", "CKHST"}},
{"Pacific/Saipan", ChST}, {"Pacific/Saipan", ChST},
{"Pacific/Samoa", SAMOA}, {"Pacific/Samoa", SAMOA},
{"Pacific/Tahiti", new String[] {"Fuso hor\u00e1rio do Taiti", "TAHT", {"Pacific/Tahiti", new String[] {"Fuso hor\u00e1rio do Taiti", "TAHT",
"Fuso hor\u00e1rio de ver\u00e3o do Taiti", "TAHST"}}, "Fuso hor\u00e1rio de ver\u00e3o do Taiti", "TAHST"}},
{"Pacific/Tarawa", new String[] {"Fuso hor\u00e1rio das Ilhas Gilbert", "GILT", {"Pacific/Tarawa", new String[] {"Fuso hor\u00e1rio das Ilhas Gilbert", "GILT",
"Fuso hor\u00e1rio de ver\u00e3o das Ilhas Gilbert", "GILST"}}, "Fuso hor\u00e1rio de ver\u00e3o das Ilhas Gilbert", "GILST"}},
{"Pacific/Tongatapu", new String[] {"Fuso hor\u00e1rio de Tonga", "TOT", {"Pacific/Tongatapu", new String[] {"Fuso hor\u00e1rio de Tonga", "TOT",
"Fuso hor\u00e1rio de ver\u00e3o de Tonga", "TOST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Tonga", "TOST"}},
{"Pacific/Truk", TRUT}, {"Pacific/Truk", TRUT},
{"Pacific/Wake", new String[] {"Fuso hor\u00e1rio de Wake", "WAKT", {"Pacific/Wake", new String[] {"Fuso hor\u00e1rio de Wake", "WAKT",
"Fuso hor\u00e1rio de ver\u00e3o de Wake", "WAKST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Wake", "WAKST"}},
{"Pacific/Wallis", new String[] {"Fuso hor\u00e1rio de Wallis e Futuna", "WFT", {"Pacific/Wallis", new String[] {"Fuso hor\u00e1rio de Wallis e Futuna", "WFT",
"Fuso hor\u00e1rio de ver\u00e3o de Wallis e Futuna", "WFST"}}, "Fuso hor\u00e1rio de ver\u00e3o de Wallis e Futuna", "WFST"}},
{"Pacific/Yap", TRUT}, {"Pacific/Yap", TRUT},
{"Poland", CET}, {"Poland", CET},
{"PRC", CTT}, {"PRC", CTT},
{"PST8PDT", PST}, {"PST8PDT", PST},
{"ROK", KST}, {"ROK", KST},
{"Singapore", SGT}, {"Singapore", SGT},
{"SST", SBT}, {"SST", SBT},
{"SystemV/AST4", AST}, {"SystemV/AST4", AST},
{"SystemV/AST4ADT", AST}, {"SystemV/AST4ADT", AST},
{"SystemV/CST6", CST}, {"SystemV/CST6", CST},
{"SystemV/CST6CDT", CST}, {"SystemV/CST6CDT", CST},
{"SystemV/EST5", EST}, {"SystemV/EST5", EST},
{"SystemV/EST5EDT", EST}, {"SystemV/EST5EDT", EST},
{"SystemV/HST10", HST}, {"SystemV/HST10", HST},
{"SystemV/MST7", MST}, {"SystemV/MST7", MST},
{"SystemV/MST7MDT", MST}, {"SystemV/MST7MDT", MST},
{"SystemV/PST8", PST}, {"SystemV/PST8", PST},
{"SystemV/PST8PDT", PST}, {"SystemV/PST8PDT", PST},
{"SystemV/YST9", AKST}, {"SystemV/YST9", AKST},
{"SystemV/YST9YDT", AKST}, {"SystemV/YST9YDT", AKST},
{"Turkey", EET}, {"Turkey", EET},
{"UCT", UTC}, {"UCT", UTC},
{"Universal", UTC}, {"Universal", UTC},
{"US/Alaska", AKST}, {"US/Alaska", AKST},
{"US/Aleutian", HAST}, {"US/Aleutian", HAST},
{"US/Arizona", MST}, {"US/Arizona", MST},
{"US/Central", CST}, {"US/Central", CST},
{"US/Eastern", EST}, {"US/Eastern", EST},
{"US/Hawaii", HST}, {"US/Hawaii", HST},
{"US/Indiana-Starke", CST}, {"US/Indiana-Starke", CST},
{"US/East-Indiana", EST}, {"US/East-Indiana", EST},
{"US/Michigan", EST}, {"US/Michigan", EST},
{"US/Mountain", MST}, {"US/Mountain", MST},
{"US/Pacific", PST}, {"US/Pacific", PST},
{"US/Pacific-New", PST}, {"US/Pacific-New", PST},
{"US/Samoa", SAMOA}, {"US/Samoa", SAMOA},
{"UTC", UTC}, {"UTC", UTC},
{"VST", ICT}, {"VST", ICT},
{"W-SU", MSK}, {"W-SU", MSK},
{"WET", WET}, {"WET", WET},
{"Zulu", UTC}, {"Zulu", UTC},
}; };
} }
} }
...@@ -103,6 +103,14 @@ public class Win32FontManager extends SunFontManager { ...@@ -103,6 +103,14 @@ public class Win32FontManager extends SunFontManager {
}); });
} }
/**
* Whether registerFontFile expects absolute or relative
* font file names.
*/
protected boolean useAbsoluteFontFileNames() {
return false;
}
/* Unlike the shared code version, this expects a base file name - /* Unlike the shared code version, this expects a base file name -
* not a full path name. * not a full path name.
* The font configuration file has base file names and the FontConfiguration * The font configuration file has base file names and the FontConfiguration
......
...@@ -202,14 +202,6 @@ public class Win32GraphicsEnvironment ...@@ -202,14 +202,6 @@ public class Win32GraphicsEnvironment
* ----END DISPLAY CHANGE SUPPORT---- * ----END DISPLAY CHANGE SUPPORT----
*/ */
/**
* Whether registerFontFile expects absolute or relative
* font file names.
*/
protected boolean useAbsoluteFontFileNames() {
return false;
}
protected GraphicsDevice makeScreenDevice(int screennum) { protected GraphicsDevice makeScreenDevice(int screennum) {
GraphicsDevice device = null; GraphicsDevice device = null;
if (WindowsFlags.isD3DEnabled()) { if (WindowsFlags.isD3DEnabled()) {
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
* that this test case fails without the fix in some different ways, * that this test case fails without the fix in some different ways,
* including timeout, due to the memory corruption. * including timeout, due to the memory corruption.
* @build Bug6665028 * @build Bug6665028
* @run main/othervm/timeout=60 -Xmx16m Bug6665028 * @run main/othervm -Xmx16m Bug6665028 10
*/ */
import java.awt.font.TextAttribute; import java.awt.font.TextAttribute;
...@@ -36,6 +36,7 @@ import java.text.AttributedString; ...@@ -36,6 +36,7 @@ import java.text.AttributedString;
import java.text.Bidi; import java.text.Bidi;
// test1() and test2() were derived from BidiEmbeddingTest. // test1() and test2() were derived from BidiEmbeddingTest.
// Usage: java Bug6665028 [duration]
public class Bug6665028 { public class Bug6665028 {
private static boolean runrun = true; private static boolean runrun = true;
...@@ -50,6 +51,11 @@ public class Bug6665028 { ...@@ -50,6 +51,11 @@ public class Bug6665028 {
} }
public static void main(String[] args) { public static void main(String[] args) {
int duration = 45;
if (args.length == 1) {
duration = Math.max(1, Math.min(Integer.parseInt(args[0]), 45));
}
Test[] tests = new Test[4]; Test[] tests = new Test[4];
for (int i = 0; i < tests.length; i++) { for (int i = 0; i < tests.length; i++) {
Test t = new Test(); Test t = new Test();
...@@ -58,7 +64,7 @@ public class Bug6665028 { ...@@ -58,7 +64,7 @@ public class Bug6665028 {
} }
try { try {
Thread.sleep(45000); Thread.sleep(duration * 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,17 +24,22 @@ ...@@ -24,17 +24,22 @@
* @test * @test
* @bug 4518797 * @bug 4518797
* @summary Make sure that hashCode() and read/writeObject() are thread-safe. * @summary Make sure that hashCode() and read/writeObject() are thread-safe.
* @run main/timeout=200 Bug4518797 * @run main Bug4518797 10
*/ */
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
// Usage: java Bug4518797 [duration]
public class Bug4518797 { public class Bug4518797 {
static volatile boolean runrun = true; static volatile boolean runrun = true;
static volatile String message = null; static volatile String message = null;
public static void main(String[] args) { public static void main(String[] args) {
int duration = 180;
if (args.length == 1) {
duration = Math.max(5, Integer.parseInt(args[0]));
}
final Locale loc = new Locale("ja", "US"); final Locale loc = new Locale("ja", "US");
final int hashcode = loc.hashCode(); final int hashcode = loc.hashCode();
...@@ -84,7 +89,7 @@ public class Bug4518797 { ...@@ -84,7 +89,7 @@ public class Bug4518797 {
t1.start(); t1.start();
t2.start(); t2.start();
try { try {
for (int i = 0; runrun && i < 180; i++) { for (int i = 0; runrun && i < duration; i++) {
Thread.sleep(1000); Thread.sleep(1000);
} }
runrun = false; runrun = false;
......
...@@ -33,8 +33,10 @@ import java.io.ObjectInputStream; ...@@ -33,8 +33,10 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar;
import java.util.IllformedLocaleException; import java.util.IllformedLocaleException;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -43,8 +45,10 @@ import java.util.Set; ...@@ -43,8 +45,10 @@ import java.util.Set;
/** /**
* @test * @test
* @bug 6875847 6992272 7002320 7015500 7023613 * @bug 6875847 6992272 7002320 7015500 7023613 7032820 7033504
* @summary test API changes to Locale * @summary test API changes to Locale
* @compile LocaleEnhanceTest.java
* @run main/othervm -esa LocaleEnhanceTest
*/ */
public class LocaleEnhanceTest extends LocaleTestFmwk { public class LocaleEnhanceTest extends LocaleTestFmwk {
...@@ -593,6 +597,9 @@ public class LocaleEnhanceTest extends LocaleTestFmwk { ...@@ -593,6 +597,9 @@ public class LocaleEnhanceTest extends LocaleTestFmwk {
assertEquals("extension", "aa-00-bb-01", locale.getExtension('d')); assertEquals("extension", "aa-00-bb-01", locale.getExtension('d'));
assertEquals("extension c", "1234", locale.getExtension('c')); assertEquals("extension c", "1234", locale.getExtension('c'));
locale = Locale.forLanguageTag("und-U-ca-gregory-u-ca-japanese");
assertEquals("Unicode extension", "ca-gregory", locale.getExtension(Locale.UNICODE_LOCALE_EXTENSION));
// redundant Unicode locale keys in an extension are ignored // redundant Unicode locale keys in an extension are ignored
locale = Locale.forLanguageTag("und-u-aa-000-bb-001-bB-002-cc-003-c-1234"); locale = Locale.forLanguageTag("und-u-aa-000-bb-001-bB-002-cc-003-c-1234");
assertEquals("Unicode keywords", "aa-000-bb-001-cc-003", locale.getExtension(Locale.UNICODE_LOCALE_EXTENSION)); assertEquals("Unicode keywords", "aa-000-bb-001-cc-003", locale.getExtension(Locale.UNICODE_LOCALE_EXTENSION));
...@@ -1275,6 +1282,35 @@ public class LocaleEnhanceTest extends LocaleTestFmwk { ...@@ -1275,6 +1282,35 @@ public class LocaleEnhanceTest extends LocaleTestFmwk {
} }
} }
/*
* 7033504: (lc) incompatible behavior change for ja_JP_JP and th_TH_TH locales
*/
public void testBug7033504() {
checkCalendar(new Locale("ja", "JP", "jp"), "java.util.GregorianCalendar");
checkCalendar(new Locale("ja", "jp", "jp"), "java.util.GregorianCalendar");
checkCalendar(new Locale("ja", "JP", "JP"), "java.util.JapaneseImperialCalendar");
checkCalendar(new Locale("ja", "jp", "JP"), "java.util.JapaneseImperialCalendar");
checkCalendar(Locale.forLanguageTag("en-u-ca-japanese"),
"java.util.JapaneseImperialCalendar");
checkDigit(new Locale("th", "TH", "th"), '0');
checkDigit(new Locale("th", "th", "th"), '0');
checkDigit(new Locale("th", "TH", "TH"), '\u0e50');
checkDigit(new Locale("th", "TH", "TH"), '\u0e50');
checkDigit(Locale.forLanguageTag("en-u-nu-thai"), '\u0e50');
}
private void checkCalendar(Locale loc, String expected) {
Calendar cal = Calendar.getInstance(loc);
assertEquals("Wrong calendar", expected, cal.getClass().getName());
}
private void checkDigit(Locale loc, Character expected) {
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(loc);
Character zero = dfs.getZeroDigit();
assertEquals("Wrong digit zero char", expected, zero);
}
/// ///
/// utility asserts /// utility asserts
/// ///
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,12 +24,13 @@ ...@@ -24,12 +24,13 @@
* @test * @test
* @bug 5102289 * @bug 5102289
* @summary Stress test for ResourceBundle.getBundle with ResourceBundle.Control. * @summary Stress test for ResourceBundle.getBundle with ResourceBundle.Control.
* @run main/timeout=300/othervm -esa StressTest * @run main/othervm -esa StressTest 2 15
*/ */
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
// Usage: java StressTest [threadsFactor [duration]]
public class StressTest { public class StressTest {
static final Locale ROOT_LOCALE = new Locale(""); static final Locale ROOT_LOCALE = new Locale("");
static final Random rand = new Random(); static final Random rand = new Random();
...@@ -60,16 +61,16 @@ public class StressTest { ...@@ -60,16 +61,16 @@ public class StressTest {
static volatile boolean runrun = true; static volatile boolean runrun = true;
public static void main(String[] args) { public static void main(String[] args) {
int nThreads = 2; int threadsFactor = 2;
if (args.length > 0) { if (args.length > 0) {
nThreads = Math.max(Integer.parseInt(args[0]), 2); threadsFactor = Math.max(2, Integer.parseInt(args[0]));
} }
int nSeconds = 180; int duration = 180;
if (args.length > 1) { if (args.length > 1) {
nSeconds = Integer.parseInt(args[1]); duration = Math.max(5, Integer.parseInt(args[1]));
} }
Locale.setDefault(Locale.US); Locale.setDefault(Locale.US);
Thread[] tasks = new Thread[locales.length * nThreads]; Thread[] tasks = new Thread[locales.length * threadsFactor];
counters = new AtomicIntegerArray(tasks.length); counters = new AtomicIntegerArray(tasks.length);
for (int i = 0; i < tasks.length; i++) { for (int i = 0; i < tasks.length; i++) {
...@@ -84,8 +85,8 @@ public class StressTest { ...@@ -84,8 +85,8 @@ public class StressTest {
System.out.printf("%d processors, intervalForCounterCheck = %d [sec]%n", System.out.printf("%d processors, intervalForCounterCheck = %d [sec]%n",
nProcessors, intervalForCounterCheck); nProcessors, intervalForCounterCheck);
try { try {
for (int i = 0; runrun && i < nSeconds; i++) { for (int i = 0; runrun && i < duration; i++) {
Thread.sleep(1000); // 1 seconds Thread.sleep(1000); // 1 second
if ((i % intervalForCounterCheck) == 0) { if ((i % intervalForCounterCheck) == 0) {
checkCounters(); checkCounters();
} }
......
...@@ -59,9 +59,7 @@ public class bug6989617 { ...@@ -59,9 +59,7 @@ public class bug6989617 {
toolkit.realSync(); toolkit.realSync();
SwingUtilities.invokeAndWait(new Runnable() { SwingUtilities.invokeAndWait(new Runnable() {
public void run() { public void run() {
if (panel.getPaintRectangle() != null) { panel.resetPaintRectangle();
throw new RuntimeException("paint rectangle is not null");
}
button.repaint(); button.repaint();
} }
}); });
......
/* /*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -21,94 +21,75 @@ ...@@ -21,94 +21,75 @@
* questions. * questions.
*/ */
/* /* @test
* @test @bug 6596966
* @bug 6539700 @summary Some JFileChooser mnemonics do not work with sticky keys
* @summary test that the long space-less lines are correctly soft-wrapped * @library ../../regtesthelpers
* @author Sergey Groznyh * @build Util
* @run main bug6539700 @run main bug6596966
*/ @author Pavel Porvatov
*/
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.text.ParagraphView;
import javax.swing.text.View;
public class bug6539700 {
static JFrame f;
static JEditorPane ep;
static String text = "AAAAAAAA<b>AAAAAA</b>AAAAAAAA<b>AAAAAAAAA</b>" +
"AA<b>AAA</b>AAAAAAAAA";
static int size = 100;
static Class rowClass = null;
static void createContentPane() {
ep = new JEditorPane();
ep.setContentType("text/html");
ep.setEditable(false);
ep.setText(text);
f = new JFrame();
f.setSize(size, 2 * size);
f.add(ep);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
static void checkRows(View v, boolean last) { import javax.swing.*;
int width = (int) v.getPreferredSpan(View.X_AXIS); import java.awt.*;
import java.awt.event.KeyEvent;
if (v.getClass() == rowClass) { public class bug6596966 {
// Row width shouldn't exceed the container width private static JFrame frame;
if (width > size) {
throw new RuntimeException("too long row: " + width);
}
// Row shouldn't be too short (except for the last one) private static JLabel label;
if (!last) { private static JButton button;
if (width < size * 2 / 3) { private static JComboBox comboBox;
throw new RuntimeException("too short row: " + width);
} public static void main(String[] args) throws Exception {
} Robot robot = new Robot();
}
int n = v.getViewCount(); SwingUtilities.invokeAndWait(new Runnable() {
if (n > 0) { public void run() {
for (int i = 0; i < n; i++) { button = new JButton("Button");
View c = v.getView(i); comboBox = new JComboBox();
checkRows(c, i == n - 1);
label = new JLabel("Label");
label.setDisplayedMnemonic('L');
label.setLabelFor(comboBox);
JPanel pnContent = new JPanel();
pnContent.add(button);
pnContent.add(label);
pnContent.add(comboBox);
frame = new JFrame();
frame.add(pnContent);
frame.pack();
frame.setVisible(true);
} }
} });
}
Util.blockTillDisplayed(frame);
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_L);
robot.waitForIdle();
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new KeyEvent(label, KeyEvent.KEY_RELEASED,
EventQueue.getMostRecentEventTime(), 0, KeyEvent.VK_L, 'L'));
robot.waitForIdle();
public static void main(String[] argv) {
try { try {
SwingUtilities.invokeAndWait(new Runnable() { SwingUtilities.invokeAndWait(new Runnable() {
public void run() { public void run() {
createContentPane(); if (!comboBox.isFocusOwner()) {
throw new RuntimeException("comboBox isn't focus owner");
}
} }
}); });
} catch (Exception ex) { } finally {
throw new RuntimeException(ex); robot.keyRelease(KeyEvent.VK_ALT);
} }
Class[] pvchildren = ParagraphView.class.getDeclaredClasses();
for (Class c : pvchildren) {
if (c.getName().equals("javax.swing.text.ParagraphView$Row")) {
rowClass = c;
break;
}
}
if (rowClass == null) {
throw new RuntimeException("can't find ParagraphView.Row class");
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
checkRows(ep.getUI().getRootView(ep), true);
}
});
System.out.println("OK");
} }
} }
...@@ -52,7 +52,13 @@ public class bug7004134 { ...@@ -52,7 +52,13 @@ public class bug7004134 {
frame.add(label); frame.add(label);
frame.pack(); frame.pack();
frame.setVisible(true); frame.setVisible(true);
}
});
((SunToolkit) SunToolkit.getDefaultToolkit()).realSync();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
toolTipManager.setInitialDelay(0); toolTipManager.setInitialDelay(0);
...@@ -83,7 +89,13 @@ public class bug7004134 { ...@@ -83,7 +89,13 @@ public class bug7004134 {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); frame.pack();
frame.setVisible(true); frame.setVisible(true);
}
});
((SunToolkit) SunToolkit.getDefaultToolkit()).realSync();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
toolTipManager.setInitialDelay(0); toolTipManager.setInitialDelay(0);
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7036148
* @summary NullPointerException with null JMenu name
* @author Alexander Potochkin
* @run main bug7036148
*/
import javax.swing.*;
import java.awt.event.ActionEvent;
public class bug7036148 extends JFrame {
public bug7036148() {
JMenuBar bar = new JMenuBar();
Action menuAction = new AbstractAction(null, null){
public void actionPerformed(ActionEvent e) {
}
};
JMenu menu = new JMenu(menuAction);
menu.add(new JMenuItem("test"));
bar.add(menu);
setJMenuBar(bar);
pack();
}
public static void main(String[] args) {
new bug7036148();
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7034614
* @summary Tests that TitledBorder does not modify Insets
* @author Sergey Malenkov
*/
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
public class Test7034614 {
public static void main(String[] args) {
Graphics g = new BufferedImage(9, 9, 9).getGraphics();
BrokenBorder broken = new BrokenBorder();
TitledBorder titled = new TitledBorder(broken, broken.getClass().getName());
Insets insets = (Insets) broken.getBorderInsets(broken).clone();
titled.getBorderInsets(broken);
broken.validate(insets);
for (int i = 0; i < 10; i++) {
titled.paintBorder(broken, g, 0, 0, i, i);
broken.validate(insets);
titled.getBaseline(broken, i, i);
broken.validate(insets);
}
}
private static class BrokenBorder extends Component implements Border {
private Insets insets = new Insets(1, 2, 3, 4);
private void validate(Insets insets) {
if (!this.insets.equals(insets)) {
throw new Error("unexpected change");
}
}
public Insets getBorderInsets(Component c) {
return this.insets;
}
public boolean isBorderOpaque() {
return false;
}
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
}
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 7032791
* @author Alexander Potochkin
* @summary TableCellRenderer.getTableCellRendererComponent() doesn't accept null JTable with GTK+ L&F
*/
import javax.swing.*;
import javax.swing.plaf.synth.SynthLookAndFeel;
import javax.swing.table.TableCellRenderer;
public class bug7032791 {
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(new SynthLookAndFeel());
Object value = "Test value";
JTable table = new JTable(1, 1);
TableCellRenderer renderer = table.getDefaultRenderer(Object.class);
renderer.getTableCellRendererComponent(null, value, true, true, 0, 0);
System.out.println("OK");
}
}
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
@run main bug6796710 @run main bug6796710
*/ */
import sun.awt.SunToolkit;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
...@@ -91,7 +93,7 @@ public class bug6796710 { ...@@ -91,7 +93,7 @@ public class bug6796710 {
} }
}); });
robot.waitForIdle(); ((SunToolkit) SunToolkit.getDefaultToolkit()).realSync();
BufferedImage bufferedImage = getPnBottomImage(); BufferedImage bufferedImage = getPnBottomImage();
...@@ -101,7 +103,10 @@ public class bug6796710 { ...@@ -101,7 +103,10 @@ public class bug6796710 {
} }
}); });
robot.waitForIdle(); ((SunToolkit) SunToolkit.getDefaultToolkit()).realSync();
// On Linux platforms realSync doesn't guaranties setSize completion
Thread.sleep(1000);
if (!Util.compareBufferedImages(bufferedImage, getPnBottomImage())) { if (!Util.compareBufferedImages(bufferedImage, getPnBottomImage())) {
throw new RuntimeException("The test failed"); throw new RuntimeException("The test failed");
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 7003777
@summary Nonexistent html entities not parsed properly.
@author Pavel Porvatov
*/
import javax.swing.*;
import javax.swing.text.BadLocationException;
public class bug7003777 {
private static final String[] TEST_STRINGS = {
"&a",
"&aa",
"&a;",
"&aa;",
};
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JTextPane pane = new JTextPane();
pane.setContentType("text/html");
for (String testString : TEST_STRINGS) {
pane.setText(testString);
String parsedText;
try {
parsedText = pane.getDocument().getText(0, pane.getDocument().getLength());
} catch (BadLocationException e) {
throw new RuntimeException("The test failed.", e);
}
if (parsedText.charAt(0) != '\n') {
throw new RuntimeException("The first char should be \\n");
}
parsedText = parsedText.substring(1);
if (!testString.equals(parsedText)) {
throw new RuntimeException("The '" + testString +
"' string wasn't parsed correctly. Parsed value is '" + parsedText + "'");
}
}
}
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册