/*
* 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.managers;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import ca.ualberta.cmput301w14t08.geochan.helpers.GsonHelper;
import ca.ualberta.cmput301w14t08.geochan.models.Comment;
import ca.ualberta.cmput301w14t08.geochan.models.ThreadComment;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/**
* Class responsible for managing local saving of threadsList, threads, and
* comments. As well as managing and saving the queues of comments and
* threadComments which are to be posted when internet connection is acquired.
*
* @author Artem Chikin
*
*/
public class CacheManager {
private static CacheManager instance = null;
private Context context;
private Gson offlineGson;
private Gson onlineGson;
private static final String EXTENSION = ".sav";
// File for saving ThreadList
private static final String FILENAME = "threads.sav";
private static final String IMAGE = "IMG";
// File for the Queue of Comments to post
private static final String FILENAME2 = "commentq.sav";
// File for the Queue of ChreadComments to post
private static final String FILENAME3 = "threadq.sav";
private ArrayList<Comment> commentQueue;
private ArrayList<ThreadComment> threadCommentQueue;
/**
* Initializes the CacheManager fields, private because of the Singleton
* pattern.
*
* @param context The Context the CacheManager is running in.
*/
private CacheManager(Context context) {
this.context = context;
this.offlineGson = GsonHelper.getOfflineGson();
// thread Gson is same as online - all the data except for the comments.
this.onlineGson = GsonHelper.getOnlineGson();
commentQueue = deserializeCommentQueue();
threadCommentQueue = deserializeThreadCommentQueue();
}
/**
* Adds a comment to the Queue of comments to post when Internet connection
* is acquired. Serializes the queue.
*
* @param comment The Comment to be added to the queue.
*/
public void addCommentToQueue(Comment comment) {
commentQueue.add(comment);
serializeCommentQueue();
}
/**
* Adds a threadComment to the Queue of threadComments to post when Internet
* connection is acquired. Serializes the queue.
*
* @param thread The ThreadComment to be added to the queue.
*/
public void addThreadCommentToQueue(ThreadComment thread) {
threadCommentQueue.add(thread);
serializeThreadCommentQueue();
}
/**
* Using the ThreadManager, posts all the comments and threadComments in the
* queue, called once internet connection is acquired.
*/
public void postAll() {
for (Comment comment : commentQueue) {
ThreadManager.startPost(comment, null, comment.getLocation(), null,
false);
commentQueue.remove(comment);
}
for (ThreadComment threadComment : threadCommentQueue) {
Comment bodyComment = threadComment.getBodyComment();
ThreadManager.startPost(bodyComment, threadComment.getTitle(),
bodyComment.getLocation(), null, false);
threadCommentQueue.remove(threadComment);
}
serializeCommentQueue();
serializeThreadCommentQueue();
}
public static CacheManager getInstance() {
return instance;
}
public static void generateInstance(Context context) {
instance = new CacheManager(context);
}
public ArrayList<Comment> getCommentQueue() {
return commentQueue;
}
public void setCommentQueue(ArrayList<Comment> commentQueue) {
this.commentQueue = commentQueue;
}
public ArrayList<ThreadComment> getThreadCommentQueue() {
return threadCommentQueue;
}
public void setThreadCommentQueue(
ArrayList<ThreadComment> threadCommentQueue) {
this.threadCommentQueue = threadCommentQueue;
}
/**
* Serializes the comment queue to JSON.
*/
public void serializeCommentQueue() {
try {
String json = offlineGson.toJson(getCommentQueue());
FileOutputStream f = context.openFileOutput(FILENAME2,
Context.MODE_PRIVATE);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(f));
w.write(json);
w.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Deserializes the comment queue from JSON.
* @return An ArrayList of the deserialized Comments.
*/
public ArrayList<Comment> deserializeCommentQueue() {
ArrayList<Comment> list = new ArrayList<Comment>();
try {
FileInputStream f = context.openFileInput(FILENAME2);
BufferedReader r = new BufferedReader(new InputStreamReader(f));
String json = "";
String temp = "";
temp = r.readLine();
while (temp != null) {
json = json + temp;
temp = r.readLine();
}
r.close();
f.close();
Type type = new TypeToken<ArrayList<Comment>>() {
}.getType();
list = onlineGson.fromJson(json, type);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
/**
* Serializes the ThreadComment queue to JSON.
*/
public void serializeThreadCommentQueue() {
try {
String json = offlineGson.toJson(getThreadCommentQueue());
FileOutputStream f = context.openFileOutput(FILENAME3,
Context.MODE_PRIVATE);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(f));
w.write(json);
w.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Deserializes the ThreadComment queue from JSON.
* @return An ArrayList of the deserialized ThreadComments.
*/
public ArrayList<ThreadComment> deserializeThreadCommentQueue() {
ArrayList<ThreadComment> list = new ArrayList<ThreadComment>();
try {
FileInputStream f = context.openFileInput(FILENAME3);
BufferedReader r = new BufferedReader(new InputStreamReader(f));
String json = "";
String temp = "";
temp = r.readLine();
while (temp != null) {
json = json + temp;
temp = r.readLine();
}
r.close();
f.close();
Type type = new TypeToken<ArrayList<ThreadComment>>() {
}.getType();
list = onlineGson.fromJson(json, type);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
/**
* Serializes a Bitmap into JSON and stores it in the cache.
* @param image The Bitmap to be serialized.
* @param id The ID of the image being serialized.
*/
public void serializeImage(Bitmap image, String id) {
try {
String json = onlineGson.toJson(image);
FileOutputStream f = context.openFileOutput(IMAGE + id + EXTENSION,
Context.MODE_PRIVATE);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(f));
w.write(json);
w.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Deserializes an image from the cache and returns it.
* @param id The ID of the comment to retrieve.
* @return The deserialized Bitmap.
*/
public Bitmap deserializeImage(String id) {
Bitmap image = null;
try {
FileInputStream f = context.openFileInput(IMAGE + id + EXTENSION);
BufferedReader r = new BufferedReader(new InputStreamReader(f));
String json = "";
String temp = "";
temp = r.readLine();
while (temp != null) {
json = json + temp;
temp = r.readLine();
}
r.close();
f.close();
image = onlineGson.fromJson(json, Bitmap.class);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
/**
* Serialize the list of threads with all the data with the exception of all
* the comment children of the Thread body comment.
*
* @param list The ArrayList of ThreadComments to serialize.
*/
public void serializeThreadList(ArrayList<ThreadComment> list) {
try {
String json = onlineGson.toJson(list);
FileOutputStream f = context.openFileOutput(FILENAME,
Context.MODE_PRIVATE);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(f));
w.write(json);
w.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Deserialize a list of ThreadComment objects without comments.
*
* @return The ArrayList of ThreadComments.
*/
public ArrayList<ThreadComment> deserializeThreadList() {
ArrayList<ThreadComment> list = new ArrayList<ThreadComment>();
try {
FileInputStream f = context.openFileInput(FILENAME);
BufferedReader r = new BufferedReader(new InputStreamReader(f));
String json = "";
String temp = "";
temp = r.readLine();
while (temp != null) {
json = json + temp;
temp = r.readLine();
}
r.close();
f.close();
Type type = new TypeToken<ArrayList<ThreadComment>>() {
}.getType();
list = onlineGson.fromJson(json, type);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
/**
* Serialize ThreadComment object into a file with the file's name being
* ThreadComment's id.
*
* @param thread The ThreadComment to serialize.
*/
public void serializeThreadCommentById(ThreadComment thread) {
try {
String json = offlineGson.toJson(thread);
FileOutputStream f = context.openFileOutput(thread.getId()
+ EXTENSION, Context.MODE_PRIVATE);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(f));
w.write(json);
w.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Retrieve ThreadComment object by id and return the children of its body
* comment. This is done because we already have ThreadComment object and
* its BodyComment from the ThreadComment Deserializers. This deserializer
* runs when a thread is opened and we need to retrieve comments only from
* the cache.
*
* @param id The id of the ThreadComment to deserialize.
* @return An ArrayList of the ThreadComment's body comment's children.
*/
public ArrayList<Comment> deserializeThreadCommentById(String id) {
ThreadComment thread = null;
try {
FileInputStream f = context.openFileInput(id + EXTENSION);
BufferedReader r = new BufferedReader(new InputStreamReader(f));
String json = "";
String temp = "";
temp = r.readLine();
while (temp != null) {
json = json + temp;
temp = r.readLine();
}
r.close();
f.close();
thread = offlineGson.fromJson(json, ThreadComment.class);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (thread != null) {
return thread.getBodyComment().getChildren();
} else {
return null;
}
}
}