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

Allow to use custom mapper on Enum #341

Merged
merged 4 commits into from
Oct 20, 2021
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
74 changes: 66 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,12 +432,12 @@ A _Data object_ is a type that can be converted back and forth to a Json type.

You can declare data objects by:

* Defining an annotated `@Mapper` method for it
* Defining a mapper in the `META-INF/vertx/json-mappers.properties` file
* Or annotating the type itself with `@DataObject`

### Json mappers

A json mapper for type `T` is a method that maps any object of type `Type`, where `J` can be:
A json mapper for type `T` is a method that maps any object or enum of type `Type`, where `J` can be:

* `JsonArray` or `JsonObject`
* a concrete type extending `Number` such as `Long` or `Double`
Expand All @@ -448,19 +448,77 @@ Json mapped types can be used anywhere a json types used are.

A json mapper turns any Java type into a data object type.

####Object
You can declare them as public static methods:
```java
package com.example;

public class MyMappers {

public static String serialize(ZonedDateTime date) {
return date.toString();
}

public static ZonedDateTime deserialize(String s) {
return ZonedDateTime.parse(s);
}
}
```
These mappers needs to be declared in a `META-INF/vertx/json-mappers.properties` file as follow:
```properties
java.time.ZonedDateTime.serializer=com.example.MyMappers#serializeZonedDateTime
java.time.ZonedDateTime.deserializer=com.example.MyMappers#deserializedZoneDateTime
```
####Enum
Enum can be define with values parameters passed to a constructor. In this use case, you can't use default behavior of codegen (#valueOf() and #name()), you need to define like Object `serializer` and `deserializer`.
```java
@Mapper
public static String serialize(ZonedDateTime date) {
return date.toString();
package com.example;

public enum MyEnumWithCustomFactory {
DEV("dev", "development"), ITEST("itest", "integration-test");

private String[] names = new String[2];

MyEnumWithCustomFactory(String pShortName, String pLongName) {
names[0] = pShortName;
names[1] = pLongName;
}

public String getLongName() {
return names[1];
}

public String getShortName() {
return names[0];
}

public static MyEnumWithCustomFactory of(String pName) {
for (MyEnumWithCustomFactory item : MyEnumWithCustomFactory.values()) {
if (item.names[0].equalsIgnoreCase(pName) || item.names[1].equalsIgnoreCase(pName)
|| pName.equalsIgnoreCase(item.name())) {
return item;
}
}
return DEV;
}

}
```
You can declare them as public static methods:
```java
public static String serialize(MyEnumWithCustomFactory value) {
return value.getLongName();
}

@Mapper
public static ZonedDateTime deserialize(String s) {
return ZonedDateTime.parse(s);
public static MyEnumWithCustomFactory deserialize(String value) {
return MyEnumWithCustomFactory.of(value);
}
```
These mappers needs to be declared in a `META-INF/vertx/json-mappers.properties` file as follow:
```properties
com.example.MyEnumWithCustomFactory.serializer=com.example.MyEnumWithCustomFactory#serialize
com.example.MyEnumWithCustomFactory.deserializer=com.example.MyEnumWithCustomFactory#deserialize
```

