@Override public synchronized void deleteMessage(String nonce) { fetchEntries(); for (int i = 0; i < messageEntries.size(); ++i) { if (StringUtils.equal(nonce, messageEntries.get(i).nonce)) { messageEntries.remove(i); writeToFile(); break; } } }
private synchronized void writeToFile() { try { writeToFileGuarded(); } catch (Exception e) { ApptentiveLog.e(MESSAGES, e, "Exception while saving messages"); logException(e); } shouldFetchFromFile = false; // mark it as not shouldFetchFromFile to keep a memory version }
private synchronized void fetchEntries() { if (shouldFetchFromFile) { readFromFile(); shouldFetchFromFile = false; } }
private synchronized void readFromFile() { messageEntries.clear(); try { if (file.exists()) { List<MessageEntry> entries = readFromFileGuarded(); messageEntries.addAll(entries); } } catch (Exception e) { ApptentiveLog.e(MESSAGES, e, "Exception while reading entries"); logException(e); } }
@Override public synchronized void updateMessage(ApptentiveMessage apptentiveMessage) { fetchEntries(); MessageEntry entry = findMessageEntry(apptentiveMessage); if (entry != null) { entry.id = apptentiveMessage.getId(); entry.clientCreatedAt = apptentiveMessage.getClientCreatedAt(); entry.nonce = apptentiveMessage.getNonce(); entry.state = apptentiveMessage.getState().name(); if (apptentiveMessage.isRead()) { // A apptentiveMessage can't be unread after being read. entry.isRead = true; } entry.json = apptentiveMessage.getJsonObject().toString(); writeToFile(); } }
public void migrateLegacyStorage() { try { File unencryptedFile = Util.getUnencryptedFilename(file); if (unencryptedFile.exists()) { try { List<MessageEntry> entries = readFromLegacyFile(unencryptedFile); messageEntries.addAll(entries); writeToFile(); } finally { boolean deleted = unencryptedFile.delete(); ApptentiveLog.d(CONVERSATION, "Deleted legacy message storage: %b", deleted); } } } catch (Exception e) { ApptentiveLog.e(CONVERSATION, e, "Exception while migrating messages"); logException(e); } }
public Conversation(File conversationDataFile, File conversationMessagesFile, @NonNull EncryptionKey encryptionKey) { if (conversationDataFile == null) { throw new IllegalArgumentException("Data file is null"); } if (conversationMessagesFile == null) { throw new IllegalArgumentException("Messages file is null"); } if (encryptionKey == null) { throw new IllegalArgumentException("Data encryption key is null"); } this.conversationDataFile = conversationDataFile; this.conversationMessagesFile = conversationMessagesFile; this.encryptionKey = encryptionKey; conversationData = new ConversationData(); messageStore = new FileMessageStore(conversationMessagesFile, encryptionKey); messageStore.migrateLegacyStorage(); messageManager = new MessageManager(this, messageStore); // it's important to initialize message manager in a constructor since other SDK parts depend on it via Apptentive singleton }
@Override public synchronized int getUnreadMessageCount() { fetchEntries(); int count = 0; for (MessageEntry entry : messageEntries) { if (!entry.isRead && entry.id != null) { ++count; } } return count; }
@Override public synchronized void deleteAllMessages() { messageEntries.clear(); writeToFile(); }
public void setEncryptionKey(@NonNull EncryptionKey encryptionKey) { this.encryptionKey = encryptionKey; // we need to update the old message store encryption key and overwrite current data file messageStore.updateEncryptionKey(encryptionKey); }
private MessageEntry findMessageEntry(ApptentiveMessage message) { Assert.assertNotNull(message); return message != null ? findMessageEntry(message.getNonce()) : null; }
@Override public synchronized void addOrUpdateMessages(ApptentiveMessage... apptentiveMessages) { fetchEntries(); for (ApptentiveMessage apptentiveMessage : apptentiveMessages) { MessageEntry existing = findMessageEntry(apptentiveMessage); if (existing != null) { // Update existing.id = apptentiveMessage.getId(); existing.state = apptentiveMessage.getState().name(); if (apptentiveMessage.isRead()) { // A message can't be unread after being read. existing.isRead = true; } existing.json = apptentiveMessage.getJsonObject().toString(); } else { // Insert MessageEntry entry = new MessageEntry(); entry.id = apptentiveMessage.getId(); entry.clientCreatedAt = apptentiveMessage.getClientCreatedAt(); entry.nonce = apptentiveMessage.getNonce(); entry.state = apptentiveMessage.getState().name(); entry.isRead = apptentiveMessage.isRead(); entry.json = apptentiveMessage.getJsonObject().toString(); messageEntries.add(entry); } } writeToFile(); }
@Override public synchronized String getLastReceivedMessageId() throws Exception { fetchEntries(); final String savedState = ApptentiveMessage.State.saved.name(); for (int i = messageEntries.size() - 1; i >= 0; --i) { final MessageEntry entry = messageEntries.get(i); if (StringUtils.equal(entry.state, savedState) && entry.id != null) { return entry.id; } } return null; }
void updateEncryptionKey(@NonNull EncryptionKey encryptionKey) { if (encryptionKey == null) { throw new IllegalArgumentException("Encryption key is null"); } this.encryptionKey = encryptionKey; // update storage writeToFile(); }
@Override public ApptentiveMessage findMessage(String nonce) { fetchEntries(); for (int i = 0; i < messageEntries.size(); ++i) { final MessageEntry messageEntry = messageEntries.get(i); if (StringUtils.equal(nonce, messageEntry.nonce)) { return MessageFactory.fromJson(messageEntry.json); } } return null; }
@Override public synchronized List<ApptentiveMessage> getAllMessages() throws Exception { fetchEntries(); List<ApptentiveMessage> apptentiveMessages = new ArrayList<>(); for (MessageEntry entry : messageEntries) { ApptentiveMessage apptentiveMessage = MessageFactory.fromJson(entry.json); if (apptentiveMessage == null) { ApptentiveLog.e(MESSAGES, "Error parsing Record json from database: %s", entry.json); continue; } apptentiveMessage.setState(ApptentiveMessage.State.parse(entry.state)); apptentiveMessage.setRead(entry.isRead); apptentiveMessages.add(apptentiveMessage); } return apptentiveMessages; }