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