Home | History | Annotate | Download | only in pps
      1 package com.android.hotspot2.pps;
      2 
      3 import com.android.hotspot2.Utils;
      4 
      5 import java.util.ArrayList;
      6 import java.util.Collections;
      7 import java.util.HashMap;
      8 import java.util.Iterator;
      9 import java.util.List;
     10 import java.util.Map;
     11 
     12 public 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      *
     80      * @param domain Domain to be checked.
     81      * @return None if domain is not a sub-domain, Primary if it matched one of the primary domains
     82      * or Secondary if it matched on of the secondary domains.
     83      */
     84     public Match isSubDomain(List<String> domain) {
     85 
     86         Label label = mRoot;
     87         for (String labelString : domain) {
     88             label = label.getSubLabel(labelString);
     89             if (label == null) {
     90                 return Match.None;
     91             } else if (label.getMatch() != Match.None) {
     92                 return label.getMatch();
     93             }
     94         }
     95         return Match.None;  // Domain is a super domain
     96     }
     97 
     98     public static boolean arg2SubdomainOfArg1(List<String> arg1, List<String> arg2) {
     99         if (arg2.size() < arg1.size()) {
    100             return false;
    101         }
    102 
    103         Iterator<String> l1 = arg1.iterator();
    104         Iterator<String> l2 = arg2.iterator();
    105 
    106         while (l1.hasNext()) {
    107             if (!l1.next().equals(l2.next())) {
    108                 return false;
    109             }
    110         }
    111         return true;
    112     }
    113 
    114     @Override
    115     public String toString() {
    116         return "Domain matcher " + mRoot;
    117     }
    118 
    119     private static final String[] TestDomains = {
    120             "garbage.apple.com",
    121             "apple.com",
    122             "com",
    123             "jan.android.google.com.",
    124             "jan.android.google.com",
    125             "android.google.com",
    126             "google.com",
    127             "jan.android.google.net.",
    128             "jan.android.google.net",
    129             "android.google.net",
    130             "google.net",
    131             "net.",
    132             "."
    133     };
    134 
    135     public static void main(String[] args) {
    136         DomainMatcher dm1 = new DomainMatcher(Utils.splitDomain("android.google.com"),
    137                 Collections.<List<String>>emptyList());
    138         for (String domain : TestDomains) {
    139             System.out.println(domain + ": " + dm1.isSubDomain(Utils.splitDomain(domain)));
    140         }
    141         List<List<String>> secondaries = new ArrayList<List<String>>();
    142         secondaries.add(Utils.splitDomain("apple.com"));
    143         secondaries.add(Utils.splitDomain("net"));
    144         DomainMatcher dm2 = new DomainMatcher(Utils.splitDomain("android.google.com"), secondaries);
    145         for (String domain : TestDomains) {
    146             System.out.println(domain + ": " + dm2.isSubDomain(Utils.splitDomain(domain)));
    147         }
    148     }
    149 }
    150