KnownHostsAdapter.java

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