1ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpackage com.android.hotspot2.pps; 2ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 3ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.Utils; 4ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 5ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.ArrayList; 6ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Collections; 7ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.HashMap; 8ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Iterator; 9ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.List; 10ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Map; 11ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 12ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpublic class DomainMatcher { 13ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 14ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public enum Match {None, Primary, Secondary} 15ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 16ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private final Label mRoot; 17ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 18ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static class Label { 19ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private final Map<String, Label> mSubDomains; 20ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private final Match mMatch; 21ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 22ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private Label(Match match) { 23ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mMatch = match; 24ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mSubDomains = match == Match.None ? new HashMap<String, Label>() : null; 25ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 26ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 27ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private void addDomain(Iterator<String> labels, Match match) { 28ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String labelName = labels.next(); 29ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (labels.hasNext()) { 30ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Label subLabel = new Label(Match.None); 31ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mSubDomains.put(labelName, subLabel); 32ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist subLabel.addDomain(labels, match); 33ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 34ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mSubDomains.put(labelName, new Label(match)); 35ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 36ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 37ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 38ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private Label getSubLabel(String labelString) { 39ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return mSubDomains.get(labelString); 40ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 41ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 42ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public Match getMatch() { 43ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return mMatch; 44ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 45ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 46ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private void toString(StringBuilder sb) { 47ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (mSubDomains != null) { 48ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sb.append(".{"); 49ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (Map.Entry<String, Label> entry : mSubDomains.entrySet()) { 50ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sb.append(entry.getKey()); 51ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist entry.getValue().toString(sb); 52ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 53ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sb.append('}'); 54ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 55ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sb.append('=').append(mMatch); 56ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 57ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 58ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 59ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist @Override 60ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public String toString() { 61ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist StringBuilder sb = new StringBuilder(); 62ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist toString(sb); 63ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return sb.toString(); 64ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 65ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 66ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 67ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public DomainMatcher(List<String> primary, List<List<String>> secondary) { 68ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mRoot = new Label(Match.None); 69ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (List<String> secondaryLabel : secondary) { 70ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mRoot.addDomain(secondaryLabel.iterator(), Match.Secondary); 71ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 72ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // Primary overwrites secondary. 73ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mRoot.addDomain(primary.iterator(), Match.Primary); 74ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 75ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 76ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist /** 77ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * Check if domain is either a the same or a sub-domain of any of the domains in the domain tree 78ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * in this matcher, i.e. all or or a sub-set of the labels in domain matches a path in the tree. 79ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * 80ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * @param domain Domain to be checked. 81ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * @return None if domain is not a sub-domain, Primary if it matched one of the primary domains 82ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * or Secondary if it matched on of the secondary domains. 83ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist */ 84ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public Match isSubDomain(List<String> domain) { 85ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 86ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Label label = mRoot; 87ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (String labelString : domain) { 88ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist label = label.getSubLabel(labelString); 89ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (label == null) { 90ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Match.None; 91ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (label.getMatch() != Match.None) { 92ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return label.getMatch(); 93ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 94ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 95ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Match.None; // Domain is a super domain 96ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 97ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 98ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static boolean arg2SubdomainOfArg1(List<String> arg1, List<String> arg2) { 99ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (arg2.size() < arg1.size()) { 100ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return false; 101ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 102ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 103ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Iterator<String> l1 = arg1.iterator(); 104ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Iterator<String> l2 = arg2.iterator(); 105ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 106ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist while (l1.hasNext()) { 107ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!l1.next().equals(l2.next())) { 108ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return false; 109ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 110ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 111ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return true; 112ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 113ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 114ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist @Override 115ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public String toString() { 116ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return "Domain matcher " + mRoot; 117ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 118ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 119ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static final String[] TestDomains = { 120ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "garbage.apple.com", 121ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "apple.com", 122ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "com", 123ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "jan.android.google.com.", 124ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "jan.android.google.com", 125ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "android.google.com", 126ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "google.com", 127ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "jan.android.google.net.", 128ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "jan.android.google.net", 129ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "android.google.net", 130ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "google.net", 131ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "net.", 132ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "." 133ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist }; 134ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 135ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static void main(String[] args) { 136ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist DomainMatcher dm1 = new DomainMatcher(Utils.splitDomain("android.google.com"), 137ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Collections.<List<String>>emptyList()); 138ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (String domain : TestDomains) { 139ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist System.out.println(domain + ": " + dm1.isSubDomain(Utils.splitDomain(domain))); 140ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 141ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<List<String>> secondaries = new ArrayList<List<String>>(); 142ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist secondaries.add(Utils.splitDomain("apple.com")); 143ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist secondaries.add(Utils.splitDomain("net")); 144ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist DomainMatcher dm2 = new DomainMatcher(Utils.splitDomain("android.google.com"), secondaries); 145ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (String domain : TestDomains) { 146ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist System.out.println(domain + ": " + dm2.isSubDomain(Utils.splitDomain(domain))); 147ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 148ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 149ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist} 150