org.leopub.mat.model.User.java Source code

Java tutorial

Introduction

Here is the source code for org.leopub.mat.model.User.java

Source

/*
 * Copyright (C) 2015 Liang Jing
 *
 * 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 org.leopub.mat.model;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.leopub.mat.Configure;
import org.leopub.mat.HttpUtil;
import org.leopub.mat.Logger;
import org.leopub.mat.R;
import org.leopub.mat.exception.AuthException;
import org.leopub.mat.exception.HintException;
import org.leopub.mat.exception.NetworkDataException;
import org.leopub.mat.exception.NetworkException;

import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;

public class User {
    private Context mContext;
    private Configure mConfigure;
    private int mUserId;
    private String mSessionId;
    private String mCookieId;
    private SQLiteDatabase mDatabase = null;
    private Map<String, String> mMajorStringMap;
    private Map<Character, String> mUnitTitleStringMap;
    private List<InboxItem> mInboxItemsCache;
    private List<InboxItem> mUndoneInboxItemsCache;
    private List<InboxItem> mUnconfirmedInboxItemsCache;
    private List<InboxItem> mCalendarInboxItemsCache;
    private List<SentItem> mSentItemsCache;
    private DateTime mLastUpdateTimestamp;
    private DateTime mLastSyncTimestamp;

    public User(Context context, int userId) {
        mContext = context;
        mConfigure = new Configure(userId);

        mUserId = userId;
        mSessionId = null;
        mCookieId = null;

        mInboxItemsCache = null;
        mUndoneInboxItemsCache = null;
        mUnconfirmedInboxItemsCache = null;
        mCalendarInboxItemsCache = null;
        mSentItemsCache = null;
        initStringMap();
        initDatabase();
        initTimestamp();
    }

    private void initDatabase() {
        mDatabase = SQLiteDatabase.openOrCreateDatabase(mConfigure.getSQLitePath(), null);
        // create table contact
        String query = "CREATE TABLE IF NOT EXISTS contact (`id` integer PRIMARY KEY, name varchar(255), name_char varchar(10), type char, unit varchar(10), title varchar(10), `f` integer, `b` integer, `t` integer, timestamp timestamp);";
        mDatabase.execSQL(query);
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_contact_timestamp ON contact (timestamp);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_contact_unit ON contact (unit);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_contact_name_char ON contact (name_char);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_contact_f ON contact (f);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_contact_b ON contact (b);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_contact_t ON contact (t);");
        // create table inbox 
        mDatabase.execSQL(
                "CREATE TABLE IF NOT EXISTS `inbox` (`msg_id` integer PRIMARY KEY, `src_id` integer, `src_title` varchar(40), param integer, `type` integer, `start_time` datetime, `end_time` datetime, place varchar(160), `text` varchar(2048), `status` integer, `timestamp` timestamp);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_inbox_timestamp ON inbox (`timestamp`);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_inbox_status ON inbox(`status`);");
        // create table sent
        mDatabase.execSQL(
                "CREATE TABLE IF NOT EXISTS sent (`msg_id` integer PRIMARY KEY, `dst_str` varchar(300), `dst_title` varchar(300), parsm integer, `type` integer, `start_time` datetime, `end_time` datetime, place varchar(160), `text` varchar(2048), `status` integer, `timestamp` timestamp);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_sent_timestamp ON sent (`timestamp`);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_sent_status ON sent (`status`);");
        // create table confirm
        mDatabase.execSQL(
                "CREATE TABLE IF NOT EXISTS `confirm` (confirm_id integer PRIMARY KEY, `msg_id` integer, dst_id integer, dst_title varchar(40), `status` integer, timestamp timestamp);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_confirm_timestamp ON confirm(`timestamp`);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_confirm_msg ON confirm(`msg_id`);");
        // create table update_record
        mDatabase.execSQL(
                "CREATE TABLE IF NOT EXISTS `sync_record`(`id` integer PRIMARY KEY, timestamp timestamp, length integer, updated integer)");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_sync_record_timestamp ON sync_record(`timestamp`);");
        mDatabase.execSQL("CREATE INDEX IF NOT EXISTS idx_sync_record_updated ON sync_record(`updated`);");
    }

    private void initTimestamp() {
        String sql = "SELECT timestamp FROM sync_record WHERE updated=1 ORDER BY timestamp DESC LIMIT 1;";
        Cursor cursor = mDatabase.rawQuery(sql, null);
        if (cursor.moveToNext()) {
            mLastUpdateTimestamp = new DateTime(cursor.getString(0));
        } else {
            mLastUpdateTimestamp = new DateTime(0);
        }

        sql = "SELECT timestamp FROM sync_record ORDER BY timestamp DESC LIMIT 1;";
        cursor = mDatabase.rawQuery(sql, null);
        if (cursor.moveToNext()) {
            mLastSyncTimestamp = new DateTime(cursor.getString(0));
        } else {
            mLastSyncTimestamp = new DateTime(0);
        }
        cursor.close();
    }

    private void initStringMap() {
        mMajorStringMap = new HashMap<>();
        mUnitTitleStringMap = new HashMap<>();
        mMajorStringMap.put("cs", mContext.getString(R.string.short_name_of_cs));
        mUnitTitleStringMap.put('a', mContext.getString(R.string.title_for_a));
        mUnitTitleStringMap.put('b', mContext.getString(R.string.title_for_b));
        mUnitTitleStringMap.put('c', mContext.getString(R.string.title_for_c));
        mUnitTitleStringMap.put('h', mContext.getString(R.string.title_for_h));
        mUnitTitleStringMap.put('l', mContext.getString(R.string.title_for_l));
        mUnitTitleStringMap.put('t', mContext.getString(R.string.title_for_t));
        mUnitTitleStringMap.put('w', mContext.getString(R.string.title_for_w));
        mUnitTitleStringMap.put('x', mContext.getString(R.string.title_for_x));
        mUnitTitleStringMap.put('y', mContext.getString(R.string.title_for_y));
        mUnitTitleStringMap.put('z', mContext.getString(R.string.title_for_z));
    }

    public int getUserId() {
        return mUserId;
    }

    public String getSessionId() {
        return mSessionId;
    }

    public void setSessionId(String sessionId) {
        mSessionId = sessionId;
    }

    public String getCookieId() {
        return mCookieId;
    }

    public void setCookieId(String cookieId) {
        mCookieId = cookieId;
    }

    public boolean isLogedIn() {
        return mCookieId != null;
    }

    public boolean sync(String data) throws NetworkException, NetworkDataException, AuthException {
        if (data == null) {
            String since = mLastSyncTimestamp.toDigitString();
            data = HttpUtil.getUrl(this, Configure.MSG_FETCH_URL + "?since=" + since);
        }
        try {
            boolean updated;

            JSONObject jsonObj = new JSONObject(data);

            updated = updateContact(jsonObj.getJSONArray("contact"));

            updated = updateInbox(jsonObj.getJSONArray("inbox")) || updated;
            mInboxItemsCache = null;
            mUndoneInboxItemsCache = null;
            mUnconfirmedInboxItemsCache = null;
            mCalendarInboxItemsCache = null;

            updated = updateConfirm(jsonObj.getJSONArray("confirm")) || updated;

            updated = updateSent(jsonObj.getJSONArray("sent")) || updated;
            mSentItemsCache = null;

            String timestamp = jsonObj.getString("timestamp");
            mLastSyncTimestamp = new DateTime(timestamp);
            if (updated) {
                mLastUpdateTimestamp = mLastSyncTimestamp;
            }
            addUpdateRecord(jsonObj.getString("timestamp"), data.length(), updated);
            return updated;
        } catch (JSONException e) {
            throw new NetworkDataException("Invalid JSON File", e);
        }
    }

    public boolean updateContact(JSONArray arr) throws NetworkDataException {
        try {
            int n = arr.length();
            for (int i = 0; i < n; i++) {
                JSONObject obj = arr.getJSONObject(i);
                //contact (`id` integer PRIMARY KEY, name varchar(255), type char, unit varchar(10), title varchar(10), timestamp timestamp)
                String query = String.format(
                        "INSERT OR REPLACE INTO contact VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');",
                        obj.getString("id"), obj.getString("name"), obj.getString("name_char"),
                        obj.getString("type"), obj.getString("unit"), obj.getString("title"), obj.getString("f"),
                        obj.getString("b"), obj.getString("t"), obj.getString("timestamp"));
                Logger.d("SQL", query);
                mDatabase.execSQL(query);
            }
            return n != 0;
        } catch (JSONException e) {
            throw new NetworkDataException("JSON/Contact:" + e.getMessage());
        }
    }

    public boolean updateInbox(JSONArray arr) throws NetworkDataException {
        try {
            int n = arr.length();
            for (int i = 0; i < n; i++) {
                JSONObject obj = arr.getJSONObject(i);
                String query = String.format(
                        "INSERT OR REPLACE INTO `inbox` VALUES('%s', '%s', '%s', '%s', '%s', %s, %s, %s, %s, '%s', '%s');",
                        obj.getString("msg_id"), obj.getString("src_id"), getContactTitle(obj.getString("src_id")),
                        obj.getString("param"), obj.getInt("type"),
                        DatabaseUtils.sqlEscapeString(obj.getString("start_time")),
                        DatabaseUtils.sqlEscapeString(obj.getString("end_time")),
                        DatabaseUtils.sqlEscapeString(obj.getString("place")),
                        DatabaseUtils.sqlEscapeString(obj.getString("text")), obj.getString("status"),
                        obj.getString("timestamp"));
                Logger.d("SQL", query);
                mDatabase.execSQL(query);
            }
            return n != 0;
        } catch (JSONException e) {
            throw new NetworkDataException("JSON/Inbox:" + e.getMessage());
        }
    }

    public boolean updateSent(JSONArray arr) throws NetworkDataException {
        try {
            int n = arr.length();
            for (int i = 0; i < n; i++) {
                JSONObject obj = arr.getJSONObject(i);
                //sent (`msg_id` integer PRIMARY KEY, `dst_str` varchar(300), `dst_title` varchar(300), `content` varchar(2048), `status` integer, `timestamp` timestamp)
                String query = String.format(
                        "INSERT OR REPLACE INTO sent VALUES('%s', '%s', '%s', '%s', %d, %s, %s, %s, %s, '%s', '%s');",
                        obj.getString("msg_id"), obj.getString("dst_str"), getGroupsTitle(obj.getString("dst_str")),
                        obj.getString("param"), obj.getInt("type"),
                        DatabaseUtils.sqlEscapeString(obj.getString("start_time")),
                        DatabaseUtils.sqlEscapeString(obj.getString("end_time")),
                        DatabaseUtils.sqlEscapeString(obj.getString("place")),
                        DatabaseUtils.sqlEscapeString(obj.getString("text")), obj.getString("status"),
                        obj.getString("timestamp"));
                Logger.d("SQL", query);
                mDatabase.execSQL(query);
            }
            return n != 0;
        } catch (JSONException e) {
            throw new NetworkDataException("JSON/Sent:" + e.getMessage());
        }
    }

    public boolean updateConfirm(JSONArray arr) throws NetworkDataException {
        try {
            int n = arr.length();
            for (int i = 0; i < n; i++) {
                JSONObject obj = arr.getJSONObject(i);
                //confirm (confirm_id integer PRIMARY KEY, `msg_id` integer, dst_id integer, dst_title varchar(40), `status` integer, timestamp timestamp
                String query = String.format(
                        "INSERT OR REPLACE INTO `confirm` VALUES('%s', '%s', '%s', '%s', '%s', '%s');",
                        obj.getString("confirm_id"), obj.getString("msg_id"), obj.getString("dst_id"),
                        getContactTitle(obj.getString("dst_id")), obj.getString("status"),
                        obj.getString("timestamp"));
                Logger.d("SQL", query);
                mDatabase.execSQL(query);
            }
            return n != 0;
        } catch (JSONException e) {
            throw new NetworkDataException("JSON/Confirm:" + e.getMessage());
        }
    }

    public void addUpdateRecord(String timestamp, int length, boolean isDataUpdated) throws NetworkDataException {
        String query = String.format("INSERT INTO sync_record VALUES(NULL, '%s', '%d', '%d');", timestamp, length,
                isDataUpdated ? 1 : 0);
        Logger.d("SQL", query);
        mDatabase.execSQL(query);
    }

    public DateTime getLastSyncTime() {
        return mLastSyncTimestamp;
    }

    public DateTime getLastUpdateTime() {
        return mLastUpdateTimestamp;
    }

    public List<Contact> getContactsByInitChars(String initChars) {
        List<Contact> res = new ArrayList<>();
        String sql = "SELECT id, name, type, unit, title FROM contact WHERE name_char=? ORDER BY id;";
        String params[] = { initChars };
        Cursor cursor = mDatabase.rawQuery(sql, params);
        while (cursor.moveToNext()) {
            Contact contact = new Contact();
            contact.setId(cursor.getInt(0));
            contact.setName(cursor.getString(1));
            contact.setType(Contact.Type.valueOf(cursor.getString(2)));
            contact.setUnit(cursor.getString(3));
            contact.setTitle(cursor.getString(4));
            res.add(contact);
        }
        cursor.close();
        return res;
    }

    public List<Contact> getUnderling() {
        List<Contact> res = new ArrayList<>();
        Contact me = getContact(mUserId);
        if (me.getTitle().length() == 0) {
            return res;
        }
        String sql = "SELECT id, name, type, unit, title FROM contact WHERE `" + me.getTitle() + "`='" + me.getId()
                + "'ORDER BY id;";
        Cursor cursor = mDatabase.rawQuery(sql, null);
        while (cursor.moveToNext()) {
            Contact contact = new Contact();
            contact.setId(cursor.getInt(0));
            contact.setName(cursor.getString(1));
            contact.setType(Contact.Type.valueOf(cursor.getString(2)));
            contact.setUnit(cursor.getString(3));
            contact.setTitle(cursor.getString(4));
            res.add(contact);
        }
        cursor.close();
        return res;
    }

    public Contact getContact(int id) {
        String sql = "SELECT id, name, type, unit, title FROM contact WHERE id=? ORDER BY id;";
        String params[] = { String.valueOf(id) };
        Cursor cursor = mDatabase.rawQuery(sql, params);
        Contact contact = null;
        if (cursor.moveToNext()) {
            contact = new Contact();
            contact.setId(cursor.getInt(0));
            contact.setName(cursor.getString(1));
            contact.setType(Contact.Type.valueOf(cursor.getString(2)));
            contact.setUnit(cursor.getString(3));
            contact.setTitle(cursor.getString(4));
        }
        cursor.close();
        return contact;
    }

    private List<InboxItem> getInboxItemsPrime(String suffix, String[] params) {
        List<InboxItem> res = new ArrayList<>();
        String sql = "SELECT msg_id, src_id, src_title, type, start_time, end_time, place, text, status, timestamp FROM inbox "
                + suffix;
        Cursor cursor = mDatabase.rawQuery(sql, params);
        while (cursor.moveToNext()) {
            InboxItem item = new InboxItem();
            item.setMsgId(cursor.getInt(0));
            item.setSrcId(cursor.getInt(1));
            item.setSrcTitle(cursor.getString(2));
            item.setType(MessageType.fromOrdial(cursor.getInt(3)));
            item.setStartTime(new DateTime(cursor.getString(4)));
            item.setEndTime(new DateTime(cursor.getString(5)));
            item.setPlace(cursor.getString(6));
            item.setText(cursor.getString(7));
            item.setStatus(MessageStatus.fromOrdial(cursor.getInt(8)));
            item.setTimestamp(new DateTime(cursor.getString(9)));
            res.add(item);
        }
        cursor.close();
        return res;
    }

    public List<InboxItem> getInboxItems() {
        if (mInboxItemsCache != null)
            return mInboxItemsCache;

        List<InboxItem> res = getInboxItemsPrime("ORDER BY status ASC, inbox.timestamp DESC;", null);
        mInboxItemsCache = res;
        return res;
    }

    public InboxItem getInboxItemByMsgId(int msgId) {
        String[] params = { String.valueOf(msgId) };
        List<InboxItem> res = getInboxItemsPrime(" WHERE msg_id=? ORDER BY status ASC, timestamp DESC;", params);
        if (res.size() > 0) {
            return res.get(0);
        } else {
            return null;
        }
    }

    public List<InboxItem> getUndoneInboxItems() {
        if (mUndoneInboxItemsCache != null)
            return mUndoneInboxItemsCache;

        List<InboxItem> res = getInboxItemsPrime(
                "WHERE status < 2 ORDER BY status, type, end_time, timestamp DESC;", null);
        mUndoneInboxItemsCache = res;
        return res;
    }

    public List<InboxItem> getUnconfirmedInboxItems() {
        if (mUnconfirmedInboxItemsCache != null)
            return mUnconfirmedInboxItemsCache;

        List<InboxItem> res = getInboxItemsPrime("WHERE status=0 ORDER BY timestamp DESC;", null);
        mUnconfirmedInboxItemsCache = res;
        return res;
    }

    private List<SentItem> getSentItemsPrime(String suffix, String[] params) {
        List<SentItem> res = new ArrayList<>();
        String sql = "SELECT msg_id, dst_title, type, start_time, end_time, place, text, status, timestamp FROM sent ";
        Cursor cursor = mDatabase.rawQuery(sql + suffix, params);
        while (cursor.moveToNext()) {
            SentItem item = new SentItem();
            item.setMsgId(cursor.getInt(0));
            item.setDstTitle(cursor.getString(1));
            item.setType(MessageType.fromOrdial(cursor.getInt(2)));
            item.setStartTime(new DateTime(cursor.getString(3)));
            item.setEndTime(new DateTime(cursor.getString(4)));
            item.setPlace(cursor.getString(5));
            item.setText(cursor.getString(6));
            item.setStatus(MessageStatus.fromOrdial(cursor.getInt(7)));
            item.setTimestamp(new DateTime(cursor.getString(8)));
            item.setProgress(getSentItemProgress(item.getMsgId()));
            res.add(item);
        }
        cursor.close();
        return res;
    }

    public List<SentItem> getSentItems() {
        if (mSentItemsCache != null)
            return mSentItemsCache;

        List<SentItem> res = getSentItemsPrime("ORDER BY timestamp DESC;", null);
        mSentItemsCache = res;
        return res;
    }

    public SentItem getSentItemByMsgId(int msgId) {
        String[] params = { String.valueOf(msgId) };
        List<SentItem> items = getSentItemsPrime("WHERE msg_id=? ORDER BY timestamp DESC;", params);
        if (items.size() > 0) {
            return items.get(0);
        } else {
            return null;
        }
    }

    public List<ConfirmItem> getConfirmItems(int msgId) {
        List<ConfirmItem> res = new ArrayList<>();
        String sql = "SELECT confirm_id, dst_id, dst_title, status, timestamp FROM confirm "
                + "WHERE msg_id=? ORDER BY timestamp ASC;";
        String[] params = { String.valueOf(msgId) };
        Cursor cursor = mDatabase.rawQuery(sql, params);
        while (cursor.moveToNext()) {
            ConfirmItem item = new ConfirmItem();
            item.setId(cursor.getInt(0));
            item.setMsgId(msgId);
            item.setDstId(cursor.getInt(1));
            item.setDstTitle(cursor.getString(2));
            item.setStatus(MessageStatus.fromOrdial(cursor.getInt(3)));
            item.setTimestamp(new DateTime(cursor.getString(4)));
            res.add(item);
        }
        cursor.close();
        return res;
    }

    public String getSentItemProgress(int msgId) {
        String sql = "SELECT status, COUNT(*) FROM confirm WHERE msg_id=? GROUP BY status;";
        String[] params = { String.valueOf(msgId) };
        Cursor cursor = mDatabase.rawQuery(sql, params);
        int all = 0;
        int confirmed = 0;
        while (cursor.moveToNext()) {
            if (cursor.getInt(0) > 0) {
                confirmed += cursor.getInt(1);
            }
            all += cursor.getInt(1);
        }
        cursor.close();
        return confirmed + "/" + all;
    }

    public String getContactTitle(String id) {
        String params[] = { id };
        Cursor cursor = mDatabase.rawQuery("SELECT name, type FROM contact WHERE id=?;", params);
        String res = null;
        if (cursor.moveToNext()) {
            String name = cursor.getString(0);
            String type = cursor.getString(1);
            if (type.equals("T")) {
                res = name + mContext.getString(R.string.type_for_U);
            } else if (type.equals("S")) {
                res = name + mContext.getString(R.string.type_for_S);
            }
        }
        cursor.close();
        return res;
    }

    private String getGroupsTitle(String groups) {
        StringBuilder sb = new StringBuilder();
        String groupArray[] = groups.split(";");

        for (String group : groupArray) {
            if (group.isEmpty()) {
                continue;
            }
            if (!group.contains(".")) {
                sb.append(getContactTitle(group));
            } else {
                sb.append(getUnitTitle(group));
            }
            sb.append(";");
        }
        return sb.toString();
    }

    public String getUnitTitle(String expr) {
        String exprArray[] = expr.split("\\.");
        String title = exprArray[0];
        String unit = exprArray[1];
        String major = unit.substring(0, 2);
        StringBuilder sb = new StringBuilder();
        if (!major.equals("__")) {
            sb.append(mMajorStringMap.get(major));
        }
        String grade = unit.substring(3, 4);
        if (!grade.equals("_")) {
            sb.append("1");
            sb.append(grade);
            sb.append(mContext.getString(R.string.unit_grade));
        }
        String className = unit.substring(5, 6);
        if (!className.equals("_")) {
            sb.append(className);
            sb.append(mContext.getString(R.string.unit_class));
        }
        if (title.length() == 0) {
            sb.append(mContext.getString(R.string.all_students));
        } else {
            sb.append(mUnitTitleStringMap.get(title.charAt(0)));
        }
        int nTitle = title.length();
        for (int i = 1; i < nTitle; i++) {
            sb.append(",");
            sb.append(mUnitTitleStringMap.get(title.charAt(i)));
        }
        return sb.toString();
    }

    public String getCategoryJSON(int id) throws NetworkException, AuthException {
        return HttpUtil.getUrl(this, Configure.INFO_CATEGORY_URL + "?id=" + id);
    }

    public void sendMessage(String dst, int type, String startTime, String endTime, String place, String text)
            throws AuthException, HintException, NetworkException, NetworkDataException {
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("since=");
            sb.append(mLastSyncTimestamp.toDigitString());
            sb.append("&dst=");
            sb.append(URLEncoder.encode(dst, "utf-8"));
            sb.append("&type=");
            sb.append(type);
            sb.append("&start_time=");
            sb.append(URLEncoder.encode(startTime, "utf-8"));
            sb.append("&end_time=");
            sb.append(URLEncoder.encode(endTime, "utf-8"));
            sb.append("&place=");
            sb.append(URLEncoder.encode(place, "utf-8"));
            sb.append("&text=");
            sb.append(URLEncoder.encode(text, "utf-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        String response = HttpUtil.postURL(this, Configure.MSG_POST_URL, sb.toString());
        if (response.charAt(0) != '[' && response.charAt(0) != '{') {
            throw new HintException(mContext.getString(R.string.send_msg_fail));
        }
        sync(response);
    }

    public void confirmMessage(int srcId, int msgId, int status)
            throws AuthException, HintException, NetworkException, NetworkDataException {
        String url = String.format(Configure.MSG_CONFIRM_URL, srcId, msgId, status,
                mLastSyncTimestamp.toDigitString());
        String response = HttpUtil.getUrl(this, url);
        if (response.charAt(0) != '[' && response.charAt(0) != '{') {
            throw new HintException(mContext.getString(R.string.confirm_msg_fail));
        }
        sync(response);
    }

    public void changePassword(String oldPassword, String newPassword)
            throws AuthException, HintException, NetworkException {
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("old_password=");
            sb.append(URLEncoder.encode(oldPassword, "utf-8"));
            sb.append("&new_password=");
            sb.append(URLEncoder.encode(newPassword, "utf-8"));
            sb.append("&repeat_password=");
            sb.append(URLEncoder.encode(newPassword, "utf-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        String response = HttpUtil.postURL(this, Configure.CHANGE_PASSWORD_URL, sb.toString());
        if (!response.startsWith("Password Updated!")) {
            throw new HintException(response);
        }
    }

    public List<InboxItem> getCalendarInboxItems(DateTime start, DateTime end) {
        if (mCalendarInboxItemsCache != null)
            return mCalendarInboxItemsCache;

        List<InboxItem> res = getInboxItemsPrime("WHERE status = 1 AND type == 1 AND start_time > '"
                + start.toCompleteString() + "' AND end_time < '" + end.toCompleteString()
                + "' ORDER BY status, type, end_time, timestamp DESC;", null);
        mCalendarInboxItemsCache = res;
        return res;
    }
}