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