1package eu.siacs.conversations.entities;
2
3import android.util.Base64;
4import android.util.Log;
5
6import java.security.MessageDigest;
7import java.security.NoSuchAlgorithmException;
8import java.util.ArrayList;
9import java.util.Collection;
10import java.util.Collections;
11import java.util.List;
12
13import eu.siacs.conversations.Config;
14import eu.siacs.conversations.android.PhoneNumberContact;
15import eu.siacs.conversations.xml.Element;
16import rocks.xmpp.addr.Jid;
17
18public class Entry implements Comparable<Entry> {
19 private final List<Jid> jids;
20 private final String number;
21
22 private Entry(String number, List<Jid> jids) {
23 this.number = number;
24 this.jids = jids;
25 }
26
27 public static Entry of(Element element) {
28 final String number = element.getAttribute("number");
29 final List<Jid> jids = new ArrayList<>();
30 for (Element jidElement : element.getChildren()) {
31 String content = jidElement.getContent();
32 if (content != null) {
33 jids.add(Jid.of(content));
34 }
35 }
36 return new Entry(number, jids);
37 }
38
39 public static List<Entry> ofPhoneBook(Element phoneBook) {
40 List<Entry> entries = new ArrayList<>();
41 for (Element entry : phoneBook.getChildren()) {
42 if ("entry".equals(entry.getName())) {
43 entries.add(of(entry));
44 }
45 }
46 return entries;
47 }
48
49 public static String statusQuo(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) {
50 return statusQuo(ofPhoneNumberContactsAndContacts(phoneNumberContacts, systemContacts));
51 }
52
53 private static String statusQuo(final List<Entry> entries) {
54 Collections.sort(entries);
55 StringBuilder builder = new StringBuilder();
56 for(Entry entry : entries) {
57 if (builder.length() != 0) {
58 builder.append('\u001d');
59 }
60 builder.append(entry.getNumber());
61 List<Jid> jids = entry.getJids();
62 Collections.sort(jids);
63 for(Jid jid : jids) {
64 builder.append('\u001e');
65 builder.append(jid.asBareJid().toEscapedString());
66 }
67 }
68 MessageDigest md;
69 try {
70 md = MessageDigest.getInstance("SHA-1");
71 } catch (NoSuchAlgorithmException e) {
72 return "";
73 }
74 Log.d(Config.LOGTAG,"status quo string: "+builder.toString());
75 byte[] sha1 = md.digest(builder.toString().getBytes());
76 return new String(Base64.encode(sha1, Base64.DEFAULT)).trim();
77 }
78
79 private static List<Entry> ofPhoneNumberContactsAndContacts(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) {
80 ArrayList<Entry> entries = new ArrayList<>();
81 for(Contact contact : systemContacts) {
82 PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(phoneNumberContacts, contact.getSystemAccount());
83 if (phoneNumberContact != null && phoneNumberContact.getPhoneNumber() != null) {
84 Entry entry = findOrCreateByPhoneNumber(entries, phoneNumberContact.getPhoneNumber());
85 entry.jids.add(contact.getJid().asBareJid());
86 }
87 }
88 return entries;
89 }
90
91 private static Entry findOrCreateByPhoneNumber(final List<Entry> entries, String number) {
92 for(Entry entry : entries) {
93 if (entry.number.equals(number)) {
94 return entry;
95 }
96 }
97 Entry entry = new Entry(number, new ArrayList<>());
98 entries.add(entry);
99 return entry;
100 }
101
102 public List<Jid> getJids() {
103 return jids;
104 }
105
106 public String getNumber() {
107 return number;
108 }
109
110 @Override
111 public int compareTo(Entry o) {
112 return number.compareTo(o.number);
113 }
114}