/* * Firetweet - Twitter client for Android * * Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.getlantern.firetweet.util; import android.content.Context; import android.content.SharedPreferences; import org.json.JSONObject; import org.getlantern.jsonserializer.JSONFileIO; import org.getlantern.jsonserializer.JSONSerializer; import org.getlantern.firetweet.Constants; import org.getlantern.firetweet.annotation.Preference; import org.getlantern.firetweet.constant.SharedPreferenceConstants; import org.getlantern.firetweet.model.RawSharedPreferencesData; import org.getlantern.firetweet.model.SharedPreferencesData; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import static org.getlantern.firetweet.annotation.Preference.Type.INVALID; public class DataImportExportUtils implements Constants { public static void exportData(final Context context, final File dst, final int flags) throws IOException { if (dst == null) throw new FileNotFoundException(); dst.delete(); final FileOutputStream fos = new FileOutputStream(dst); final ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos)); if (hasFlag(flags, FLAG_PREFERENCES)) { writeSharedPreferencesData(zos, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES); } if (hasFlag(flags, FLAG_NICKNAMES)) { writeRawSharedPreferencesData(zos, context, USER_NICKNAME_PREFERENCES_NAME, ENTRY_NICKNAMES); } if (hasFlag(flags, FLAG_USER_COLORS)) { writeRawSharedPreferencesData(zos, context, USER_COLOR_PREFERENCES_NAME, ENTRY_USER_COLORS); } if (hasFlag(flags, FLAG_HOST_MAPPING)) { writeRawSharedPreferencesData(zos, context, HOST_MAPPING_PREFERENCES_NAME, ENTRY_HOST_MAPPING); } zos.finish(); zos.flush(); Utils.closeSilently(zos); Utils.closeSilently(fos); } public static int getImportedSettingsFlags(final File src) throws IOException { if (src == null) return 0; final ZipFile zipFile = new ZipFile(src); int flags = 0; if (zipFile.getEntry(ENTRY_PREFERENCES) != null) { flags |= FLAG_PREFERENCES; } if (zipFile.getEntry(ENTRY_NICKNAMES) != null) { flags |= FLAG_NICKNAMES; } if (zipFile.getEntry(ENTRY_USER_COLORS) != null) { flags |= FLAG_USER_COLORS; } if (zipFile.getEntry(ENTRY_HOST_MAPPING) != null) { flags |= FLAG_HOST_MAPPING; } zipFile.close(); return flags; } public static HashMap<String, Preference> getSupportedPreferencesMap() { final Field[] fields = SharedPreferenceConstants.class.getDeclaredFields(); final HashMap<String, Preference> supportedPrefsMap = new HashMap<String, Preference>(); for (final Field field : fields) { final Preference annotation = field.getAnnotation(Preference.class); if (Modifier.isStatic(field.getModifiers()) && CompareUtils.classEquals(field.getType(), String.class) && annotation != null && annotation.exportable() && annotation.type() != INVALID) { try { supportedPrefsMap.put((String) field.get(null), annotation); } catch (final IllegalAccessException e) { } catch (final IllegalArgumentException e) { } } } return supportedPrefsMap; } public static void importData(final Context context, final File src, final int flags) throws IOException { if (src == null) throw new FileNotFoundException(); final ZipFile zipFile = new ZipFile(src); if (hasFlag(flags, FLAG_PREFERENCES)) { readSharedPreferencesData(zipFile, context, SHARED_PREFERENCES_NAME, ENTRY_PREFERENCES); } if (hasFlag(flags, FLAG_NICKNAMES)) { readRawSharedPreferencesData(zipFile, context, USER_NICKNAME_PREFERENCES_NAME, ENTRY_NICKNAMES); } if (hasFlag(flags, FLAG_USER_COLORS)) { readRawSharedPreferencesData(zipFile, context, USER_COLOR_PREFERENCES_NAME, ENTRY_USER_COLORS); } if (hasFlag(flags, FLAG_HOST_MAPPING)) { readRawSharedPreferencesData(zipFile, context, HOST_MAPPING_PREFERENCES_NAME, ENTRY_HOST_MAPPING); } zipFile.close(); } private static byte[] getSerializedRawSharedPreferencesData(final Context context, final String name) { final SharedPreferences prefs = context.getSharedPreferences(name, Context.MODE_PRIVATE); return JSONSerializer.getByteArray(new RawSharedPreferencesData(prefs)); } private static byte[] getSerializedSharedPreferencesData(final Context context, final String name) { final SharedPreferences prefs = context.getSharedPreferences(name, Context.MODE_PRIVATE); return JSONSerializer.getByteArray(new SharedPreferencesData(prefs)); } private static boolean hasFlag(final int flags, final int flag) { return (flags & flag) != 0; } private static void readRawSharedPreferencesData(final ZipFile zipFile, final Context context, final String preferencesName, final String entryName) throws IOException { final ZipEntry entry = zipFile.getEntry(entryName); if (entry == null) return; final JSONObject json = JSONFileIO.convertJSONObject(zipFile.getInputStream(entry)); final RawSharedPreferencesData data = JSONSerializer.createObject(RawSharedPreferencesData.JSON_CREATOR, json); if (data != null) { data.writeToSharedPreferences(context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE)); } } private static void readSharedPreferencesData(final ZipFile zipFile, final Context context, final String preferencesName, final String entryName) throws IOException { final ZipEntry entry = zipFile.getEntry(entryName); if (entry == null) return; final JSONObject json = JSONFileIO.convertJSONObject(zipFile.getInputStream(entry)); final SharedPreferencesData data = JSONSerializer.createObject(SharedPreferencesData.JSON_CREATOR, json); if (data != null) { data.writeToSharedPreferences(context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE)); } } private static void writeRawSharedPreferencesData(final ZipOutputStream zos, final Context context, final String preferencesName, final String entryName) throws IOException { final byte[] data = getSerializedRawSharedPreferencesData(context, preferencesName); if (data == null) return; zos.putNextEntry(new ZipEntry(entryName)); zos.write(data); zos.closeEntry(); } private static void writeSharedPreferencesData(final ZipOutputStream zos, final Context context, final String preferencesName, final String entryName) throws IOException { final byte[] data = getSerializedSharedPreferencesData(context, preferencesName); if (data == null) return; zos.putNextEntry(new ZipEntry(entryName)); zos.write(data); zos.closeEntry(); } }