Added methods for managing uri query parameters
Change-Id: Ic98c1bd159740dd4d895889079f9f2abae4fc2b9
This commit is contained in:
@@ -105431,6 +105431,17 @@
|
||||
<parameter name="key" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getQueryParameterNames"
|
||||
return="java.util.Set<java.lang.String>"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getQueryParameters"
|
||||
return="java.util.List<java.lang.String>"
|
||||
abstract="false"
|
||||
@@ -105677,6 +105688,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="clearQuery"
|
||||
return="android.net.Uri.Builder"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="encodedAuthority"
|
||||
return="android.net.Uri.Builder"
|
||||
abstract="false"
|
||||
|
||||
@@ -28,8 +28,10 @@ import java.net.URLEncoder;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Immutable URI reference. A URI reference includes a URI and a fragment, the
|
||||
@@ -47,7 +49,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
/*
|
||||
|
||||
This class aims to do as little up front work as possible. To accomplish
|
||||
that, we vary the implementation dependending on what the user passes in.
|
||||
that, we vary the implementation depending on what the user passes in.
|
||||
For example, we have one implementation if the user passes in a
|
||||
URI string (StringUri) and another if the user passes in the
|
||||
individual components (OpaqueUri).
|
||||
@@ -1261,6 +1263,8 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
*
|
||||
* <p>An opaque URI follows this pattern:
|
||||
* {@code <scheme>:<opaque part>#<fragment>}
|
||||
*
|
||||
* <p>Use {@link Uri#buildUpon()} to obtain a builder representing an existing URI.
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
@@ -1446,6 +1450,13 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the the previously set query.
|
||||
*/
|
||||
public Builder clearQuery() {
|
||||
return query((Part) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Uri with the current attributes.
|
||||
*
|
||||
@@ -1490,6 +1501,45 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of the unique names of all query parameters. Iterating
|
||||
* over the set will return the names in order of their first occurrence.
|
||||
*
|
||||
* @throws UnsupportedOperationException if this isn't a hierarchical URI
|
||||
*
|
||||
* @return a set of decoded names
|
||||
*/
|
||||
public Set<String> getQueryParameterNames() {
|
||||
if (isOpaque()) {
|
||||
throw new UnsupportedOperationException(NOT_HIERARCHICAL);
|
||||
}
|
||||
|
||||
String query = getEncodedQuery();
|
||||
if (query == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
Set<String> names = new LinkedHashSet<String>();
|
||||
int start = 0;
|
||||
do {
|
||||
int next = query.indexOf('&', start);
|
||||
int end = (next == -1) ? query.length() : next;
|
||||
|
||||
int separator = query.indexOf('=', start);
|
||||
if (separator > end || separator == -1) {
|
||||
separator = end;
|
||||
}
|
||||
|
||||
String name = query.substring(start, separator);
|
||||
names.add(decode(name));
|
||||
|
||||
// Move start to end of name.
|
||||
start = end + 1;
|
||||
} while (start < query.length());
|
||||
|
||||
return Collections.unmodifiableSet(names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the query string for parameter values with the given key.
|
||||
*
|
||||
@@ -1497,13 +1547,15 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
*
|
||||
* @throws UnsupportedOperationException if this isn't a hierarchical URI
|
||||
* @throws NullPointerException if key is null
|
||||
*
|
||||
* @return a list of decoded values
|
||||
*/
|
||||
public List<String> getQueryParameters(String key) {
|
||||
if (isOpaque()) {
|
||||
throw new UnsupportedOperationException(NOT_HIERARCHICAL);
|
||||
}
|
||||
if (key == null) {
|
||||
throw new NullPointerException("key");
|
||||
}
|
||||
|
||||
String query = getEncodedQuery();
|
||||
if (query == null) {
|
||||
@@ -1517,39 +1569,34 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
// Prepend query with "&" making the first parameter the same as the
|
||||
// rest.
|
||||
query = "&" + query;
|
||||
|
||||
// Parameter prefix.
|
||||
String prefix = "&" + encodedKey + "=";
|
||||
|
||||
ArrayList<String> values = new ArrayList<String>();
|
||||
|
||||
int start = 0;
|
||||
int length = query.length();
|
||||
while (start < length) {
|
||||
start = query.indexOf(prefix, start);
|
||||
do {
|
||||
int nextAmpersand = query.indexOf('&', start);
|
||||
int end = nextAmpersand != -1 ? nextAmpersand : query.length();
|
||||
|
||||
if (start == -1) {
|
||||
// No more values.
|
||||
int separator = query.indexOf('=', start);
|
||||
if (separator > end || separator == -1) {
|
||||
separator = end;
|
||||
}
|
||||
|
||||
if (separator - start == encodedKey.length()
|
||||
&& query.regionMatches(start, encodedKey, 0, encodedKey.length())) {
|
||||
if (separator == end) {
|
||||
values.add("");
|
||||
} else {
|
||||
values.add(decode(query.substring(separator + 1, end)));
|
||||
}
|
||||
}
|
||||
|
||||
// Move start to end of name.
|
||||
if (nextAmpersand != -1) {
|
||||
start = nextAmpersand + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// Move start to start of value.
|
||||
start += prefix.length();
|
||||
|
||||
// Find end of value.
|
||||
int end = query.indexOf('&', start);
|
||||
if (end == -1) {
|
||||
end = query.length();
|
||||
}
|
||||
|
||||
String value = query.substring(start, end);
|
||||
values.add(decode(value));
|
||||
|
||||
start = end;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return Collections.unmodifiableList(values);
|
||||
}
|
||||
@@ -1560,7 +1607,6 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
* @param key which will be encoded
|
||||
* @throws UnsupportedOperationException if this isn't a hierarchical URI
|
||||
* @throws NullPointerException if key is null
|
||||
*
|
||||
* @return the decoded value or null if no parameter is found
|
||||
*/
|
||||
public String getQueryParameter(String key) {
|
||||
@@ -1577,34 +1623,33 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
|
||||
}
|
||||
|
||||
final String encodedKey = encode(key, null);
|
||||
final int encodedKeyLength = encodedKey.length();
|
||||
final int length = query.length();
|
||||
int start = 0;
|
||||
do {
|
||||
int nextAmpersand = query.indexOf('&', start);
|
||||
int end = nextAmpersand != -1 ? nextAmpersand : length;
|
||||
|
||||
int encodedKeySearchIndex = 0;
|
||||
final int encodedKeySearchEnd = query.length() - (encodedKeyLength + 1);
|
||||
int separator = query.indexOf('=', start);
|
||||
if (separator > end || separator == -1) {
|
||||
separator = end;
|
||||
}
|
||||
|
||||
while (encodedKeySearchIndex <= encodedKeySearchEnd) {
|
||||
int keyIndex = query.indexOf(encodedKey, encodedKeySearchIndex);
|
||||
if (keyIndex == -1) {
|
||||
break;
|
||||
}
|
||||
final int equalsIndex = keyIndex + encodedKeyLength;
|
||||
if (equalsIndex >= query.length()) {
|
||||
break;
|
||||
}
|
||||
if (query.charAt(equalsIndex) != '=') {
|
||||
encodedKeySearchIndex = equalsIndex + 1;
|
||||
continue;
|
||||
}
|
||||
if (keyIndex == 0 || query.charAt(keyIndex - 1) == '&') {
|
||||
int end = query.indexOf('&', equalsIndex);
|
||||
if (end == -1) {
|
||||
end = query.length();
|
||||
if (separator - start == encodedKey.length()
|
||||
&& query.regionMatches(start, encodedKey, 0, encodedKey.length())) {
|
||||
if (separator == end) {
|
||||
return "";
|
||||
} else {
|
||||
return decode(query.substring(separator + 1, end));
|
||||
}
|
||||
return decode(query.substring(equalsIndex + 1, end));
|
||||
} else {
|
||||
encodedKeySearchIndex = equalsIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Move start to end of name.
|
||||
if (nextAmpersand != -1) {
|
||||
start = nextAmpersand + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ import junit.framework.TestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class UriTest extends TestCase {
|
||||
|
||||
@@ -52,20 +55,20 @@ public class UriTest extends TestCase {
|
||||
|
||||
private void parcelAndUnparcel(Uri u) {
|
||||
Parcel p = Parcel.obtain();
|
||||
try {
|
||||
Uri.writeToParcel(p, u);
|
||||
p.setDataPosition(0);
|
||||
assertEquals(u, Uri.CREATOR.createFromParcel(p));
|
||||
try {
|
||||
Uri.writeToParcel(p, u);
|
||||
p.setDataPosition(0);
|
||||
assertEquals(u, Uri.CREATOR.createFromParcel(p));
|
||||
|
||||
p.setDataPosition(0);
|
||||
u = u.buildUpon().build();
|
||||
Uri.writeToParcel(p, u);
|
||||
p.setDataPosition(0);
|
||||
assertEquals(u, Uri.CREATOR.createFromParcel(p));
|
||||
}
|
||||
finally {
|
||||
p.recycle();
|
||||
}
|
||||
p.setDataPosition(0);
|
||||
u = u.buildUpon().build();
|
||||
Uri.writeToParcel(p, u);
|
||||
p.setDataPosition(0);
|
||||
assertEquals(u, Uri.CREATOR.createFromParcel(p));
|
||||
}
|
||||
finally {
|
||||
p.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@@ -603,4 +606,122 @@ public class UriTest extends TestCase {
|
||||
assertEquals("", uri.getQueryParameter("b"));
|
||||
assertEquals("", uri.getQueryParameter("c"));
|
||||
}
|
||||
|
||||
public void testGetQueryParameterEmptyKey() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?=b");
|
||||
assertEquals("b", uri.getQueryParameter(""));
|
||||
}
|
||||
|
||||
public void testGetQueryParameterEmptyKey2() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d");
|
||||
assertEquals("", uri.getQueryParameter(""));
|
||||
}
|
||||
|
||||
public void testGetQueryParameterEmptyKey3() {
|
||||
Uri uri = Uri.parse("http://www.google.com?");
|
||||
assertEquals("", uri.getQueryParameter(""));
|
||||
}
|
||||
|
||||
public void testGetQueryParameterEmptyKey4() {
|
||||
Uri uri = Uri.parse("http://www.google.com?a=b&");
|
||||
assertEquals("", uri.getQueryParameter(""));
|
||||
}
|
||||
|
||||
public void testGetQueryParametersEmptyKey() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?=b&");
|
||||
List<String> values = uri.getQueryParameters("");
|
||||
assertEquals(2, values.size());
|
||||
assertEquals("b", values.get(0));
|
||||
assertEquals("", values.get(1));
|
||||
}
|
||||
|
||||
public void testGetQueryParametersEmptyKey2() {
|
||||
Uri uri = Uri.parse("http://www.google.com?");
|
||||
List<String> values = uri.getQueryParameters("");
|
||||
assertEquals(1, values.size());
|
||||
assertEquals("", values.get(0));
|
||||
}
|
||||
|
||||
public void testGetQueryParametersEmptyKey3() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d");
|
||||
List<String> values = uri.getQueryParameters("");
|
||||
assertEquals(1, values.size());
|
||||
assertEquals("", values.get(0));
|
||||
}
|
||||
|
||||
public void testGetQueryParameterNames() {
|
||||
Uri uri = Uri.parse("http://test?a=1");
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
assertEquals(1, names.size());
|
||||
assertEquals("a", names.iterator().next());
|
||||
}
|
||||
|
||||
public void testGetQueryParameterNamesEmptyKey() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a=x&&c=z");
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
Iterator<String> iter = names.iterator();
|
||||
assertEquals(3, names.size());
|
||||
assertEquals("a", iter.next());
|
||||
assertEquals("", iter.next());
|
||||
assertEquals("c", iter.next());
|
||||
}
|
||||
|
||||
public void testGetQueryParameterNamesEmptyKey2() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a=x&=d&c=z");
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
Iterator<String> iter = names.iterator();
|
||||
assertEquals(3, names.size());
|
||||
assertEquals("a", iter.next());
|
||||
assertEquals("", iter.next());
|
||||
assertEquals("c", iter.next());
|
||||
}
|
||||
|
||||
public void testGetQueryParameterNamesEmptyValues() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a=foo&b=&c=");
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
Iterator<String> iter = names.iterator();
|
||||
assertEquals(3, names.size());
|
||||
assertEquals("a", iter.next());
|
||||
assertEquals("b", iter.next());
|
||||
assertEquals("c", iter.next());
|
||||
}
|
||||
|
||||
public void testGetQueryParameterNamesEdgeCases() {
|
||||
Uri uri = Uri.parse("http://foo?a=bar&b=bar&c=&&d=baz&e&f&g=buzz&&&a&b=bar&h");
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
Iterator<String> iter = names.iterator();
|
||||
assertEquals(9, names.size());
|
||||
assertEquals("a", iter.next());
|
||||
assertEquals("b", iter.next());
|
||||
assertEquals("c", iter.next());
|
||||
assertEquals("", iter.next());
|
||||
assertEquals("d", iter.next());
|
||||
assertEquals("e", iter.next());
|
||||
assertEquals("f", iter.next());
|
||||
assertEquals("g", iter.next());
|
||||
assertEquals("h", iter.next());
|
||||
}
|
||||
|
||||
public void testGetQueryParameterNamesEscapedKeys() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
assertEquals(2, names.size());
|
||||
Iterator<String> iter = names.iterator();
|
||||
assertEquals("a b", iter.next());
|
||||
assertEquals("c d", iter.next());
|
||||
}
|
||||
|
||||
public void testGetQueryParameterEscapedKeys() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
|
||||
String value = uri.getQueryParameter("a b");
|
||||
assertEquals("foo", value);
|
||||
}
|
||||
|
||||
public void testClearQueryParameters() {
|
||||
Uri uri = Uri.parse("http://www.google.com/?a=x&b=y&c=z").buildUpon()
|
||||
.clearQuery().appendQueryParameter("foo", "bar").build();
|
||||
Set<String> names = uri.getQueryParameterNames();
|
||||
assertEquals(1, names.size());
|
||||
assertEquals("foo", names.iterator().next());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user