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