Skip to content
This repository was archived by the owner on Sep 21, 2020. It is now read-only.

Commit 1f165f4

Browse files
committed
Add DimensionJsonSerialzer and DimensionJsonDeserializer
1 parent 42dbbc5 commit 1f165f4

5 files changed

Lines changed: 187 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.opower.unitsofmeasure;
2+
3+
import com.fasterxml.jackson.core.JsonParser;
4+
import com.fasterxml.jackson.core.JsonProcessingException;
5+
import com.fasterxml.jackson.databind.DeserializationContext;
6+
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
7+
import java.io.IOException;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.stream.Collectors;
11+
import javax.measure.Dimension;
12+
import tec.uom.se.quantity.QuantityDimension;
13+
14+
/**
15+
*
16+
* @author richter
17+
*/
18+
public class DimensionJsonDeserializer extends StdScalarDeserializer<Dimension> {
19+
20+
public DimensionJsonDeserializer() {
21+
super(Dimension.class);
22+
}
23+
24+
@Override
25+
public Dimension deserialize(JsonParser p,
26+
DeserializationContext ctxt) throws IOException,
27+
JsonProcessingException {
28+
Map<String, Integer> baseDimensionsStrings = p.readValueAs(Map.class);
29+
Map<Dimension, Integer> baseDimensions = new HashMap<>(baseDimensionsStrings
30+
.entrySet()
31+
.stream()
32+
.collect(Collectors.toMap(entry -> parseBaseDimension(entry.getKey()),
33+
entry -> entry.getValue())));
34+
Dimension retValue = QuantityDimension.NONE;
35+
for(Dimension baseDimension : baseDimensions.keySet()) {
36+
int exp = baseDimensions.get(baseDimension);
37+
retValue = retValue.multiply(baseDimension.pow(exp));
38+
}
39+
return retValue;
40+
}
41+
42+
private static Dimension parseBaseDimension(String symbol) {
43+
switch(symbol) {
44+
case "[N]":
45+
return QuantityDimension.AMOUNT_OF_SUBSTANCE;
46+
case "[I]":
47+
return QuantityDimension.ELECTRIC_CURRENT;
48+
case "[L]":
49+
return QuantityDimension.LENGTH;
50+
case "[J]":
51+
return QuantityDimension.LUMINOUS_INTENSITY;
52+
case "[M]":
53+
return QuantityDimension.MASS;
54+
case "[\u0398]":
55+
return QuantityDimension.TEMPERATURE;
56+
case "[T]":
57+
return QuantityDimension.TIME;
58+
default:
59+
throw new IllegalArgumentException(String.format("dimension "
60+
+ "symbol '%s' not supported, maybe dimensionless or "
61+
+ "wrong universe?",
62+
symbol));
63+
}
64+
}
65+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.opower.unitsofmeasure;
2+
3+
import com.fasterxml.jackson.core.JsonGenerator;
4+
import com.fasterxml.jackson.databind.JsonSerializer;
5+
import com.fasterxml.jackson.databind.SerializerProvider;
6+
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
7+
import java.io.IOException;
8+
import javax.measure.Dimension;
9+
10+
/**
11+
*
12+
* @author richter
13+
*/
14+
public class DimensionJsonSerializer extends StdScalarSerializer<Dimension> {
15+
16+
public DimensionJsonSerializer() {
17+
super(Dimension.class);
18+
}
19+
20+
/**
21+
* Serializes a dimension by serializing it's base dimension map.
22+
*
23+
* Based on my question and answer at
24+
* https://stackoverflow.com/questions/48509189/jsr-275-dimension-string-serialization-and-deserialization
25+
* which might contain better alternatives meanwhile.
26+
*
27+
* @param value the dimension to serialize
28+
* @param gen the generator as provided by {@link JsonSerializer}
29+
* @param serializers the serializers as provided by {@link JsonSerializer}
30+
* @throws IOException if an I/O exception occurs
31+
*/
32+
@Override
33+
public void serialize(Dimension value,
34+
JsonGenerator gen,
35+
SerializerProvider serializers) throws IOException {
36+
gen.writeObject(value.getBaseDimensions());
37+
}
38+
}

src/main/java/com/opower/unitsofmeasure/UnitJacksonModule.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
1313
import com.fasterxml.jackson.databind.module.SimpleModule;
1414
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
15+
import javax.measure.Dimension;
1516

1617
import systems.uom.ucum.format.UCUMFormat;
1718
import systems.uom.ucum.format.UCUMFormat.Variant;
@@ -33,7 +34,9 @@ public UnitJacksonModule() {
3334
UnitJacksonModule.class.getPackage().getName(), "jackson-module-unitsofmeasure"));
3435

