Skip to content

Commit

Permalink
Merge pull request #74 from raynigon/bugfix/72/quantity-reader
Browse files Browse the repository at this point in the history
Fix Quantity Reader/Writer Bug
  • Loading branch information
raynigon authored Jun 19, 2021
2 parents 97be9fe + 65fe4ee commit a052bb5
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static QuantityReader getReaderInstance(JsonQuantityReader readerWrapper)

public static QuantityWriter getWriterInstance(JsonQuantityWriter writerWrapper) {
if (writerWrapper == null) return null;
return createInstace(writerWrapper.value(), "Reader");
return createInstace(writerWrapper.value(), "Writer");
}

private static <T> T createInstace(Class<? extends T> readerType, String type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@

import com.raynigon.unit_api.core.io.QuantityReader;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;

@Target({METHOD, FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonQuantityReader {

Class<? extends QuantityReader> value();

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

import com.raynigon.unit_api.core.io.QuantityWriter;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;

@Target({METHOD, FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonQuantityWriter {

Class<? extends QuantityWriter> value();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty
(Class<Quantity>) property.getType().getBindings().getBoundType(0).getRawClass();
unit = UnitsApiService.getInstance().getUnit(quantityType);

JsonQuantityWriter writerWrapper = property.getAnnotation(JsonQuantityWriter.class);
if (writerWrapper != null) {
writer = JsonQuantityHelper.getWriterInstance(writerWrapper);
}

JsonUnit unitWrapper = property.getAnnotation(JsonUnit.class);
if (unitWrapper == null) return new QuantitySerializer(config, unit, shape, writer);
shape = JsonUnitHelper.getShape(unitWrapper);
Expand All @@ -67,6 +62,12 @@ public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty
throw new UnknownUnitException(prov.getGenerator(), quantityType);
}

JsonQuantityWriter writerWrapper = property.getAnnotation(JsonQuantityWriter.class);
if (writerWrapper != null) {
writer = JsonQuantityHelper.getWriterInstance(writerWrapper);
shape = QuantityShape.STRING;
}

return new QuantitySerializer(config, unit, shape, writer);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.raynigon.unit_api.jackson

import com.fasterxml.jackson.databind.ObjectMapper
import com.raynigon.unit_api.jackson.helpers.BasicApplicationConfig
import com.raynigon.unit_api.jackson.helpers.BasicRestController
import com.raynigon.unit_api.jackson.helpers.BasicService
import com.raynigon.unit_api.jackson.helpers.WeatherEntity
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.web.client.TestRestTemplate
import spock.lang.Specification

import static com.raynigon.unit_api.core.units.si.SISystemUnitsConstants.Celsius
import static com.raynigon.unit_api.core.units.si.SISystemUnitsConstants.MetrePerSecond
import static com.raynigon.unit_api.core.units.si.SISystemUnitsConstants.Percent

@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
Expand All @@ -29,6 +33,9 @@ class JacksonStarterApplicationSpec extends Specification {
@Autowired
TestRestTemplate restTemplate

@Autowired
ObjectMapper objectMapper

def 'context setup works'() {
expect:
true
Expand All @@ -53,4 +60,39 @@ class JacksonStarterApplicationSpec extends Specification {
service.getEntity("1") != null
service.getEntity("1").speed == MetrePerSecond(100)
}

def 'entity with custom reader'() {

given:
true

when:
WeatherEntity result = objectMapper.readValue(input, WeatherEntity)

then:
expected.temperature == result.temperature
expected.humidity == result.humidity

where:
input | expected
'{ "temperature": "30 °C", "humidity": "10 %" }' | new WeatherEntity(Celsius(30), Percent(10))
'{ "temperature": "30°C", "humidity": "10 %" }' | new WeatherEntity(Celsius(30), Percent(10))
'{ "temperature": "-30 °C", "humidity": "10 %" }' | new WeatherEntity(Celsius(-30), Percent(10))
'{ "temperature": "-30°C", "humidity": "10 %" }' | new WeatherEntity(Celsius(-30), Percent(10))
}

def 'entity with custom writer'() {

when:
def result = objectMapper.writeValueAsString(entity)

then:
expected == result

where:
entity | expected
new WeatherEntity(Celsius(30), Percent(10)) | '{"temperature":30.0,"humidity":"10.0%"}'
new WeatherEntity(Celsius(30), Percent(10.1)) | '{"temperature":30.0,"humidity":"10.1%"}'
new WeatherEntity(Celsius(30), Percent(-10)) | '{"temperature":30.0,"humidity":"-10.0%"}'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.raynigon.unit_api.jackson.helpers

import com.raynigon.unit_api.core.io.QuantityReader

import javax.measure.Quantity

import static com.raynigon.unit_api.core.units.si.SISystemUnitsConstants.Celsius

class CelsiusReader implements QuantityReader {

@Override
Quantity<?> read(String input) {
if (!input.endsWith("°C")) return null
return Celsius(Double.parseDouble(input.replace("°C", "").trim()))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.raynigon.unit_api.jackson.helpers

import com.raynigon.unit_api.core.io.QuantityWriter
import com.raynigon.unit_api.core.units.si.dimensionless.Percent

import javax.measure.Quantity

class PercentWriter implements QuantityWriter {
@Override
String write(Quantity input) {
return "${input.to(new Percent()).value.doubleValue()}%"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.raynigon.unit_api.jackson.helpers


import com.raynigon.unit_api.core.units.si.dimensionless.Percent
import com.raynigon.unit_api.core.units.si.temperature.Celsius
import com.raynigon.unit_api.jackson.annotation.JsonQuantityReader
import com.raynigon.unit_api.jackson.annotation.JsonQuantityWriter
import com.raynigon.unit_api.jackson.annotation.JsonUnit

import javax.measure.Quantity
import javax.measure.quantity.Dimensionless
import javax.measure.quantity.Temperature

class WeatherEntity {

public WeatherEntity() {}

public WeatherEntity(Quantity<Temperature> temperature, Quantity<Dimensionless> humidity) {
this.temperature = temperature
this.humidity = humidity
}

@JsonUnit(unit = Celsius)
@JsonQuantityReader(CelsiusReader.class)
public Quantity<Temperature> temperature

@JsonUnit(unit = Percent)
@JsonQuantityWriter(PercentWriter.class)
public Quantity<Dimensionless> humidity
}

0 comments on commit a052bb5

Please sign in to comment.