DomainMatcher.java revision 77f2b82a2e80af8da52c22d69a76def6d4209757
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 // Primary overwrites secondary. 73 mRoot.addDomain(primary.iterator(), Match.Primary); 74 } 75 76 /** 77 * Check if domain is either a the same or a sub-domain of any of the domains in the domain tree 78 * in this matcher, i.e. all or or a sub-set of the labels in domain matches a path in the tree. 79 * @param domain Domain to be checked. 80 * @return None if domain is not a sub-domain, Primary if it matched one of the primary domains 81 * or Secondary if it matched on of the secondary domains. 82 */ 83 public Match isSubDomain(List<String> domain) { 84 85 Label label = mRoot; 86 for (String labelString : domain) { 87 label = label.getSubLabel(labelString); 88 if (label == null) { 89 return Match.None; 90 } else if (label.getMatch() != Match.None) { 91 return label.getMatch(); 92 } 93 } 94 return Match.None; // Domain is a super domain 95 } 96 97 public static boolean arg2SubdomainOfArg1(List<String> arg1, List<String> arg2) { 98 if (arg2.size() < arg1.size()) { 99 return false; 100 } 101 102 Iterator<String> l1 = arg1.listIterator(arg1.size()); 103 Iterator<String> l2 = arg2.listIterator(arg2.size()); 104 105 while(l1.hasNext()) { 106 if (!l1.next().equals(l2.next())) { 107 return false; 108 } 109 } 110 return true; 111 } 112 113 @Override 114 public String toString() { 115 return "Domain matcher " + mRoot; 116 } 117 118 private static final String[] TestDomains = { 119 "garbage.apple.com", 120 "apple.com", 121 "com", 122 "jan.android.google.com.", 123 "jan.android.google.com", 124 "android.google.com", 125 "google.com", 126 "jan.android.google.net.", 127 "jan.android.google.net", 128 "android.google.net", 129 "google.net", 130 "net.", 131 "." 132 }; 133 134 public static void main(String[] args) { 135 DomainMatcher dm1 = new DomainMatcher(Utils.splitDomain("android.google.com"), 136 Collections.<List<String>>emptyList()); 137 for (String domain : TestDomains) { 138 System.out.println(domain + ": " + dm1.isSubDomain(Utils.splitDomain(domain))); 139 } 140 List<List<String>> secondaries = new ArrayList<List<String>>(); 141 secondaries.add(Utils.splitDomain("apple.com")); 142 secondaries.add(Utils.splitDomain("net")); 143 DomainMatcher dm2 = new DomainMatcher(Utils.splitDomain("android.google.com"), secondaries); 144 for (String domain : TestDomains) { 145 System.out.println(domain + ": " + dm2.isSubDomain(Utils.splitDomain(domain))); 146 } 147 } 148} 149