/*
* 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.Date;
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 ca.ualberta.cmput301w14t08.geochan.models.ThreadComment;
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 serialization of a ThreadComment object into JSON format.
*
* @author Artem Herasymchuk
*/
public class ThreadCommentJsonConverter 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);
}
return object;
}
/**
* Deserializes a ThreadComment object from JSON format.
*
* @param json the JsonElement
* @param type the Type
* @param context the JsonDeserializationContext
*
* @return The deserialized ThreadComment.
*
* @throws JsonParseException
*/
@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();
}
Bitmap thumbnail = null;
if (hasImage) {
/*
* http://stackoverflow.com/questions/20594833/convert-byte-array-or-
* bitmap-to-picture
*/
// http://stackoverflow.com/a/5878773
// Sando's workaround for running out of memory on decoding bitmaps.
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inDither = false; // Disable Dithering mode
opts.inPurgeable = true; // Tell to gc that whether it needs free
// memory, the Bitmap can be cleared
opts.inInputShareable = true; // Which kind of reference will be
// used to recover the Bitmap data
// after being clear, when it will be
// used in the future
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);
}
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));
if (hasImage) {
c.setImageThumb(thumbnail);
}
final ThreadComment comment = new ThreadComment(c, title);
comment.setThreadDate(new Date(threadDate));
comment.setId(Long.parseLong(id));
return comment;
}
}