8357281: sun.util.Locale.LanguageTag should be immutable
Reviewed-by: naoto, liach
This commit is contained in:
parent
917c1546f3
commit
2f530f89e0
@ -1691,37 +1691,37 @@ public final class Locale implements Cloneable, Serializable {
|
|||||||
LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
|
LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
String subtag = tag.getLanguage();
|
String subtag = tag.language();
|
||||||
if (!subtag.isEmpty()) {
|
if (!subtag.isEmpty()) {
|
||||||
buf.append(LanguageTag.canonicalizeLanguage(subtag));
|
buf.append(LanguageTag.canonicalizeLanguage(subtag));
|
||||||
}
|
}
|
||||||
|
|
||||||
subtag = tag.getScript();
|
subtag = tag.script();
|
||||||
if (!subtag.isEmpty()) {
|
if (!subtag.isEmpty()) {
|
||||||
buf.append(LanguageTag.SEP);
|
buf.append(LanguageTag.SEP);
|
||||||
buf.append(LanguageTag.canonicalizeScript(subtag));
|
buf.append(LanguageTag.canonicalizeScript(subtag));
|
||||||
}
|
}
|
||||||
|
|
||||||
subtag = tag.getRegion();
|
subtag = tag.region();
|
||||||
if (!subtag.isEmpty()) {
|
if (!subtag.isEmpty()) {
|
||||||
buf.append(LanguageTag.SEP);
|
buf.append(LanguageTag.SEP);
|
||||||
buf.append(LanguageTag.canonicalizeRegion(subtag));
|
buf.append(LanguageTag.canonicalizeRegion(subtag));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String>subtags = tag.getVariants();
|
List<String>subtags = tag.variants();
|
||||||
for (String s : subtags) {
|
for (String s : subtags) {
|
||||||
buf.append(LanguageTag.SEP);
|
buf.append(LanguageTag.SEP);
|
||||||
// preserve casing
|
// preserve casing
|
||||||
buf.append(s);
|
buf.append(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
subtags = tag.getExtensions();
|
subtags = tag.extensions();
|
||||||
for (String s : subtags) {
|
for (String s : subtags) {
|
||||||
buf.append(LanguageTag.SEP);
|
buf.append(LanguageTag.SEP);
|
||||||
buf.append(LanguageTag.canonicalizeExtension(s));
|
buf.append(LanguageTag.canonicalizeExtension(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
subtag = tag.getPrivateuse();
|
subtag = tag.privateuse();
|
||||||
if (!subtag.isEmpty()) {
|
if (!subtag.isEmpty()) {
|
||||||
if (buf.length() > 0) {
|
if (buf.length() > 0) {
|
||||||
buf.append(LanguageTag.SEP);
|
buf.append(LanguageTag.SEP);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2010, 2025, 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
|
||||||
@ -347,18 +347,18 @@ public final class InternalLocaleBuilder {
|
|||||||
*/
|
*/
|
||||||
public InternalLocaleBuilder setLanguageTag(LanguageTag langtag) {
|
public InternalLocaleBuilder setLanguageTag(LanguageTag langtag) {
|
||||||
clear();
|
clear();
|
||||||
if (!langtag.getExtlangs().isEmpty()) {
|
if (!langtag.extlangs().isEmpty()) {
|
||||||
language = langtag.getExtlangs().get(0);
|
language = langtag.extlangs().get(0);
|
||||||
} else {
|
} else {
|
||||||
String lang = langtag.getLanguage();
|
String lang = langtag.language();
|
||||||
if (!lang.equals(LanguageTag.UNDETERMINED)) {
|
if (!lang.equals(LanguageTag.UNDETERMINED)) {
|
||||||
language = lang;
|
language = lang;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
script = langtag.getScript();
|
script = langtag.script();
|
||||||
region = langtag.getRegion();
|
region = langtag.region();
|
||||||
|
|
||||||
List<String> bcpVariants = langtag.getVariants();
|
List<String> bcpVariants = langtag.variants();
|
||||||
if (!bcpVariants.isEmpty()) {
|
if (!bcpVariants.isEmpty()) {
|
||||||
StringBuilder var = new StringBuilder(bcpVariants.get(0));
|
StringBuilder var = new StringBuilder(bcpVariants.get(0));
|
||||||
int size = bcpVariants.size();
|
int size = bcpVariants.size();
|
||||||
@ -368,7 +368,7 @@ public final class InternalLocaleBuilder {
|
|||||||
variant = var.toString();
|
variant = var.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
setExtensions(langtag.getExtensions(), langtag.getPrivateuse());
|
setExtensions(langtag.extensions(), langtag.privateuse());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -42,30 +42,21 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
public class LanguageTag {
|
// List fields are unmodifiable
|
||||||
//
|
public record LanguageTag(String language, String script, String region, String privateuse,
|
||||||
// static fields
|
List<String> extlangs, List<String> variants, List<String> extensions) {
|
||||||
//
|
|
||||||
public static final String SEP = "-";
|
public static final String SEP = "-";
|
||||||
public static final String PRIVATEUSE = "x";
|
public static final String PRIVATEUSE = "x";
|
||||||
public static final 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";
|
||||||
|
private static final String EMPTY_SUBTAG = "";
|
||||||
|
private static final List<String> EMPTY_SUBTAGS = Collections.emptyList();
|
||||||
|
|
||||||
//
|
|
||||||
// Language subtag fields
|
|
||||||
//
|
|
||||||
private String language = ""; // language subtag
|
|
||||||
private String script = ""; // script subtag
|
|
||||||
private String region = ""; // region subtag
|
|
||||||
private String privateuse = ""; // privateuse
|
|
||||||
|
|
||||||
private List<String> extlangs = Collections.emptyList(); // extlang subtags
|
|
||||||
private List<String> variants = Collections.emptyList(); // variant subtags
|
|
||||||
private List<String> extensions = Collections.emptyList(); // extensions
|
|
||||||
// Map contains legacy language tags and its preferred mappings from
|
// Map contains legacy language tags and its preferred mappings from
|
||||||
// http://www.ietf.org/rfc/rfc5646.txt
|
// http://www.ietf.org/rfc/rfc5646.txt
|
||||||
// Keys are lower-case strings.
|
// Keys are lower-case strings.
|
||||||
private static final Map<String, String[]> LEGACY = new HashMap<>();
|
private static final Map<String, String[]> LEGACY;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// grandfathered = irregular ; non-redundant tags registered
|
// grandfathered = irregular ; non-redundant tags registered
|
||||||
@ -128,14 +119,12 @@ public class LanguageTag {
|
|||||||
{"zh-min-nan", "nan"},
|
{"zh-min-nan", "nan"},
|
||||||
{"zh-xiang", "hsn"},
|
{"zh-xiang", "hsn"},
|
||||||
};
|
};
|
||||||
|
LEGACY = HashMap.newHashMap(entries.length);
|
||||||
for (String[] e : entries) {
|
for (String[] e : entries) {
|
||||||
LEGACY.put(LocaleUtils.toLowerString(e[0]), e);
|
LEGACY.put(LocaleUtils.toLowerString(e[0]), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LanguageTag() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BNF in RFC5646
|
* BNF in RFC5646
|
||||||
*
|
*
|
||||||
@ -195,17 +184,27 @@ public class LanguageTag {
|
|||||||
itr = new StringTokenIterator(languageTag, SEP);
|
itr = new StringTokenIterator(languageTag, SEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
LanguageTag tag = new LanguageTag();
|
String language = parseLanguage(itr, pp);
|
||||||
|
List<String> extlangs;
|
||||||
|
String script;
|
||||||
|
String region;
|
||||||
|
List<String> variants;
|
||||||
|
List<String> extensions;
|
||||||
// langtag must start with either language or privateuse
|
// langtag must start with either language or privateuse
|
||||||
if (tag.parseLanguage(itr, pp)) {
|
if (!language.isEmpty()) {
|
||||||
tag.parseExtlangs(itr, pp);
|
extlangs = parseExtlangs(itr, pp);
|
||||||
tag.parseScript(itr, pp);
|
script = parseScript(itr, pp);
|
||||||
tag.parseRegion(itr, pp);
|
region = parseRegion(itr, pp);
|
||||||
tag.parseVariants(itr, pp);
|
variants = parseVariants(itr, pp);
|
||||||
tag.parseExtensions(itr, pp, errorMsg);
|
extensions = parseExtensions(itr, pp, errorMsg);
|
||||||
|
} else {
|
||||||
|
extlangs = EMPTY_SUBTAGS;
|
||||||
|
script = EMPTY_SUBTAG;
|
||||||
|
region = EMPTY_SUBTAG;
|
||||||
|
variants = EMPTY_SUBTAGS;
|
||||||
|
extensions = EMPTY_SUBTAGS;
|
||||||
}
|
}
|
||||||
tag.parsePrivateuse(itr, pp, errorMsg);
|
String privateuse = parsePrivateuse(itr, pp, errorMsg);
|
||||||
|
|
||||||
if (!itr.isDone() && pp.getErrorIndex() == -1) {
|
if (!itr.isDone() && pp.getErrorIndex() == -1) {
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
@ -221,110 +220,94 @@ public class LanguageTag {
|
|||||||
throw new IllformedLocaleException(errorMsg.toString(), pp.getErrorIndex());
|
throw new IllformedLocaleException(errorMsg.toString(), pp.getErrorIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return new LanguageTag(language, script, region, privateuse, extlangs, variants, extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Language subtag parsers
|
// Language subtag parsers
|
||||||
//
|
//
|
||||||
|
|
||||||
private boolean parseLanguage(StringTokenIterator itr, ParsePosition pp) {
|
private static String parseLanguage(StringTokenIterator itr, ParsePosition pp) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
if (isLanguage(s)) {
|
if (isLanguage(s)) {
|
||||||
found = true;
|
|
||||||
language = s;
|
|
||||||
pp.setIndex(itr.currentEnd());
|
pp.setIndex(itr.currentEnd());
|
||||||
itr.next();
|
itr.next();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseExtlangs(StringTokenIterator itr, ParsePosition pp) {
|
private static List<String> parseExtlangs(StringTokenIterator itr, ParsePosition pp) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAGS;
|
||||||
}
|
}
|
||||||
|
List<String> extlangs = null;
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
while (!itr.isDone()) {
|
while (!itr.isDone()) {
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
if (!isExtlang(s)) {
|
if (!isExtlang(s)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
found = true;
|
if (extlangs == null) {
|
||||||
if (extlangs.isEmpty()) {
|
|
||||||
extlangs = new ArrayList<>(3);
|
extlangs = new ArrayList<>(3);
|
||||||
}
|
}
|
||||||
extlangs.add(s);
|
extlangs.add(s);
|
||||||
pp.setIndex(itr.currentEnd());
|
pp.setIndex(itr.currentEnd());
|
||||||
itr.next();
|
itr.next();
|
||||||
|
|
||||||
if (extlangs.size() == 3) {
|
if (extlangs.size() == 3) {
|
||||||
// Maximum 3 extlangs
|
// Maximum 3 extlangs
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return extlangs == null ? EMPTY_SUBTAGS :
|
||||||
return found;
|
Collections.unmodifiableList(extlangs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseScript(StringTokenIterator itr, ParsePosition pp) {
|
private static String parseScript(StringTokenIterator itr, ParsePosition pp) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
if (isScript(s)) {
|
if (isScript(s)) {
|
||||||
found = true;
|
|
||||||
script = s;
|
|
||||||
pp.setIndex(itr.currentEnd());
|
pp.setIndex(itr.currentEnd());
|
||||||
itr.next();
|
itr.next();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseRegion(StringTokenIterator itr, ParsePosition pp) {
|
private static String parseRegion(StringTokenIterator itr, ParsePosition pp) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
if (isRegion(s)) {
|
if (isRegion(s)) {
|
||||||
found = true;
|
|
||||||
region = s;
|
|
||||||
pp.setIndex(itr.currentEnd());
|
pp.setIndex(itr.currentEnd());
|
||||||
itr.next();
|
itr.next();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseVariants(StringTokenIterator itr, ParsePosition pp) {
|
private static List<String> parseVariants(StringTokenIterator itr, ParsePosition pp) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAGS;
|
||||||
}
|
}
|
||||||
|
List<String> variants = null;
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
while (!itr.isDone()) {
|
while (!itr.isDone()) {
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
if (!isVariant(s)) {
|
if (!isVariant(s)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
found = true;
|
if (variants == null) {
|
||||||
if (variants.isEmpty()) {
|
|
||||||
variants = new ArrayList<>(3);
|
variants = new ArrayList<>(3);
|
||||||
}
|
}
|
||||||
variants.add(s);
|
variants.add(s);
|
||||||
@ -332,16 +315,16 @@ public class LanguageTag {
|
|||||||
itr.next();
|
itr.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return variants == null ? EMPTY_SUBTAGS :
|
||||||
|
Collections.unmodifiableList(variants);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseExtensions(StringTokenIterator itr, ParsePosition pp,
|
private static List<String> parseExtensions(StringTokenIterator itr, ParsePosition pp,
|
||||||
StringBuilder err) {
|
StringBuilder err) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAGS;
|
||||||
}
|
}
|
||||||
|
List<String> extensions = null;
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
while (!itr.isDone()) {
|
while (!itr.isDone()) {
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
@ -368,26 +351,24 @@ public class LanguageTag {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extensions.isEmpty()) {
|
if (extensions == null) {
|
||||||
extensions = new ArrayList<>(4);
|
extensions = new ArrayList<>(4);
|
||||||
}
|
}
|
||||||
extensions.add(sb.toString());
|
extensions.add(sb.toString());
|
||||||
found = true;
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return extensions == null ? EMPTY_SUBTAGS :
|
||||||
|
Collections.unmodifiableList(extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parsePrivateuse(StringTokenIterator itr, ParsePosition pp,
|
private static String parsePrivateuse(StringTokenIterator itr, ParsePosition pp,
|
||||||
StringBuilder err) {
|
StringBuilder err) {
|
||||||
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
if (itr.isDone() || pp.getErrorIndex() != -1) {
|
||||||
return false;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
String s = itr.current();
|
String s = itr.current();
|
||||||
if (isPrivateusePrefix(s)) {
|
if (isPrivateusePrefix(s)) {
|
||||||
int start = itr.currentStart();
|
int start = itr.currentStart();
|
||||||
@ -410,12 +391,11 @@ public class LanguageTag {
|
|||||||
pp.setErrorIndex(start);
|
pp.setErrorIndex(start);
|
||||||
err.append("Incomplete privateuse");
|
err.append("Incomplete privateuse");
|
||||||
} else {
|
} else {
|
||||||
privateuse = sb.toString();
|
return sb.toString();
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String caseFoldTag(String tag) {
|
public static String caseFoldTag(String tag) {
|
||||||
@ -462,48 +442,50 @@ public class LanguageTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LanguageTag parseLocale(BaseLocale baseLocale, LocaleExtensions localeExtensions) {
|
public static LanguageTag parseLocale(BaseLocale baseLocale, LocaleExtensions localeExtensions) {
|
||||||
LanguageTag tag = new LanguageTag();
|
|
||||||
|
|
||||||
String language = baseLocale.getLanguage();
|
String language = EMPTY_SUBTAG;
|
||||||
String script = baseLocale.getScript();
|
String script = EMPTY_SUBTAG;
|
||||||
String region = baseLocale.getRegion();
|
String region = EMPTY_SUBTAG;
|
||||||
String variant = baseLocale.getVariant();
|
|
||||||
|
String baseLanguage = baseLocale.getLanguage();
|
||||||
|
String baseScript = baseLocale.getScript();
|
||||||
|
String baseRegion = baseLocale.getRegion();
|
||||||
|
String baseVariant = baseLocale.getVariant();
|
||||||
|
|
||||||
boolean hasSubtag = false;
|
boolean hasSubtag = false;
|
||||||
|
|
||||||
String privuseVar = null; // store ill-formed variant subtags
|
String privuseVar = null; // store ill-formed variant subtags
|
||||||
|
|
||||||
if (isLanguage(language)) {
|
if (isLanguage(baseLanguage)) {
|
||||||
// Convert a deprecated language code to its new code
|
// Convert a deprecated language code to its new code
|
||||||
if (language.equals("iw")) {
|
baseLanguage = switch (baseLanguage) {
|
||||||
language = "he";
|
case "iw" -> "he";
|
||||||
} else if (language.equals("ji")) {
|
case "ji" -> "yi";
|
||||||
language = "yi";
|
case "in" -> "id";
|
||||||
} else if (language.equals("in")) {
|
default -> baseLanguage;
|
||||||
language = "id";
|
};
|
||||||
}
|
language = baseLanguage;
|
||||||
tag.language = language;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isScript(script)) {
|
if (isScript(baseScript)) {
|
||||||
tag.script = canonicalizeScript(script);
|
script = canonicalizeScript(baseScript);
|
||||||
hasSubtag = true;
|
hasSubtag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRegion(region)) {
|
if (isRegion(baseRegion)) {
|
||||||
tag.region = canonicalizeRegion(region);
|
region = canonicalizeRegion(baseRegion);
|
||||||
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 (language.equals("no") && region.equals("NO") && baseVariant.equals("NY")) {
|
||||||
tag.language = "nn";
|
language = "nn";
|
||||||
variant = "";
|
baseVariant = EMPTY_SUBTAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variant.isEmpty()) {
|
|
||||||
List<String> variants = null;
|
List<String> variants = null;
|
||||||
StringTokenIterator varitr = new StringTokenIterator(variant, BaseLocale.SEP);
|
if (!baseVariant.isEmpty()) {
|
||||||
|
StringTokenIterator varitr = new StringTokenIterator(baseVariant, BaseLocale.SEP);
|
||||||
while (!varitr.isDone()) {
|
while (!varitr.isDone()) {
|
||||||
String var = varitr.current();
|
String var = varitr.current();
|
||||||
if (!isVariant(var)) {
|
if (!isVariant(var)) {
|
||||||
@ -516,7 +498,6 @@ public class LanguageTag {
|
|||||||
varitr.next();
|
varitr.next();
|
||||||
}
|
}
|
||||||
if (variants != null) {
|
if (variants != null) {
|
||||||
tag.variants = variants;
|
|
||||||
hasSubtag = true;
|
hasSubtag = true;
|
||||||
}
|
}
|
||||||
if (!varitr.isDone()) {
|
if (!varitr.isDone()) {
|
||||||
@ -556,7 +537,6 @@ public class LanguageTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (extensions != null) {
|
if (extensions != null) {
|
||||||
tag.extensions = extensions;
|
|
||||||
hasSubtag = true;
|
hasSubtag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,59 +550,21 @@ public class LanguageTag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (privateuse != null) {
|
if (language.isEmpty() && (hasSubtag || privateuse == null)) {
|
||||||
tag.privateuse = privateuse;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag.language.isEmpty() && (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;
|
language = UNDETERMINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
privateuse = privateuse == null ? EMPTY_SUBTAG : privateuse;
|
||||||
}
|
extensions = extensions == null ? EMPTY_SUBTAGS :
|
||||||
|
Collections.unmodifiableList(extensions);
|
||||||
|
variants = variants == null ? EMPTY_SUBTAGS :
|
||||||
|
Collections.unmodifiableList(variants);
|
||||||
|
|
||||||
//
|
// extlangs always empty for locale parse
|
||||||
// Getter methods for language subtag fields
|
return new LanguageTag(language, script, region, privateuse, EMPTY_SUBTAGS, variants, extensions);
|
||||||
//
|
|
||||||
|
|
||||||
public String getLanguage() {
|
|
||||||
return language;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getExtlangs() {
|
|
||||||
if (extlangs.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList(extlangs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getScript() {
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegion() {
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getVariants() {
|
|
||||||
if (variants.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList(variants);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getExtensions() {
|
|
||||||
if (extensions.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList(extensions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrivateuse() {
|
|
||||||
return privateuse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user