### `@DataObject` annotated types

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ public static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json,
});
}
break;
case "addedEnumMappeds":
if (member.getValue() instanceof JsonArray) {
((Iterable<Object>)member.getValue()).forEach( item -> {
if (item instanceof String)
obj.addAddedEnumMapped(io.vertx.test.codegen.converter.TestDataObject.deserializeCustomEnum((String)item));
});
}
break;
case "addedHttpMethods":
if (member.getValue() instanceof JsonArray) {
((Iterable<Object>)member.getValue()).forEach( item -> {
Expand Down Expand Up @@ -467,6 +475,41 @@ public static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json,
obj.setBufferSet(list);
}
break;
case "enumMapped":
if (member.getValue() instanceof String) {
obj.setEnumMapped(io.vertx.test.codegen.converter.TestDataObject.deserializeCustomEnum((String)member.getValue()));
}
break;
case "enumMappedList":
if (member.getValue() instanceof JsonArray) {
java.util.ArrayList<io.vertx.test.codegen.converter.TestCustomEnum> list = new java.util.ArrayList<>();
((Iterable<Object>)member.getValue()).forEach( item -> {
if (item instanceof String)
list.add(io.vertx.test.codegen.converter.TestDataObject.deserializeCustomEnum((String)item));
});
obj.setEnumMappedList(list);
}
break;
case "enumMappedMap":
if (member.getValue() instanceof JsonObject) {
java.util.Map<String, io.vertx.test.codegen.converter.TestCustomEnum> map = new java.util.LinkedHashMap<>();
((Iterable<java.util.Map.Entry<String, Object>>)member.getValue()).forEach(entry -> {
if (entry.getValue() instanceof String)
map.put(entry.getKey(), io.vertx.test.codegen.converter.TestDataObject.deserializeCustomEnum((String)entry.getValue()));
});
obj.setEnumMappedMap(map);
}
break;
case "enumMappedSet":
if (member.getValue() instanceof JsonArray) {
java.util.LinkedHashSet<io.vertx.test.codegen.converter.TestCustomEnum> list = new java.util.LinkedHashSet<>();
((Iterable<Object>)member.getValue()).forEach( item -> {
if (item instanceof String)
list.add(io.vertx.test.codegen.converter.TestDataObject.deserializeCustomEnum((String)item));
});
obj.setEnumMappedSet(list);
}
break;
case "httpMethod":
if (member.getValue() instanceof String) {
obj.setHttpMethod(java.util.concurrent.TimeUnit.valueOf((String)member.getValue()));
Expand Down Expand Up @@ -679,6 +722,14 @@ public static void fromJson(Iterable<java.util.Map.Entry<String, Object>> json,
});
}
break;
case "keyedEnumMappedValues":
if (member.getValue() instanceof JsonObject) {
((Iterable<java.util.Map.Entry<String, Object>>)member.getValue()).forEach(entry -> {
if (entry.getValue() instanceof String)
obj.addKeyedEnumMappedValue(entry.getKey(), io.vertx.test.codegen.converter.TestDataObject.deserializeCustomEnum((String)entry.getValue()));
});
}
break;
case "keyedEnumValues":
if (member.getValue() instanceof JsonObject) {
((Iterable<java.util.Map.Entry<String, Object>>)member.getValue()).forEach(entry -> {
Expand Down Expand Up @@ -1007,6 +1058,11 @@ public static void toJson(TestDataObject obj, java.util.Map<String, Object> json
obj.getAddedBuffers().forEach(item -> array.add(JsonUtil.BASE64_ENCODER.encodeToString(item.getBytes())));
json.put("addedBuffers", array);
}
if (obj.getAddedEnumMappeds() != null) {
JsonArray array = new JsonArray();
obj.getAddedEnumMappeds().forEach(item -> array.add(io.vertx.test.codegen.converter.TestDataObject.serializeCustomEnum(item)));
json.put("addedEnumMappeds", array);
}
if (obj.getAddedHttpMethods() != null) {
JsonArray array = new JsonArray();
obj.getAddedHttpMethods().forEach(item -> array.add(item.name()));
Expand Down Expand Up @@ -1209,6 +1265,24 @@ public static void toJson(TestDataObject obj, java.util.Map<String, Object> json
obj.getBufferSet().forEach(item -> array.add(JsonUtil.BASE64_ENCODER.encodeToString(item.getBytes())));
json.put("bufferSet", array);
}
if (obj.getEnumMapped() != null) {
json.put("enumMapped", io.vertx.test.codegen.converter.TestDataObject.serializeCustomEnum(obj.getEnumMapped()));
}
if (obj.getEnumMappedList() != null) {
JsonArray array = new JsonArray();
obj.getEnumMappedList().forEach(item -> array.add(io.vertx.test.codegen.converter.TestDataObject.serializeCustomEnum(item)));
json.put("enumMappedList", array);
}
if (obj.getEnumMappedMap() != null) {
JsonObject map = new JsonObject();
obj.getEnumMappedMap().forEach((key, value) -> map.put(key, io.vertx.test.codegen.converter.TestDataObject.serializeCustomEnum(value)));
json.put("enumMappedMap", map);
}
if (obj.getEnumMappedSet() != null) {
JsonArray array = new JsonArray();
obj.getEnumMappedSet().forEach(item -> array.add(io.vertx.test.codegen.converter.TestDataObject.serializeCustomEnum(item)));
json.put("enumMappedSet", array);
}
if (obj.getHttpMethod() != null) {
json.put("httpMethod", obj.getHttpMethod().name());
}
Expand Down Expand Up @@ -1326,6 +1400,11 @@ public static void toJson(TestDataObject obj, java.util.Map<String, Object> json
obj.getKeyedBufferValues().forEach((key, value) -> map.put(key, JsonUtil.BASE64_ENCODER.encodeToString(value.getBytes())));
json.put("keyedBufferValues", map);
}
if (obj.getKeyedEnumMappedValues() != null) {
JsonObject map = new JsonObject();
obj.getKeyedEnumMappedValues().forEach((key, value) -> map.put(key, io.vertx.test.codegen.converter.TestDataObject.serializeCustomEnum(value)));
json.put("keyedEnumMappedValues", map);
}
if (obj.getKeyedEnumValues() != null) {
JsonObject map = new JsonObject();
obj.getKeyedEnumValues().forEach((key, value) -> map.put(key, value.name()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.vertx.test.codegen.converter;

public enum TestCustomEnum {

DEV("dev", "development"),

ITEST("itest", "integration-test");

public static TestCustomEnum of(String pName) {
for (TestCustomEnum item : TestCustomEnum.values()) {
if (item.names[0].equalsIgnoreCase(pName) || item.names[1].equalsIgnoreCase(pName)
|| pName.equalsIgnoreCase(item.name())) {
return item;
}
}
return DEV;
}

private String[] names = new String[2];

TestCustomEnum(String pShortName, String pLongName) {
names[0] = pShortName;
names[1] = pLongName;
}

public String getLongName() {
return names[1];
}

public String getShortName() {
return names[0];
}

}
Loading