1package eu.siacs.conversations.entities;
2
3import java.io.Serializable;
4import java.util.HashSet;
5import java.util.Hashtable;
6import java.util.Set;
7
8import org.json.JSONArray;
9import org.json.JSONException;
10import org.json.JSONObject;
11
12import eu.siacs.conversations.xml.Element;
13
14import android.content.ContentValues;
15import android.database.Cursor;
16import android.util.Log;
17
18public class Contact extends AbstractEntity implements Serializable {
19 private static final long serialVersionUID = -4570817093119419962L;
20
21 public static final String TABLENAME = "contacts";
22
23 public static final String DISPLAYNAME = "name";
24 public static final String JID = "jid";
25 public static final String SUBSCRIPTION = "subscription";
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 PRESENCES = "presences";
30 public static final String ACCOUNT = "accountUuid";
31
32 protected String accountUuid;
33 protected String displayName;
34 protected String jid;
35 protected int subscription = 0;
36 protected String systemAccount;
37 protected String photoUri;
38 protected JSONObject keys = new JSONObject();
39 protected Presences presences = new Presences();
40
41 protected Account account;
42
43 protected boolean inRoster = true;
44
45 public Contact(Account account, String displayName, String jid,
46 String photoUri) {
47 if (account == null) {
48 this.accountUuid = null;
49 } else {
50 this.accountUuid = account.getUuid();
51 }
52 this.account = account;
53 this.displayName = displayName;
54 this.jid = jid;
55 this.photoUri = photoUri;
56 this.uuid = java.util.UUID.randomUUID().toString();
57 }
58
59 public Contact(String uuid, String account, String displayName, String jid,
60 int subscription, String photoUri, String systemAccount,
61 String keys, String presences) {
62 this.uuid = uuid;
63 this.accountUuid = account;
64 this.displayName = displayName;
65 this.jid = jid;
66 this.subscription = subscription;
67 this.photoUri = photoUri;
68 this.systemAccount = systemAccount;
69 if (keys == null) {
70 keys = "";
71 }
72 try {
73 this.keys = new JSONObject(keys);
74 } catch (JSONException e) {
75 this.keys = new JSONObject();
76 }
77 this.presences = Presences.fromJsonString(presences);
78 }
79
80 public String getDisplayName() {
81 return this.displayName;
82 }
83
84 public String getProfilePhoto() {
85 return this.photoUri;
86 }
87
88 public String getJid() {
89 return this.jid;
90 }
91
92 public boolean match(String needle) {
93 return (jid.toLowerCase().contains(needle.toLowerCase()) || (displayName
94 .toLowerCase().contains(needle.toLowerCase())));
95 }
96
97 @Override
98 public ContentValues getContentValues() {
99 ContentValues values = new ContentValues();
100 values.put(UUID, uuid);
101 values.put(ACCOUNT, accountUuid);
102 values.put(DISPLAYNAME, displayName);
103 values.put(JID, jid);
104 values.put(SUBSCRIPTION, subscription);
105 values.put(SYSTEMACCOUNT, systemAccount);
106 values.put(PHOTOURI, photoUri);
107 values.put(KEYS, keys.toString());
108 values.put(PRESENCES, presences.toJsonString());
109 return values;
110 }
111
112 public static Contact fromCursor(Cursor cursor) {
113 return new Contact(cursor.getString(cursor.getColumnIndex(UUID)),
114 cursor.getString(cursor.getColumnIndex(ACCOUNT)),
115 cursor.getString(cursor.getColumnIndex(DISPLAYNAME)),
116 cursor.getString(cursor.getColumnIndex(JID)),
117 cursor.getInt(cursor.getColumnIndex(SUBSCRIPTION)),
118 cursor.getString(cursor.getColumnIndex(PHOTOURI)),
119 cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
120 cursor.getString(cursor.getColumnIndex(KEYS)),
121 cursor.getString(cursor.getColumnIndex(PRESENCES)));
122 }
123
124 public int getSubscription() {
125 return this.subscription;
126 }
127
128 public void setSystemAccount(String account) {
129 this.systemAccount = account;
130 }
131
132 public void setAccount(Account account) {
133 this.account = account;
134 this.accountUuid = account.getUuid();
135 }
136
137 public Account getAccount() {
138 return this.account;
139 }
140
141 public void setUuid(String uuid) {
142 this.uuid = uuid;
143 }
144
145 public boolean couldBeMuc() {
146 String[] split = this.getJid().split("@");
147 if (split.length != 2) {
148 return false;
149 } else {
150 String[] domainParts = split[1].split("\\.");
151 if (domainParts.length < 3) {
152 return false;
153 } else {
154 return (domainParts[0].equals("conf")
155 || domainParts[0].equals("conference") || domainParts[0]
156 .equals("muc"));
157 }
158 }
159 }
160
161 public Hashtable<String, Integer> getPresences() {
162 return this.presences.getPresences();
163 }
164
165 public void updatePresence(String resource, int status) {
166 this.presences.updatePresence(resource, status);
167 Log.d("xmppService","updatingPresence for contact="+this.jid+" resource="+resource+" num="+presences.size());
168 }
169
170 public void removePresence(String resource) {
171 this.presences.removePresence(resource);
172 }
173
174 public void clearPresences() {
175 this.presences.clearPresences();
176 }
177
178 public int getMostAvailableStatus() {
179 return this.presences.getMostAvailableStatus();
180 }
181
182 public void setPresences(Presences pres) {
183 this.presences = pres;
184 }
185
186 public void setPhotoUri(String uri) {
187 this.photoUri = uri;
188 }
189
190 public void setDisplayName(String name) {
191 this.displayName = name;
192 }
193
194 public String getSystemAccount() {
195 return systemAccount;
196 }
197
198 public Set<String> getOtrFingerprints() {
199 Set<String> set = new HashSet<String>();
200 try {
201 if (this.keys.has("otr_fingerprints")) {
202 JSONArray fingerprints = this.keys.getJSONArray("otr_fingerprints");
203 for (int i = 0; i < fingerprints.length(); ++i) {
204 set.add(fingerprints.getString(i));
205 }
206 }
207 } catch (JSONException e) {
208 // TODO Auto-generated catch block
209 e.printStackTrace();
210 }
211 return set;
212 }
213
214 public void addOtrFingerprint(String print) {
215 try {
216 JSONArray fingerprints;
217 if (!this.keys.has("otr_fingerprints")) {
218 fingerprints = new JSONArray();
219
220 } else {
221 fingerprints = this.keys.getJSONArray("otr_fingerprints");
222 }
223 fingerprints.put(print);
224 this.keys.put("otr_fingerprints", fingerprints);
225 } catch (JSONException e) {
226
227 }
228 }
229
230 public void setPgpKeyId(long keyId) {
231 try {
232 this.keys.put("pgp_keyid", keyId);
233 } catch (JSONException e) {
234
235 }
236 }
237
238 public long getPgpKeyId() {
239 if (this.keys.has("pgp_keyid")) {
240 try {
241 return this.keys.getLong("pgp_keyid");
242 } catch (JSONException e) {
243 return 0;
244 }
245 } else {
246 return 0;
247 }
248 }
249
250 public void setSubscriptionOption(int option) {
251 this.subscription |= 1 << option;
252 }
253
254 public void resetSubscriptionOption(int option) {
255 this.subscription &= ~(1 << option);
256 }
257
258 public boolean getSubscriptionOption(int option) {
259 return ((this.subscription & (1 << option)) != 0);
260 }
261
262 public void parseSubscriptionFromElement(Element item) {
263 String ask = item.getAttribute("ask");
264 String subscription = item.getAttribute("subscription");
265
266 if (subscription!=null) {
267 if (subscription.equals("to")) {
268 this.resetSubscriptionOption(Contact.Subscription.FROM);
269 this.setSubscriptionOption(Contact.Subscription.TO);
270 } else if (subscription.equals("from")) {
271 this.resetSubscriptionOption(Contact.Subscription.TO);
272 this.setSubscriptionOption(Contact.Subscription.FROM);
273 } else if (subscription.equals("both")) {
274 this.setSubscriptionOption(Contact.Subscription.TO);
275 this.setSubscriptionOption(Contact.Subscription.FROM);
276 }
277 }
278
279 if ((ask!=null)&&(ask.equals("subscribe"))) {
280 this.setSubscriptionOption(Contact.Subscription.ASKING);
281 } else {
282 this.resetSubscriptionOption(Contact.Subscription.ASKING);
283 }
284 }
285
286
287 public class Subscription {
288 public static final int TO = 0;
289 public static final int FROM = 1;
290 public static final int ASKING = 2;
291 public static final int PREEMPTIVE_GRANT = 4;
292 }
293
294
295 public void flagAsNotInRoster() {
296 this.inRoster = false;
297 }
298
299 public boolean isInRoster() {
300 return this.inRoster;
301 }
302
303 public String getAccountUuid() {
304 return this.accountUuid;
305 }
306}