Skip to content

Commit

Permalink
[Feature #10] Implement and use custom deserializers for date values.
Browse files Browse the repository at this point in the history
Simplify literal value presence validation.
  • Loading branch information
ledsoft committed Mar 21, 2022
1 parent 818f462 commit ca163ae
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ private void initBuiltInDeserializers() {
deserializers.put(Date.class, new DateDeserializer(coreDatetimeDeserializer));
deserializers.put(OffsetTime.class, coreTimeDeserializer);
deserializers.put(LocalTime.class, new LocalTimeDeserializer(coreTimeDeserializer));
deserializers.put(LocalDate.class, new LocalDateDeserializer());
// TODO Period, Duration
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cz.cvut.kbss.jsonld.deserialization.datetime;

import cz.cvut.kbss.jopa.datatype.xsd.XsdDateMapper;
import cz.cvut.kbss.jsonld.JsonLd;
import cz.cvut.kbss.jsonld.deserialization.DeserializationContext;
import cz.cvut.kbss.jsonld.deserialization.ValueDeserializer;

import java.time.LocalDate;
import java.util.Map;

import static cz.cvut.kbss.jsonld.deserialization.datetime.OffsetDateTimeDeserializer.missingValueException;

/**
* Deserializes values to {@link LocalDate}.
* <p>
* The values are expected to be String in the ISO date format.
*/
public class LocalDateDeserializer implements ValueDeserializer<LocalDate> {

@Override
public LocalDate deserialize(Map<?, ?> jsonNode, DeserializationContext<LocalDate> ctx) {
final Object value = jsonNode.get(JsonLd.VALUE);
if (value == null) {
throw missingValueException(jsonNode);
}
return XsdDateMapper.map(value.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ public class OffsetDateTimeDeserializer implements ValueDeserializer<OffsetDateT
public OffsetDateTime deserialize(Map<?, ?> jsonNode, DeserializationContext<OffsetDateTime> ctx) {
final Object value = jsonNode.get(JsonLd.VALUE);
if (value == null) {
throw new JsonLdDeserializationException("Cannot deserialize node " + jsonNode + "as date time. " +
"It is missing attribute " + JsonLd.VALUE + ".");
throw missingValueException(jsonNode);
}
return value instanceof Long ? epochResolver.resolve((Long) value) : stringResolver.resolve(value.toString());
}

static JsonLdDeserializationException missingValueException(Map<?, ?> jsonNode) {
return new JsonLdDeserializationException("Cannot deserialize node " + jsonNode + "as literal. " +
"It is missing attribute " + JsonLd.VALUE + ".");
}

@Override
public void configure(Configuration config) {
stringResolver.configure(config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import cz.cvut.kbss.jsonld.JsonLd;
import cz.cvut.kbss.jsonld.deserialization.DeserializationContext;
import cz.cvut.kbss.jsonld.deserialization.ValueDeserializer;
import cz.cvut.kbss.jsonld.exception.JsonLdDeserializationException;

import java.time.OffsetTime;
import java.util.Map;

import static cz.cvut.kbss.jsonld.deserialization.datetime.OffsetDateTimeDeserializer.missingValueException;

/**
* Deserializes values to {@link OffsetTime}.
* <p>
Expand All @@ -20,8 +21,7 @@ public class OffsetTimeDeserializer implements ValueDeserializer<OffsetTime> {
public OffsetTime deserialize(Map<?, ?> jsonNode, DeserializationContext<OffsetTime> ctx) {
final Object value = jsonNode.get(JsonLd.VALUE);
if (value == null) {
throw new JsonLdDeserializationException("Cannot deserialize node " + jsonNode + "as time. " +
"It is missing attribute " + JsonLd.VALUE + ".");
throw missingValueException(jsonNode);
}
return XsdTimeMapper.map(value.toString());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cz.cvut.kbss.jsonld.deserialization.datetime;

import cz.cvut.kbss.jsonld.JsonLd;
import cz.cvut.kbss.jsonld.exception.JsonLdDeserializationException;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.time.OffsetTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Map;

import static cz.cvut.kbss.jsonld.deserialization.datetime.OffsetDateTimeDeserializerTest.deserializationContext;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.*;

class LocalDateDeserializerTest {

private final LocalDateDeserializer sut = new LocalDateDeserializer();

@Test
void deserializeDeserializesSpecifiedIsoFormattedDateString() {
final LocalDate value = LocalDate.now();
final Map<String, Object> input = Collections.singletonMap(JsonLd.VALUE, value.format(DateTimeFormatter.ISO_DATE));

final LocalDate result = sut.deserialize(input, deserializationContext(LocalDate.class));
assertEquals(value, result);
}

@Test
void deserializeThrowsJsonLdDeserializationExceptionWhenInputIsMissingValueAttribute() {
final Map<String, Object> input = Collections.singletonMap("notValue", LocalDate.now().format(DateTimeFormatter.ISO_DATE));

final JsonLdDeserializationException ex = assertThrows(JsonLdDeserializationException.class,
() -> sut.deserialize(input, deserializationContext(LocalDate.class)));
assertThat(ex.getMessage(), containsString(JsonLd.VALUE));
assertThat(ex.getMessage(), containsString("missing"));
}
}

0 comments on commit ca163ae

Please sign in to comment.