Skip to content

Commit

Permalink
fixed route index, UUID, and RouteOptions assignment across types
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasPaczos committed Feb 4, 2022
1 parent 90125a3 commit 33f7013
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,22 @@ public static TypeAdapter<DirectionsResponse> typeAdapter(Gson gson) {

/**
* Create a new instance of this class by passing in a formatted valid JSON String.
* <p>
* Consider using {@link #fromJson(String, RouteOptions)} if the result is used with
* downstream consumers of the directions models (like Mapbox Navigation SDK)
* to provide rerouting and route refreshing features.
*
* @param json a formatted valid JSON string defining a GeoJson Directions Response
* @return a new instance of this class defined by the values passed inside this static factory
* method
* @see #fromJson(String, RouteOptions)
* @since 3.0.0
*/
public static DirectionsResponse fromJson(@NonNull String json) {
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapterFactory(DirectionsAdapterFactory.create());
gson.registerTypeAdapter(Point.class, new PointAsCoordinatesTypeAdapter());
// rebuilding to ensure that underlying routes have assigned indices
// rebuilding to ensure that underlying routes have assigned indices and UUID
return gson.create().fromJson(json, DirectionsResponse.class).toBuilder().build();
}

Expand All @@ -156,24 +161,71 @@ public static DirectionsResponse fromJson(@NonNull String json) {
* method
* @see RouteOptions#fromUrl(java.net.URL)
* @see RouteOptions#fromJson(String)
* @deprecated use {@link #fromJson(String, RouteOptions)} instead
*/
@Deprecated
public static DirectionsResponse fromJson(
@NonNull String json, @Nullable RouteOptions routeOptions, @Nullable String requestUuid) {
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapterFactory(DirectionsAdapterFactory.create());
gson.registerTypeAdapter(Point.class, new PointAsCoordinatesTypeAdapter());
DirectionsResponse response = gson.create().fromJson(json, DirectionsResponse.class);
List<DirectionsRoute> routes = response.routes();
if (routeOptions != null) {
response = response.updateWithRequestData(routeOptions);
}
return response.toBuilder()
// set the provided UUID for backwards compatibility
// even though it's most likely incorrect
.uuid(requestUuid)
// rebuilding to ensure that underlying routes have assigned indices and UUID
.build();
}

/**
* Create a new instance of this class by passing in a formatted valid JSON String.
* <p>
* The parameter of {@link RouteOptions} that were used to make the original route request
* which might be required by downstream consumers of the directions models
* (like Mapbox Navigation SDK) to provide rerouting and route refreshing features.
*
* @param json a formatted valid JSON string defining a GeoJson Directions Route
* @param routeOptions options that were used during the original route request
* @return a new instance of this class defined by the values passed inside this static factory
* method
* @see RouteOptions#fromUrl(java.net.URL)
* @see RouteOptions#fromJson(String)
*/
public static DirectionsResponse fromJson(
@NonNull String json, @NonNull RouteOptions routeOptions) {
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapterFactory(DirectionsAdapterFactory.create());
gson.registerTypeAdapter(Point.class, new PointAsCoordinatesTypeAdapter());
DirectionsResponse response = gson.create().fromJson(json, DirectionsResponse.class);
// rebuilding to ensure that underlying routes have assigned indices and UUID
return response.updateWithRequestData(routeOptions);
}

/**
* Exposes an option to enhance an existing response with the request data which might be required
* by downstream consumers of the directions models (like Mapbox Navigation SDK) to provide
* rerouting and route refreshing features.
*
* @param routeOptions options used to generate this response
* @see RouteOptions#fromUrl(java.net.URL)
* @see RouteOptions#fromJson(String)
* @see #fromJson(String)
*/
@NonNull
public DirectionsResponse updateWithRequestData(@NonNull RouteOptions routeOptions) {
List<DirectionsRoute> modifiedRoutes = new ArrayList<>();
for (DirectionsRoute route : routes) {
for (DirectionsRoute route : routes()) {
modifiedRoutes.add(
route.toBuilder()
.routeOptions(routeOptions)
.requestUuid(requestUuid)
.build()
);
}
return response.toBuilder()
return this.toBuilder()
.routes(modifiedRoutes)
.build();
}
Expand Down Expand Up @@ -231,6 +283,7 @@ public abstract static class Builder {
*/
public abstract Builder routes(@NonNull List<DirectionsRoute> routes);

@NonNull
abstract List<DirectionsRoute> routes();

/**
Expand All @@ -243,6 +296,9 @@ public abstract static class Builder {
*/
public abstract Builder uuid(@Nullable String uuid);

@Nullable
abstract String uuid();

/**
* A complex data structure that provides information about the source of the response.
*
Expand All @@ -260,9 +316,18 @@ public abstract static class Builder {
* @since 3.0.0
*/
public DirectionsResponse build() {
List<DirectionsRoute> transformedRoutes = new ArrayList<>(routes().size());
for (int i = 0; i < routes().size(); i++) {
routes().set(i, routes().get(i).toBuilder().routeIndex(String.valueOf(i)).build());
transformedRoutes.add(
i,
routes().get(i)
.toBuilder()
.routeIndex(String.valueOf(i))
.requestUuid(uuid())
.build()
);
}
routes(transformedRoutes);

return autoBuild();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ public void fromJson_correctlyBuildsFromJsonWithOptionsAndUuid() throws Exceptio
assertEquals(uuid, response.routes().get(0).requestUuid());
}

@Test
public void fromJson_correctlyBuildsFromJsonWithOptions() throws Exception {
String json = loadJsonFixture(DIRECTIONS_V5_PRECISION6_FIXTURE);
RouteOptions options = RouteOptions.builder()
.profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
.coordinatesList(new ArrayList<Point>() {{
add(Point.fromLngLat(1.0, 1.0));
add(Point.fromLngLat(2.0, 2.0));
}})
.build();
DirectionsResponse response = DirectionsResponse.fromJson(json, options);

assertEquals(options, response.routes().get(0).routeOptions());
assertEquals("cjhk3ov9e1voc3vp58hcgit34", response.routes().get(0).requestUuid());
}

@Test
public void fromJson_correctlyBuildsFromJsonWithUuid() throws Exception {
String json = loadJsonFixture(DIRECTIONS_V5_PRECISION6_FIXTURE);
DirectionsResponse response = DirectionsResponse.fromJson(json);

assertEquals("cjhk3ov9e1voc3vp58hcgit34", response.routes().get(0).requestUuid());
}

@Test
public void fromJson_multipleRoutesHaveCorrectIndices() throws Exception {
String json = loadJsonFixture(DIRECTIONS_V5_MULTIPLE_ROUTES);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,30 @@
package com.mapbox.api.directions.v5;

import androidx.annotation.NonNull;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;

import java.util.ArrayList;
import java.util.List;

import com.mapbox.api.directions.v5.models.RouteOptions;
import retrofit2.Response;

class DirectionsResponseFactory {

private final MapboxDirections mapboxDirections;

DirectionsResponseFactory(MapboxDirections mapboxDirections) {
this.mapboxDirections = mapboxDirections;
}

Response<DirectionsResponse> generate(Response<DirectionsResponse> response) {
static Response<DirectionsResponse> generate(
@NonNull RouteOptions routeOptions,
Response<DirectionsResponse> response
) {
if (isNotSuccessful(response)) {
return response;
} else {
return Response.success(
response
.body()
.toBuilder()
.routes(updateRoutesWithRequestData(response))
.build(),
.updateWithRequestData(routeOptions),
response.raw()
);
}
}

private boolean isNotSuccessful(Response<DirectionsResponse> response) {
private static boolean isNotSuccessful(Response<DirectionsResponse> response) {
return !response.isSuccessful()
|| response.body() == null;
}

private List<DirectionsRoute> updateRoutesWithRequestData(Response<DirectionsResponse> response) {
List<DirectionsRoute> routes = response.body().routes();
List<DirectionsRoute> modifiedRoutes = new ArrayList<>();
for (DirectionsRoute route : routes) {
modifiedRoutes.add(
route.toBuilder()
.routeOptions(mapboxDirections.routeOptions())
.requestUuid(response.body().uuid())
.build()
);
}
return modifiedRoutes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.auto.value.AutoValue;
import com.google.gson.GsonBuilder;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.RouteOptions;
import com.mapbox.core.MapboxService;
import com.mapbox.core.utils.ApiCallHelper;

import java.io.IOException;

import okhttp3.EventListener;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
Expand Down Expand Up @@ -171,8 +168,7 @@ protected GsonBuilder getGsonBuilder() {
@Override
public Response<DirectionsResponse> executeCall() throws IOException {
Response<DirectionsResponse> response = super.executeCall();
DirectionsResponseFactory factory = new DirectionsResponseFactory(this);
return factory.generate(response);
return DirectionsResponseFactory.generate(routeOptions(), response);
}

/**
Expand All @@ -187,14 +183,20 @@ public Response<DirectionsResponse> executeCall() throws IOException {
public void enqueueCall(final Callback<DirectionsResponse> callback) {
getCall().enqueue(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
DirectionsResponseFactory factory = new DirectionsResponseFactory(MapboxDirections.this);
Response<DirectionsResponse> generatedResponse = factory.generate(response);
public void onResponse(
@NonNull Call<DirectionsResponse> call,
@NonNull Response<DirectionsResponse> response
) {
Response<DirectionsResponse> generatedResponse =
DirectionsResponseFactory.generate(routeOptions(), response);
callback.onResponse(call, generatedResponse);
}

@Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
public void onFailure(
@NonNull Call<DirectionsResponse> call,
@NonNull Throwable throwable
) {
callback.onFailure(call, throwable);
}
});
Expand Down Expand Up @@ -339,7 +341,7 @@ public abstract static class Builder {
* @param usePost true to use POST method or false and null for GET method
* @return this builder for chaining options together
*/
public abstract Builder usePostMethod(@Nullable Boolean usePost);
public abstract Builder usePostMethod(@Nullable Boolean usePost);

/**
* This uses the provided parameters set using the {@link Builder} and first checks that all
Expand Down
Loading

0 comments on commit 33f7013

Please sign in to comment.