package com.forter.contracts;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.google.common.base.Throwables;
import com.sun.corba.se.impl.orbutil.ObjectWriter;
import java.util.Collections;
import java.util.Map;
/**
* Converts {@link com.fasterxml.jackson.databind.node.ObjectNode} to a Contract
* The methods are not thread safe. Lock on the converted object in case two threads are converting the same one.
*/
public class ContractConverter {
private static class LazyHolder {
private static final ContractConverter INSTANCE = new ContractConverter();
}
public static ContractConverter instance() {
return LazyHolder.INSTANCE;
}
private final ObjectMapper mapper;
private ContractConverter() {
mapper = new ObjectMapper();
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.registerModule(new GuavaModule());
}
public <T> T convertObjectNodeToContract(ObjectNode node, ContractFactory<T> factory) throws JsonProcessingException {
return updateObjectNodeToContract(node,factory.newInstance());
}
private <T> T updateObjectNodeToContract(ObjectNode node, T defaultValues) throws JsonProcessingException {
return mapper
.readerForUpdating(defaultValues)
.treeToValue(node, (Class<? extends T>) defaultValues.getClass());
}
public <T> T convertContractToContract(Object contract, ContractFactory<T> factory) throws JsonProcessingException {
return updateContractToContract(contract, factory.newInstance());
}
private <T> T updateContractToContract(Object contract, T defaultValues) throws JsonProcessingException {
ObjectNode node = convertContractToObjectNode(contract);
return updateObjectNodeToContract(node, defaultValues);
}
public ObjectNode convertContractToObjectNode(Object contract) {
return mapper.valueToTree(contract);
}
public Map convertContractToMap(Object contract) {
return Collections.unmodifiableMap(mapper.convertValue(contract, Map.class));
}
public Map<String, Object> convertObjectNodeToMap(ObjectNode nodes) {
return mapper.convertValue(nodes, Map.class);
}
public String convertContractToJsonString(Object contract) {
try {
return mapper.writeValueAsString(contract);
} catch (JsonProcessingException e) {
throw Throwables.propagate(e);
}
}
}