3536
addSerializer(Unit.class, new UnitJsonSerializer());
37+
addSerializer(Dimension.class, new DimensionJsonSerializer());
3638
addDeserializer(Unit.class, new UnitJsonDeserializer());
39+
addDeserializer(Dimension.class, new DimensionJsonDeserializer());
3740
}
3841

3942
private class UnitJsonSerializer extends StdScalarSerializer<Unit> {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.opower.unitsofmeasure;
2+
3+
import com.fasterxml.jackson.core.JsonParser;
4+
import com.fasterxml.jackson.databind.DeserializationContext;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import java.io.ByteArrayInputStream;
7+
import java.io.IOException;
8+
import java.io.InputStream;
9+
import java.nio.charset.StandardCharsets;
10+
import javax.measure.Dimension;
11+
import static org.junit.Assert.*;
12+
import org.junit.Test;
13+
import tec.uom.se.quantity.QuantityDimension;
14+
15+
/**
16+
*
17+
* @author richter
18+
*/
19+
public class DimensionJsonDeserializerTest {
20+
21+
/**
22+
* Test of deserialize method, of class DimensionJsonDeserializer.Inspired by
23+
https://stackoverflow.com/questions/21787128/how-to-unit-test-jackson-jsonserializer-and-jsondeserializer
24+
* @throws IOException if an I/O error occurs
25+
*/
26+
@Test
27+
public void testDeserialize() throws IOException {
28+
ObjectMapper objectMapper = new ObjectMapper();
29+
InputStream stream = new ByteArrayInputStream("{\"[L]\":2,\"[T]\":1}".getBytes(StandardCharsets.UTF_8));
30+
JsonParser parser = objectMapper.getFactory().createParser(stream);
31+
DeserializationContext ctxt = objectMapper.getDeserializationContext();
32+
DimensionJsonDeserializer instance = new DimensionJsonDeserializer();
33+
Dimension expResult = QuantityDimension.LENGTH.pow(2).multiply(QuantityDimension.TIME);
34+
Dimension result = instance.deserialize(parser,
35+
ctxt);
36+
assertEquals(expResult,
37+
result);
38+
}
39+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.opower.unitsofmeasure;
2+
3+
import com.fasterxml.jackson.core.JsonGenerator;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.SerializerProvider;
6+
import java.io.IOException;
7+
import java.io.StringWriter;
8+
import javax.measure.Dimension;
9+
import static org.junit.Assert.*;
10+
import org.junit.Test;
11+
import tec.uom.se.quantity.QuantityDimension;
12+
13+
/**
14+
*
15+
* @author richter
16+
*/
17+
public class DimensionJsonSerializerTest {
18+
19+
/**
20+
* Test of serialize method, of class DimensionJsonSerializer.Inspired by
21+
https://stackoverflow.com/questions/21787128/how-to-unit-test-jackson-jsonserializer-and-jsondeserializer
22+
* @throws IOException if an I/O error occurs
23+
*/
24+
@Test
25+
public void testSerialize() throws IOException {
26+
Dimension value = QuantityDimension.LENGTH.multiply(QuantityDimension.TIME.pow(2));
27+
ObjectMapper objectMapper = new ObjectMapper();
28+
StringWriter writer = new StringWriter();
29+
try (JsonGenerator gen = objectMapper.getFactory().createGenerator(writer)) {
30+
SerializerProvider serializers = null;
31+
//unused
32+
DimensionJsonSerializer instance = new DimensionJsonSerializer();
33+
instance.serialize(value, gen, serializers);
34+
}
35+
String expResult = "{\"[T]\":2,\"[L]\":1}";
36+
//escaping is extranous here, but JsonGenertor references which work
37+
//as needed are hard to obtain
38+
String result = writer.toString();
39+
assertEquals(expResult,
40+
result);
41+
}
42+
}

0 commit comments

Comments
 (0)