blob: 16f905329d265a3b3ac336faadd828a096ee6029 [file] [log] [blame]
package org.wordpress.android.models;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Holds blog settings and provides methods to (de)serialize .com and self-hosted network calls.
*/
public class SiteSettingsModel {
public static final int RELATED_POSTS_ENABLED_FLAG = 0x1;
public static final int RELATED_POST_HEADER_FLAG = 0x2;
public static final int RELATED_POST_IMAGE_FLAG = 0x4;
// Settings table column names
public static final String ID_COLUMN_NAME = "id";
public static final String ADDRESS_COLUMN_NAME = "address";
public static final String USERNAME_COLUMN_NAME = "username";
public static final String PASSWORD_COLUMN_NAME = "password";
public static final String TITLE_COLUMN_NAME = "title";
public static final String TAGLINE_COLUMN_NAME = "tagline";
public static final String LANGUAGE_COLUMN_NAME = "language";
public static final String PRIVACY_COLUMN_NAME = "privacy";
public static final String LOCATION_COLUMN_NAME = "location";
public static final String DEF_CATEGORY_COLUMN_NAME = "defaultCategory";
public static final String DEF_POST_FORMAT_COLUMN_NAME = "defaultPostFormat";
public static final String CATEGORIES_COLUMN_NAME = "categories";
public static final String POST_FORMATS_COLUMN_NAME = "postFormats";
public static final String CREDS_VERIFIED_COLUMN_NAME = "credsVerified";
public static final String RELATED_POSTS_COLUMN_NAME = "relatedPosts";
public static final String ALLOW_COMMENTS_COLUMN_NAME = "allowComments";
public static final String SEND_PINGBACKS_COLUMN_NAME = "sendPingbacks";
public static final String RECEIVE_PINGBACKS_COLUMN_NAME = "receivePingbacks";
public static final String SHOULD_CLOSE_AFTER_COLUMN_NAME = "shouldCloseAfter";
public static final String CLOSE_AFTER_COLUMN_NAME = "closeAfter";
public static final String SORT_BY_COLUMN_NAME = "sortBy";
public static final String SHOULD_THREAD_COLUMN_NAME = "shouldThread";
public static final String THREADING_COLUMN_NAME = "threading";
public static final String SHOULD_PAGE_COLUMN_NAME = "shouldPage";
public static final String PAGING_COLUMN_NAME = "paging";
public static final String MANUAL_APPROVAL_COLUMN_NAME = "manualApproval";
public static final String IDENTITY_REQUIRED_COLUMN_NAME = "identityRequired";
public static final String USER_ACCOUNT_REQUIRED_COLUMN_NAME = "userAccountRequired";
public static final String WHITELIST_COLUMN_NAME = "whitelist";
public static final String MODERATION_KEYS_COLUMN_NAME = "moderationKeys";
public static final String BLACKLIST_KEYS_COLUMN_NAME = "blacklistKeys";
public static final String SETTINGS_TABLE_NAME = "site_settings";
public static final String CREATE_SETTINGS_TABLE_SQL =
"CREATE TABLE IF NOT EXISTS " +
SETTINGS_TABLE_NAME +
" (" +
ID_COLUMN_NAME + " INTEGER PRIMARY KEY, " +
ADDRESS_COLUMN_NAME + " TEXT, " +
USERNAME_COLUMN_NAME + " TEXT, " +
PASSWORD_COLUMN_NAME + " TEXT, " +
TITLE_COLUMN_NAME + " TEXT, " +
TAGLINE_COLUMN_NAME + " TEXT, " +
LANGUAGE_COLUMN_NAME + " INTEGER, " +
PRIVACY_COLUMN_NAME + " INTEGER, " +
LOCATION_COLUMN_NAME + " BOOLEAN, " +
DEF_CATEGORY_COLUMN_NAME + " TEXT, " +
DEF_POST_FORMAT_COLUMN_NAME + " TEXT, " +
CATEGORIES_COLUMN_NAME + " TEXT, " +
POST_FORMATS_COLUMN_NAME + " TEXT, " +
CREDS_VERIFIED_COLUMN_NAME + " BOOLEAN, " +
RELATED_POSTS_COLUMN_NAME + " INTEGER, " +
ALLOW_COMMENTS_COLUMN_NAME + " BOOLEAN, " +
SEND_PINGBACKS_COLUMN_NAME + " BOOLEAN, " +
RECEIVE_PINGBACKS_COLUMN_NAME + " BOOLEAN, " +
SHOULD_CLOSE_AFTER_COLUMN_NAME + " BOOLEAN, " +
CLOSE_AFTER_COLUMN_NAME + " INTEGER, " +
SORT_BY_COLUMN_NAME + " INTEGER, " +
SHOULD_THREAD_COLUMN_NAME + " BOOLEAN, " +
THREADING_COLUMN_NAME + " INTEGER, " +
SHOULD_PAGE_COLUMN_NAME + " BOOLEAN, " +
PAGING_COLUMN_NAME + " INTEGER, " +
MANUAL_APPROVAL_COLUMN_NAME + " BOOLEAN, " +
IDENTITY_REQUIRED_COLUMN_NAME + " BOOLEAN, " +
USER_ACCOUNT_REQUIRED_COLUMN_NAME + " BOOLEAN, " +
WHITELIST_COLUMN_NAME + " BOOLEAN, " +
MODERATION_KEYS_COLUMN_NAME + " TEXT, " +
BLACKLIST_KEYS_COLUMN_NAME + " TEXT" +
");";
public boolean isInLocalTable;
public boolean hasVerifiedCredentials;
public long localTableId;
public String address;
public String username;
public String password;
public String title;
public String tagline;
public String language;
public int languageId;
public int privacy;
public boolean location;
public int defaultCategory;
public CategoryModel[] categories;
public String defaultPostFormat;
public Map<String, String> postFormats;
public boolean showRelatedPosts;
public boolean showRelatedPostHeader;
public boolean showRelatedPostImages;
public boolean allowComments;
public boolean sendPingbacks;
public boolean receivePingbacks;
public boolean shouldCloseAfter;
public int closeCommentAfter;
public int sortCommentsBy;
public boolean shouldThreadComments;
public int threadingLevels;
public boolean shouldPageComments;
public int commentsPerPage;
public boolean commentApprovalRequired;
public boolean commentsRequireIdentity;
public boolean commentsRequireUserAccount;
public boolean commentAutoApprovalKnownUsers;
public int maxLinks;
public List<String> holdForModeration;
public List<String> blacklist;
@Override
public boolean equals(Object other) {
if (!(other instanceof SiteSettingsModel)) return false;
SiteSettingsModel otherModel = (SiteSettingsModel) other;
return localTableId == otherModel.localTableId &&
address.equals(otherModel.address) &&
username.equals(otherModel.username) &&
password.equals(otherModel.password) &&
title.equals(otherModel.title) &&
tagline.equals(otherModel.tagline) &&
languageId == otherModel.languageId &&
privacy == otherModel.privacy &&
location == otherModel.location &&
defaultPostFormat.equals(otherModel.defaultPostFormat) &&
defaultCategory == otherModel.defaultCategory &&
showRelatedPosts == otherModel.showRelatedPosts &&
showRelatedPostHeader == otherModel.showRelatedPostHeader &&
showRelatedPostImages == otherModel.showRelatedPostImages &&
allowComments == otherModel.allowComments &&
sendPingbacks == otherModel.sendPingbacks &&
receivePingbacks == otherModel.receivePingbacks &&
closeCommentAfter == otherModel.closeCommentAfter &&
sortCommentsBy == otherModel.sortCommentsBy &&
threadingLevels == otherModel.threadingLevels &&
commentsPerPage == otherModel.commentsPerPage &&
commentApprovalRequired == otherModel.commentApprovalRequired &&
commentsRequireIdentity == otherModel.commentsRequireIdentity &&
commentsRequireUserAccount == otherModel.commentsRequireUserAccount &&
commentAutoApprovalKnownUsers == otherModel.commentAutoApprovalKnownUsers &&
maxLinks == otherModel.maxLinks &&
holdForModeration != null && holdForModeration.equals(otherModel.holdForModeration) &&
blacklist != null && blacklist.equals(otherModel.blacklist);
}
/**
* Copies data from another {@link SiteSettingsModel}.
*/
public void copyFrom(SiteSettingsModel other) {
if (other == null) return;
isInLocalTable = other.isInLocalTable;
hasVerifiedCredentials = other.hasVerifiedCredentials;
localTableId = other.localTableId;
address = other.address;
username = other.username;
password = other.password;
title = other.title;
tagline = other.tagline;
language = other.language;
languageId = other.languageId;
privacy = other.privacy;
location = other.location;
defaultCategory = other.defaultCategory;
categories = other.categories;
defaultPostFormat = other.defaultPostFormat;
postFormats = other.postFormats;
showRelatedPosts = other.showRelatedPosts;
showRelatedPostHeader = other.showRelatedPostHeader;
showRelatedPostImages = other.showRelatedPostImages;
allowComments = other.allowComments;
sendPingbacks = other.sendPingbacks;
receivePingbacks = other.receivePingbacks;
shouldCloseAfter = other.shouldCloseAfter;
closeCommentAfter = other.closeCommentAfter;
sortCommentsBy = other.sortCommentsBy;
shouldThreadComments = other.shouldThreadComments;
threadingLevels = other.threadingLevels;
shouldPageComments = other.shouldPageComments;
commentsPerPage = other.commentsPerPage;
commentApprovalRequired = other.commentApprovalRequired;
commentsRequireIdentity = other.commentsRequireIdentity;
commentsRequireUserAccount = other.commentsRequireUserAccount;
commentAutoApprovalKnownUsers = other.commentAutoApprovalKnownUsers;
maxLinks = other.maxLinks;
if (other.holdForModeration != null) {
holdForModeration = new ArrayList<>(other.holdForModeration);
}
if (other.blacklist != null) {
blacklist = new ArrayList<>(other.blacklist);
}
}
/**
* Sets values from a local database {@link Cursor}.
*/
public void deserializeOptionsDatabaseCursor(Cursor cursor, Map<Integer, CategoryModel> models) {
if (cursor == null || !cursor.moveToFirst() || cursor.getCount() == 0) return;
localTableId = getIntFromCursor(cursor, ID_COLUMN_NAME);
address = getStringFromCursor(cursor, ADDRESS_COLUMN_NAME);
username = getStringFromCursor(cursor, USERNAME_COLUMN_NAME);
password = getStringFromCursor(cursor, PASSWORD_COLUMN_NAME);
title = getStringFromCursor(cursor, TITLE_COLUMN_NAME);
tagline = getStringFromCursor(cursor, TAGLINE_COLUMN_NAME);
languageId = getIntFromCursor(cursor, LANGUAGE_COLUMN_NAME);
privacy = getIntFromCursor(cursor, PRIVACY_COLUMN_NAME);
defaultCategory = getIntFromCursor(cursor, DEF_CATEGORY_COLUMN_NAME);
defaultPostFormat = getStringFromCursor(cursor, DEF_POST_FORMAT_COLUMN_NAME);
location = getBooleanFromCursor(cursor, LOCATION_COLUMN_NAME);
hasVerifiedCredentials = getBooleanFromCursor(cursor, CREDS_VERIFIED_COLUMN_NAME);
allowComments = getBooleanFromCursor(cursor, ALLOW_COMMENTS_COLUMN_NAME);
sendPingbacks = getBooleanFromCursor(cursor, SEND_PINGBACKS_COLUMN_NAME);
receivePingbacks = getBooleanFromCursor(cursor, RECEIVE_PINGBACKS_COLUMN_NAME);
shouldCloseAfter = getBooleanFromCursor(cursor, SHOULD_CLOSE_AFTER_COLUMN_NAME);
closeCommentAfter = getIntFromCursor(cursor, CLOSE_AFTER_COLUMN_NAME);
sortCommentsBy = getIntFromCursor(cursor, SORT_BY_COLUMN_NAME);
shouldThreadComments = getBooleanFromCursor(cursor, SHOULD_THREAD_COLUMN_NAME);
threadingLevels = getIntFromCursor(cursor, THREADING_COLUMN_NAME);
shouldPageComments = getBooleanFromCursor(cursor, SHOULD_PAGE_COLUMN_NAME);
commentsPerPage = getIntFromCursor(cursor, PAGING_COLUMN_NAME);
commentApprovalRequired = getBooleanFromCursor(cursor, MANUAL_APPROVAL_COLUMN_NAME);
commentsRequireIdentity = getBooleanFromCursor(cursor, IDENTITY_REQUIRED_COLUMN_NAME);
commentsRequireUserAccount = getBooleanFromCursor(cursor, USER_ACCOUNT_REQUIRED_COLUMN_NAME);
commentAutoApprovalKnownUsers = getBooleanFromCursor(cursor, WHITELIST_COLUMN_NAME);
String moderationKeys = getStringFromCursor(cursor, MODERATION_KEYS_COLUMN_NAME);
String blacklistKeys = getStringFromCursor(cursor, BLACKLIST_KEYS_COLUMN_NAME);
holdForModeration = new ArrayList<>();
blacklist = new ArrayList<>();
if (!TextUtils.isEmpty(moderationKeys)) {
Collections.addAll(holdForModeration, moderationKeys.split("\n"));
}
if (!TextUtils.isEmpty(blacklistKeys)) {
Collections.addAll(blacklist, blacklistKeys.split("\n"));
}
setRelatedPostsFlags(Math.max(0, getIntFromCursor(cursor, RELATED_POSTS_COLUMN_NAME)));
String cachedCategories = getStringFromCursor(cursor, CATEGORIES_COLUMN_NAME);
String cachedFormats = getStringFromCursor(cursor, POST_FORMATS_COLUMN_NAME);
if (models != null && !TextUtils.isEmpty(cachedCategories)) {
String[] split = cachedCategories.split(",");
categories = new CategoryModel[split.length];
for (int i = 0; i < split.length; ++i) {
int catId = Integer.parseInt(split[i]);
categories[i] = models.get(catId);
}
}
if (!TextUtils.isEmpty(cachedFormats)) {
String[] split = cachedFormats.split(";");
postFormats = new HashMap<>();
for (String format : split) {
String[] kvp = format.split(",");
postFormats.put(kvp[0], kvp[1]);
}
}
int cachedRelatedPosts = getIntFromCursor(cursor, RELATED_POSTS_COLUMN_NAME);
if (cachedRelatedPosts != -1) {
setRelatedPostsFlags(cachedRelatedPosts);
}
isInLocalTable = true;
}
/**
* Creates the {@link ContentValues} object to store this category data in a local database.
*/
public ContentValues serializeToDatabase() {
ContentValues values = new ContentValues();
values.put(ID_COLUMN_NAME, localTableId);
values.put(ADDRESS_COLUMN_NAME, address);
values.put(USERNAME_COLUMN_NAME, username);
values.put(PASSWORD_COLUMN_NAME, password);
values.put(TITLE_COLUMN_NAME, title);
values.put(TAGLINE_COLUMN_NAME, tagline);
values.put(PRIVACY_COLUMN_NAME, privacy);
values.put(LANGUAGE_COLUMN_NAME, languageId);
values.put(LOCATION_COLUMN_NAME, location);
values.put(DEF_CATEGORY_COLUMN_NAME, defaultCategory);
values.put(CATEGORIES_COLUMN_NAME, categoryIdList(categories));
values.put(DEF_POST_FORMAT_COLUMN_NAME, defaultPostFormat);
values.put(POST_FORMATS_COLUMN_NAME, postFormatList(postFormats));
values.put(CREDS_VERIFIED_COLUMN_NAME, hasVerifiedCredentials);
values.put(RELATED_POSTS_COLUMN_NAME, getRelatedPostsFlags());
values.put(ALLOW_COMMENTS_COLUMN_NAME, allowComments);
values.put(SEND_PINGBACKS_COLUMN_NAME, sendPingbacks);
values.put(RECEIVE_PINGBACKS_COLUMN_NAME, receivePingbacks);
values.put(SHOULD_CLOSE_AFTER_COLUMN_NAME, shouldCloseAfter);
values.put(CLOSE_AFTER_COLUMN_NAME, closeCommentAfter);
values.put(SORT_BY_COLUMN_NAME, sortCommentsBy);
values.put(SHOULD_THREAD_COLUMN_NAME, shouldThreadComments);
values.put(THREADING_COLUMN_NAME, threadingLevels);
values.put(SHOULD_PAGE_COLUMN_NAME, shouldPageComments);
values.put(PAGING_COLUMN_NAME, commentsPerPage);
values.put(MANUAL_APPROVAL_COLUMN_NAME, commentApprovalRequired);
values.put(IDENTITY_REQUIRED_COLUMN_NAME, commentsRequireIdentity);
values.put(USER_ACCOUNT_REQUIRED_COLUMN_NAME, commentsRequireUserAccount);
values.put(WHITELIST_COLUMN_NAME, commentAutoApprovalKnownUsers);
String moderationKeys = "";
if (holdForModeration != null) {
for (String key : holdForModeration) {
moderationKeys += key + "\n";
}
}
String blacklistKeys = "";
if (blacklist != null) {
for (String key : blacklist) {
blacklistKeys += key + "\n";
}
}
values.put(MODERATION_KEYS_COLUMN_NAME, moderationKeys);
values.put(BLACKLIST_KEYS_COLUMN_NAME, blacklistKeys);
return values;
}
public int getRelatedPostsFlags() {
int flags = 0;
if (showRelatedPosts) flags |= RELATED_POSTS_ENABLED_FLAG;
if (showRelatedPostHeader) flags |= RELATED_POST_HEADER_FLAG;
if (showRelatedPostImages) flags |= RELATED_POST_IMAGE_FLAG;
return flags;
}
public void setRelatedPostsFlags(int flags) {
showRelatedPosts = (flags & RELATED_POSTS_ENABLED_FLAG) > 0;
showRelatedPostHeader = (flags & RELATED_POST_HEADER_FLAG) > 0;
showRelatedPostImages = (flags & RELATED_POST_IMAGE_FLAG) > 0;
}
/**
* Used to serialize post formats to store in a local database.
*
* @param formats
* map of post formats where the key is the format ID and the value is the format name
* @return
* a String of semi-colon separated KVP's of Post Formats; Post Format ID -> Post Format Name
*/
private static String postFormatList(Map<String, String> formats) {
if (formats == null || formats.size() == 0) return "";
StringBuilder builder = new StringBuilder();
for (String key : formats.keySet()) {
builder.append(key).append(",").append(formats.get(key)).append(";");
}
builder.setLength(builder.length() - 1);
return builder.toString();
}
/**
* Used to serialize categories to store in a local database.
*
* @param elements
* {@link CategoryModel} array to create String ID list from
* @return
* a String of comma-separated integer Category ID's
*/
private static String categoryIdList(CategoryModel[] elements) {
if (elements == null || elements.length == 0) return "";
StringBuilder builder = new StringBuilder();
for (CategoryModel element : elements) {
builder.append(String.valueOf(element.id)).append(",");
}
builder.setLength(builder.length() - 1);
return builder.toString();
}
/**
* Helper method to get an integer value from a given column in a Cursor.
*/
private int getIntFromCursor(Cursor cursor, String columnName) {
int columnIndex = cursor.getColumnIndex(columnName);
return columnIndex != -1 ? cursor.getInt(columnIndex) : -1;
}
/**
* Helper method to get a String value from a given column in a Cursor.
*/
private String getStringFromCursor(Cursor cursor, String columnName) {
int columnIndex = cursor.getColumnIndex(columnName);
return columnIndex != -1 ? cursor.getString(columnIndex) : "";
}
/**
* Helper method to get a boolean value (stored as an int) from a given column in a Cursor.
*/
private boolean getBooleanFromCursor(Cursor cursor, String columnName) {
int columnIndex = cursor.getColumnIndex(columnName);
return columnIndex != -1 && cursor.getInt(columnIndex) != 0;
}
}