package gov.nysenate.openleg.service.spotcheck.senatesite.base;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import gov.nysenate.openleg.processor.base.ParseError;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
/**
* Created by PKS on 2/25/16.
*/
public class JsonParser {
@Autowired
ObjectMapper objectMapper;
protected <T> Optional<T> deserializeValue(JsonNode jsonNode, String fieldName, TypeReference<T> resultType) {
String jsonValue = getValue(jsonNode, fieldName);
return Optional.ofNullable(jsonValue).map(json -> {
try {
return objectMapper.readValue(json, resultType);
} catch (IOException ex) {
throw new ParseError("Error while attempting to map json. " +
"target_class: " + resultType.getType() + " field: " + fieldName + " value: " + json,
ex);
}
});
}
protected String getValue(JsonNode parentNode, String fieldName) {
JsonNode undNode = parentNode.path(fieldName)
.path("und");
if (!undNode.isArray() || !undNode.elements().hasNext()) {
return null;
}
JsonNode valueNode = undNode.elements().next()
.path("value");
if (valueNode.isTextual() || valueNode.isNull()) {
return valueNode.textValue();
}
return null;
}
protected int getIntValue(JsonNode parentNode, String fieldName) {
String rawValue = getValue(parentNode, fieldName);
if (rawValue == null) {
return 0;
}
try {
return Integer.parseInt(rawValue);
} catch (NumberFormatException ex) {
throw new ParseError("could not parse int value. field: " + fieldName + " value: " + rawValue, ex);
}
}
protected List<String> getStringListValue(JsonNode parentNode, String fieldName){
JsonNode undNode = parentNode.path(fieldName).path("und");
if(!undNode.isArray() || !undNode.elements().hasNext()){
return null;
}
List<String> stringList = new ArrayList<String>();
Iterator<JsonNode> iterator = undNode.elements();
for (JsonNode node : undNode)
{
JsonNode valueNode = node.path("value");
if (!valueNode.isNull()) {
stringList.add(valueNode.asText());
}
}
return stringList;
}
protected List<Integer> getIntListValue(JsonNode parentNode, String fieldName){
JsonNode undNode = parentNode.path(fieldName).path("und");
if(!undNode.isArray() || !undNode.elements().hasNext()){
return null;
}
List<Integer> integerList = new ArrayList<Integer>();
Iterator<JsonNode> iterator = undNode.elements();
for (JsonNode node : undNode)
{
JsonNode valueNode = node.path("value");
if (!valueNode.isNull()) {
integerList.add(valueNode.asInt());
}
}
return integerList;
}
protected boolean getBooleanValue(JsonNode parentNode, String fieldName) {
String rawValue = getValue(parentNode, fieldName);
if (rawValue == null) {
return false;
}
if ("1".equals(rawValue) ^ "0".equals(rawValue)) {
return "1".equals(getValue(parentNode, fieldName));
}
throw new ParseError("unexpected value for boolean. field: " + fieldName + " value: " + rawValue);
}
protected LocalDateTime getDateTimeValue(JsonNode parentNode, String fieldName) {
String rawValue = getValue(parentNode, fieldName);
if (rawValue == null) {
return null;
}
try {
long msvalue = Long.parseLong(rawValue);
return LocalDateTime.ofInstant(Instant.ofEpochSecond(msvalue), ZoneId.of("America/New_York"));
} catch (DateTimeException | NumberFormatException ex) {
throw new ParseError("cannot convert value into LocalDateTime. field: " + fieldName + " value: " + rawValue, ex);
}
}
}