package org.openstack.atlas.api.helpers.JsonDeserializer;
import org.openstack.atlas.api.helpers.reflection.ClassReflectionTools;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.util.List;
import static org.openstack.atlas.api.filters.helpers.StringUtilities.getExtendedStackTrace;
public class PropertyListDeserializer extends JsonDeserializer {
private final Log LOG = LogFactory.getLog(PropertyListDeserializer.class);
private ObjectMapper cleanObjectMapper = new ObjectMapper();
private Class forClass;
private Class itemClass;
private String getterName;
public PropertyListDeserializer() {
}
public PropertyListDeserializer(Class forClass,Class itemClass,String getterName) {
this.forClass = forClass;
this.itemClass = itemClass;
this.getterName = getterName;
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Object out = null;
List childList;
String nodeStr = "";
String rootName = ClassReflectionTools.getXmlRootElementName(this.forClass);
String errMsg = "";
String excMsg = "";
JsonNode node = jp.readValueAsTree();
JsonNode childNode = null;
Object nodeObj = null;
if (node.has(rootName)) { // If a root name is found on input strip it off
//and continue decoding
childNode = node.get(rootName);
JsonParser childParser = childNode.traverse();
} else {
childNode = node; // If its not wrapped don't worry about it cause
// its probably a nested child. For example Node fro Nodes
}
nodeStr = childNode.toString();
try {
out = ClassReflectionTools.newInstance(forClass);
childList = (List) ClassReflectionTools.invokeGetter(out, getterName);
for(JsonNode itemNode:childNode) {
String itemJson = itemNode.toString();
Object item = cleanObjectMapper.readValue(itemJson,itemClass);
childList.add(item);
}
} catch (Exception ex) {
excMsg = getExtendedStackTrace(ex);
errMsg = String.format("Error converting \"%s\" into class %s\n",nodeStr,forClass.toString());
LOG.error(errMsg);
throw JsonMappingException.from(jp,errMsg);
}
return out;
}
}