Skip to content

Commit f2dd354

Browse files
authored
Experimental properties for route options (#1420)
1 parent cf5dda8 commit f2dd354

6 files changed

Lines changed: 164 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Mapbox welcomes participation and contributions from everyone.
55
### main
66
- Added roundtrip of unrecognized JSON properties. [#1394](https://github.com/mapbox/mapbox-java/pull/1394)
77
- Added API to access unrecognized JSON properties. See `#getUnrecognizedProperty` and `#getUnrecognizedPropertiesNames` in each Directions API model object. [#1416](https://github.com/mapbox/mapbox-java/pull/1416)
8+
- Added `RouteOptions.Builder#unrecognizedProperties` to set custom request parameters to a URL generated by `RouteOptions#toUrl` only. The custom request parameters are not supported by `MapboxDirections` service. [#1420](https://github.com/mapbox/mapbox-java/pull/1420)
89

910
### v6.4.1 - April 22, 2022
1011
- Added correct escaping for `<white space>&<white space>` pattern in query parameters for `RouteOptions#toUrl`. [#1410](https://github.com/mapbox/mapbox-java/pull/1410).

services-directions-models/src/main/java/com/mapbox/api/directions/v5/models/DirectionsJsonObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,6 @@ public final Set<String> getUnrecognizedPropertiesNames() {
7777

7878
abstract static class Builder<T extends Builder> {
7979
@NonNull
80-
abstract T unrecognized(Map<String, SerializableJsonElement> value);
80+
abstract T unrecognized(@Nullable Map<String, SerializableJsonElement> value);
8181
}
8282
}

services-directions-models/src/main/java/com/mapbox/api/directions/v5/models/RouteOptions.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,26 @@
66
import com.google.auto.value.AutoValue;
77
import com.google.gson.Gson;
88
import com.google.gson.GsonBuilder;
9+
import com.google.gson.JsonElement;
910
import com.google.gson.JsonObject;
11+
import com.google.gson.JsonPrimitive;
1012
import com.google.gson.TypeAdapter;
1113
import com.google.gson.annotations.SerializedName;
1214
import com.mapbox.api.directions.v5.DirectionsAdapterFactory;
1315
import com.mapbox.api.directions.v5.DirectionsCriteria;
1416
import com.mapbox.api.directions.v5.utils.FormatUtils;
1517
import com.mapbox.api.directions.v5.utils.ParseUtils;
18+
import com.mapbox.auto.value.gson.SerializableJsonElement;
1619
import com.mapbox.geojson.Point;
1720
import java.io.UnsupportedEncodingException;
1821
import java.net.MalformedURLException;
1922
import java.net.URI;
2023
import java.net.URISyntaxException;
2124
import java.net.URL;
2225
import java.net.URLDecoder;
26+
import java.util.LinkedHashMap;
2327
import java.util.List;
28+
import java.util.Map;
2429

2530
/**
2631
* Defines route request parameters.
@@ -1034,6 +1039,22 @@ public URL toUrl(@NonNull String accessToken) {
10341039
if (metadata() != null) {
10351040
sb.append(String.format("&metadata=%s", metadata()));
10361041
}
1042+
if (unrecognized() != null) {
1043+
for (Map.Entry<String, SerializableJsonElement> entry : unrecognized().entrySet()) {
1044+
JsonElement element = entry.getValue().getElement();
1045+
if (element.isJsonPrimitive()) {
1046+
sb.append(String.format("&%s=%s", entry.getKey(), element.getAsString()));
1047+
} else {
1048+
throw new IllegalStateException(
1049+
String.format(
1050+
"RouteOptions.toUrl supports only primitive unrecognized properties."
1051+
+ " '%s' isn't a primitive value.",
1052+
entry.getKey()
1053+
)
1054+
);
1055+
}
1056+
}
1057+
}
10371058

10381059
// experimental
10391060
if (experimental() != null) {
@@ -2019,6 +2040,28 @@ public Builder snappingIncludeClosuresList(@Nullable List<Boolean> snappingClosu
20192040
@NonNull
20202041
public abstract Builder experimental(@Nullable Experimental experimental);
20212042

2043+
/**
2044+
* Use this method to add request parameters,
2045+
* which are not present in the model yet but are supported on the Directions API,
2046+
* to a URL generated by `RouteOptions#toUrl`.
2047+
* Use it for experimental parameters.
2048+
* @param unrecognizedProperties parameters to add to request
2049+
*/
2050+
@NonNull
2051+
public Builder unrecognizedProperties(@Nullable Map<String, String> unrecognizedProperties) {
2052+
if (unrecognizedProperties != null) {
2053+
LinkedHashMap<String, SerializableJsonElement> mapped = new LinkedHashMap<>();
2054+
for (Map.Entry<String, String> entry : unrecognizedProperties.entrySet()) {
2055+
mapped.put(
2056+
entry.getKey(),
2057+
new SerializableJsonElement(new JsonPrimitive(entry.getValue()))
2058+
);
2059+
}
2060+
return unrecognized(mapped);
2061+
}
2062+
return unrecognized(null);
2063+
}
2064+
20222065
/**
20232066
* Builds the object.
20242067
*

services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/RouteOptionsTest.java

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
package com.mapbox.api.directions.v5.models;
22

3-
import static com.google.gson.JsonParser.parseString;
4-
import static org.junit.Assert.assertEquals;
5-
import static org.junit.Assert.assertNotNull;
6-
import static org.junit.Assert.assertNull;
7-
import static org.junit.Assert.assertTrue;
8-
9-
import java.net.MalformedURLException;
10-
import java.net.URL;
11-
3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
5+
import com.google.gson.JsonObject;
126
import com.google.gson.JsonParser;
137
import com.mapbox.api.directions.v5.DirectionsCriteria;
8+
import com.mapbox.api.directions.v5.utils.MutateJsonUtil;
149
import com.mapbox.core.TestUtils;
1510
import com.mapbox.geojson.Point;
11+
import org.junit.Test;
1612

1713
import java.io.IOException;
14+
import java.net.MalformedURLException;
1815
import java.net.URL;
1916
import java.util.ArrayList;
2017
import java.util.Arrays;
2118
import java.util.Collections;
19+
import java.util.HashMap;
20+
import java.util.LinkedHashMap;
2221
import java.util.List;
22+
import java.util.Set;
2323

24-
import org.junit.Test;
24+
import static com.google.gson.JsonParser.parseString;
25+
import static com.mapbox.api.directions.v5.utils.Asserts.assertContains;
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertNotNull;
28+
import static org.junit.Assert.assertNull;
29+
import static org.junit.Assert.assertTrue;
2530

2631
public class RouteOptionsTest extends TestUtils {
2732
/**
@@ -622,6 +627,80 @@ public void cleanExcludes() {
622627
assertNull(routeOptions.exclude());
623628
}
624629

630+
@Test
631+
public void putCustomRouteOptionsParamsToUrl() {
632+
RouteOptions routeOptions = routeOptions().toBuilder()
633+
.unrecognizedProperties(new HashMap<String, String>(){{
634+
put("testName", "testValue");
635+
put("testName2", "true");
636+
}})
637+
.build();
638+
639+
URL url = routeOptions.toUrl("test");
640+
String query = url.getQuery();
641+
642+
assertContains(query, "testName=testValue");
643+
assertContains(query, "testName2=true");
644+
}
645+
646+
@Test
647+
public void nullCustomRouteOptions() {
648+
RouteOptions routeOptions = routeOptions().toBuilder()
649+
.unrecognizedProperties(null)
650+
.build();
651+
assertEquals(0, routeOptions.getUnrecognizedPropertiesNames().size());
652+
}
653+
654+
@Test
655+
public void readCustomRouteOptionsParamsFromUrl() throws MalformedURLException {
656+
String url = ROUTE_OPTIONS_URL + "&testString=test&testNumber=4.9&testBoolean=true";
657+
658+
RouteOptions routeOptions = RouteOptions.fromUrl(new URL(url));
659+
660+
Set<String> unrecognizedProperties = routeOptions.getUnrecognizedPropertiesNames();
661+
assertContains(unrecognizedProperties, "testString");
662+
assertEquals("test", routeOptions.getUnrecognizedProperty("testString").getAsString());
663+
assertContains(unrecognizedProperties, "testNumber");
664+
assertEquals(4.9, routeOptions.getUnrecognizedProperty("testNumber").getAsDouble(), 0);
665+
assertContains(unrecognizedProperties, "testBoolean");
666+
assertTrue(routeOptions.getUnrecognizedProperty("testBoolean").getAsBoolean());
667+
}
668+
669+
@Test
670+
public void unrecognizedOptionsFromJsonToUrl() {
671+
RouteOptions sourceRouteOptions = routeOptions().toBuilder()
672+
.unrecognizedProperties(new LinkedHashMap<String, String>(){{
673+
put("test1", "1");
674+
put("test2", "2");
675+
}})
676+
.build();
677+
678+
RouteOptions routeOptions = RouteOptions.fromUrl(sourceRouteOptions.toUrl("testToken"));
679+
680+
assertEquals(sourceRouteOptions, routeOptions);
681+
}
682+
683+
@Test
684+
public void allUnrecognizedPropertiesStaysAfterTransformingModelToJsonAndBack() throws IOException {
685+
Gson gson = new GsonBuilder().create();
686+
JsonObject mutatedRouteOptionsJson = gson.fromJson(loadJsonFixture(ROUTE_OPTIONS_JSON), JsonObject.class);
687+
MutateJsonUtil.mutateJson(mutatedRouteOptionsJson);
688+
689+
RouteOptions routeOptions = RouteOptions.fromJson(mutatedRouteOptionsJson.toString());
690+
JsonObject deserializedRouteOptions = gson.fromJson(routeOptions.toJson(), JsonObject.class);
691+
692+
assertEquals(mutatedRouteOptionsJson, deserializedRouteOptions);
693+
}
694+
695+
@Test(expected = IllegalStateException.class)
696+
public void routeOptionsWithUnrecognizedObjectsAndArrays() throws IOException {
697+
Gson gson = new GsonBuilder().create();
698+
JsonObject mutatedRouteOptionsJson = gson.fromJson(loadJsonFixture(ROUTE_OPTIONS_JSON), JsonObject.class);
699+
MutateJsonUtil.mutateJson(mutatedRouteOptionsJson);
700+
701+
RouteOptions.fromJson(mutatedRouteOptionsJson.toString()).toUrl("testToken");
702+
}
703+
625704
@Test
626705
public void emptyExcludeObjectsCleansUpExcludes() {
627706
RouteOptions routeOptions = routeOptions().toBuilder()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.mapbox.api.directions.v5.utils;
2+
3+
import java.util.Set;
4+
5+
import static org.junit.Assert.assertFalse;
6+
import static org.junit.Assert.assertTrue;
7+
8+
public final class Asserts {
9+
public static void assertContains(String string, String substring) {
10+
assertTrue(
11+
"String doesn't contain \"" + substring + "/" + ", string: " + string,
12+
string.contains(substring)
13+
);
14+
}
15+
16+
public static void assertDoesNotContain(String string, String substring) {
17+
assertFalse(
18+
"String contains \"" + substring + "/" + ", string: " + string,
19+
string.contains(substring)
20+
);
21+
}
22+
23+
public static <T> void assertContains(Set<T> set, T object) {
24+
assertTrue(
25+
"Set doesn't contain an object " + object.toString() + ", set: " + set.toString(),
26+
set.contains(object)
27+
);
28+
}
29+
}

services-directions/src/main/java/com/mapbox/api/directions/v5/MapboxDirections.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ public abstract static class Builder {
320320
* The options defined here reflect
321321
* <a href="https://www.mapbox.com/api-documentation/navigation/#directions">Directions API
322322
* documentation</a>.
323+
* Warning: `MapboxDirections` doesn't support unrecognized properties from `RouteOptions`.
323324
*
324325
* @param routeOptions route request options
325326
* @return this builder for chaining options together

0 commit comments

Comments
 (0)