package net.dev123.yibo.service.cache; import java.util.ArrayList; import java.util.Date; import java.util.List; import net.dev123.commons.Paging; import net.dev123.commons.util.ListUtil; import net.dev123.commons.util.StringUtil; import net.dev123.mblog.entity.DirectMessage; import net.dev123.yibo.R; import net.dev123.yibo.db.BaseDao; import net.dev123.yibo.db.DirectMessageDao; import net.dev123.yibo.db.LocalAccount; import net.dev123.yibo.db.LocalDirectMessage; import net.dev123.yibo.service.cache.wrap.DirectMessageWrap; import android.content.Context; import android.content.res.Resources; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; public class DirectMessageCache implements ListCache<DirectMessageWrap, DirectMessage> { private static final int REMAIN_LEVEL_LIGHT_COUNT = 40; private static final int REMAIN_LEVEL_MODERATE_COUNT = 20; private static final int REMAIN_LEVEL_WEIGHT_COUNT = 10; private Context context = null; private LocalAccount account = null; private List<DirectMessageWrap> listCache = null; public DirectMessageCache(Context context, LocalAccount account) { this.context = context; this.account = account; listCache = new ArrayList<DirectMessageWrap>(); } @Override public void clear() { flush(); listCache.clear(); } @Override public boolean reclaim(ReclaimLevel level) { int remainCount = size(); if (remainCount >= REMAIN_LEVEL_LIGHT_COUNT) { level = ReclaimLevel.MODERATE; } switch(level) { case LIGHT: remainCount = REMAIN_LEVEL_LIGHT_COUNT; break; case MODERATE: remainCount = REMAIN_LEVEL_MODERATE_COUNT; break; case WEIGHT: remainCount = REMAIN_LEVEL_WEIGHT_COUNT; break; } if (size() <= remainCount) { return false; } flush(); while (size() > remainCount) { listCache.remove(remainCount); } LocalDirectMessage divider = new LocalDirectMessage(); divider.setDivider(true); divider.setLocalDivider(true); DirectMessageWrap wrap = new DirectMessageWrap(divider); listCache.add(wrap); return true; } @Override public void flush() { DirectMessageWrap wrap = null; List<DirectMessage> listMessage = new ArrayList<DirectMessage>(); for (int i = 0; i < listCache.size(); i++) { try { wrap = listCache.get(i); } catch(Exception e) { break; } if (wrap == null || wrap.isLocalCached()) { continue; } DirectMessage message = wrap.getWrap(); if (message instanceof LocalDirectMessage && ((LocalDirectMessage)message).isLocalDivider()) { continue; } listMessage.add(wrap.getWrap()); wrap.setLocalCached(true); } if (listMessage.size() > 0) { DirectMessageDao dao = new DirectMessageDao(context); dao.batchSave(listMessage, account); } } @Override public DirectMessageWrap get(int i) { if (i < 0 || i >= size()) { return null; } return listCache.get(i); } @Override public void add(int i, DirectMessageWrap value) { if (i < 0 || i > size()) { return; } listCache.add(i, value); } /** 默认是加前面 **/ @Override public void add(DirectMessageWrap value) { listCache.add(0, value); } public void addAll(int i, List<DirectMessageWrap> values) { if (i < 0 || i > size() || ListUtil.isEmpty(values)) { return; } DirectMessage last = null; if (size() > 0) { last = get(size() - 1).getWrap(); } if (last != null && last instanceof LocalDirectMessage && ((LocalDirectMessage)last).isDivider()) { remove(size() - 1); } String myId = account.getUser().getId(); int insertPos = 0; boolean isInsert = true; for (int j = 0; j < values.size(); j++) { DirectMessageWrap newWrap = values.get(j); DirectMessage newMessage = newWrap.getWrap(); if (newMessage instanceof LocalDirectMessage && ((LocalDirectMessage)newMessage).isDivider()) { continue; } String targetId = newMessage.getSenderId(); if (targetId.equals(myId)) { targetId = newMessage.getRecipientId(); } insertPos = listCache.size(); isInsert = true; for (int k = 0; k < listCache.size(); k++) { DirectMessageWrap oldWrap = listCache.get(k); DirectMessage oldMessage = oldWrap.getWrap(); if (newMessage.getCreatedAt().after(oldMessage.getCreatedAt()) && insertPos == listCache.size()) { insertPos = k; } if (!targetId.equals(oldMessage.getSenderId()) && !targetId.equals(oldMessage.getRecipientId())) { continue; } oldWrap.setCoversationCount(oldWrap.getCoversationCount() + 1); if (newMessage.getCreatedAt().after(oldMessage.getCreatedAt())) { newWrap.setCoversationCount(oldWrap.getCoversationCount()); listCache.remove(k); } else { isInsert = false; } break; } if (isInsert) { listCache.add(insertPos, newWrap); } } LocalDirectMessage divider = new LocalDirectMessage(); divider.setDivider(true); divider.setLocalDivider(true); DirectMessageWrap wrap = new DirectMessageWrap(divider); listCache.add(wrap); } public void addAll(List<DirectMessageWrap> value) { if (ListUtil.isEmpty(value)) { return; } addAll(0, value); } @Override public void remove(int i) { if (i < 0 || i >= size()) { return; } DirectMessageWrap dWrap = get(i); if (dWrap == null) { return; } listCache.remove(i); if (dWrap.getWrap() == null) { return; } DirectMessageDao dao = new DirectMessageDao(context); dao.delete(dWrap.getWrap(), account); } @Override public void remove(DirectMessageWrap value) { if (value == null || value.getWrap() == null) { return; } int i = indexOf(value); if (i != -1) { remove(i); } } @Override public List<DirectMessageWrap> read(Paging<DirectMessage> page) { List<DirectMessageWrap> listWrap = null; if (page == null || page.getPageSize() < 0 || page.getPageIndex() <= 0) { return listWrap; } String myId = account.getUser().getId(); Resources res = context.getResources(); String[] querySqls = res.getStringArray(R.array.db_query_direct_message_sql); String sql = String.format( querySqls[0], myId, account.getAccountId(), myId, account.getAccountId() ); StringDao stringDao = new StringDao(context); List<String> listConversationId = stringDao.find(sql, page.getPageIndex(), page.getPageSize()); if (ListUtil.isEmpty(listConversationId)) { return listWrap; } //如果最后一条刚好是间隔时,再读取一条 String lastId = listConversationId.get(listConversationId.size() - 1); if (lastId == null) { listConversationId = stringDao.find(sql, page.getPageIndex(), page.getPageSize() + 1); } Date currentDate = new Date(); listWrap = new ArrayList<DirectMessageWrap>(listConversationId.size()); DirectMessageDao dao = new DirectMessageDao(context); for (String coversationId : listConversationId) { if (StringUtil.isEmpty(coversationId)) { continue; } sql = String.format(querySqls[1], coversationId, coversationId, account.getAccountId()); DirectMessage lastMessage = dao.query(sql); if (lastMessage == null) { continue; } DirectMessageWrap wrap = new DirectMessageWrap(lastMessage); wrap.setLocalCached(true); wrap.setReadedTime(currentDate); wrap.setReaded(true); sql = String.format(querySqls[2], coversationId, coversationId, account.getAccountId()); String count = stringDao.query(sql); wrap.setCoversationCount(Integer.parseInt(count)); listWrap.add(wrap); } if (ListUtil.isNotEmpty(listWrap)) { LocalDirectMessage divider = new LocalDirectMessage(); divider.setDivider(true); divider.setLocalDivider(true); DirectMessageWrap wrap = new DirectMessageWrap(divider); listWrap.add(wrap); } return listWrap; } @Override public void write(DirectMessageWrap value) { if (value == null) { return; } DirectMessageDao dao = new DirectMessageDao(context); dao.save(value.getWrap(), account); value.setLocalCached(true); } public void write(List<DirectMessage> messageList) { if (ListUtil.isEmpty(messageList)) { return; } List<DirectMessage> filterList = new ArrayList<DirectMessage>(); for (DirectMessage message : messageList) { if (message instanceof LocalDirectMessage && ((LocalDirectMessage)message).isLocalDivider()) { continue; } filterList.add(message); } DirectMessageDao dao = new DirectMessageDao(context); dao.batchSave(filterList, account); } @Override public int indexOf(DirectMessageWrap value) { int index = -1; if (value == null || value.getWrap() == null) { return index; } for (int i = 0; i < size(); i++) { DirectMessageWrap temp = get(i); if (temp == null) { continue; } DirectMessage wrap = temp.getWrap(); if (wrap != null && wrap.equals(value.getWrap())) { index = i; break; } } return index; } @Override public int size() { return listCache.size(); } public DirectMessage getInboxMax() { DirectMessageDao dao = new DirectMessageDao(context); String myId = account.getUser().getId(); long accountId = account.getAccountId(); String sql = "select * from Direct_Message where Account_ID = " + accountId + " and Recipient_ID = '" + myId + "' order by Created_At desc limit 1"; DirectMessage message = dao.query(sql); return message; } public DirectMessage getOutboxMax() { DirectMessageDao dao = new DirectMessageDao(context); String myId = account.getUser().getId(); long accountId = account.getAccountId(); String sql = "select * from Direct_Message where Account_ID = " + accountId + " and Sender_ID = '" + myId + "' order by Created_At desc limit 1"; DirectMessage message = dao.query(sql); return message; } public DirectMessage getInboxMin() { DirectMessageDao dao = new DirectMessageDao(context); String myId = account.getUser().getId(); String sql = "select * from Direct_Message where Account_ID = " + account.getAccountId() + " and Recipient_ID = '" + myId + "' order by Created_At asc limit 1"; DirectMessage message = dao.query(sql); return message; } public DirectMessage getOutboxMin() { DirectMessageDao dao = new DirectMessageDao(context); String myId = account.getUser().getId(); String sql = "select * from Direct_Message where Account_ID = " + account.getAccountId() + " and Sender_ID = '" + myId + "' order by Created_At asc limit 1"; DirectMessage message = dao.query(sql); return message; } public class StringDao extends BaseDao<String> { public StringDao(Context context) { super(context); } @Override public String extractData(SQLiteDatabase sqLiteDatabase, Cursor cursor) { String str = cursor.getString(0); return str; } } }