Skip to content
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

Issue #1313: New IgnoreCase feature to deserialize enums #1520

Merged
merged 1 commit into from
Feb 23, 2017
Merged
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 @@ -106,6 +106,14 @@ public enum DeserializationFeature implements ConfigFeature
*/
READ_ENUMS_USING_TO_STRING(false),

/**
* Feature that determines if Enum deserialization should be case sensitive or not.
* If enabled, Enum deserialization will ignore case.
* <p>
* Feature is disabled by default.
*/
READ_ENUMS_IGNORING_CASE(false),

/*
/******************************************************
* Error handling features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ private final Object _deserializeAltString(JsonParser p, DeserializationContext
if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
return null;
}
} else if (ctxt.isEnabled(DeserializationFeature.READ_ENUMS_IGNORING_CASE)) {
// [databind#1313]: Case insensitive enum deserialization
for (String key : lookup.keys()) {
if (key.equalsIgnoreCase(name)) {
return lookup.find(key);
}
}
} else if (!ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) {
// [databind#149]: Allow use of 'String' indexes as well -- unless prohibited (as per above)
char c = name.charAt(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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;

@SuppressWarnings("serial")
Expand Down Expand Up @@ -510,4 +511,56 @@ public void testExceptionFromCustomEnumKeyDeserializer() {
assertTrue(e.getMessage().contains("Undefined AnEnum"));
}
}

public void testFailWhenCaseSensitiveAndNameIsNotUpperCase() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();

try {
objectMapper.readValue("\"Jackson\"", TestEnum.class);
fail("InvalidFormatException expected");
} catch (InvalidFormatException e) {
assertTrue(e.getMessage().contains("value not one of declared Enum instance names: [JACKSON, OK, RULES]"));
}
}

public void testFailWhenCaseSensitiveAndToStringIsUpperCase() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);

try {
objectMapper.readValue("\"A\"", LowerCaseEnum.class);
fail("InvalidFormatException expected");
} catch (InvalidFormatException e) {
assertTrue(e.getMessage().contains("value not one of declared Enum instance names: [a, b, c]"));
}
}

public void testEnumDesIgnoringCaseWithLowerCaseContent() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.READ_ENUMS_IGNORING_CASE);

TestEnum testEnum = objectMapper.readValue("\"jackson\"", TestEnum.class);

assertEquals(TestEnum.JACKSON, testEnum);
}

public void testEnumDesIgnoringCaseWithUpperCaseToString() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
objectMapper.enable(DeserializationFeature.READ_ENUMS_IGNORING_CASE);

LowerCaseEnum lowerCaseEnum = objectMapper.readValue("\"A\"", LowerCaseEnum.class);

assertEquals(LowerCaseEnum.A, lowerCaseEnum);
}

public void testIgnoreCaseInEnumList() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.READ_ENUMS_IGNORING_CASE);

TestEnum[] testEnum = objectMapper.readValue("[\"jackson\", \"rules\"]", TestEnum[].class);

assertEquals(TestEnum.JACKSON, testEnum[0]);
assertEquals(TestEnum.RULES, testEnum[1]);
}
}