From ce0096d94f4b5d2bec892eee7bfd2daa5dc5dfc8 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 13 May 2020 15:41:50 -0700 Subject: [PATCH] Document the requests package. --- .../requests/AuthenticatedRequest.kt | 14 ++++++++++++++ .../requests/CollarDetailRequest.kt | 10 ++++++++++ .../requests/CollarHistoryRequest.kt | 11 +++++++++++ .../requests/CollarRequest.kt | 9 +++++++++ .../requests/DistanceTraveledRequest.kt | 10 ++++++++++ .../fencelessgrazing/requests/GsonListener.kt | 19 +++++++++++++++++++ .../fencelessgrazing/requests/LoginRequest.kt | 10 ++++++++++ 7 files changed, 83 insertions(+) diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/AuthenticatedRequest.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/AuthenticatedRequest.kt index 902a8e9..02b1b09 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/AuthenticatedRequest.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/AuthenticatedRequest.kt @@ -3,6 +3,20 @@ package com.danilafe.fencelessgrazing.requests import com.android.volley.Response import com.android.volley.toolbox.StringRequest +/** + * General request aimed at a protected endpoint of the API. The [token] can be retrieved + * via a [LoginRequest], or, if you've made it past the login screen, via Shared Preferences. + * + * The [AuthenticatedRequest] expects to receive a string from the API endpoint; how this string + * is handled is determined by the [Response.Listener] object. One may use + * [Response.Listener.toGsonListener] to create a JSON deserializer that expects a [String]. + * + * @param baseUrl the API URL base (for example, `https://dev.danilafe.com`) + * @param apiEndpoint the API endpoint to which the request is being made. + * @param token the API token used for authentication. + * @param listener the listener object called if a valid response is received. + * @param error the error listener for the request. + */ open class AuthenticatedRequest( baseUrl: String, apiEndpoint: String, diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarDetailRequest.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarDetailRequest.kt index d26a7e0..c22a72c 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarDetailRequest.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarDetailRequest.kt @@ -7,6 +7,16 @@ import com.danilafe.fencelessgrazing.model.CollarPos import com.danilafe.fencelessgrazing.model.CollarSummary import com.google.gson.reflect.TypeToken +/** + * Request to the `/collars//details` API endpoint. Retrieves detailed information + * about a single collar, stored in a [CollarDetails] object. + * + * @param baseUrl the base URL of the API. + * @param collarId the identifier of the collar whose details are being retrieved. + * @param token the API token for authentication. + * @param listener the listener that will be called if a valid list of collar details is received. + * @param error the error listener for the request. + */ class CollarDetailRequest( baseUrl: String, collarId: Int, diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarHistoryRequest.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarHistoryRequest.kt index e414854..e9c1bc1 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarHistoryRequest.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarHistoryRequest.kt @@ -6,6 +6,17 @@ import com.danilafe.fencelessgrazing.model.CollarPos import com.danilafe.fencelessgrazing.model.CollarSummary import com.google.gson.reflect.TypeToken +/** + * A request to the `/collars//history` API endpoint. Retrieves the entire list + * of coordinates, represented as [CollarPos] objects, that the collar has transmitted. + * The coordinates are sorted by date. + * + * @param baseUrl the base URL of the API. + * @param collarId the identifier of the collar whose history is being retrieved. + * @param token the API token for authentication. + * @param listener the listener that will be called if a valid list of coordinates is received. + * @param error the error listener for the request. + */ class CollarHistoryRequest( baseUrl: String, collarId: Int, diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarRequest.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarRequest.kt index 83867ef..c7dab0f 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarRequest.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/CollarRequest.kt @@ -5,6 +5,15 @@ import com.android.volley.toolbox.StringRequest import com.danilafe.fencelessgrazing.model.CollarSummary import com.google.gson.reflect.TypeToken +/** + * A request to the `/collars` API endpoint. Retrieves a list of collar summaries, represented + * as [CollarSummary] objects. + * + * @param baseUrl the base URL of the API. + * @param token the API token for authentication. + * @param listener the listener that will be called if a valid list of coordinates is received. + * @param error the error listener for the request. + */ class CollarRequest( baseUrl: String, token : String, diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/DistanceTraveledRequest.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/DistanceTraveledRequest.kt index 2901e61..5bf7319 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/DistanceTraveledRequest.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/DistanceTraveledRequest.kt @@ -5,6 +5,16 @@ import com.android.volley.Response import com.android.volley.toolbox.StringRequest import com.google.gson.reflect.TypeToken +/** + * A request to the `/collars/stats/distance` API endpoint. Retrieves + * a list of [CollarDistance] objects, containing, among other things, the total + * distance traveled by each animal. + * + * @param baseUrl the base URL of the API. + * @param token the API token for authentication. + * @param listener the listener that will be called if a valid list of distances is received. + * @param error the error listener for the request. + */ class DistanceTraveledRequest( baseUrl: String, token : String, diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/GsonListener.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/GsonListener.kt index 729ad1f..7be8afb 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/GsonListener.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/GsonListener.kt @@ -6,6 +6,17 @@ import com.google.gson.Gson import com.google.gson.reflect.TypeToken import java.lang.reflect.Type +/** + * It appears as though a type parameter, even on that's `reified`, is erased when an anonymous + * object is declared inside an `inline` function. This means that [Gson] serialization with + * a [TypeToken] created inside this anonymous object wil _still_ fail, even though the + * surrounding function is `inline` and with a `reified` type. To work around this, + * we create the type in the function itself, and pass it as an argument to this + * [GsonListener]. + * + * @param listener the underlying listener expecting a value of type [T]. + * @param type the type to which [Gson] should deserialize the expected string. + */ class GsonListener(val listener: Response.Listener, private val type: Type) : Response.Listener { override fun onResponse(response: String?) { val transformed = response?.let { Gson().fromJson(it, type) } @@ -13,6 +24,14 @@ class GsonListener(val listener: Response.Listener, private val type: Type } } +/** + * Converts a [Response.Listener] of an arbitrary type [T] to a listener of type [String]. + * This is done by converting the input [String] into [T] via [Gson]. + * This function must be reified to prevent type erasure. + * + * @receiver the listener that will be called when the [String] is converted into [T]. + * @return the resulting [String]-based listener. + */ inline fun Response.Listener.toGsonListener(): Response.Listener { return GsonListener(this, object : TypeToken(){}.type) } diff --git a/app/src/main/java/com/danilafe/fencelessgrazing/requests/LoginRequest.kt b/app/src/main/java/com/danilafe/fencelessgrazing/requests/LoginRequest.kt index 7d8ce92..061d19e 100644 --- a/app/src/main/java/com/danilafe/fencelessgrazing/requests/LoginRequest.kt +++ b/app/src/main/java/com/danilafe/fencelessgrazing/requests/LoginRequest.kt @@ -4,6 +4,16 @@ import com.android.volley.Response import com.android.volley.toolbox.StringRequest import com.danilafe.fencelessgrazing.model.LoginResult +/** + * A request to the `/login` endpoint of the API, intended to retrieve the JWT authentication + * token to be used for the remainder of the interaction with the API. + * + * @param baseUrl the base URL of the API. + * @param username the username with which to attempt to authenticate. + * @param password the password with which to attempt to authenticate. + * @param listener the listener that will be called if authentication succeeds. + * @param error the error listener for the request. + */ class LoginRequest( baseUrl: String, private val username: String,