1package eu.siacs.conversations.entities;
2
3import java.util.HashSet;
4import java.util.Hashtable;
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 {
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;
83 }
84
85 public boolean match(String needle) {
86 return (jid.toLowerCase().contains(needle.toLowerCase()) || (getDisplayName()
87 .toLowerCase().contains(needle.toLowerCase())));
88 }
89
90 public ContentValues getContentValues() {
91 ContentValues values = new ContentValues();
92 values.put(ACCOUNT, accountUuid);
93 values.put(SYSTEMNAME, systemName);
94 values.put(SERVERNAME, serverName);
95 values.put(JID, jid);
96 values.put(OPTIONS, subscription);
97 values.put(SYSTEMACCOUNT, systemAccount);
98 values.put(PHOTOURI, photoUri);
99 values.put(KEYS, keys.toString());
100 return values;
101 }
102
103 public static Contact fromCursor(Cursor cursor) {
104 return new Contact(cursor.getString(cursor.getColumnIndex(ACCOUNT)),
105 cursor.getString(cursor.getColumnIndex(SYSTEMNAME)),
106 cursor.getString(cursor.getColumnIndex(SERVERNAME)),
107 cursor.getString(cursor.getColumnIndex(JID)),
108 cursor.getInt(cursor.getColumnIndex(OPTIONS)),
109 cursor.getString(cursor.getColumnIndex(PHOTOURI)),
110 cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
111 cursor.getString(cursor.getColumnIndex(KEYS)));
112 }
113
114 public int getSubscription() {
115 return this.subscription;
116 }
117
118 public void setSystemAccount(String account) {
119 this.systemAccount = account;
120 }
121
122 public void setAccount(Account account) {
123 this.account = account;
124 this.accountUuid = account.getUuid();
125 }
126
127 public Account getAccount() {
128 return this.account;
129 }
130
131 public boolean couldBeMuc() {
132 String[] split = this.getJid().split("@");
133 if (split.length != 2) {
134 return false;
135 } else {
136 String[] domainParts = split[1].split("\\.");
137 if (domainParts.length < 3) {
138 return false;
139 } else {
140 return (domainParts[0].equals("conf")
141 || domainParts[0].equals("conference")
142 || domainParts[0].equals("room")
143 || domainParts[0].equals("muc")
144 || domainParts[0].equals("chat")
145 || domainParts[0].equals("sala")
146 || domainParts[0].equals("salas"));
147 }
148 }
149 }
150
151 public Presences getPresences() {
152 return this.presences;
153 }
154
155 public void updatePresence(String resource, int status) {
156 this.presences.updatePresence(resource, status);
157 }
158
159 public void removePresence(String resource) {
160 this.presences.removePresence(resource);
161 }
162
163 public void clearPresences() {
164 this.presences.clearPresences();
165 }
166
167 public int getMostAvailableStatus() {
168 return this.presences.getMostAvailableStatus();
169 }
170
171 public void setPresences(Presences pres) {
172 this.presences = pres;
173 }
174
175 public void setPhotoUri(String uri) {
176 this.photoUri = uri;
177 }
178
179 public void setServerName(String serverName) {
180 this.serverName = serverName;
181 }
182
183 public void setSystemName(String systemName) {
184 this.systemName = systemName;
185 }
186
187 public String getSystemAccount() {
188 return systemAccount;
189 }
190
191 public Set<String> getOtrFingerprints() {
192 Set<String> set = new HashSet<String>();
193 try {
194 if (this.keys.has("otr_fingerprints")) {
195 JSONArray fingerprints = this.keys
196 .getJSONArray("otr_fingerprints");
197 for (int i = 0; i < fingerprints.length(); ++i) {
198 set.add(fingerprints.getString(i));
199 }
200 }
201 } catch (JSONException e) {
202 // TODO Auto-generated catch block
203 e.printStackTrace();
204 }
205 return set;
206 }
207
208 public void addOtrFingerprint(String print) {
209 try {
210 JSONArray fingerprints;
211 if (!this.keys.has("otr_fingerprints")) {
212 fingerprints = new JSONArray();
213
214 } else {
215 fingerprints = this.keys.getJSONArray("otr_fingerprints");
216 }
217 fingerprints.put(print);
218 this.keys.put("otr_fingerprints", fingerprints);
219 } catch (JSONException e) {
220
221 }
222 }
223
224 public void setPgpKeyId(long keyId) {
225 try {
226 this.keys.put("pgp_keyid", keyId);
227 } catch (JSONException e) {
228
229 }
230 }
231
232 public long getPgpKeyId() {
233 if (this.keys.has("pgp_keyid")) {
234 try {
235 return this.keys.getLong("pgp_keyid");
236 } catch (JSONException e) {
237 return 0;
238 }
239 } else {
240 return 0;
241 }
242 }
243
244 public void setOption(int option) {
245 this.subscription |= 1 << option;
246 }
247
248 public void resetOption(int option) {
249 this.subscription &= ~(1 << option);
250 }
251
252 public boolean getOption(int option) {
253 return ((this.subscription & (1 << option)) != 0);
254 }
255
256 public boolean showInRoster() {
257 return (this.getOption(Contact.Options.IN_ROSTER) && (!this
258 .getOption(Contact.Options.DIRTY_DELETE)))
259 || (this.getOption(Contact.Options.DIRTY_PUSH));
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.resetOption(Contact.Options.FROM);
269 this.setOption(Contact.Options.TO);
270 } else if (subscription.equals("from")) {
271 this.resetOption(Contact.Options.TO);
272 this.setOption(Contact.Options.FROM);
273 } else if (subscription.equals("both")) {
274 this.setOption(Contact.Options.TO);
275 this.setOption(Contact.Options.FROM);
276 } else if (subscription.equals("none")) {
277 this.resetOption(Contact.Options.FROM);
278 this.resetOption(Contact.Options.TO);
279 }
280 }
281
282 // do NOT override asking if pending push request
283 if (!this.getOption(Contact.Options.DIRTY_PUSH)) {
284 if ((ask != null) && (ask.equals("subscribe"))) {
285 this.setOption(Contact.Options.ASKING);
286 } else {
287 this.resetOption(Contact.Options.ASKING);
288 }
289 }
290 }
291
292 public Element asElement() {
293 Element item = new Element("item");
294 item.setAttribute("jid", this.jid);
295 if (this.serverName != null) {
296 item.setAttribute("name", this.serverName);
297 }
298 return item;
299 }
300
301 public class Options {
302 public static final int TO = 0;
303 public static final int FROM = 1;
304 public static final int ASKING = 2;
305 public static final int PREEMPTIVE_GRANT = 3;
306 public static final int IN_ROSTER = 4;
307 public static final int PENDING_SUBSCRIPTION_REQUEST = 5;
308 public static final int DIRTY_PUSH = 6;
309 public static final int DIRTY_DELETE = 7;
310 }
311
312 public class Lastseen {
313 public long time = 0;
314 public String presence = null;
315 }
316}