package de.rwth.idsg.steve.ocpp.ws.custom;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import ocpp.cs._2012._06.MeterValue;
import org.joda.time.DateTime;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Custom deserializer to work around broken charging station implementations,
* that set the field name wrongfully to "values" rather than the correct "value".
* We handle the situation by looking both fields up in the message.
*
* @author Sevket Goekay <goekay@dbis.rwth-aachen.de>
* @since 01.09.2015
*/
@Slf4j
public class MeterValue15Deserializer extends JsonDeserializer<List<MeterValue>> {
@Override
public List<MeterValue> deserialize(JsonParser jp, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode node = mapper.readTree(jp);
if (node == null) {
return Collections.emptyList();
}
return parseListMeterValue(mapper, node);
}
// List<MeterValue>
private List<MeterValue> parseListMeterValue(ObjectMapper mapper, JsonNode listNode)
throws JsonProcessingException {
if (listNode.isMissingNode()) {
return Collections.emptyList();
} else {
List<MeterValue> rootList = new ArrayList<>();
for (JsonNode node : listNode) {
rootList.add(buildMeterValue(mapper, node));
}
return rootList;
}
}
// MeterValue
private MeterValue buildMeterValue(ObjectMapper mapper, JsonNode node)
throws JsonProcessingException {
MeterValue meterValue = new MeterValue();
List<MeterValue.Value> list = meterValue.getValue();
parseValue(mapper, list, node.path("value"));
parseValue(mapper, list, node.path("values"));
parseDateTime(meterValue, node.path("timestamp"));
return meterValue;
}
// List<MeterValue.Value>
private void parseValue(ObjectMapper mapper, List<MeterValue.Value> list, JsonNode listNode)
throws JsonProcessingException {
if (!listNode.isMissingNode()) {
for (JsonNode node : listNode) {
list.add(mapper.treeToValue(node, MeterValue.Value.class));
}
}
}
private void parseDateTime(MeterValue meterValue, JsonNode node) {
if (!node.isMissingNode()) {
meterValue.setTimestamp(new DateTime(node.asText()));
}
}
}