Skip to content

Fix #1948 can force deser Locale use java style #1951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ public static class Std extends FromStringDeserializer<Object>
public final static int STD_INET_ADDRESS = 11;
public final static int STD_INET_SOCKET_ADDRESS = 12;
public final static int STD_STRING_BUILDER = 13;
/**
* If you are using java's {@linkplain Locale#toString()} serialize Locale
* (split language, country and variant with '_')<br>
* You can force jackson deserialize String to Locale with java Locale style.<br>
* config: {@linkplain System#setProperty(String, String) System.setProperty("jackson.std.locale.de.java", "not empty")}
*/
public final static String STD_LOCALE_DE_JAVA = "jackson.std.locale.de.java";

protected final int _kind;

Expand Down Expand Up @@ -255,6 +262,10 @@ protected Object _deserialize(String value, DeserializationContext ctxt) throws
return Pattern.compile(value);
case STD_LOCALE:
{
if (!System.getProperty(STD_LOCALE_DE_JAVA, "").isEmpty()) {
return deJavaLocale(value);
}

int ix = _firstHyphenOrUnderscore(value);
if (ix < 0) { // single argument
return new Locale(value);
Expand Down Expand Up @@ -330,5 +341,30 @@ protected int _firstHyphenOrUnderscore(String str)
}
return -1;
}

/** see {@link Locale#toString()}, but ignore extends */
private Locale deJavaLocale(String value) {
if (value.isEmpty()) {
return new Locale("");
}

int extStart = value.indexOf("_#");
if (extStart != -1) value = value.substring(0, extStart);

String language = value, country = "", variant = "";
int pos1 = value.indexOf('_');
if (pos1 != -1) {
language = value.substring(0, pos1++);

int pos2 = value.indexOf('_', pos1);
if (pos2 == -1) {
country = value.substring(pos1);
} else {
country = value.substring(pos1, pos2);
variant = value.substring(pos2 + 1);
}
}
return new Locale(language, country, variant);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.FromStringDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.module.SimpleModule;
Expand Down Expand Up @@ -132,6 +133,23 @@ public void testFile() throws Exception

public void testLocale() throws IOException
{
// [databind #1948]
String deJavaKey = FromStringDeserializer.Std.STD_LOCALE_DE_JAVA;
String old = System.setProperty(deJavaKey, "1");
try {
assertLocale(new Locale(""));
assertLocale(new Locale("en"));
assertLocale(new Locale("en", "US"));
assertLocale(new Locale("zh", "CN"));
assertLocale(new Locale("zh-hant", "CN"));
} finally {
if (old == null) {
System.getProperties().remove(deJavaKey);
} else {
System.setProperty(deJavaKey, old);
}
}

assertEquals(new Locale("en"), MAPPER.readValue(quote("en"), Locale.class));
assertEquals(new Locale("es", "ES"), MAPPER.readValue(quote("es_ES"), Locale.class));
assertEquals(new Locale("FI", "fi", "savo"),
Expand All @@ -144,6 +162,10 @@ public void testLocale() throws IOException
assertSame(Locale.ROOT, loc);
}

private void assertLocale(Locale loc) throws IOException {
assertEquals(loc, MAPPER.readValue(MAPPER.writeValueAsString(loc), Locale.class));
}

public void testCharSequence() throws IOException
{
CharSequence cs = MAPPER.readValue("\"abc\"", CharSequence.class);
Expand Down