KnownHostsAdapter.java

 1package eu.siacs.conversations.ui.adapter;
 2
 3import android.content.Context;
 4import androidx.annotation.NonNull;
 5import android.widget.ArrayAdapter;
 6import android.widget.Filter;
 7
 8import java.util.ArrayList;
 9import java.util.Collection;
10import java.util.Collections;
11import java.util.Locale;
12import java.util.regex.Pattern;
13
14import eu.siacs.conversations.Config;
15
16public class KnownHostsAdapter extends ArrayAdapter<String> {
17
18    private static Pattern E164_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
19
20    private ArrayList<String> domains;
21    private Filter domainFilter = new Filter() {
22
23        @Override
24        protected FilterResults performFiltering(CharSequence constraint) {
25            final ArrayList<String> suggestions = new ArrayList<>();
26            final String[] split = constraint == null ? new String[0] : constraint.toString().split("@");
27            if (split.length == 1) {
28                final String local = split[0].toLowerCase(Locale.ENGLISH);
29                if (Config.QUICKSY_DOMAIN != null && E164_PATTERN.matcher(local).matches()) {
30                    suggestions.add(local + '@' + Config.QUICKSY_DOMAIN.toEscapedString());
31                } else {
32                    for (String domain : domains) {
33                        suggestions.add(local + '@' + domain);
34                    }
35                }
36            } else if (split.length == 2) {
37                final String localPart = split[0].toLowerCase(Locale.ENGLISH);
38                final String domainPart = split[1].toLowerCase(Locale.ENGLISH);
39                if (domains.contains(domainPart)) {
40                    return new FilterResults();
41                }
42                for (String domain : domains) {
43                    if (domain.contains(domainPart)) {
44                        suggestions.add(localPart + "@" + domain);
45                    }
46                }
47            } else {
48                return new FilterResults();
49            }
50            FilterResults filterResults = new FilterResults();
51            filterResults.values = suggestions;
52            filterResults.count = suggestions.size();
53            return filterResults;
54        }
55
56        @Override
57        protected void publishResults(CharSequence constraint, FilterResults results) {
58            ArrayList filteredList = (ArrayList) results.values;
59            if (results.count > 0) {
60                clear();
61                addAll(filteredList);
62                notifyDataSetChanged();
63            }
64        }
65    };
66
67    public KnownHostsAdapter(Context context, int viewResourceId, Collection<String> mKnownHosts) {
68        super(context, viewResourceId, new ArrayList<>());
69        domains = new ArrayList<>(mKnownHosts);
70        Collections.sort(domains);
71    }
72
73    public KnownHostsAdapter(Context context, int viewResourceId) {
74        super(context, viewResourceId, new ArrayList<>());
75        domains = new ArrayList<>();
76    }
77
78    public void refresh(Collection<String> knownHosts) {
79        domains = new ArrayList<>(knownHosts);
80        Collections.sort(domains);
81        notifyDataSetChanged();
82    }
83
84    @Override
85    @NonNull
86    public Filter getFilter() {
87        return domainFilter;
88    }
89}