Skip to content

Instantly share code, notes, and snippets.

@tspspi
Last active October 25, 2018 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tspspi/6fa212c01204970539b2555cda0e8788 to your computer and use it in GitHub Desktop.
Save tspspi/6fa212c01204970539b2555cda0e8788 to your computer and use it in GitHub Desktop.
UriMatcher like available on Android without Android dependencies
/*
Derived from Android Source Code
Source: platform_frameworks_base/core/java/android/content/UriMatcher.java
(see for example: https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r33/core/java/android/content/UriMatcher.java )
Original License: Apache License, Version 2 (http://www.apache.org/licenses/LICENSE-2.0)
Original Copyright: Copyright (C) 2006 The Android Open Source Project
Modifications made:
To be useable outside the Android Framework android.net.Uri has been changed to
java.net.URL, reordered constant definitions towards the top of the class, no
Android specific annotations, etc.
*/
import java.util.ArrayList;
import java.util.List;
import java.net.URL;
public class UriMatcher {
public static final int NO_MATCH = -1;
private static final int EXACT = 0;
private static final int NUMBER = 1;
private static final int TEXT = 2;
private int mCode;
private int mWhich;
private String mText;
private ArrayList<UriMatcher> mChildren;
public UriMatcher(int code) {
mCode = code;
mWhich = -1;
mChildren = new ArrayList<UriMatcher>();
mText = null;
}
private UriMatcher() {
mCode = NO_MATCH;
mWhich = -1;
mChildren = new ArrayList<UriMatcher>();
mText = null;
}
public void addURI(String authority, String path, int code) {
if (code < 0) {
throw new IllegalArgumentException("code " + code + " is invalid: it must be positive");
}
String[] tokens = null;
if (path != null) {
String newPath = path;
// Strip leading slash if present.
if (path.length() > 1 && path.charAt(0) == '/') {
newPath = path.substring(1);
}
tokens = newPath.split("/");
}
int numTokens = tokens != null ? tokens.length : 0;
UriMatcher node = this;
for (int i = -1; i < numTokens; i++) {
String token = i < 0 ? authority : tokens[i];
ArrayList<UriMatcher> children = node.mChildren;
int numChildren = children.size();
UriMatcher child;
int j;
for (j = 0; j < numChildren; j++) {
child = children.get(j);
if (token.equals(child.mText)) {
node = child;
break;
}
}
if (j == numChildren) {
// Child not found, create it
child = new UriMatcher();
if (token.equals("#")) {
child.mWhich = NUMBER;
} else if (token.equals("*")) {
child.mWhich = TEXT;
} else {
child.mWhich = EXACT;
}
child.mText = token;
node.mChildren.add(child);
node = child;
}
}
node.mCode = code;
}
public int match(URL uri) {
final String[] pathSegments = uri.getPath().split("/");
final int li = pathSegments.length;
UriMatcher node = this;
if (li == 0) {
return this.mCode;
}
for (int i=-1; i<li; i++) {
String u = pathSegments[i];
ArrayList<UriMatcher> list = node.mChildren;
if (list == null) {
break;
}
node = null;
int lj = list.size();
for (int j=0; j<lj; j++) {
UriMatcher n = list.get(j);
which_switch:
switch (n.mWhich) {
case EXACT:
if (n.mText.equals(u)) {
node = n;
}
break;
case NUMBER:
int lk = u.length();
for (int k=0; k<lk; k++) {
char c = u.charAt(k);
if (c < '0' || c > '9') {
break which_switch;
}
}
node = n;
break;
case TEXT:
node = n;
break;
}
if (node != null) {
break;
}
}
if (node == null) {
return NO_MATCH;
}
}
return node.mCode;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment