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