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