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

Custom property naming in present property json type resolver #1

Merged

Conversation

marek-sontag
Copy link
Member

@marek-sontag marek-sontag commented Sep 17, 2020

Although PresentPropertyJsonTypeResolver works well for lowercase json properties (e.g. in json: "foo", in TypeProvider: "FOO"), the problem shows up when json properties are in camel case or with any character not allowed in enum values names (e.g. json property is "userName").
Here I introduced NamedPropertyTypeProvider which one can use in such cases. PresentPropertyJsonTypeResolver can works with both kind of providers.

return constant.toString().toLowerCase();
}

private List<Type> getAllInterfaces(Class<?> type) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is copied from JsonTypeResolverFactory. Maybe it should extracted to some util class? Or maybe assume that the NamedPropertyTypeProvider have to be implemented directly on enum - then, instead of this method, calling constant.getClass().getInterfaces() would be enough. What do you think?


public interface NamedPropertyTypeProvider extends TypeProvider {

String getJsonPropertyName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of flexibility doesn't make sense to me, it seems equal to just implementing the JsonTypeResolver manually on the use case site.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in simple case, when you have one set of types (like one TypeProvider). But if you have N sets of types, you add only N NamedPropertyTypeProvider - all handled by one PresentPropertyJsonTypeResolver. Implementing it on use case side would require either N custom resolvers (all very similar) or one generic - but here resolving a target type need to be added (as it is already done in JsonTypeResolverFactory).

@@ -14,11 +14,33 @@ public PresentPropertyJsonTypeResolver(Class<E> type) {
@Override
public final Class<?> resolve(Map<String, Object> json) {
for (E constant : type.getEnumConstants()) {
if (json.containsKey(constant.toString().toLowerCase())) {
if (json.containsKey(resolvePropertyName(constant))) {
Copy link
Member

@lpandzic lpandzic Sep 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now evident that default use case of camelCase field to camelCase json property doesn't work (it works only for simple names with which there's no casing actually).
I suggest you add guava(29.0-jre) to this project and introduce CaseFormat field to this class which should be overridable by a specific constructor and for current one the default should be CaseFormat.LOWER_CAMEL.
Then instead of new resolvePropertyName(constant) and related new infrastructure CaseFormat.UPPER_UNDERSCORE.to(caseFormat, constant.toString()) on this line should be sufficient.

Suggested change
if (json.containsKey(resolvePropertyName(constant))) {
if (json.containsKey(CaseFormat.UPPER_UNDERSCORE.to(caseFormat, constant.toString()))) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll try with this approach 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed as you suggested. Tests as well as readme tuned to reflect current changes.

README.md Outdated
@Value
static class RoadBike implements Bike {

private final String road_bike;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's never a convention to use snakeCase in field names, you should use @JsonNaming instead

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@marek-sontag marek-sontag merged commit 2722e8e into master Sep 22, 2020
@marek-sontag marek-sontag deleted the custom-property-naming-in-PresentPropertuJsonTypeResolver branch September 22, 2020 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants