DomainMatcher.java revision 71a988c8e9859244b83cd55bb6b6ee913fcaf95c
1package com.android.server.wifi.hotspot2.pps;
2
3import com.android.server.wifi.hotspot2.Utils;
4
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.HashMap;
8import java.util.Iterator;
9import java.util.List;
10import java.util.Map;
11
12public class DomainMatcher {
13
14    public enum Match {None, Primary, Secondary}
15
16    private final Label mRoot;
17
18    private static class Label {
19        private final Map<String, Label> mSubDomains;
20        private final Match mMatch;
21
22        private Label(Match match) {
23            mMatch = match;
24            mSubDomains = match == Match.None ? new HashMap<String, Label>() : null;
25        }
26
27        private void addDomain(Iterator<String> labels, Match match) {
28            String labelName = labels.next();
29            if (labels.hasNext()) {
30                Label subLabel = new Label(Match.None);
31                mSubDomains.put(labelName, subLabel);
32                subLabel.addDomain(labels, match);
33            } else {
34                mSubDomains.put(labelName, new Label(match));
35            }
36        }
37
38        private Label getSubLabel(String labelString) {
39            return mSubDomains.get(labelString);
40        }
41
42        public Match getMatch() {
43            return mMatch;
44        }
45
46        private void toString(StringBuilder sb) {
47            if (mSubDomains != null) {
48                sb.append(".{");
49                for (Map.Entry<String, Label> entry : mSubDomains.entrySet()) {
50                    sb.append(entry.getKey());
51                    entry.getValue().toString(sb);
52                }
53                sb.append('}');
54            } else {
55                sb.append('=').append(mMatch);
56            }
57        }
58
59        @Override
60        public String toString() {
61            StringBuilder sb = new StringBuilder();
62            toString(sb);
63            return sb.toString();
64        }
65    }
66
67    public DomainMatcher(List<String> primary, List<List<String>> secondary) {
68        mRoot = new Label(Match.None);
69        for (List<String> secondaryLabel : secondary) {
70            mRoot.addDomain(secondaryLabel.iterator(), Match.Secondary);
71        }
72        System.out.println("Primary: " + primary);
73        // Primary overwrites secondary.
74        mRoot.addDomain(primary.iterator(), Match.Primary);
75    }
76
77    public Match isSubDomain(List<String> domain) {
78
79        Label label = mRoot;
80        for (String labelString : domain) {
81            label = label.getSubLabel(labelString);
82            if (label == null) {
83                return Match.None;
84            } else if (label.getMatch() != Match.None) {
85                return label.getMatch();
86            }
87        }
88        return Match.None;  // Domain is a super domain
89    }
90
91    @Override
92    public String toString() {
93        return "Domain matcher " + mRoot;
94    }
95
96    private static final String[] TestDomains = {
97            "garbage.apple.com",
98            "apple.com",
99            "com",
100            "jan.android.google.com.",
101            "jan.android.google.com",
102            "android.google.com",
103            "google.com",
104            "jan.android.google.net.",
105            "jan.android.google.net",
106            "android.google.net",
107            "google.net",
108            "net.",
109            "."
110    };
111
112    public static void main(String[] args) {
113        DomainMatcher dm1 = new DomainMatcher(Utils.splitDomain("android.google.com"),
114                Collections.<List<String>>emptyList());
115        for (String domain : TestDomains) {
116            System.out.println(domain + ": " + dm1.isSubDomain(Utils.splitDomain(domain)));
117        }
118        List<List<String>> secondaries = new ArrayList<List<String>>();
119        secondaries.add(Utils.splitDomain("apple.com"));
120        secondaries.add(Utils.splitDomain("net"));
121        DomainMatcher dm2 = new DomainMatcher(Utils.splitDomain("android.google.com"), secondaries);
122        for (String domain : TestDomains) {
123            System.out.println(domain + ": " + dm2.isSubDomain(Utils.splitDomain(domain)));
124        }
125    }
126}
127