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