Conversations/src/main/java/eu/siacs/conversations/entities/Contact.java

486 lines
13 KiB
Java
Raw Normal View History

2014-10-22 12:38:44 -04:00
package eu.siacs.conversations.entities;
import android.content.ContentValues;
import android.database.Cursor;
2014-10-22 12:38:44 -04:00
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
2014-11-16 11:21:21 -05:00
import java.util.List;
import java.util.Locale;
2014-11-16 11:21:21 -05:00
import eu.siacs.conversations.utils.UIHelper;
2014-10-22 12:38:44 -04:00
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
2014-10-22 12:38:44 -04:00
public class Contact implements ListItem {
public static final String TABLENAME = "contacts";
public static final String SYSTEMNAME = "systemname";
public static final String SERVERNAME = "servername";
public static final String JID = "jid";
public static final String OPTIONS = "options";
public static final String SYSTEMACCOUNT = "systemaccount";
public static final String PHOTOURI = "photouri";
public static final String KEYS = "pgpkey";
public static final String ACCOUNT = "accountUuid";
public static final String AVATAR = "avatar";
2014-11-16 17:58:30 -05:00
public static final String LAST_PRESENCE = "last_presence";
public static final String LAST_TIME = "last_time";
2014-11-16 11:21:21 -05:00
public static final String GROUPS = "groups";
2014-11-16 17:58:30 -05:00
public Lastseen lastseen = new Lastseen();
2014-10-22 12:38:44 -04:00
protected String accountUuid;
protected String systemName;
protected String serverName;
protected String presenceName;
protected Jid jid;
2014-10-22 12:38:44 -04:00
protected int subscription = 0;
protected String systemAccount;
protected String photoUri;
protected String avatar;
protected JSONObject keys = new JSONObject();
2014-11-16 11:21:21 -05:00
protected JSONArray groups = new JSONArray();
2014-10-22 12:38:44 -04:00
protected Presences presences = new Presences();
protected Account account;
public Contact(final String account, final String systemName, final String serverName,
2014-11-16 17:58:30 -05:00
final Jid jid, final int subscription, final String photoUri,
final String systemAccount, final String keys, final String avatar, final Lastseen lastseen, final String groups) {
2014-10-22 12:38:44 -04:00
this.accountUuid = account;
this.systemName = systemName;
this.serverName = serverName;
this.jid = jid;
this.subscription = subscription;
this.photoUri = photoUri;
this.systemAccount = systemAccount;
try {
this.keys = (keys == null ? new JSONObject("") : new JSONObject(keys));
2014-10-22 12:38:44 -04:00
} catch (JSONException e) {
this.keys = new JSONObject();
}
this.avatar = avatar;
2014-11-16 11:21:21 -05:00
try {
this.groups = (groups == null ? new JSONArray() : new JSONArray(groups));
} catch (JSONException e) {
this.groups = new JSONArray();
}
this.lastseen = lastseen;
2014-10-22 12:38:44 -04:00
}
public Contact(final Jid jid) {
2014-10-22 12:38:44 -04:00
this.jid = jid;
}
2014-11-16 17:58:30 -05:00
public static Contact fromCursor(final Cursor cursor) {
final Lastseen lastseen = new Lastseen(
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
cursor.getLong(cursor.getColumnIndex(LAST_TIME)));
final Jid jid;
try {
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(JID)));
} catch (final InvalidJidException e) {
// TODO: Borked DB... handle this somehow?
return null;
}
return new Contact(cursor.getString(cursor.getColumnIndex(ACCOUNT)),
cursor.getString(cursor.getColumnIndex(SYSTEMNAME)),
cursor.getString(cursor.getColumnIndex(SERVERNAME)),
jid,
cursor.getInt(cursor.getColumnIndex(OPTIONS)),
cursor.getString(cursor.getColumnIndex(PHOTOURI)),
cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
cursor.getString(cursor.getColumnIndex(KEYS)),
cursor.getString(cursor.getColumnIndex(AVATAR)),
lastseen,
cursor.getString(cursor.getColumnIndex(GROUPS)));
}
2014-10-22 12:38:44 -04:00
public String getDisplayName() {
if (this.systemName != null) {
2014-11-16 17:58:30 -05:00
return this.systemName;
} else if (this.serverName != null) {
return this.serverName;
2014-10-22 12:38:44 -04:00
} else if (this.presenceName != null) {
2014-11-16 17:58:30 -05:00
return this.presenceName;
} else if (jid.hasLocalpart()) {
2014-11-16 17:58:30 -05:00
return jid.getLocalpart();
2014-10-22 12:38:44 -04:00
} else {
2014-11-16 17:58:30 -05:00
return jid.getDomainpart();
}
2014-10-22 12:38:44 -04:00
}
public String getProfilePhoto() {
return this.photoUri;
}
public Jid getJid() {
return jid;
2014-10-22 12:38:44 -04:00
}
2014-11-16 11:21:21 -05:00
@Override
public List<Tag> getTags() {
ArrayList<Tag> tags = new ArrayList<Tag>();
2014-11-16 17:58:30 -05:00
for (String group : getGroups()) {
2014-11-16 11:21:21 -05:00
tags.add(new Tag(group, UIHelper.getColorForName(group)));
}
int status = getMostAvailableStatus();
switch (getMostAvailableStatus()) {
case Presences.CHAT:
case Presences.ONLINE:
2014-11-16 17:58:30 -05:00
tags.add(new Tag("online", 0xff259b24));
2014-11-16 11:21:21 -05:00
break;
case Presences.AWAY:
2014-11-16 17:58:30 -05:00
tags.add(new Tag("away", 0xffff9800));
2014-11-16 11:21:21 -05:00
break;
case Presences.XA:
2014-11-16 17:58:30 -05:00
tags.add(new Tag("not available", 0xffe51c23));
2014-11-16 11:21:21 -05:00
break;
case Presences.DND:
2014-11-16 17:58:30 -05:00
tags.add(new Tag("dnd", 0xffe51c23));
2014-11-16 11:21:21 -05:00
break;
}
return tags;
}
2014-10-22 12:38:44 -04:00
public boolean match(String needle) {
2014-11-17 11:31:26 -05:00
if (needle == null || needle.isEmpty()) {
2014-11-16 17:58:30 -05:00
return true;
}
needle = needle.toLowerCase(Locale.US).trim();
String[] parts = needle.split("\\s+");
if (parts.length > 1) {
for(int i = 0; i < parts.length; ++i) {
if (!match(parts[i])) {
return false;
}
}
return true;
} else {
return jid.toString().contains(needle) ||
getDisplayName().toLowerCase(Locale.US).contains(needle) ||
matchInTag(needle);
}
2014-11-16 17:58:30 -05:00
}
private boolean matchInTag(String needle) {
needle = needle.toLowerCase(Locale.US);
2014-11-16 17:58:30 -05:00
for (Tag tag : getTags()) {
if (tag.getName().toLowerCase(Locale.US).contains(needle)) {
2014-11-16 17:58:30 -05:00
return true;
}
}
return false;
2014-10-22 12:38:44 -04:00
}
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put(ACCOUNT, accountUuid);
values.put(SYSTEMNAME, systemName);
values.put(SERVERNAME, serverName);
values.put(JID, jid.toString());
2014-10-22 12:38:44 -04:00
values.put(OPTIONS, subscription);
values.put(SYSTEMACCOUNT, systemAccount);
values.put(PHOTOURI, photoUri);
values.put(KEYS, keys.toString());
values.put(AVATAR, avatar);
values.put(LAST_PRESENCE, lastseen.presence);
values.put(LAST_TIME, lastseen.time);
2014-11-16 17:58:30 -05:00
values.put(GROUPS, groups.toString());
2014-10-22 12:38:44 -04:00
return values;
}
public int getSubscription() {
return this.subscription;
}
2014-11-16 17:58:30 -05:00
public Account getAccount() {
return this.account;
2014-10-22 12:38:44 -04:00
}
public void setAccount(Account account) {
this.account = account;
this.accountUuid = account.getUuid();
}
public Presences getPresences() {
return this.presences;
}
2014-11-16 17:58:30 -05:00
public void setPresences(Presences pres) {
this.presences = pres;
}
2014-10-22 12:38:44 -04:00
public void updatePresence(String resource, int status) {
this.presences.updatePresence(resource, status);
}
public void removePresence(String resource) {
this.presences.removePresence(resource);
}
public void clearPresences() {
this.presences.clearPresences();
this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
}
public int getMostAvailableStatus() {
return this.presences.getMostAvailableStatus();
}
public void setPhotoUri(String uri) {
this.photoUri = uri;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public void setSystemName(String systemName) {
this.systemName = systemName;
}
public void setPresenceName(String presenceName) {
this.presenceName = presenceName;
}
public String getSystemAccount() {
return systemAccount;
}
2014-11-16 17:58:30 -05:00
public void setSystemAccount(String account) {
this.systemAccount = account;
}
2014-11-16 11:21:21 -05:00
public List<String> getGroups() {
ArrayList<String> groups = new ArrayList<String>();
2014-11-16 17:58:30 -05:00
for (int i = 0; i < this.groups.length(); ++i) {
2014-11-16 11:21:21 -05:00
try {
groups.add(this.groups.getString(i));
} catch (final JSONException ignored) {
}
}
return groups;
}
public ArrayList<String> getOtrFingerprints() {
final ArrayList<String> fingerprints = new ArrayList<String>();
2014-10-22 12:38:44 -04:00
try {
if (this.keys.has("otr_fingerprints")) {
final JSONArray prints = this.keys.getJSONArray("otr_fingerprints");
for (int i = 0; i < prints.length(); ++i) {
2014-12-20 10:01:28 -05:00
final String print = prints.isNull(i) ? null : prints.getString(i);
if (print != null && !print.isEmpty()) {
fingerprints.add(prints.getString(i));
}
2014-10-22 12:38:44 -04:00
}
}
} catch (final JSONException ignored) {
2014-10-22 12:38:44 -04:00
}
return fingerprints;
2014-10-22 12:38:44 -04:00
}
public boolean addOtrFingerprint(String print) {
if (getOtrFingerprints().contains(print)) {
return false;
}
2014-10-22 12:38:44 -04:00
try {
JSONArray fingerprints;
if (!this.keys.has("otr_fingerprints")) {
fingerprints = new JSONArray();
} else {
fingerprints = this.keys.getJSONArray("otr_fingerprints");
}
fingerprints.put(print);
this.keys.put("otr_fingerprints", fingerprints);
return true;
} catch (final JSONException ignored) {
return false;
2014-10-22 12:38:44 -04:00
}
}
public long getPgpKeyId() {
if (this.keys.has("pgp_keyid")) {
try {
return this.keys.getLong("pgp_keyid");
} catch (JSONException e) {
return 0;
}
} else {
return 0;
}
}
2014-11-16 17:58:30 -05:00
public void setPgpKeyId(long keyId) {
try {
this.keys.put("pgp_keyid", keyId);
} catch (final JSONException ignored) {
}
}
2014-10-22 12:38:44 -04:00
public void setOption(int option) {
this.subscription |= 1 << option;
}
public void resetOption(int option) {
this.subscription &= ~(1 << option);
}
public boolean getOption(int option) {
return ((this.subscription & (1 << option)) != 0);
}
public boolean showInRoster() {
return (this.getOption(Contact.Options.IN_ROSTER) && (!this
.getOption(Contact.Options.DIRTY_DELETE)))
|| (this.getOption(Contact.Options.DIRTY_PUSH));
}
public void parseSubscriptionFromElement(Element item) {
String ask = item.getAttribute("ask");
String subscription = item.getAttribute("subscription");
if (subscription != null) {
2014-11-16 17:58:30 -05:00
switch (subscription) {
case "to":
this.resetOption(Options.FROM);
this.setOption(Options.TO);
break;
case "from":
this.resetOption(Options.TO);
this.setOption(Options.FROM);
this.resetOption(Options.PREEMPTIVE_GRANT);
break;
case "both":
this.setOption(Options.TO);
this.setOption(Options.FROM);
this.resetOption(Options.PREEMPTIVE_GRANT);
break;
case "none":
this.resetOption(Options.FROM);
this.resetOption(Options.TO);
break;
}
2014-10-22 12:38:44 -04:00
}
// do NOT override asking if pending push request
if (!this.getOption(Contact.Options.DIRTY_PUSH)) {
if ((ask != null) && (ask.equals("subscribe"))) {
this.setOption(Contact.Options.ASKING);
} else {
this.resetOption(Contact.Options.ASKING);
}
}
}
2014-11-16 11:21:21 -05:00
public void parseGroupsFromElement(Element item) {
this.groups = new JSONArray();
2014-11-16 17:58:30 -05:00
for (Element element : item.getChildren()) {
2014-11-16 11:21:21 -05:00
if (element.getName().equals("group") && element.getContent() != null) {
this.groups.put(element.getContent());
}
}
}
2014-10-22 12:38:44 -04:00
public Element asElement() {
final Element item = new Element("item");
item.setAttribute("jid", this.jid.toString());
2014-10-22 12:38:44 -04:00
if (this.serverName != null) {
item.setAttribute("name", this.serverName);
}
2014-11-16 17:58:30 -05:00
for (String group : getGroups()) {
2014-11-16 11:21:21 -05:00
item.addChild("group").setContent(group);
}
2014-10-22 12:38:44 -04:00
return item;
}
@Override
public int compareTo(final ListItem another) {
2014-10-22 12:38:44 -04:00
return this.getDisplayName().compareToIgnoreCase(
another.getDisplayName());
}
public Jid getServer() {
return getJid().toDomainJid();
2014-10-22 12:38:44 -04:00
}
public boolean setAvatar(String filename) {
if (this.avatar != null && this.avatar.equals(filename)) {
return false;
} else {
this.avatar = filename;
return true;
}
}
public String getAvatar() {
return this.avatar;
}
public boolean deleteOtrFingerprint(String fingerprint) {
boolean success = false;
try {
if (this.keys.has("otr_fingerprints")) {
JSONArray newPrints = new JSONArray();
JSONArray oldPrints = this.keys
.getJSONArray("otr_fingerprints");
for (int i = 0; i < oldPrints.length(); ++i) {
if (!oldPrints.getString(i).equals(fingerprint)) {
newPrints.put(oldPrints.getString(i));
} else {
success = true;
}
}
this.keys.put("otr_fingerprints", newPrints);
}
return success;
} catch (JSONException e) {
return false;
}
}
public boolean trusted() {
return getOption(Options.FROM) && getOption(Options.TO);
}
public String getShareableUri() {
if (getOtrFingerprints().size() >= 1) {
String otr = getOtrFingerprints().get(0);
2014-11-16 17:58:30 -05:00
return "xmpp:" + getJid().toBareJid().toString() + "?otr-fingerprint=" + otr.replace(" ", "");
} else {
2014-11-16 17:58:30 -05:00
return "xmpp:" + getJid().toBareJid().toString();
}
}
2014-11-16 17:58:30 -05:00
public static class Lastseen {
public long time;
public String presence;
public Lastseen() {
time = 0;
presence = null;
}
public Lastseen(final String presence, final long time) {
this.time = time;
this.presence = presence;
}
}
public class Options {
public static final int TO = 0;
public static final int FROM = 1;
public static final int ASKING = 2;
public static final int PREEMPTIVE_GRANT = 3;
public static final int IN_ROSTER = 4;
public static final int PENDING_SUBSCRIPTION_REQUEST = 5;
public static final int DIRTY_PUSH = 6;
public static final int DIRTY_DELETE = 7;
}
2014-10-22 12:38:44 -04:00
}