ca.ualberta.cmput301w14t08.geochan.json.ThreadCommentOfflineJsonConverter.java Source code

Java tutorial

Introduction

Here is the source code for ca.ualberta.cmput301w14t08.geochan.json.ThreadCommentOfflineJsonConverter.java

Source

/*
 * Copyright 2014 Artem Chikin
 * Copyright 2014 Artem Herasymchuk
 * Copyright 2014 Tom Krywitsky
 * Copyright 2014 Henry Pabst
 * Copyright 2014 Bradley Simons
 * 
 * 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 ca.ualberta.cmput301w14t08.geochan.json;

import java.io.ByteArrayOutputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import ca.ualberta.cmput301w14t08.geochan.helpers.GsonHelper;
import ca.ualberta.cmput301w14t08.geochan.models.Comment;
import ca.ualberta.cmput301w14t08.geochan.models.GeoLocation;
import ca.ualberta.cmput301w14t08.geochan.models.ThreadComment;

import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 * Handles the serialization of a ThreadComment object into JSON format for
 * offline caching.
 * 
 * @author Artem Chikin
 * @author Artem Herasymchuk
 */
public class ThreadCommentOfflineJsonConverter
        implements JsonSerializer<ThreadComment>, JsonDeserializer<ThreadComment> {

    /*
     * (non-Javadoc)
     * 
     * @see com.google.gson.JsonSerializer#serialize(java.lang.Object,
     * java.lang.reflect.Type, com.google.gson.JsonSerializationContext)
     */
    /**
     * Serializes a ThreadComment object into JSON format.
     * 
     * @param thread The ThreadComment to serialize.
     * @param type The Type.
     * @param context The JsonSerializationContext
     * 
     * @return A JsonElement representing the serialized ThreadComment.
     */
    @Override
    public JsonElement serialize(ThreadComment thread, Type type, JsonSerializationContext context) {
        JsonObject object = new JsonObject();
        object.addProperty("title", thread.getTitle());
        object.addProperty("threadDate", thread.getThreadDate().getTime());
        object.addProperty("hasImage", thread.getBodyComment().hasImage());
        object.addProperty("id", thread.getId());
        if (thread.getBodyComment().getLocation() != null) {
            object.addProperty("location", thread.getBodyComment().getLocation().getLatitude() + ","
                    + thread.getBodyComment().getLocation().getLongitude());
            if (thread.getBodyComment().getLocation().getLocationDescription() != null) {
                object.addProperty("locationDescription",
                        thread.getBodyComment().getLocation().getLocationDescription());
            }
        } else {
            object.addProperty("location", "-999,-999");
        }
        object.addProperty("user", thread.getBodyComment().getUser());
        object.addProperty("hash", thread.getBodyComment().getHash());
        object.addProperty("textPost", thread.getBodyComment().getTextPost());

        if (thread.getBodyComment().hasImage()) {
            Bitmap bitmapThumb = thread.getBodyComment().getImageThumb();

            /*
             * http://stackoverflow.com/questions/9224056/android-bitmap-to-base64
             * -string
             */
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            bitmapThumb.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream);
            byte[] byteThumbArray = byteArrayOutputStream.toByteArray();
            String encodedThumb = Base64.encodeToString(byteThumbArray, Base64.NO_WRAP);
            object.addProperty("imageThumbnail", encodedThumb);
        }
        recursiveSerialize(object, thread.getBodyComment(), thread.getBodyComment().getChildren());

        // Serialize all the images in the thread.
        return object;
    }

    /**
     * Deserializes a ThreadComment object from JSON format.
     * 
     * @param json The JsonElement to deserialize.
     * @param type The Type.
     * @param context The JsonDeserializationContext.
     * 
     * @return The deserialized ThreadComment.
     */
    @Override
    public ThreadComment deserialize(JsonElement json, Type type, JsonDeserializationContext context)
            throws JsonParseException {
        JsonObject object = json.getAsJsonObject();
        String title = object.get("title").getAsString();
        long threadDate = object.get("threadDate").getAsLong();
        boolean hasImage = object.get("hasImage").getAsBoolean();
        String locationString = object.get("location").getAsString();
        List<String> locationEntries = Arrays.asList(locationString.split(","));
        double latitude = Double.parseDouble(locationEntries.get(0));
        double longitude = Double.parseDouble(locationEntries.get(1));
        String user = object.get("user").getAsString();
        String hash = object.get("hash").getAsString();
        String id = object.get("id").getAsString();
        String textPost = object.get("textPost").getAsString();
        String locationDescription = null;
        if (object.get("locationDescription") != null) {
            locationDescription = object.get("locationDescription").getAsString();
        }
        ArrayList<Comment> topList = new ArrayList<Comment>();
        recursiveDeserialize(object, id, topList);
        Bitmap thumbnail = null;
        if (hasImage) {
            /*
             * http://stackoverflow.com/questions/20594833/convert-byte-array-or-
             * bitmap-to-picture
             */
            String encodedThumb = object.get("imageThumbnail").getAsString();
            byte[] thumbArray = Base64.decode(encodedThumb, Base64.NO_WRAP);
            thumbnail = BitmapFactory.decodeByteArray(thumbArray, 0, thumbArray.length);
        }
        GeoLocation location = new GeoLocation(latitude, longitude);
        location.setLocationDescription(locationDescription);
        final Comment c = new Comment(textPost, null, location, null);
        c.getCommentDate().setTime(threadDate);
        c.setUser(user);
        c.setHash(hash);
        c.setId(Long.parseLong(id));
        c.setChildren(topList);
        if (hasImage) {
            c.setImageThumb(thumbnail);
        }
        final ThreadComment comment = new ThreadComment(c, title);
        comment.setThreadDate(new Date(threadDate));
        comment.setId(Long.parseLong(id));
        return comment;
    }

    private void recursiveSerialize(JsonObject object, Comment parent, ArrayList<Comment> list) {
        object.addProperty(parent.getId(), GsonHelper.getOfflineGson().toJson(list));
        for (Comment comment : list) {
            recursiveSerialize(object, comment, comment.getChildren());
        }
    }

    private void recursiveDeserialize(JsonObject object, String id, ArrayList<Comment> list) {
        JsonParser parser = new JsonParser();
        JsonArray array = parser.parse(object.get(id).getAsString()).getAsJsonArray();
        for (int i = 0; i < array.size(); ++i) {
            list.add(GsonHelper.getOfflineGson().fromJson(array.get(i), Comment.class));
        }
        for (Comment comment : list) {
            ArrayList<Comment> childList = new ArrayList<Comment>();
            recursiveDeserialize(object, comment.getId(), childList);
            comment.setChildren(childList);
        }
    }
}