195 itr = new StringTokenIterator(gfmap[1], SEP);
196 } else {
197 itr = new StringTokenIterator(languageTag, SEP);
198 }
199
200 LanguageTag tag = new LanguageTag();
201
202 // langtag must start with either language or privateuse
203 if (tag.parseLanguage(itr, sts)) {
204 tag.parseExtlangs(itr, sts);
205 tag.parseScript(itr, sts);
206 tag.parseRegion(itr, sts);
207 tag.parseVariants(itr, sts);
208 tag.parseExtensions(itr, sts);
209 }
210 tag.parsePrivateuse(itr, sts);
211
212 if (!itr.isDone() && !sts.isError()) {
213 String s = itr.current();
214 sts.errorIndex = itr.currentStart();
215 if (s.length() == 0) {
216 sts.errorMsg = "Empty subtag";
217 } else {
218 sts.errorMsg = "Invalid subtag: " + s;
219 }
220 }
221
222 return tag;
223 }
224
225 //
226 // Language subtag parsers
227 //
228
229 private boolean parseLanguage(StringTokenIterator itr, ParseStatus sts) {
230 if (itr.isDone() || sts.isError()) {
231 return false;
232 }
233
234 boolean found = false;
235
437 }
438 tag.language = language;
439 }
440
441 if (isScript(script)) {
442 tag.script = canonicalizeScript(script);
443 hasSubtag = true;
444 }
445
446 if (isRegion(region)) {
447 tag.region = canonicalizeRegion(region);
448 hasSubtag = true;
449 }
450
451 // Special handling for no_NO_NY - use nn_NO for language tag
452 if (tag.language.equals("no") && tag.region.equals("NO") && variant.equals("NY")) {
453 tag.language = "nn";
454 variant = "";
455 }
456
457 if (variant.length() > 0) {
458 List<String> variants = null;
459 StringTokenIterator varitr = new StringTokenIterator(variant, BaseLocale.SEP);
460 while (!varitr.isDone()) {
461 String var = varitr.current();
462 if (!isVariant(var)) {
463 break;
464 }
465 if (variants == null) {
466 variants = new ArrayList<>();
467 }
468 variants.add(var); // Do not canonicalize!
469 varitr.next();
470 }
471 if (variants != null) {
472 tag.variants = variants;
473 hasSubtag = true;
474 }
475 if (!varitr.isDone()) {
476 // ill-formed variant subtags
477 StringJoiner sj = new StringJoiner(SEP);
510
511 if (extensions != null) {
512 tag.extensions = extensions;
513 hasSubtag = true;
514 }
515
516 // append ill-formed variant subtags to private use
517 if (privuseVar != null) {
518 if (privateuse == null) {
519 privateuse = PRIVUSE_VARIANT_PREFIX + SEP + privuseVar;
520 } else {
521 privateuse = privateuse + SEP + PRIVUSE_VARIANT_PREFIX
522 + SEP + privuseVar.replace(BaseLocale.SEP, SEP);
523 }
524 }
525
526 if (privateuse != null) {
527 tag.privateuse = privateuse;
528 }
529
530 if (tag.language.length() == 0 && (hasSubtag || privateuse == null)) {
531 // use lang "und" when 1) no language is available AND
532 // 2) any of other subtags other than private use are available or
533 // no private use tag is available
534 tag.language = UNDETERMINED;
535 }
536
537 return tag;
538 }
539
540 //
541 // Getter methods for language subtag fields
542 //
543
544 public String getLanguage() {
545 return language;
546 }
547
548 public List<String> getExtlangs() {
549 if (extlangs.isEmpty()) {
550 return Collections.emptyList();
695 public static String canonicalizeExtensionSingleton(String s) {
696 return LocaleUtils.toLowerString(s);
697 }
698
699 public static String canonicalizeExtensionSubtag(String s) {
700 return LocaleUtils.toLowerString(s);
701 }
702
703 public static String canonicalizePrivateuse(String s) {
704 return LocaleUtils.toLowerString(s);
705 }
706
707 public static String canonicalizePrivateuseSubtag(String s) {
708 return LocaleUtils.toLowerString(s);
709 }
710
711 @Override
712 public String toString() {
713 StringBuilder sb = new StringBuilder();
714
715 if (language.length() > 0) {
716 sb.append(language);
717
718 for (String extlang : extlangs) {
719 sb.append(SEP).append(extlang);
720 }
721
722 if (script.length() > 0) {
723 sb.append(SEP).append(script);
724 }
725
726 if (region.length() > 0) {
727 sb.append(SEP).append(region);
728 }
729
730 for (String variant : variants) {
731 sb.append(SEP).append(variant);
732 }
733
734 for (String extension : extensions) {
735 sb.append(SEP).append(extension);
736 }
737 }
738 if (privateuse.length() > 0) {
739 if (sb.length() > 0) {
740 sb.append(SEP);
741 }
742 sb.append(privateuse);
743 }
744
745 return sb.toString();
746 }
747 }
|
195 itr = new StringTokenIterator(gfmap[1], SEP);
196 } else {
197 itr = new StringTokenIterator(languageTag, SEP);
198 }
199
200 LanguageTag tag = new LanguageTag();
201
202 // langtag must start with either language or privateuse
203 if (tag.parseLanguage(itr, sts)) {
204 tag.parseExtlangs(itr, sts);
205 tag.parseScript(itr, sts);
206 tag.parseRegion(itr, sts);
207 tag.parseVariants(itr, sts);
208 tag.parseExtensions(itr, sts);
209 }
210 tag.parsePrivateuse(itr, sts);
211
212 if (!itr.isDone() && !sts.isError()) {
213 String s = itr.current();
214 sts.errorIndex = itr.currentStart();
215 if (s.isEmpty()) {
216 sts.errorMsg = "Empty subtag";
217 } else {
218 sts.errorMsg = "Invalid subtag: " + s;
219 }
220 }
221
222 return tag;
223 }
224
225 //
226 // Language subtag parsers
227 //
228
229 private boolean parseLanguage(StringTokenIterator itr, ParseStatus sts) {
230 if (itr.isDone() || sts.isError()) {
231 return false;
232 }
233
234 boolean found = false;
235
437 }
438 tag.language = language;
439 }
440
441 if (isScript(script)) {
442 tag.script = canonicalizeScript(script);
443 hasSubtag = true;
444 }
445
446 if (isRegion(region)) {
447 tag.region = canonicalizeRegion(region);
448 hasSubtag = true;
449 }
450
451 // Special handling for no_NO_NY - use nn_NO for language tag
452 if (tag.language.equals("no") && tag.region.equals("NO") && variant.equals("NY")) {
453 tag.language = "nn";
454 variant = "";
455 }
456
457 if (!variant.isEmpty()) {
458 List<String> variants = null;
459 StringTokenIterator varitr = new StringTokenIterator(variant, BaseLocale.SEP);
460 while (!varitr.isDone()) {
461 String var = varitr.current();
462 if (!isVariant(var)) {
463 break;
464 }
465 if (variants == null) {
466 variants = new ArrayList<>();
467 }
468 variants.add(var); // Do not canonicalize!
469 varitr.next();
470 }
471 if (variants != null) {
472 tag.variants = variants;
473 hasSubtag = true;
474 }
475 if (!varitr.isDone()) {
476 // ill-formed variant subtags
477 StringJoiner sj = new StringJoiner(SEP);
510
511 if (extensions != null) {
512 tag.extensions = extensions;
513 hasSubtag = true;
514 }
515
516 // append ill-formed variant subtags to private use
517 if (privuseVar != null) {
518 if (privateuse == null) {
519 privateuse = PRIVUSE_VARIANT_PREFIX + SEP + privuseVar;
520 } else {
521 privateuse = privateuse + SEP + PRIVUSE_VARIANT_PREFIX
522 + SEP + privuseVar.replace(BaseLocale.SEP, SEP);
523 }
524 }
525
526 if (privateuse != null) {
527 tag.privateuse = privateuse;
528 }
529
530 if (tag.language.isEmpty() && (hasSubtag || privateuse == null)) {
531 // use lang "und" when 1) no language is available AND
532 // 2) any of other subtags other than private use are available or
533 // no private use tag is available
534 tag.language = UNDETERMINED;
535 }
536
537 return tag;
538 }
539
540 //
541 // Getter methods for language subtag fields
542 //
543
544 public String getLanguage() {
545 return language;
546 }
547
548 public List<String> getExtlangs() {
549 if (extlangs.isEmpty()) {
550 return Collections.emptyList();
695 public static String canonicalizeExtensionSingleton(String s) {
696 return LocaleUtils.toLowerString(s);
697 }
698
699 public static String canonicalizeExtensionSubtag(String s) {
700 return LocaleUtils.toLowerString(s);
701 }
702
703 public static String canonicalizePrivateuse(String s) {
704 return LocaleUtils.toLowerString(s);
705 }
706
707 public static String canonicalizePrivateuseSubtag(String s) {
708 return LocaleUtils.toLowerString(s);
709 }
710
711 @Override
712 public String toString() {
713 StringBuilder sb = new StringBuilder();
714
715 if (!language.isEmpty()) {
716 sb.append(language);
717
718 for (String extlang : extlangs) {
719 sb.append(SEP).append(extlang);
720 }
721
722 if (!script.isEmpty()) {
723 sb.append(SEP).append(script);
724 }
725
726 if (!region.isEmpty()) {
727 sb.append(SEP).append(region);
728 }
729
730 for (String variant : variants) {
731 sb.append(SEP).append(variant);
732 }
733
734 for (String extension : extensions) {
735 sb.append(SEP).append(extension);
736 }
737 }
738 if (!privateuse.isEmpty()) {
739 if (sb.length() > 0) {
740 sb.append(SEP);
741 }
742 sb.append(privateuse);
743 }
744
745 return sb.toString();
746 }
747 }
|