diff options
author | David Luhmer <david-dev@live.de> | 2019-05-21 19:54:45 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-21 19:54:45 +0300 |
commit | 590a7871ba9edad01d7e945c4072d786b666c5ef (patch) | |
tree | 9b7c4d747b35386c3b8ee4c554d89421956364b9 | |
parent | 22f7eb22abb055020241ca2c7000ff392bc9329b (diff) | |
parent | e77876c0bba8885651756c7b0bfaa4e388e1c138 (diff) |
Merge pull request #64 from nextcloud/improve-query-params-parsing0.3.1
parse query parameters in url and put them into the parameterMap
3 files changed, 69 insertions, 22 deletions
diff --git a/src/main/java/com/nextcloud/android/sso/api/NextcloudRetrofitServiceMethod.java b/src/main/java/com/nextcloud/android/sso/api/NextcloudRetrofitServiceMethod.java index 80ad3d7..4ca6adc 100644 --- a/src/main/java/com/nextcloud/android/sso/api/NextcloudRetrofitServiceMethod.java +++ b/src/main/java/com/nextcloud/android/sso/api/NextcloudRetrofitServiceMethod.java @@ -1,8 +1,9 @@ package com.nextcloud.android.sso.api; -import androidx.annotation.Nullable; import android.util.Log; +import androidx.annotation.Nullable; + import com.nextcloud.android.sso.aidl.NextcloudRequest; import com.nextcloud.android.sso.helper.Okhttp3Helper; import com.nextcloud.android.sso.helper.ReactivexHelper; @@ -22,6 +23,7 @@ import java.lang.reflect.Type; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -63,6 +65,7 @@ public class NextcloudRetrofitServiceMethod<T> { private @Nullable Headers headers; private Type returnType; private boolean followRedirects = false; + private Map<String, String> queryParameters; //private boolean formUrlEncoded = false; private final NextcloudRequest.Builder requestBuilder; @@ -79,6 +82,8 @@ public class NextcloudRetrofitServiceMethod<T> { parseMethodAnnotation(annotation); } + this.queryParameters = parsePathParameters(); + if(headers == null) { headers = new Headers.Builder().build(); } @@ -105,6 +110,10 @@ public class NextcloudRetrofitServiceMethod<T> { Map<String, String> parameters = new HashMap<>(); + // Copy all static query params into parameters array + parameters.putAll(this.queryParameters); + + // Build/parse dynamic parameters for(int i = 0; i < parameterAnnotationsArray.length; i++) { Annotation annotation = parameterAnnotationsArray[i][0]; @@ -237,20 +246,7 @@ public class NextcloudRetrofitServiceMethod<T> { return; } - // Get the relative URL path and existing query string, if present. - int question = value.indexOf('?'); - if (question != -1 && question < value.length() - 1) { - // Ensure the query string does not have any named parameters. - String queryParams = value.substring(question + 1); - Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams); - if (queryParamMatcher.find()) { - throw methodError(method, "URL query string \"%s\" must not have replace block. " - + "For dynamic query parameters use @Query.", queryParams); - } - } - this.relativeUrl = value; - //Set<String> relativeUrlParamNames = parsePathParameters(value); } private Headers parseHeaders(String[] headers) { @@ -282,16 +278,37 @@ public class NextcloudRetrofitServiceMethod<T> { * Gets the set of unique path parameters used in the given URI. If a parameter is used twice * in the URI, it will only show up once in the set. */ - /* - private static Set<String> parsePathParameters(String path) { - Matcher m = PARAM_URL_REGEX.matcher(path); - Set<String> patterns = new LinkedHashSet<>(); - while (m.find()) { - patterns.add(m.group(1)); + private Map<String, String> parsePathParameters() { + Map<String, String> queryPairs = new LinkedHashMap<>(); + + if(this.relativeUrl == null) { + return queryPairs; + } + + int idxQuery = this.relativeUrl.indexOf("?"); + if (idxQuery != -1 && idxQuery < this.relativeUrl.length() - 1) { + // Ensure the query string does not have any named parameters. + String query = this.relativeUrl.substring(idxQuery + 1); + + // Check for named parameters + Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(query); + if (queryParamMatcher.find()) { + throw methodError(method, "URL query string \"%s\" must not have replace block. " + + "For dynamic query parameters use @Query.", query); + } + + // If none found.. parse the static query parameters + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + queryPairs.put(pair.substring(0, idx), pair.substring(idx + 1)); + } + + // Remove query params from url + this.relativeUrl = this.relativeUrl.substring(0, idxQuery); } - return patterns; + return queryPairs; } - */ diff --git a/src/test/java/com/nextcloud/android/sso/api/API.java b/src/test/java/com/nextcloud/android/sso/api/API.java index 917976b..68147c7 100644 --- a/src/test/java/com/nextcloud/android/sso/api/API.java +++ b/src/test/java/com/nextcloud/android/sso/api/API.java @@ -100,4 +100,7 @@ public interface API { @POST("/test") Call<ResponseBody> postFormUrlEncodedField(@Field("name") String name); + @GET("cloud/capabilities?format=json") + Call<ResponseBody> getCapabilities(@Query("test") long test); + } diff --git a/src/test/java/com/nextcloud/android/sso/api/TestRetrofitAPI.java b/src/test/java/com/nextcloud/android/sso/api/TestRetrofitAPI.java index ab971c4..b3eecb8 100644 --- a/src/test/java/com/nextcloud/android/sso/api/TestRetrofitAPI.java +++ b/src/test/java/com/nextcloud/android/sso/api/TestRetrofitAPI.java @@ -426,6 +426,33 @@ public class TestRetrofitAPI { @Test + public void testQueryParamInUrl() { + try { + mApi.getCapabilities(1).execute(); + } catch (IOException e) { + fail(e.getMessage()); + } + + Map<String, String> map = new HashMap<>(); + map.put("format", "json"); + map.put("test", "1"); + + NextcloudRequest request = new NextcloudRequest.Builder() + .setMethod("GET") + .setUrl(mApiEndpoint + "cloud/capabilities") + .setParameter(map) + .build(); + + Type type = new TypeToken<ResponseBody>() {}.getType(); + try { + verify(nextcloudApiMock).performRequest(eq(type), eq(request)); + } catch (Exception e) { + fail(e.getMessage()); + } + } + + + @Test public void testExecute() { try { mApi.getFollowRedirects().execute(); |