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