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