1package eu.siacs.conversations.entities;
2
3import java.util.HashSet;
4import java.util.Set;
5
6import org.json.JSONArray;
7import org.json.JSONException;
8import org.json.JSONObject;
9
10import eu.siacs.conversations.xml.Element;
11import android.content.ContentValues;
12import android.database.Cursor;
13
14public class Contact {
15 public static final String TABLENAME = "contacts";
16
17 public static final String SYSTEMNAME = "systemname";
18 public static final String SERVERNAME = "servername";
19 public static final String JID = "jid";
20 public static final String OPTIONS = "options";
21 public static final String SYSTEMACCOUNT = "systemaccount";
22 public static final String PHOTOURI = "photouri";
23 public static final String KEYS = "pgpkey";
24 public static final String ACCOUNT = "accountUuid";
25
26 protected String accountUuid;
27 protected String systemName;
28 protected String serverName;
29 protected String jid;
30 protected int subscription = 0;
31 protected String systemAccount;
32 protected String photoUri;
33 protected JSONObject keys = new JSONObject();
34 protected Presences presences = new Presences();
35
36 protected Account account;
37
38 protected boolean inRoster = true;
39
40 public Lastseen lastseen = new Lastseen();
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("room")
142 || domainParts[0].equals("muc")
143 || domainParts[0].equals("chat")
144 || domainParts[0].equals("sala")
145 || domainParts[0].equals("salas"));
146 }
147 }
148 }
149
150 public Presences getPresences() {
151 return this.presences;
152 }
153
154 public void updatePresence(String resource, int status) {
155 this.presences.updatePresence(resource, status);
156 }
157
158 public void removePresence(String resource) {
159 this.presences.removePresence(resource);
160 }
161
162 public void clearPresences() {
163 this.presences.clearPresences();
164 }
165
166 public int getMostAvailableStatus() {
167 return this.presences.getMostAvailableStatus();
168 }
169
170 public void setPresences(Presences pres) {
171 this.presences = pres;
172 }
173
174 public void setPhotoUri(String uri) {
175 this.photoUri = uri;
176 }
177
178 public void setServerName(String serverName) {
179 this.serverName = serverName;
180 }
181
182 public void setSystemName(String systemName) {
183 this.systemName = systemName;
184 }
185
186 public String getSystemAccount() {
187 return systemAccount;
188 }
189
190 public Set<String> getOtrFingerprints() {
191 Set<String> set = new HashSet<String>();
192 try {
193 if (this.keys.has("otr_fingerprints")) {
194 JSONArray fingerprints = this.keys
195 .getJSONArray("otr_fingerprints");
196 for (int i = 0; i < fingerprints.length(); ++i) {
197 set.add(fingerprints.getString(i));
198 }
199 }
200 } catch (JSONException e) {
201 // TODO Auto-generated catch block
202 e.printStackTrace();
203 }
204 return set;
205 }
206
207 public void addOtrFingerprint(String print) {
208 try {
209 JSONArray fingerprints;
210 if (!this.keys.has("otr_fingerprints")) {
211 fingerprints = new JSONArray();
212
213 } else {
214 fingerprints = this.keys.getJSONArray("otr_fingerprints");
215 }
216 fingerprints.put(print);
217 this.keys.put("otr_fingerprints", fingerprints);
218 } catch (JSONException e) {
219
220 }
221 }
222
223 public void setPgpKeyId(long keyId) {
224 try {
225 this.keys.put("pgp_keyid", keyId);
226 } catch (JSONException e) {
227
228 }
229 }
230
231 public long getPgpKeyId() {
232 if (this.keys.has("pgp_keyid")) {
233 try {
234 return this.keys.getLong("pgp_keyid");
235 } catch (JSONException e) {
236 return 0;
237 }
238 } else {
239 return 0;
240 }
241 }
242
243 public void setOption(int option) {
244 this.subscription |= 1 << option;
245 }
246
247 public void resetOption(int option) {
248 this.subscription &= ~(1 << option);
249 }
250
251 public boolean getOption(int option) {
252 return ((this.subscription & (1 << option)) != 0);
253 }
254
255 public boolean showInRoster() {
256 return (this.getOption(Contact.Options.IN_ROSTER) && (!this
257 .getOption(Contact.Options.DIRTY_DELETE)))
258 || (this.getOption(Contact.Options.DIRTY_PUSH));
259 }
260
261 public void parseSubscriptionFromElement(Element item) {
262 String ask = item.getAttribute("ask");
263 String subscription = item.getAttribute("subscription");
264
265 if (subscription != null) {
266 if (subscription.equals("to")) {
267 this.resetOption(Contact.Options.FROM);
268 this.setOption(Contact.Options.TO);
269 } else if (subscription.equals("from")) {
270 this.resetOption(Contact.Options.TO);
271 this.setOption(Contact.Options.FROM);
272 } else if (subscription.equals("both")) {
273 this.setOption(Contact.Options.TO);
274 this.setOption(Contact.Options.FROM);
275 } else if (subscription.equals("none")) {
276 this.resetOption(Contact.Options.FROM);
277 this.resetOption(Contact.Options.TO);
278 }
279 }
280
281 // do NOT override asking if pending push request
282 if (!this.getOption(Contact.Options.DIRTY_PUSH)) {
283 if ((ask != null) && (ask.equals("subscribe"))) {
284 this.setOption(Contact.Options.ASKING);
285 } else {
286 this.resetOption(Contact.Options.ASKING);
287 }
288 }
289 }
290
291 public Element asElement() {
292 Element item = new Element("item");
293 item.setAttribute("jid", this.jid);
294 if (this.serverName != null) {
295 item.setAttribute("name", this.serverName);
296 }
297 return item;
298 }
299
300 public class Options {
301 public static final int TO = 0;
302 public static final int FROM = 1;
303 public static final int ASKING = 2;
304 public static final int PREEMPTIVE_GRANT = 3;
305 public static final int IN_ROSTER = 4;
306 public static final int PENDING_SUBSCRIPTION_REQUEST = 5;
307 public static final int DIRTY_PUSH = 6;
308 public static final int DIRTY_DELETE = 7;
309 }
310
311 public class Lastseen {
312 public long time = 0;
313 public String presence = null;
314 }
315}