package com.vaguehope.onosendai.config; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import android.os.Environment; import com.vaguehope.onosendai.C; import com.vaguehope.onosendai.util.IoHelper; import com.vaguehope.onosendai.util.StringHelper; public class Config { private static final String SECTION_ACCOUNTS = "accounts"; private static final String SECTION_FEEDS = "feeds"; public static boolean isConfigFilePresent () { return configFile().exists(); } public static File writeExampleConfig () throws ConfigException { try { final File t = configFile(); if (t.exists()) throw new ConfigException("Configuration file '" + t.getAbsolutePath() + "' already exists."); IoHelper.resourceToFile("/deck.conf", t); return t; } catch (final IOException e) { throw new ConfigException(e); } } public static Config getConfig () throws ConfigUnavailableException { final File f = configFile(); if (!f.exists()) throw new ConfigUnavailableException("Configuration file '" + f.getAbsolutePath() + "' does not exist."); try { return new Config(f); } catch (final IOException e) { throw new ConfigUnavailableException(e); } catch (final JSONException e) { throw new ConfigUnavailableException(e); } } public static File configFile () { return new File(Environment.getExternalStorageDirectory().getPath(), C.CONFIG_FILE_NAME); } private final Map<String, Account> accounts; private final List<Column> feeds; private Config (final File f) throws IOException, JSONException { final String s = IoHelper.fileToString(f); final JSONObject o = (JSONObject) new JSONTokener(s).nextValue(); this.accounts = parseAccounts(o.getJSONArray(SECTION_ACCOUNTS)); this.feeds = parseFeeds(o.getJSONArray(SECTION_FEEDS)); } Config (final Collection<Account> accounts, final Collection<Column> columns) { final Map<String, Account> a = new LinkedHashMap<String, Account>(); for (final Account account : accounts) { a.put(account.getId(), account); } final List<Column> f = new ArrayList<Column>(); f.addAll(columns); this.accounts = Collections.unmodifiableMap(a); this.feeds = Collections.unmodifiableList(f); } public Map<String, Account> getAccounts () { return this.accounts; } public Account getAccount (final String accountId) { if (StringHelper.isEmpty(accountId)) return null; return this.accounts.get(accountId); } public List<Account> getAccounts (final Collection<String> accountIds) { if (accountIds == null || accountIds.size() < 1) return Collections.emptyList(); final List<Account> ret = new ArrayList<Account>(accountIds.size()); for (final String id : accountIds) { final Account a = getAccount(id); if (a != null) ret.add(a); } return ret; } public Account firstAccountOfType (final AccountProvider provider) { for (final Account a : this.accounts.values()) { if (a.getProvider() == provider) return a; } return null; } public int getColumnCount () { return this.feeds.size(); } public List<Column> getColumns () { return this.feeds; } public Column getColumnByPosition (final int position) { return this.feeds.get(position); } public Column getColumnById (final int columnId) { for (final Column col : this.feeds) { if (columnId == col.getId()) return col; } return null; } public int getColumnPositionById (final int columnId) { for (final Column col : this.feeds) { if (columnId == col.getId()) return this.feeds.indexOf(col); } return -1; } public Column findInternalColumn (final InternalColumnType res) { for (final Column col : getColumns()) { if (res.matchesColumn(col)) return col; } return null; } public int countAccountsWithoutSecrets () { int ret = 0; for (final Account account : this.accounts.values()) { if (!account.hasSecrets()) ret += 1; } return ret; } public JSONObject toJson () throws JSONException { final JSONObject j = new JSONObject(); final JSONArray aj = new JSONArray(); for (final Account a : this.accounts.values()) { aj.put(a.withoutSecrets().toJson()); } j.put(SECTION_ACCOUNTS, aj); final JSONArray fj = new JSONArray(); for (final Column c : this.feeds) { fj.put(c.toJson()); } j.put(SECTION_FEEDS, fj); return j; } private static Map<String, Account> parseAccounts (final JSONArray accountsJson) throws JSONException { final Map<String, Account> ret = new LinkedHashMap<String, Account>(); for (int i = 0; i < accountsJson.length(); i++) { final Account account = Account.parseJson(accountsJson.getJSONObject(i)); ret.put(account.getId(), account); } return Collections.unmodifiableMap(ret); } /** * // TODO allow multiple feeds per column. */ private static List<Column> parseFeeds (final JSONArray columnsJson) throws JSONException { final List<Column> ret = new ArrayList<Column>(); for (int i = 0; i < columnsJson.length(); i++) { final Column column = Column.parseJson(columnsJson.getJSONObject(i)); ret.add(column); } return Collections.unmodifiableList(ret); } }