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