Removed countermeasures, rewritten operation handling

This commit is contained in:
M66B 2018-08-02 20:52:06 +00:00
parent bb63ef2cfa
commit 921b31abec
2 changed files with 100 additions and 128 deletions

View File

@ -80,6 +80,9 @@ public class EntityOperation {
return; return;
} }
purged = dao.deleteOperations(message.id, name); purged = dao.deleteOperations(message.id, name);
} else if (DELETE.equals(name)) {
if (message.uid == null)
return;
} }
EntityOperation operation = new EntityOperation(); EntityOperation operation = new EntityOperation();

View File

@ -498,7 +498,7 @@ public class ServiceSynchronize extends LifecycleService {
}; };
// Listen for process operations requests // Listen for process operations requests
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(ServiceSynchronize.this); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(receiver, new IntentFilter(ACTION_PROCESS_OPERATIONS + folder.id)); lbm.registerReceiver(receiver, new IntentFilter(ACTION_PROCESS_OPERATIONS + folder.id));
Log.i(Helper.TAG, folder.name + " listen process id=" + folder.id); Log.i(Helper.TAG, folder.name + " listen process id=" + folder.id);
try { try {
@ -561,7 +561,7 @@ public class ServiceSynchronize extends LifecycleService {
try { try {
Log.i(Helper.TAG, folder.name + " start process"); Log.i(Helper.TAG, folder.name + " start process");
DB db = DB.getInstance(ServiceSynchronize.this); DB db = DB.getInstance(this);
DaoOperation operation = db.operation(); DaoOperation operation = db.operation();
DaoMessage message = db.message(); DaoMessage message = db.message();
for (TupleOperationEx op : operation.getOperations(folder.id)) { for (TupleOperationEx op : operation.getOperations(folder.id)) {
@ -571,99 +571,59 @@ public class ServiceSynchronize extends LifecycleService {
" msg=" + op.message); " msg=" + op.message);
JSONArray jargs = new JSONArray(op.args); JSONArray jargs = new JSONArray(op.args);
try {
if (EntityOperation.SEEN.equals(op.name)) { if (EntityOperation.SEEN.equals(op.name)) {
// Mark message (un)seen // Mark message (un)seen
try {
Message imessage = ifolder.getMessageByUID(op.uid); Message imessage = ifolder.getMessageByUID(op.uid);
if (imessage != null) if (imessage == null)
imessage.setFlag(Flags.Flag.SEEN, jargs.getBoolean(0)); throw new MessageRemovedException();
else imessage.setFlag(Flags.Flag.SEEN, jargs.getBoolean(0));
Log.w(Helper.TAG, "Remote message not found uid=" + op.uid);
} catch (MessagingException ex) {
// Countermeasure
Log.i(Helper.TAG, folder.name + " countermeasure " + op.id + "/" + op.name);
EntityMessage msg = message.getMessage(op.message);
msg.ui_seen = msg.seen;
message.updateMessage(msg);
throw ex;
}
} else if (EntityOperation.ADD.equals(op.name)) { } else if (EntityOperation.ADD.equals(op.name)) {
// Append message // Append message
try {
EntityMessage msg = message.getMessage(op.message); EntityMessage msg = message.getMessage(op.message);
Properties props = MessageHelper.getSessionProperties(); Properties props = MessageHelper.getSessionProperties();
Session isession = Session.getDefaultInstance(props, null); Session isession = Session.getDefaultInstance(props, null);
MimeMessage imessage = MessageHelper.from(msg, isession); MimeMessage imessage = MessageHelper.from(msg, isession);
ifolder.appendMessages(new Message[]{imessage}); ifolder.appendMessages(new Message[]{imessage});
// Draft can be saved multiple times // Drafts can be appended multiple times
if (msg.uid != null) { try {
Message previously = ifolder.getMessageByUID(msg.uid); if (msg.uid != null) {
previously.setFlag(Flags.Flag.DELETED, true); Message previously = ifolder.getMessageByUID(msg.uid);
ifolder.expunge(); previously.setFlag(Flags.Flag.DELETED, true);
ifolder.expunge();
}
} finally {
// Remote will report appended
message.deleteMessage(op.message);
} }
message.deleteMessage(op.message); } else if (EntityOperation.MOVE.equals(op.name)) {
} catch (MessagingException ex) { // Move message
// Countermeasure
// TODO: try again?
throw ex;
}
} else if (EntityOperation.MOVE.equals(op.name)) {
// Move message
try {
Message imessage = ifolder.getMessageByUID(op.uid);
EntityFolder archive = db.folder().getFolder(jargs.getLong(0)); EntityFolder archive = db.folder().getFolder(jargs.getLong(0));
Message imessage = ifolder.getMessageByUID(op.uid);
Folder target = istore.getFolder(archive.name); Folder target = istore.getFolder(archive.name);
ifolder.moveMessages(new Message[]{imessage}, target); ifolder.moveMessages(new Message[]{imessage}, target);
message.deleteMessage(op.message); message.deleteMessage(op.message);
} catch (MessagingException ex) {
// Countermeasure
Log.i(Helper.TAG, folder.name + " countermeasure " + op.id + "/" + op.name);
EntityMessage msg = message.getMessage(op.message);
msg.ui_hide = false;
message.updateMessage(msg);
throw ex;
}
} else if (EntityOperation.DELETE.equals(op.name)) { } else if (EntityOperation.DELETE.equals(op.name)) {
// Delete message // Delete message
try { Message imessage = ifolder.getMessageByUID(op.uid);
if (op.uid != null) { if (imessage == null)
Message imessage = ifolder.getMessageByUID(op.uid); throw new MessageRemovedException();
if (imessage != null) { imessage.setFlag(Flags.Flag.DELETED, true);
imessage.setFlag(Flags.Flag.DELETED, true); ifolder.expunge();
ifolder.expunge();
} else
Log.w(Helper.TAG, "Remote message not found uid=" + op.uid);
} else {
// Not appended draft
Log.w(Helper.TAG, "Delete without uid id=" + op.message);
}
message.deleteMessage(op.message); message.deleteMessage(op.message);
} catch (MessagingException ex) {
// Countermeasure } else if (EntityOperation.SEND.equals(op.name)) {
Log.i(Helper.TAG, folder.name + " countermeasure " + op.id + "/" + op.name); // Send message
EntityMessage msg = message.getMessage(op.message); EntityMessage msg = message.getMessage(op.message);
msg.ui_hide = false; EntityMessage reply = (msg.replying == null ? null : message.getMessage(msg.replying));
message.updateMessage(msg); EntityIdentity ident = db.identity().getIdentity(msg.identity);
throw ex;
}
} else if (EntityOperation.SEND.equals(op.name)) {
// Send message
EntityMessage msg = message.getMessage(op.message);
EntityMessage reply = (msg.replying == null ? null : message.getMessage(msg.replying));
EntityIdentity ident = db.identity().getIdentity(msg.identity);
try {
Properties props = MessageHelper.getSessionProperties(); Properties props = MessageHelper.getSessionProperties();
Session isession = Session.getDefaultInstance(props, null); Session isession = Session.getDefaultInstance(props, null);
@ -686,26 +646,22 @@ public class ServiceSynchronize extends LifecycleService {
// Make sure the message is sent only once // Make sure the message is sent only once
operation.deleteOperation(op.id); operation.deleteOperation(op.id);
message.deleteMessage(op.message); message.deleteMessage(op.message);
} finally { } finally {
itransport.close(); itransport.close();
} }
} catch (MessagingException ex) { } else
// Countermeasure throw new MessagingException("Unknown operation name=" + op.name);
Log.i(Helper.TAG, folder.name + " countermeasure " + op.id + "/" + op.name);
EntityFolder drafts = db.folder().getPrimaryDraftFolder();
msg.folder = drafts.id;
message.updateMessage(msg);
// Message will not be sent to remote
throw ex;
}
} else // Operation succeeded
throw new MessagingException("Unknown operation name=" + op.name); operation.deleteOperation(op.id);
operation.deleteOperation(op.id); } catch (MessageRemovedException ex) {
// There is no use in repeating
operation.deleteOperation(op.id);
throw ex;
}
} }
} finally { } finally {
Log.i(Helper.TAG, folder.name + " end process"); Log.i(Helper.TAG, folder.name + " end process");
@ -769,7 +725,7 @@ public class ServiceSynchronize extends LifecycleService {
try { try {
Log.i(Helper.TAG, folder.name + " start sync after=" + folder.after); Log.i(Helper.TAG, folder.name + " start sync after=" + folder.after);
DB db = DB.getInstance(ServiceSynchronize.this); DB db = DB.getInstance(this);
DaoMessage dao = db.message(); DaoMessage dao = db.message();
// Get reference times // Get reference times
@ -851,50 +807,63 @@ public class ServiceSynchronize extends LifecycleService {
ifolder.fetch(new Message[]{imessage}, fp); ifolder.fetch(new Message[]{imessage}, fp);
long uid = ifolder.getUID(imessage); long uid = ifolder.getUID(imessage);
Log.i(Helper.TAG, folder.name + " sync uid=" + uid); try {
Log.i(Helper.TAG, folder.name + " start sync uid=" + uid);
MessageHelper helper = new MessageHelper(imessage); if (imessage.isExpunged()) {
boolean seen = helper.getSeen(); Log.i(Helper.TAG, folder.name + " expunged uid=" + uid);
return;
}
if (imessage.isSet(Flags.Flag.DELETED)) {
Log.i(Helper.TAG, folder.name + " deleted uid=" + uid);
return;
}
DB db = DB.getInstance(ServiceSynchronize.this); MessageHelper helper = new MessageHelper(imessage);
EntityMessage message = db.message().getMessage(folder.id, uid); boolean seen = helper.getSeen();
if (message == null) {
FetchProfile fp1 = new FetchProfile();
fp1.add(FetchProfile.Item.ENVELOPE);
fp1.add(FetchProfile.Item.CONTENT_INFO);
fp1.add(IMAPFolder.FetchProfileItem.HEADERS);
fp1.add(IMAPFolder.FetchProfileItem.MESSAGE);
ifolder.fetch(new Message[]{imessage}, fp1);
message = new EntityMessage(); DB db = DB.getInstance(this);
message.account = folder.account; EntityMessage message = db.message().getMessage(folder.id, uid);
message.folder = folder.id; if (message == null) {
message.uid = uid; FetchProfile fp1 = new FetchProfile();
message.msgid = helper.getMessageID(); fp1.add(FetchProfile.Item.ENVELOPE);
message.references = TextUtils.join(" ", helper.getReferences()); fp1.add(FetchProfile.Item.CONTENT_INFO);
message.inreplyto = helper.getInReplyTo(); fp1.add(IMAPFolder.FetchProfileItem.HEADERS);
message.thread = helper.getThreadId(uid); fp1.add(IMAPFolder.FetchProfileItem.MESSAGE);
message.from = helper.getFrom(); ifolder.fetch(new Message[]{imessage}, fp1);
message.to = helper.getTo();
message.cc = helper.getCc();
message.bcc = null;
message.reply = helper.getReply();
message.subject = imessage.getSubject();
message.body = helper.getHtml();
message.received = imessage.getReceivedDate().getTime();
message.sent = imessage.getSentDate().getTime();
message.seen = seen;
message.ui_seen = seen;
message.ui_hide = false;
message.id = db.message().insertMessage(message); message = new EntityMessage();
Log.i(Helper.TAG, folder.name + " added uid=" + uid + " id=" + message.id); message.account = folder.account;
} else if (message.seen != seen) { message.folder = folder.id;
message.seen = seen; message.uid = uid;
message.ui_seen = seen; message.msgid = helper.getMessageID();
message.references = TextUtils.join(" ", helper.getReferences());
message.inreplyto = helper.getInReplyTo();
message.thread = helper.getThreadId(uid);
message.from = helper.getFrom();
message.to = helper.getTo();
message.cc = helper.getCc();
message.bcc = null;
message.reply = helper.getReply();
message.subject = imessage.getSubject();
message.body = helper.getHtml();
message.received = imessage.getReceivedDate().getTime();
message.sent = imessage.getSentDate().getTime();
message.seen = seen;
message.ui_seen = seen;
message.ui_hide = false;
db.message().updateMessage(message); message.id = db.message().insertMessage(message);
Log.i(Helper.TAG, folder.name + " updated uid=" + uid + " id=" + message.id); Log.i(Helper.TAG, folder.name + " added id=" + message.id);
} else if (message.seen != seen) {
message.seen = seen;
message.ui_seen = seen;
db.message().updateMessage(message);
Log.i(Helper.TAG, folder.name + " updated id=" + message.id);
}
} finally {
Log.i(Helper.TAG, folder.name + " end sync uid=" + uid);
} }
} }