@@ -131,11 +131,12 @@ public class LocaleResources {
131131
132132 // Input Skeleton map for "preferred" and "allowed"
133133 // Map<"preferred"/"allowed", Map<"region", "skeleton">>
134- private static Map <String , Map <String , String >> inputSkeletons ;
134+ private static final LazyConstant <Map <String , Map <String , String >>> INPUT_SKELETONS =
135+ LazyConstant .of (LocaleResources ::initSkeletons );
135136
136137 // Skeletons for "j" and "C" input skeleton symbols for this locale
137- private String jPattern ;
138- private String CPattern ;
138+ private final LazyConstant < String > jPattern = LazyConstant . of (() -> resolveInputSkeleton ( "preferred" )) ;
139+ private final LazyConstant < String > CPattern = LazyConstant . of ( this :: initCPattern ) ;
139140
140141 LocaleResources (ResourceBundleBasedAdapter adapter , Locale locale ) {
141142 this .locale = locale ;
@@ -607,8 +608,6 @@ public String getLocalizedPattern(String requestedTemplate, String calType) {
607608 }
608609
609610 private String getLocalizedPatternImpl (String requestedTemplate , String calType ) {
610- initSkeletonIfNeeded ();
611-
612611 // input skeleton substitution
613612 var skeleton = substituteInputSkeletons (requestedTemplate );
614613
@@ -657,12 +656,14 @@ private String matchSkeleton(String skeleton, String calType) {
657656 .orElse (null );
658657 }
659658
660- private void initSkeletonIfNeeded () {
659+ private static Map < String , Map < String , String >> initSkeletons () {
661660 // "preferred"/"allowed" input skeleton maps
662- if (inputSkeletons == null ) {
663- inputSkeletons = new HashMap <>();
664- Pattern p = Pattern .compile ("([^:]+):([^;]+);" );
665- ResourceBundle r = localeData .getDateFormatData (Locale .ROOT );
661+ var inputSkeletons = new HashMap <String , Map <String , String >>();
662+ Pattern p = Pattern .compile ("([^:]+):([^;]+);" );
663+
664+ // CLDR is guaranteed to implement ResourceBundleBasedAdapter
665+ if (LocaleProviderAdapter .forType (LocaleProviderAdapter .Type .CLDR ) instanceof ResourceBundleBasedAdapter rbba ) {
666+ var r = rbba .getLocaleData ().getDateFormatData (Locale .ROOT );
666667 Stream .of ("preferred" , "allowed" ).forEach (type -> {
667668 var inputRegionsKey = SKELETON_INPUT_REGIONS_KEY + "." + type ;
668669 Map <String , String > typeMap = new HashMap <>();
@@ -676,19 +677,17 @@ private void initSkeletonIfNeeded() {
676677 inputSkeletons .put (type , typeMap );
677678 });
678679 }
680+ return inputSkeletons ;
681+ }
679682
680- // j/C patterns for this locale
681- if (jPattern == null ) {
682- jPattern = resolveInputSkeleton ("preferred" );
683- CPattern = resolveInputSkeleton ("allowed" );
684- // hack: "allowed" contains reversed order for hour/period, e.g, "hB" which should be "Bh" as a skeleton
685- if (CPattern .length () == 2 ) {
686- var ba = new byte [2 ];
687- ba [0 ] = (byte )CPattern .charAt (1 );
688- ba [1 ] = (byte )CPattern .charAt (0 );
689- CPattern = new String (ba );
690- }
683+ private String initCPattern () {
684+ // C patterns for this locale
685+ var cp = resolveInputSkeleton ("allowed" );
686+ // hack: "allowed" contains reversed order for hour/period, e.g, "hB" which should be "Bh" as a skeleton
687+ if (cp .length () == 2 ) {
688+ cp = "" + cp .charAt (1 ) + cp .charAt (0 );
691689 }
690+ return cp ;
692691 }
693692
694693 /**
@@ -698,11 +697,22 @@ private void initSkeletonIfNeeded() {
698697 * @return resolved skeletons for this locale, defaults to "h" if none found.
699698 */
700699 private String resolveInputSkeleton (String type ) {
701- var regionToSkeletonMap = inputSkeletons .get (type );
702- return regionToSkeletonMap .getOrDefault (locale .getLanguage () + "-" + locale .getCountry (),
703- regionToSkeletonMap .getOrDefault (locale .getCountry (),
704- regionToSkeletonMap .getOrDefault (locale .getLanguage () + "-001" ,
705- regionToSkeletonMap .getOrDefault ("001" , "h" ))));
700+ var regionToSkeletonMap = INPUT_SKELETONS .get ().get (type );
701+
702+ if (regionToSkeletonMap != null ) {
703+ for (var region : new String [] {
704+ locale .getLanguage () + "-" + locale .getCountry (),
705+ locale .getCountry (),
706+ locale .getLanguage () + "-001" ,
707+ "001" }) {
708+ var hour = regionToSkeletonMap .get (region );
709+ if (hour != null ) {
710+ return hour ;
711+ }
712+ }
713+ }
714+
715+ return "h" ;
706716 }
707717
708718 /**
@@ -714,8 +724,8 @@ private String resolveInputSkeleton(String type) {
714724 */
715725 private String substituteInputSkeletons (String requestedTemplate ) {
716726 var cCount = requestedTemplate .chars ().filter (c -> c == 'C' ).count ();
717- return requestedTemplate .replaceAll ("j" , jPattern )
718- .replaceFirst ("C+" , CPattern .replaceAll ("([hkHK])" , "$1" .repeat ((int )cCount )));
727+ return requestedTemplate .replaceAll ("j" , jPattern . get () )
728+ .replaceFirst ("C+" , CPattern .get (). replaceAll ("([hkHK])" , "$1" .repeat ((int )cCount )));
719729 }
720730
721731 /**
0 commit comments