diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleTypeDescriptor.java index f1b0d40eafd2..75520f47062c 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleTypeDescriptor.java @@ -51,43 +51,33 @@ public Locale fromString(String string) { return Locale.ROOT; } - boolean separatorFound = false; - int position = 0; - char[] chars = string.toCharArray(); - - for ( int i = 0; i < chars.length; i++ ) { - // We just look for separators - if ( chars[i] == '_' ) { - if ( !separatorFound ) { - // On the first separator we know that we have at least a language - string = new String( chars, position, i - position ); - position = i + 1; - } - else { - // On the second separator we have to check whether there are more chars available for variant - if ( chars.length > i + 1 ) { - // There is a variant so add it to the constructor - return new Locale( string, new String( chars, position, i - position ), new String( chars, - i + 1, chars.length - i - 1 ) ); + Locale.Builder builder = new Locale.Builder(); + String[] parts = string.split("_"); + + for (int i = 0; i < parts.length; i++) { + String s = parts[i]; + switch (i) { + case 0: + builder.setLanguage(s); + break; + case 1: + builder.setRegion(s); + break; + case 2: + if (i < parts.length - 1 || !s.startsWith("#")) { + builder.setVariant(s); + break; } - else { - // No variant given, we just have language and country - return new Locale( string, new String( chars, position, i - position ), "" ); + case 3: + if (s.startsWith("#")) { + s = s.substring(1); } - } - - separatorFound = true; + builder.setScript(s); + break; } } - if ( !separatorFound ) { - // No separator found, there is only a language - return new Locale( string ); - } - else { - // Only one separator found, there is a language and a country - return new Locale( string, new String( chars, position, chars.length - position ) ); - } + return builder.build(); } @SuppressWarnings({ "unchecked" }) diff --git a/hibernate-core/src/test/java/org/hibernate/test/type/descriptor/java/LocaleTypeDescriptorTest.java b/hibernate-core/src/test/java/org/hibernate/test/type/descriptor/java/LocaleTypeDescriptorTest.java index ee2e63dd2502..ae98a3d7d5d0 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/type/descriptor/java/LocaleTypeDescriptorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/type/descriptor/java/LocaleTypeDescriptorTest.java @@ -25,18 +25,19 @@ public class LocaleTypeDescriptorTest extends BaseUnitTestCase { @Test public void testConversionFromString() { - assertEquals( toLocale( "de", null, null ), LocaleTypeDescriptor.INSTANCE.fromString( "de" ) ); - assertEquals( toLocale( "de", "DE", null ), LocaleTypeDescriptor.INSTANCE.fromString( "de_DE" ) ); - assertEquals( toLocale( null, "DE", null ), LocaleTypeDescriptor.INSTANCE.fromString( "_DE" ) ); - assertEquals( toLocale( null, null, "ch123" ), LocaleTypeDescriptor.INSTANCE.fromString( "__ch123" ) ); - assertEquals( toLocale( null, "DE", "ch123" ), LocaleTypeDescriptor.INSTANCE.fromString( "_DE_ch123" ) ); - assertEquals( toLocale( "de", null, "ch123" ), LocaleTypeDescriptor.INSTANCE.fromString( "de__ch123" ) ); - assertEquals( toLocale( "de", "DE", "ch123" ), LocaleTypeDescriptor.INSTANCE.fromString( "de_DE_ch123" ) ); - assertEquals( toLocale( "", "", "" ), LocaleTypeDescriptor.INSTANCE.fromString( "" ) ); + assertEquals( toLocale( "de", null, null, null ), LocaleTypeDescriptor.INSTANCE.fromString( "de" ) ); + assertEquals( toLocale( "de", "DE", null, null ), LocaleTypeDescriptor.INSTANCE.fromString( "de_DE" ) ); + assertEquals( toLocale( null, "DE", null, null ), LocaleTypeDescriptor.INSTANCE.fromString( "_DE" ) ); + assertEquals( toLocale( null, null, "ch123", null ), LocaleTypeDescriptor.INSTANCE.fromString( "__ch123" ) ); + assertEquals( toLocale( null, "DE", "ch123", null ), LocaleTypeDescriptor.INSTANCE.fromString( "_DE_ch123" ) ); + assertEquals( toLocale( "de", null, "ch123", null ), LocaleTypeDescriptor.INSTANCE.fromString( "de__ch123" ) ); + assertEquals( toLocale( "de", "DE", "ch123", null ), LocaleTypeDescriptor.INSTANCE.fromString( "de_DE_ch123" ) ); + assertEquals( toLocale( "zh", "HK", null, "Hant"), LocaleTypeDescriptor.INSTANCE.fromString( "zh_HK_#Hant" ) ); + assertEquals( toLocale( "", "", "", null ), LocaleTypeDescriptor.INSTANCE.fromString( "" ) ); assertEquals( Locale.ROOT, LocaleTypeDescriptor.INSTANCE.fromString( "" ) ); } - public Locale toLocale(String lang, String region, String variant) { + public Locale toLocale(String lang, String region, String variant, String script) { final Locale.Builder builder = new Locale.Builder(); if ( StringHelper.isNotEmpty( lang ) ) { builder.setLanguage( lang ); @@ -47,6 +48,9 @@ public Locale toLocale(String lang, String region, String variant) { if ( StringHelper.isNotEmpty( variant ) ) { builder.setVariant( variant ); } + if ( StringHelper.isNotEmpty( script ) ) { + builder.setScript( script ); + } return builder.build(); } }