can.yrt.oba.serialization.JacksonSerializer.java Source code

Java tutorial

Introduction

Here is the source code for can.yrt.oba.serialization.JacksonSerializer.java

Source

/*
 * Copyright (C) 2010-2012 Paul Watts (paulcwatts@gmail.com)
 *                and individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package can.yrt.oba.serialization;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.TextNode;
import com.fasterxml.jackson.databind.node.TreeTraversingParser;
import can.yrt.oba.ObaApi;

import android.util.Log;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;

public class JacksonSerializer implements ObaApi.SerializationHandler {

    private static final String TAG = "JacksonSerializer";

    private static class SingletonHolder {

        public static final JacksonSerializer INSTANCE = new JacksonSerializer();
    }

    private static final ObjectMapper mMapper = new ObjectMapper();

    static {
        mMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mMapper.setVisibilityChecker(
                VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
    }

    private JacksonSerializer() {
        /* singleton */ }

    /**
     * Make the singleton instance available
     */
    public static ObaApi.SerializationHandler getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static JsonParser getJsonParser(Reader reader) throws IOException, JsonProcessingException {
        TreeTraversingParser parser = new TreeTraversingParser(mMapper.readTree(reader));
        parser.setCodec(mMapper);
        return parser;
    }

    public String toJson(String input) {
        TextNode node = JsonNodeFactory.instance.textNode(input);
        return node.toString();
    }

    @Override
    public <T> T createFromError(Class<T> cls, int code, String error) {
        // This is not very efficient, but it's an error case and it's easier
        // than instantiating one ourselves.
        final String jsonErr = toJson(error);
        final String json = getErrorJson(code, jsonErr);

        try {
            // Hopefully this never returns null or throws.
            return mMapper.readValue(json, cls);
        } catch (JsonParseException e) {
            Log.e(TAG, e.toString());
        } catch (JsonMappingException e) {
            Log.e(TAG, e.toString());
        } catch (IOException e) {
            Log.e(TAG, e.toString());
        }
        return null;
    }

    private String getErrorJson(int code, final String jsonErr) {
        return String.format("{\"code\": %d,\"version\":\"2\",\"text\":%s}", code, jsonErr);
    }

    public <T> T deserialize(Reader reader, Class<T> cls) {
        try {
            T t = getJsonParser(reader).readValueAs(cls);
            if (t == null) {
                // TODO: test switching from Gson for errors
                t = createFromError(cls, ObaApi.OBA_INTERNAL_ERROR, "Json error");
            }
            return t;
        } catch (FileNotFoundException e) {
            return createFromError(cls, ObaApi.OBA_NOT_FOUND, e.toString());
        } catch (JsonProcessingException e) {
            return createFromError(cls, ObaApi.OBA_INTERNAL_ERROR, e.toString());
        } catch (IOException e) {
            return createFromError(cls, ObaApi.OBA_IO_EXCEPTION, e.toString());
        }
    }

    public String serialize(Object obj) {
        StringWriter writer = new StringWriter();
        JsonGenerator jsonGenerator;

        try {
            jsonGenerator = new MappingJsonFactory().createJsonGenerator(writer);
            mMapper.writeValue(jsonGenerator, obj);

            return writer.toString();

        } catch (JsonGenerationException e) {
            Log.e(TAG, e.toString());
            return getErrorJson(ObaApi.OBA_INTERNAL_ERROR, e.toString());
        } catch (JsonMappingException e) {
            Log.e(TAG, e.toString());
            return getErrorJson(ObaApi.OBA_INTERNAL_ERROR, e.toString());
        } catch (IOException e) {
            Log.e(TAG, e.toString());
            return getErrorJson(ObaApi.OBA_IO_EXCEPTION, e.toString());
        }
    }
}