package org.springframework.data.simpledb.util.marshaller;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.mrbean.MrBeanModule;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mapping.model.MappingException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;

public class
        JsonMarshaller implements Marshaller {

    private static final Logger log = LoggerFactory.getLogger(JsonMarshaller.class);

    private ObjectMapper mapper;

    public JsonMarshaller() {
        JsonFactory factory = new JsonFactory();
        mapper = new ObjectMapper(factory);
        JsonUnknownPropertyHandler jsonUnknownPropertyHandler = new JsonUnknownPropertyHandler();
        mapper.getDeserializationConfig().addHandler(jsonUnknownPropertyHandler);
        mapper.registerModule(new MrBeanModule());
    }

    @Override
    public <T> T unmarshal(String input, Class<T> clazz) {

        if (input == null) {
            log.warn("Null input given to unmarshal, will return null.");
            return null;
        }

        T unmarshalledObject;
        try {
            unmarshalledObject = mapper.readValue(input, clazz);
        } catch (JsonParseException e) {
            //in case of error, if the required class is string, just return the original input
            if (clazz.equals(String.class)) {
                return (T) input;
            }
            throw new MappingException(e.getMessage(), e);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        return unmarshalledObject;
    }

    @Override
    public <T> T unmarshal(String input, TypeReference<T> typeReference) {

        if (input == null) {
            log.warn("Null input given to unmarshal, will return null.");
            return null;
        }

        T unmarshalledObject;
        try {
            unmarshalledObject = mapper.<T>readValue(input, typeReference);
        } catch (Exception e) {
            throw new MappingException(e.getMessage(), e);
        }

        return unmarshalledObject;
    }

    @Override
    public <T> T unmarshal(InputStream input, Class<T> clazz) {

        if (input == null) {
            log.warn("Null input given to unmarshal, will return null.");
            return null;
        }

        BufferedReader jsonReader = new BufferedReader(new InputStreamReader(input));
        StringBuilder jsonOut = new StringBuilder();
        try {
            String line = jsonReader.readLine();
            while (line != null) {
                jsonOut.append(line);
                line = jsonReader.readLine();
            }
            String json = jsonOut.toString();
            return unmarshal(json, clazz);
        }
        catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

    }

    @Override
    public <T> String marshal(T input) {

        if (input == null) {
            log.warn("Null input given to marshal, will return null.");
            return null;
        }

        String marshalledObject;
        try {
            marshalledObject = mapper.writeValueAsString(input);
        } catch (Exception e) {
            throw new MappingException(e.getMessage(), e);
        }

        return marshalledObject;
    }

}

@@ -531,30 +531,8 @@
 der;
-%0Aimport java.util.Map;
 %0A%0Apu
@@ -541,24 +541,16 @@
 ic class
-%0A       
  JsonMar
@@ -2963,24 +2963,16 @@
        %7D
-%0A       
  catch (

Format code.