Skip to content

Commit

Permalink
feat: support collection of records
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-grgt committed Mar 2, 2024
1 parent 196f974 commit 51f7ce6
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,15 @@ private Supplier<Object> collectionSupplierForType(Class<?> typeArgument) {
if (collectionCacheType.get(typeArgument) != null) {
return collectionCacheType.get(typeArgument);
}
Object listTypeInstance = TypeReflector.reflect(typeArgument).instanceReflector().instance();
collectionCacheType.put(typeArgument, listTypeInstance);
return listTypeInstance;
if (typeArgument.isRecord()) {
var recordWrapper = new RecordWrapper<>(typeArgument);
collectionCacheType.put(typeArgument, recordWrapper);
return recordWrapper;
} else {
Object listTypeInstance = TypeReflector.reflect(typeArgument).instanceReflector().instance();
collectionCacheType.put(typeArgument, listTypeInstance);
return listTypeInstance;
}
};
}

Expand Down Expand Up @@ -278,15 +284,20 @@ private void indexComplexListTypeArgument(Map<Path, PathWriter> index, Collectio
throw new XjxDeserializationException(
"""
Field (%s) requires @Tag to have items parameter describing\
the tag name of a single repeated tag""".formatted(typeArgument.getSimpleName(), field.name()));
the tag name of a single repeated tag""".formatted(typeArgument.getSimpleName() ));
}
Path path = Path.parse(tag.path()).append(Path.parse(tag.items()));
index.put(path, PathWriter.objectInitializer(() -> {
collectionCacheType.clear();
Object listTypeInstance = listTypeInstanceSupplier.get();
list.add(listTypeInstance);
return listTypeInstance;
}));
}).setValueInitializer((value) -> {
if (value instanceof RecordWrapper<?> recordWrapperValue) {
list.remove(recordWrapperValue);
list.add(recordWrapperValue.record());
}
}));
doBuildIndex(typeArgument, path, index, listTypeInstanceSupplier);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,36 @@ void deserializeIntoListField_whereRootTagContainsRepeatedElements() {
assertThat(gpx.wayPoints.get(1).time).isEqualTo("2001-06-02T03:26:55Z");
}

@Test
void recordWithListOfRecord() {
// given
String data = """
<?xml version="1.0" encoding="UTF-8"?>
<WeatherReport>
<City>
<Name>New York</Name>
<Condition>Sunny</Condition>
</City>
<City>
<Name>London</Name>
<Condition>Cloudy</Condition>
</City>
</WeatherReport>
""";
record CityWeather(@Tag(path = "Condition") String condition, @Tag(path = "Name") String name) {}

record WeatherReport(@Tag(path = "/WeatherReport", items = "City") List<CityWeather> cityWeather) {}


// when
var weatherReport = new XjxSerdes().read(data, WeatherReport.class);

// then
assertThat(weatherReport.cityWeather).containsExactly(
new CityWeather("Sunny", "New York"),
new CityWeather("Cloudy", "London"));
}

static class Gpx {
public Gpx() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Objects;
import java.util.Set;

Expand All @@ -11,6 +12,8 @@

import io.jonasg.xjx.serdes.Tag;
import io.jonasg.xjx.serdes.XjxSerdes;
import io.jonasg.xjx.serdes.deserialize.ListDeserializationTest.Gpx;
import io.jonasg.xjx.serdes.deserialize.ListDeserializationTest.Wpt;

public class SetDeserializationTest {

Expand Down Expand Up @@ -459,7 +462,40 @@ void deserializeIntoSetField_whereRootTagContainsRepeatedElements() {
Assertions.assertThat(gpx.wayPoints).extracting(r -> r.time).containsExactlyInAnyOrder("2001-11-28T21:05:28Z", "2001-06-02T03:26:55Z");
}

static class Gpx {

@Test
void recordWithSetOfRecord() {
// given
String data = """
<?xml version="1.0" encoding="UTF-8"?>
<WeatherReport>
<City>
<Name>New York</Name>
<Condition>Sunny</Condition>
</City>
<City>
<Name>London</Name>
<Condition>Cloudy</Condition>
</City>
</WeatherReport>
""";
record CityWeather(@Tag(path = "Condition") String condition,
@Tag(path = "Name") String name) {}

record WeatherReport(
@Tag(path = "/WeatherReport", items = "City") Set<CityWeather> cityWeather) {}


// when
var weatherReport = new XjxSerdes().read(data, WeatherReport.class);

// then
assertThat(weatherReport.cityWeather).containsExactly(
new CityWeather("Cloudy", "London"),
new CityWeather("Sunny", "New York"));
}

static class Gpx {
public Gpx() {
}

Expand Down

0 comments on commit 51f7ce6

Please sign in to comment.