Contact.java

  1package eu.siacs.conversations.entities;
  2
  3import java.util.HashSet;
  4import java.util.Locale;
  5import java.util.Set;
  6
  7import org.json.JSONArray;
  8import org.json.JSONException;
  9import org.json.JSONObject;
 10
 11import eu.siacs.conversations.xml.Element;
 12import android.content.ContentValues;
 13import android.database.Cursor;
 14
 15public class Contact implements ListItem {
 16	public static final String TABLENAME = "contacts";
 17
 18	public static final String SYSTEMNAME = "systemname";
 19	public static final String SERVERNAME = "servername";
 20	public static final String JID = "jid";
 21	public static final String OPTIONS = "options";
 22	public static final String SYSTEMACCOUNT = "systemaccount";
 23	public static final String PHOTOURI = "photouri";
 24	public static final String KEYS = "pgpkey";
 25	public static final String ACCOUNT = "accountUuid";
 26	public static final String AVATAR = "avatar";
 27
 28	protected String accountUuid;
 29	protected String systemName;
 30	protected String serverName;
 31	protected String presenceName;
 32	protected String jid;
 33	protected int subscription = 0;
 34	protected String systemAccount;
 35	protected String photoUri;
 36	protected String avatar;
 37	protected JSONObject keys = new JSONObject();
 38	protected Presences presences = new Presences();
 39
 40	protected Account account;
 41
 42	protected boolean inRoster = true;
 43
 44	public Lastseen lastseen = new Lastseen();
 45
 46	public Contact(String account, String systemName, String serverName,
 47			String jid, int subscription, String photoUri,
 48			String systemAccount, String keys, String avatar) {
 49		this.accountUuid = account;
 50		this.systemName = systemName;
 51		this.serverName = serverName;
 52		this.jid = jid;
 53		this.subscription = subscription;
 54		this.photoUri = photoUri;
 55		this.systemAccount = systemAccount;
 56		if (keys == null) {
 57			keys = "";
 58		}
 59		try {
 60			this.keys = new JSONObject(keys);
 61		} catch (JSONException e) {
 62			this.keys = new JSONObject();
 63		}
 64		this.avatar = avatar;
 65	}
 66
 67	public Contact(String jid) {
 68		this.jid = jid;
 69	}
 70
 71	public String getDisplayName() {
 72		if (this.systemName != null) {
 73			return this.systemName;
 74		} else if (this.serverName != null) {
 75			return this.serverName;
 76		} else if (this.presenceName != null) {
 77			return this.presenceName;
 78		} else {
 79			return this.jid.split("@")[0];
 80		}
 81	}
 82
 83	public String getProfilePhoto() {
 84		return this.photoUri;
 85	}
 86
 87	public String getJid() {
 88		return this.jid.toLowerCase(Locale.getDefault());
 89	}
 90
 91	public boolean match(String needle) {
 92		return needle == null
 93				|| jid.contains(needle.toLowerCase())
 94				|| getDisplayName().toLowerCase()
 95						.contains(needle.toLowerCase());
 96	}
 97
 98	public ContentValues getContentValues() {
 99		ContentValues values = new ContentValues();
100		values.put(ACCOUNT, accountUuid);
101		values.put(SYSTEMNAME, systemName);
102		values.put(SERVERNAME, serverName);
103		values.put(JID, jid);
104		values.put(OPTIONS, subscription);
105		values.put(SYSTEMACCOUNT, systemAccount);
106		values.put(PHOTOURI, photoUri);
107		values.put(KEYS, keys.toString());
108		values.put(AVATAR, avatar);
109		return values;
110	}
111
112	public static Contact fromCursor(Cursor cursor) {
113		return new Contact(cursor.getString(cursor.getColumnIndex(ACCOUNT)),
114				cursor.getString(cursor.getColumnIndex(SYSTEMNAME)),
115				cursor.getString(cursor.getColumnIndex(SERVERNAME)),
116				cursor.getString(cursor.getColumnIndex(JID)),
117				cursor.getInt(cursor.getColumnIndex(OPTIONS)),
118				cursor.getString(cursor.getColumnIndex(PHOTOURI)),
119				cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
120				cursor.getString(cursor.getColumnIndex(KEYS)),
121				cursor.getString(cursor.getColumnIndex(AVATAR)));
122	}
123
124	public int getSubscription() {
125		return this.subscription;
126	}
127
128	public void setSystemAccount(String account) {
129		this.systemAccount = account;
130	}
131
132	public void setAccount(Account account) {
133		this.account = account;
134		this.accountUuid = account.getUuid();
135	}
136
137	public Account getAccount() {
138		return this.account;
139	}
140
141	public Presences getPresences() {
142		return this.presences;
143	}
144
145	public void updatePresence(String resource, int status) {
146		this.presences.updatePresence(resource, status);
147	}
148
149	public void removePresence(String resource) {
150		this.presences.removePresence(resource);
151	}
152
153	public void clearPresences() {
154		this.presences.clearPresences();
155		this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
156	}
157
158	public int getMostAvailableStatus() {
159		return this.presences.getMostAvailableStatus();
160	}
161
162	public void setPresences(Presences pres) {
163		this.presences = pres;
164	}
165
166	public void setPhotoUri(String uri) {
167		this.photoUri = uri;
168	}
169
170	public void setServerName(String serverName) {
171		this.serverName = serverName;
172	}
173
174	public void setSystemName(String systemName) {
175		this.systemName = systemName;
176	}
177
178	public void setPresenceName(String presenceName) {
179		this.presenceName = presenceName;
180	}
181
182	public String getSystemAccount() {
183		return systemAccount;
184	}
185
186	public Set<String> getOtrFingerprints() {
187		Set<String> set = new HashSet<String>();
188		try {
189			if (this.keys.has("otr_fingerprints")) {
190				JSONArray fingerprints = this.keys
191						.getJSONArray("otr_fingerprints");
192				for (int i = 0; i < fingerprints.length(); ++i) {
193					set.add(fingerprints.getString(i));
194				}
195			}
196		} catch (JSONException e) {
197			// TODO Auto-generated catch block
198			e.printStackTrace();
199		}
200		return set;
201	}
202
203	public void addOtrFingerprint(String print) {
204		try {
205			JSONArray fingerprints;
206			if (!this.keys.has("otr_fingerprints")) {
207				fingerprints = new JSONArray();
208
209			} else {
210				fingerprints = this.keys.getJSONArray("otr_fingerprints");
211			}
212			fingerprints.put(print);
213			this.keys.put("otr_fingerprints", fingerprints);
214		} catch (JSONException e) {
215
216		}
217	}
218
219	public void setPgpKeyId(long keyId) {
220		try {
221			this.keys.put("pgp_keyid", keyId);
222		} catch (JSONException e) {
223
224		}
225	}
226
227	public long getPgpKeyId() {
228		if (this.keys.has("pgp_keyid")) {
229			try {
230				return this.keys.getLong("pgp_keyid");
231			} catch (JSONException e) {
232				return 0;
233			}
234		} else {
235			return 0;
236		}
237	}
238
239	public void setOption(int option) {
240		this.subscription |= 1 << option;
241	}
242
243	public void resetOption(int option) {
244		this.subscription &= ~(1 << option);
245	}
246
247	public boolean getOption(int option) {
248		return ((this.subscription & (1 << option)) != 0);
249	}
250
251	public boolean showInRoster() {
252		return (this.getOption(Contact.Options.IN_ROSTER) && (!this
253				.getOption(Contact.Options.DIRTY_DELETE)))
254				|| (this.getOption(Contact.Options.DIRTY_PUSH));
255	}
256
257	public void parseSubscriptionFromElement(Element item) {
258		String ask = item.getAttribute("ask");
259		String subscription = item.getAttribute("subscription");
260
261		if (subscription != null) {
262			if (subscription.equals("to")) {
263				this.resetOption(Contact.Options.FROM);
264				this.setOption(Contact.Options.TO);
265			} else if (subscription.equals("from")) {
266				this.resetOption(Contact.Options.TO);
267				this.setOption(Contact.Options.FROM);
268				this.resetOption(Contact.Options.PREEMPTIVE_GRANT);
269			} else if (subscription.equals("both")) {
270				this.setOption(Contact.Options.TO);
271				this.setOption(Contact.Options.FROM);
272				this.resetOption(Contact.Options.PREEMPTIVE_GRANT);
273			} else if (subscription.equals("none")) {
274				this.resetOption(Contact.Options.FROM);
275				this.resetOption(Contact.Options.TO);
276			}
277		}
278
279		// do NOT override asking if pending push request
280		if (!this.getOption(Contact.Options.DIRTY_PUSH)) {
281			if ((ask != null) && (ask.equals("subscribe"))) {
282				this.setOption(Contact.Options.ASKING);
283			} else {
284				this.resetOption(Contact.Options.ASKING);
285			}
286		}
287	}
288
289	public Element asElement() {
290		Element item = new Element("item");
291		item.setAttribute("jid", this.jid);
292		if (this.serverName != null) {
293			item.setAttribute("name", this.serverName);
294		}
295		return item;
296	}
297
298	public class Options {
299		public static final int TO = 0;
300		public static final int FROM = 1;
301		public static final int ASKING = 2;
302		public static final int PREEMPTIVE_GRANT = 3;
303		public static final int IN_ROSTER = 4;
304		public static final int PENDING_SUBSCRIPTION_REQUEST = 5;
305		public static final int DIRTY_PUSH = 6;
306		public static final int DIRTY_DELETE = 7;
307	}
308
309	public class Lastseen {
310		public long time = 0;
311		public String presence = null;
312	}
313
314	@Override
315	public int compareTo(ListItem another) {
316		return this.getDisplayName().compareToIgnoreCase(
317				another.getDisplayName());
318	}
319
320	public String getServer() {
321		String[] split = getJid().split("@");
322		if (split.length >= 2) {
323			return split[1];
324		} else {
325			return null;
326		}
327	}
328
329	public boolean setAvatar(String filename) {
330		if (this.avatar != null && this.avatar.equals(filename)) {
331			return false;
332		} else {
333			this.avatar = filename;
334			return true;
335		}
336	}
337
338	public String getAvatar() {
339		return this.avatar;
340	}
341
342	public boolean deleteOtrFingerprint(String fingerprint) {
343		boolean success = false;
344		try {
345			if (this.keys.has("otr_fingerprints")) {
346				JSONArray newPrints = new JSONArray();
347				JSONArray oldPrints = this.keys
348						.getJSONArray("otr_fingerprints");
349				for (int i = 0; i < oldPrints.length(); ++i) {
350					if (!oldPrints.getString(i).equals(fingerprint)) {
351						newPrints.put(oldPrints.getString(i));
352					} else {
353						success = true;
354					}
355				}
356				this.keys.put("otr_fingerprints", newPrints);
357			}
358			return success;
359		} catch (JSONException e) {
360			return false;
361		}
362	}
363
364	public boolean trusted() {
365		return getOption(Options.FROM) && getOption(Options.TO);
366	}
367}