Simplify address handling by using type converters

pull/30/head
M66B 6 years ago
parent 5f48e38d6d
commit d5a55f9e27

@ -46,13 +46,14 @@ public class ApplicationEx extends Application {
EntityFolder drafts = db.folder().getPrimaryFolder(EntityFolder.TYPE_DRAFTS); EntityFolder drafts = db.folder().getPrimaryFolder(EntityFolder.TYPE_DRAFTS);
if (drafts != null) { if (drafts != null) {
Address to = new InternetAddress("marcel+email@faircode.eu" , "FairCode"); Address to = new InternetAddress("marcel+email@faircode.eu" , "FairCode");
String body = ex + "\n" + Log.getStackTraceString(ex);
EntityMessage draft = new EntityMessage(); EntityMessage draft = new EntityMessage();
draft.account = drafts.account; draft.account = drafts.account;
draft.folder = drafts.id; draft.folder = drafts.id;
draft.to = MessageHelper.encodeAddresses(new Address[]{to}); draft.to = new Address[]{to};
draft.subject = BuildConfig.APPLICATION_ID + " crash info"; draft.subject = BuildConfig.APPLICATION_ID + " crash info";
draft.body = "<pre>" + ex.toString().replaceAll("\\r?\\n" , "<br />") + "</pre>"; draft.body = "<pre>" + body.replaceAll("\\r?\\n" , "<br />") + "</pre>";
draft.received = new Date().getTime(); draft.received = new Date().getTime();
draft.seen = false; draft.seen = false;
draft.ui_seen = false; draft.ui_seen = false;

@ -11,6 +11,16 @@ import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import javax.mail.Address;
import javax.mail.internet.InternetAddress;
/* /*
This file is part of Safe email. This file is part of Safe email.
@ -132,6 +142,57 @@ public abstract class DB extends RoomDatabase {
public static String toStringArray(String[] value) { public static String toStringArray(String[] value) {
return TextUtils.join("," , value); return TextUtils.join("," , value);
} }
@TypeConverter
public static String encodeAddresses(Address[] addresses) {
if (addresses == null)
return null;
JSONArray jaddresses = new JSONArray();
if (addresses != null)
for (Address address : addresses)
try {
if (address instanceof InternetAddress) {
String a = ((InternetAddress) address).getAddress();
String p = ((InternetAddress) address).getPersonal();
JSONObject jaddress = new JSONObject();
if (a != null)
jaddress.put("address" , a);
if (p != null)
jaddress.put("personal" , p);
jaddresses.put(jaddress);
} else {
JSONObject jaddress = new JSONObject();
jaddress.put("address" , address.toString());
jaddresses.put(jaddress);
}
} catch (JSONException ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
return jaddresses.toString();
}
@TypeConverter
public static Address[] decodeAddresses(String json) {
if (json == null)
return null;
List<Address> result = new ArrayList<>();
try {
JSONArray jaddresses = new JSONArray(json);
for (int i = 0; i < jaddresses.length(); i++) {
JSONObject jaddress = (JSONObject) jaddresses.get(i);
if (jaddress.has("personal"))
result.add(new InternetAddress(
jaddress.getString("address"),
jaddress.getString("personal")));
else
result.add(new InternetAddress(
jaddress.getString("address")));
}
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
return result.toArray(new Address[0]);
}
} }
} }

@ -25,6 +25,8 @@ import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey; import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import javax.mail.Address;
import static android.arch.persistence.room.ForeignKey.CASCADE; import static android.arch.persistence.room.ForeignKey.CASCADE;
// https://developer.android.com/training/data-storage/room/defining-data // https://developer.android.com/training/data-storage/room/defining-data
@ -64,11 +66,11 @@ public class EntityMessage {
public String references; public String references;
public String inreplyto; public String inreplyto;
public String thread; // compose = null public String thread; // compose = null
public String from; public Address[] from;
public String to; public Address[] to;
public String cc; public Address[] cc;
public String bcc; public Address[] bcc;
public String reply; public Address[] reply;
public String subject; public String subject;
public String body; public String body;
public Long sent; // compose = null public Long sent; // compose = null

@ -72,7 +72,7 @@ public class FragmentAbout extends FragmentEx {
EntityMessage draft = new EntityMessage(); EntityMessage draft = new EntityMessage();
draft.account = drafts.account; draft.account = drafts.account;
draft.folder = drafts.id; draft.folder = drafts.id;
draft.to = MessageHelper.encodeAddresses(new Address[]{to}); draft.to = new Address[]{to};
draft.subject = BuildConfig.APPLICATION_ID + " debug info"; draft.subject = BuildConfig.APPLICATION_ID + " debug info";
draft.body = "<pre>" + info.toString().replaceAll("\\r?\\n" , "<br />") + "</pre>"; draft.body = "<pre>" + info.toString().replaceAll("\\r?\\n" , "<br />") + "</pre>";
draft.received = new Date().getTime(); draft.received = new Date().getTime();

@ -339,8 +339,8 @@ public class FragmentCompose extends FragmentEx {
result.putLong("iid" , msg.identity); result.putLong("iid" , msg.identity);
if (msg.replying != null) if (msg.replying != null)
result.putLong("rid" , msg.replying); result.putLong("rid" , msg.replying);
result.putString("cc" , msg.cc); result.putSerializable("cc" , msg.cc);
result.putString("bcc" , msg.bcc); result.putSerializable("bcc" , msg.bcc);
result.putString("thread" , msg.thread); result.putString("thread" , msg.thread);
result.putString("subject" , msg.subject); result.putString("subject" , msg.subject);
result.putString("body" , msg.body); result.putString("body" , msg.body);
@ -348,50 +348,37 @@ public class FragmentCompose extends FragmentEx {
if (TextUtils.isEmpty(action)) { if (TextUtils.isEmpty(action)) {
if (msg != null) { if (msg != null) {
result.putString("from" , msg.from); result.putSerializable("from" , msg.from);
result.putString("to" , msg.to); result.putSerializable("to" , msg.to);
} }
} else if ("reply".equals(action)) { } else if ("reply".equals(action)) {
String to = null; Address[] to = null;
if (msg != null) if (msg != null)
try { to = (msg.reply == null || msg.reply.length == 0 ? msg.from : msg.reply);
Address[] reply = MessageHelper.decodeAddresses(msg.reply);
to = (reply.length == 0 ? msg.from : msg.reply);
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
result.putLong("rid" , msg.id); result.putLong("rid" , msg.id);
result.putString("from" , msg.to); result.putSerializable("from" , msg.to);
result.putString("to" , to); result.putSerializable("to" , to);
} else if ("reply_all".equals(action)) { } else if ("reply_all".equals(action)) {
String to = null; Address[] to = null;
if (msg != null) { if (msg != null) {
try { List<Address> addresses = new ArrayList<>();
Address[] from = MessageHelper.decodeAddresses(msg.from); if (msg.reply != null)
Address[] reply = MessageHelper.decodeAddresses(msg.reply); addresses.addAll(Arrays.asList(msg.reply));
Address[] cc = MessageHelper.decodeAddresses(msg.cc); else if (msg.from != null)
List<Address> addresses = new ArrayList<>(); addresses.addAll(Arrays.asList(msg.from));
addresses.addAll(Arrays.asList(reply.length == 0 ? from : reply)); if (msg.cc != null)
addresses.addAll(Arrays.asList(cc)); addresses.addAll(Arrays.asList(msg.cc));
to = MessageHelper.encodeAddresses(addresses.toArray(new Address[0])); to = addresses.toArray(new Address[0]);
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
} }
result.putLong("rid" , msg.id); result.putLong("rid" , msg.id);
result.putString("from" , msg.to); result.putSerializable("from" , msg.to);
result.putString("to" , to); result.putSerializable("to" , to);
} else if ("forward".equals(action)) { } else if ("forward".equals(action)) {
String to = null; Address[] to = null;
if (msg != null) if (msg != null)
try { to = (msg.reply == null || msg.reply.length == 0 ? msg.from : msg.reply);
Address[] reply = MessageHelper.decodeAddresses(msg.reply); result.putSerializable("from" , msg.to);
to = (reply.length == 0 ? msg.from : msg.reply); result.putSerializable("to" , to);
} catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
result.putString("from" , msg.to);
result.putString("to" , to);
} }
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
@ -416,10 +403,10 @@ public class FragmentCompose extends FragmentEx {
long iid = result.getLong("iid" , -1); long iid = result.getLong("iid" , -1);
long rid = result.getLong("rid" , -1); long rid = result.getLong("rid" , -1);
String thread = result.getString("thread"); String thread = result.getString("thread");
String from = result.getString("from"); Address[] from = (Address[]) result.getSerializable("from");
String to = result.getString("to"); Address[] to = (Address[]) result.getSerializable("to");
String cc = result.getString("cc"); Address[] cc = (Address[]) result.getSerializable("cc");
String bcc = result.getString("bcc"); Address[] bcc = (Address[]) result.getSerializable("bcc");
String subject = result.getString("subject"); String subject = result.getString("subject");
String body = result.getString("body"); String body = result.getString("body");
String action = result.getString("action"); String action = result.getString("action");
@ -433,10 +420,11 @@ public class FragmentCompose extends FragmentEx {
ArrayAdapter adapter = (ArrayAdapter) spFrom.getAdapter(); ArrayAdapter adapter = (ArrayAdapter) spFrom.getAdapter();
if (adapter != null) { if (adapter != null) {
InternetAddress[] afrom = MessageHelper.decodeAddresses(from);
for (int pos = 0; pos < adapter.getCount(); pos++) { for (int pos = 0; pos < adapter.getCount(); pos++) {
EntityIdentity identity = (EntityIdentity) adapter.getItem(pos); EntityIdentity identity = (EntityIdentity) adapter.getItem(pos);
if (iid < 0 ? afrom.length > 0 && afrom[0].getAddress().equals(identity.email) : iid == identity.id) { if (iid < 0
? from != null && from.length > 0 && ((InternetAddress) from[0]).getAddress().equals(identity.email)
: iid == identity.id) {
spFrom.setSelection(pos); spFrom.setSelection(pos);
break; break;
} }
@ -449,11 +437,11 @@ public class FragmentCompose extends FragmentEx {
Handler handler = new Handler(); Handler handler = new Handler();
etCc.setText(TextUtils.join(", " , MessageHelper.decodeAddresses(cc))); etCc.setText(cc == null ? null : TextUtils.join(", " , cc));
etBcc.setText(TextUtils.join(", " , MessageHelper.decodeAddresses(bcc))); etBcc.setText(bcc == null ? null : TextUtils.join(", " , bcc));
if (action == null) { if (action == null) {
etTo.setText(TextUtils.join(", " , MessageHelper.decodeAddresses(to))); etTo.setText(to == null ? null : TextUtils.join(", " , to));
etSubject.setText(subject); etSubject.setText(subject);
if (body != null) if (body != null)
etBody.setText(Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false))); etBody.setText(Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false)));
@ -464,10 +452,10 @@ public class FragmentCompose extends FragmentEx {
} }
}); });
} else if ("reply".equals(action) || "reply_all".equals(action)) { } else if ("reply".equals(action) || "reply_all".equals(action)) {
etTo.setText(TextUtils.join(", " , MessageHelper.decodeAddresses(to))); etTo.setText(to == null ? null : TextUtils.join(", " , to));
String text = String.format("<br><br>%s %s:<br><br>%s" , String text = String.format("<br><br>%s %s:<br><br>%s" ,
Html.escapeHtml(new Date().toString()), Html.escapeHtml(new Date().toString()),
Html.escapeHtml(TextUtils.join(", " , MessageHelper.decodeAddresses(to))), Html.escapeHtml(to == null ? "" : TextUtils.join(", " , to)),
HtmlHelper.sanitize(getContext(), body, true)); HtmlHelper.sanitize(getContext(), body, true));
etSubject.setText(getContext().getString(R.string.title_subject_reply, subject)); etSubject.setText(getContext().getString(R.string.title_subject_reply, subject));
etBody.setText(Html.fromHtml(text)); etBody.setText(Html.fromHtml(text));
@ -480,7 +468,7 @@ public class FragmentCompose extends FragmentEx {
} else if ("forward".equals(action)) { } else if ("forward".equals(action)) {
String text = String.format("<br><br>%s %s:<br><br>%s" , String text = String.format("<br><br>%s %s:<br><br>%s" ,
Html.escapeHtml(new Date().toString()), Html.escapeHtml(new Date().toString()),
Html.escapeHtml(TextUtils.join(", " , MessageHelper.decodeAddresses(to))), Html.escapeHtml(to == null ? "" : TextUtils.join(", " , to)),
HtmlHelper.sanitize(getContext(), body, true)); HtmlHelper.sanitize(getContext(), body, true));
etSubject.setText(getContext().getString(R.string.title_subject_forward, subject)); etSubject.setText(getContext().getString(R.string.title_subject_forward, subject));
etBody.setText(Html.fromHtml(text)); etBody.setText(Html.fromHtml(text));
@ -539,7 +527,7 @@ public class FragmentCompose extends FragmentEx {
String body = args.getString("body"); String body = args.getString("body");
String subject = args.getString("subject"); String subject = args.getString("subject");
Address afrom = (ident == null ? null : new InternetAddress(ident.email, ident.name)); Address afrom[] = (ident == null ? null : new Address[]{new InternetAddress(ident.email, ident.name)});
Address ato[] = (TextUtils.isEmpty(to) ? null : InternetAddress.parse(to)); Address ato[] = (TextUtils.isEmpty(to) ? null : InternetAddress.parse(to));
Address acc[] = (TextUtils.isEmpty(cc) ? null : InternetAddress.parse(cc)); Address acc[] = (TextUtils.isEmpty(cc) ? null : InternetAddress.parse(cc));
Address abcc[] = (TextUtils.isEmpty(bcc) ? null : InternetAddress.parse(bcc)); Address abcc[] = (TextUtils.isEmpty(bcc) ? null : InternetAddress.parse(bcc));
@ -553,10 +541,10 @@ public class FragmentCompose extends FragmentEx {
draft.identity = (ident == null ? null : ident.id); draft.identity = (ident == null ? null : ident.id);
draft.replying = (rid < 0 ? null : rid); draft.replying = (rid < 0 ? null : rid);
draft.thread = thread; draft.thread = thread;
draft.from = MessageHelper.encodeAddresses(new Address[]{afrom}); draft.from = afrom;
draft.to = MessageHelper.encodeAddresses(ato); draft.to = ato;
draft.cc = MessageHelper.encodeAddresses(acc); draft.cc = acc;
draft.bcc = MessageHelper.encodeAddresses(abcc); draft.bcc = abcc;
draft.subject = subject; draft.subject = subject;
draft.body = "<pre>" + body.replaceAll("\\r?\\n" , "<br />") + "</pre>"; draft.body = "<pre>" + body.replaceAll("\\r?\\n" , "<br />") + "</pre>";
draft.received = new Date().getTime(); draft.received = new Date().getTime();

@ -23,10 +23,6 @@ import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -85,20 +81,17 @@ public class MessageHelper {
static MimeMessageEx from(EntityMessage message, Session isession) throws MessagingException { static MimeMessageEx from(EntityMessage message, Session isession) throws MessagingException {
MimeMessageEx imessage = new MimeMessageEx(isession, message.id); MimeMessageEx imessage = new MimeMessageEx(isession, message.id);
if (message.from != null) { if (message.from != null && message.from.length > 0)
Address[] from = MessageHelper.decodeAddresses(message.from); imessage.setFrom(message.from[0]);
if (from.length > 0)
imessage.setFrom(from[0]);
}
if (message.to != null) if (message.to != null && message.to.length > 0)
imessage.setRecipients(Message.RecipientType.TO, MessageHelper.decodeAddresses(message.to)); imessage.setRecipients(Message.RecipientType.TO, message.to);
if (message.cc != null) if (message.cc != null && message.cc.length > 0)
imessage.setRecipients(Message.RecipientType.CC, MessageHelper.decodeAddresses(message.cc)); imessage.setRecipients(Message.RecipientType.CC, message.cc);
if (message.bcc != null) if (message.bcc != null && message.bcc.length > 0)
imessage.setRecipients(Message.RecipientType.BCC, MessageHelper.decodeAddresses(message.bcc)); imessage.setRecipients(Message.RecipientType.BCC, message.bcc);
if (message.subject != null) if (message.subject != null)
imessage.setSubject(message.subject); imessage.setSubject(message.subject);
@ -153,86 +146,42 @@ public class MessageHelper {
return (TextUtils.isEmpty(msgid) ? Long.toString(uid) : msgid); return (TextUtils.isEmpty(msgid) ? Long.toString(uid) : msgid);
} }
String getFrom() throws MessagingException, JSONException { Address[] getFrom() throws MessagingException {
return encodeAddresses(imessage.getFrom()); return imessage.getFrom();
} }
String getTo() throws MessagingException, JSONException { Address[] getTo() throws MessagingException {
return encodeAddresses(imessage.getRecipients(Message.RecipientType.TO)); return imessage.getRecipients(Message.RecipientType.TO);
} }
String getCc() throws MessagingException, JSONException { Address[] getCc() throws MessagingException {
return encodeAddresses(imessage.getRecipients(Message.RecipientType.CC)); return imessage.getRecipients(Message.RecipientType.CC);
} }
String getBcc() throws MessagingException, JSONException { Address[] getBcc() throws MessagingException {
return encodeAddresses(imessage.getRecipients(Message.RecipientType.BCC)); return imessage.getRecipients(Message.RecipientType.BCC);
} }
String getReply() throws MessagingException, JSONException { Address[] getReply() throws MessagingException {
return encodeAddresses(imessage.getReplyTo()); return imessage.getReplyTo();
} }
static String encodeAddresses(Address[] addresses) throws JSONException { static String getFormattedAddresses(Address[] addresses) {
if (addresses == null) if (addresses == null)
return null; return null;
JSONArray jaddresses = new JSONArray();
if (addresses != null)
for (Address address : addresses)
if (address instanceof InternetAddress) {
String a = ((InternetAddress) address).getAddress();
String p = ((InternetAddress) address).getPersonal();
JSONObject jaddress = new JSONObject();
if (a != null)
jaddress.put("address" , a);
if (p != null)
jaddress.put("personal" , p);
jaddresses.put(jaddress);
}
return jaddresses.toString();
}
static InternetAddress[] decodeAddresses(String json) { List<String> formatted = new ArrayList<>();
if (json == null) for (Address address : addresses)
return new InternetAddress[0]; if (address instanceof InternetAddress) {
List<Address> result = new ArrayList<>(); InternetAddress a = (InternetAddress) address;
try { String personal = a.getPersonal();
JSONArray jaddresses = new JSONArray(json); if (TextUtils.isEmpty(personal))
for (int i = 0; i < jaddresses.length(); i++) { formatted.add(address.toString());
JSONObject jaddress = (JSONObject) jaddresses.get(i);
if (jaddress.has("personal"))
result.add(new InternetAddress(
jaddress.getString("address"),
jaddress.getString("personal")));
else else
result.add(new InternetAddress( formatted.add(personal);
jaddress.getString("address"))); } else
} formatted.add(address.toString());
} catch (Throwable ex) { return TextUtils.join(", " , formatted);
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
}
return result.toArray(new InternetAddress[0]);
}
static String getFormattedAddresses(String json) {
if (json == null)
return null;
try {
List<String> addresses = new ArrayList<>();
for (Address address : decodeAddresses(json))
if (address instanceof InternetAddress) {
InternetAddress a = (InternetAddress) address;
String personal = a.getPersonal();
if (TextUtils.isEmpty(personal))
addresses.add(address.toString());
else
addresses.add(personal);
} else
addresses.add(address.toString());
return TextUtils.join(", " , addresses);
} catch (Throwable ex) {
return ex.getMessage();
}
} }
String getHtml() throws MessagingException { String getHtml() throws MessagingException {

Loading…
Cancel
Save