Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import java.util.Arrays;
      4 import java.util.HashMap;
      5 import java.util.List;
      6 
      7 import android.content.UriMatcher;
      8 import android.net.Uri;
      9 
     10 import com.xtremelabs.robolectric.internal.Implementation;
     11 import com.xtremelabs.robolectric.internal.Implements;
     12 
     13 @Implements(UriMatcher.class)
     14 public class ShadowUriMatcher {
     15 
     16 	public static class MatchNode {
     17 		public int code = UriMatcher.NO_MATCH;
     18 		public HashMap<String, MatchNode> map = new HashMap<String, ShadowUriMatcher.MatchNode>();
     19 		public MatchNode number;
     20 		public MatchNode text;
     21 
     22 		public MatchNode(int code) {
     23 			this.code = code;
     24 		}
     25 	}
     26 
     27 	public MatchNode rootNode;
     28 
     29 	public void __constructor__(int code) {
     30 		rootNode = new MatchNode(code);
     31 	}
     32 
     33 	@Implementation
     34 	public void addURI(String authority, String path, int code) {
     35 		MatchNode authNode = rootNode.map.get(authority);
     36 		if (authNode == null) {
     37 			authNode = new MatchNode(rootNode.code);
     38 			rootNode.map.put(authority, authNode);
     39 		}
     40 
     41 		String[] segments = path.split("/");
     42 		addNodes(authNode, Arrays.asList(segments), code);
     43 	}
     44 
     45 	@Implementation
     46 	public int match(Uri uri) {
     47 		String auth = uri.getAuthority();
     48 		List<String> segments = uri.getPathSegments();
     49 
     50 		if (!rootNode.map.containsKey(auth)) {
     51 			return rootNode.code;
     52 		}
     53 
     54 		return matchSegments(rootNode.map.get(auth), segments);
     55 	}
     56 
     57 	private int matchSegments(MatchNode node, List<String> segments) {
     58 		if (segments.isEmpty()) return node.code;
     59 		String segment = segments.get(0);
     60 		segments = segments.subList(1, segments.size());
     61 
     62 		if (node.map.containsKey(segment)) {
     63 			return matchSegments(node.map.get(segment), segments);
     64 		}
     65 		if (node.number != null) {
     66 			long id;
     67 			try {
     68 				id = Long.parseLong(segment);
     69 				if (id >= 0) {
     70 					return matchSegments(node.number, segments);
     71 				}
     72 			}
     73 			catch (NumberFormatException e) {}
     74 		}
     75 		if (node.text != null) {
     76 			return matchSegments(node.text, segments);
     77 		}
     78 
     79 		return rootNode.code;
     80 	}
     81 
     82 	private void addNodes(MatchNode baseNode, List<String> segments, int code) {
     83 		MatchNode nextNode = null;
     84 		String segment = segments.get(0);
     85 
     86 		if (segment.equals("#")) {
     87 			nextNode = baseNode.number;
     88 			if (nextNode == null) {
     89 				nextNode = new MatchNode(rootNode.code);
     90 				baseNode.number = nextNode;
     91 			}
     92 		}
     93 		else if (segment.equals("*")) {
     94 			nextNode = baseNode.text;
     95 			if (nextNode == null) {
     96 				nextNode = new MatchNode(rootNode.code);
     97 				baseNode.text = nextNode;
     98 			}
     99 		}
    100 		else {
    101 			nextNode = baseNode.map.get(segment);
    102 			if (nextNode == null) {
    103 				nextNode = new MatchNode(rootNode.code);
    104 				baseNode.map.put(segment, nextNode);
    105 			}
    106 		}
    107 
    108 		if (segments.size() > 1) {
    109 			addNodes(nextNode, segments.subList(1, segments.size()), code);
    110 		}
    111 		else {
    112 			nextNode.code = code;
    113 		}
    114 	}
    115 
    116 }
    117