package org.getlantern.jsonserializer;
import android.content.Context;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.getlantern.firetweet.util.FiretweetArrayUtils;
import org.getlantern.firetweet.util.Utils;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
public class JSONFileIO extends JSONSerializer {
public static final String JSON_CACHE_DIR = "json_cache";
private static final String KEY_OBJECT = "object";
private static final String KEY_CLASS = "class";
public static JSONArray convertJSONArray(final InputStream stream) throws IOException {
final String string = convertString(stream);
try {
return new JSONArray(string);
} catch (final JSONException e) {
throw new IOException(e);
}
}
public static JSONObject convertJSONObject(final InputStream stream) throws IOException {
final String string = convertString(stream);
try {
return new JSONObject(string);
} catch (final JSONException e) {
throw new IOException(e);
}
}
public static String convertString(final InputStream stream) throws IOException {
if (stream == null) throw new FileNotFoundException();
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.defaultCharset()));
final StringBuffer buf = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append('\n');
}
reader.close();
return buf.toString();
}
public static File getSerializationFile(final Context context, final Object... args) throws IOException {
if (context == null || args == null || args.length == 0) return null;
final File cache_dir = Utils.getBestCacheDir(context, JSON_CACHE_DIR);
if (!cache_dir.exists()) {
cache_dir.mkdirs();
}
final String filename = Utils.encodeQueryParams(FiretweetArrayUtils.toString(args, '.', false));
final File cache_file = new File(cache_dir, filename + ".json");
return cache_file;
}
public static <T extends JSONParcelable> T[] readArray(final File file) throws IOException {
if (file == null) throw new FileNotFoundException();
return readArray(new FileInputStream(file));
}
public static <T extends JSONParcelable> T[] readArray(final InputStream stream) throws IOException {
try {
final JSONObject json = new JSONObject(convertString(stream));
final JSONParcelable.Creator<T> creator = getCreator(json.getString(KEY_CLASS));
return createArray(creator, json.getJSONArray(KEY_OBJECT));
} catch (final JSONException e) {
throw new IOException(e);
}
}
public static <T extends JSONParcelable> ArrayList<T> readArrayList(final File file) throws IOException {
if (file == null) throw new FileNotFoundException();
return readArrayList(new FileInputStream(file));
}
public static <T extends JSONParcelable> ArrayList<T> readArrayList(final InputStream stream) throws IOException {
try {
final JSONObject json = new JSONObject(convertString(stream));
final JSONParcelable.Creator<T> creator = getCreator(json.getString(KEY_CLASS));
return createArrayList(creator, json.getJSONArray(KEY_OBJECT));
} catch (final JSONException e) {
throw new IOException(e);
}
}
public static <T extends JSONParcelable> T readObject(final File file) throws IOException {
if (file == null) throw new FileNotFoundException();
return readObject(new FileInputStream(file));
}
public static <T extends JSONParcelable> T readObject(final InputStream stream) throws IOException {
try {
final JSONObject json = new JSONObject(convertString(stream));
final JSONParcelable.Creator<T> creator = getCreator(json.optString(KEY_CLASS));
return createObject(creator, json.optJSONObject(KEY_OBJECT));
} catch (final JSONException e) {
throw new IOException(e);
}
}
public static <T extends JSONParcelable> void writeArray(final File file, final T[] array) throws IOException {
writeArray(new FileOutputStream(file), array);
}
public static <T extends JSONParcelable> void writeArray(final OutputStream stream, final T[] array)
throws IOException {
if (stream == null || array == null) return;
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream, Charset.defaultCharset()));
final JSONObject json = new JSONObject();
try {
json.put(KEY_CLASS, array.getClass().getComponentType().getName());
json.put(KEY_OBJECT, toJSONArray(array));
writer.write(jsonToString(json));
writer.flush();
} catch (final JSONException e) {
throw new IOException(e);
} finally {
writer.close();
}
}
public static <T extends JSONParcelable> void writeObject(final File file, final T parcelable) throws IOException {
writeObject(new FileOutputStream(file), parcelable);
}
public static <T extends JSONParcelable> void writeObject(final OutputStream stream, final T parcelable)
throws IOException {
if (stream == null || parcelable == null) return;
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream, Charset.defaultCharset()));
final JSONObject json = new JSONObject();
try {
json.put(KEY_CLASS, parcelable.getClass().getName());
json.put(KEY_OBJECT, toJSONObject(parcelable));
writer.write(jsonToString(json));
writer.flush();
} catch (final JSONException e) {
throw new IOException(e);
} finally {
Utils.closeSilently(writer);
}
}
@SuppressWarnings("unchecked")
private static <T extends JSONParcelable> JSONParcelable.Creator<T> getCreator(final String name)
throws IOException {
try {
final Class<?> cls = Class.forName(name);
return (JSONParcelable.Creator<T>) cls.getField("JSON_CREATOR").get(null);
} catch (final Exception e) {
throw new IOException(e);
}
}
}