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

Java tutorial

Introduction

Here is the source code for ca.ualberta.cmput301w14t08.geochan.json.CommentOfflineJsonConverter.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.Arrays;
import java.util.List;

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

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.JsonSerializationContext;
import com.google.gson.JsonSerializer;

/**
 * Handles the offline serialization and deserialization of Comment objects 
 * to and from JSON format.
 * 
 * @author Artem Chikin
 * @author Artem Herasymchuk
 * 
 */
public class CommentOfflineJsonConverter implements JsonSerializer<Comment>, JsonDeserializer<Comment> {

    /**
     * Serializes a Comment object into JSON format (for offline storage).
     * 
     * @param comment
     *            the Comment to serialize
     * @param type
     *            the Type
     * @param context
     *            the JSON serialization context
     *            
     * @return A JsonElement representing the serialized Comment.
     */
    @Override
    public JsonElement serialize(Comment comment, Type type, JsonSerializationContext context) {
        JsonObject object = new JsonObject();

        object.addProperty("commentDate", comment.getCommentDate().getTime());

        if (comment.getLocation() != null) {
            object.addProperty("location",
                    comment.getLocation().getLatitude() + "," + comment.getLocation().getLongitude());
            if (comment.getLocation().getLocationDescription() != null) {
                object.addProperty("locationDescription", comment.getLocation().getLocationDescription());
            }
        } else {
            object.addProperty("location", "-999,-999");
        }

        object.addProperty("user", comment.getUser());
        object.addProperty("hash", comment.getHash());
        object.addProperty("id", comment.getId());

        object.addProperty("textPost", comment.getTextPost());

        object.addProperty("hasImage", comment.hasImage());
        if (comment.hasImage()) {
            Bitmap bitmapThumb = comment.getImageThumb();
            /*
             * http://stackoverflow.com/questions/9224056/android-bitmap-to-base64
             * -string
             * 
             * Serialize just the thumbnail as the image is serialized
             * separately
             */
            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);
        }

        object.addProperty("depth", comment.getDepth());
        if (comment.getParent() != null) {
            object.addProperty("parent", comment.getParent().getId());
        }

        return object;
    }

    /**
     * Deserializes a Comment object from JSON format (for offline storage).
     * @param json
     *            the JSON element to deserialize
     * @param type
     *            the Type
     * @param context
     *            the JSON deserialization context
     *            
     * @return The deserialized Comment.
     * 
     * @throws JsonParseException
     */
    @Override
    public Comment deserialize(JsonElement json, Type type, JsonDeserializationContext context)
            throws JsonParseException {
        JsonObject object = json.getAsJsonObject();

        long commentDate = object.get("commentDate").getAsLong();

        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 locationDescription = null;
        if (object.get("locationDescription") != null) {
            locationDescription = object.get("locationDescription").getAsString();
        }
        GeoLocation location = new GeoLocation(latitude, longitude);
        location.setLocationDescription(locationDescription);

        String user = object.get("user").getAsString();
        String hash = object.get("hash").getAsString();
        String id = object.get("id").getAsString();

        String textPost = object.get("textPost").getAsString();

        Bitmap thumbnail = null;
        boolean hasImage = object.get("hasImage").getAsBoolean();
        if (hasImage) {
            /*
             * http://stackoverflow.com/a/5878773
             * Sando's workaround for running out of memory on decoding bitmaps.
             * 
             * Only deserialize the thumbnail as the full image is deserialized 
             * separately.
             */
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inDither = false;
            opts.inPurgeable = true;
            opts.inInputShareable = true;
            opts.inTempStorage = new byte[32 * 1024];
            String encodedThumb = object.get("imageThumbnail").getAsString();
            byte[] thumbArray = Base64.decode(encodedThumb, Base64.NO_WRAP);
            thumbnail = BitmapFactory.decodeByteArray(thumbArray, 0, thumbArray.length, opts);
        }

        int depth = object.get("depth").getAsInt();

        final Comment comment = new Comment(textPost, null, location, null);
        comment.getCommentDate().setTime(commentDate);
        comment.setUser(user);
        comment.setHash(hash);
        comment.setDepth(depth);
        comment.setId(Long.parseLong(id));
        if (hasImage) {
            comment.setImageThumb(thumbnail);
        }

        return comment;
    }
}