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