From 6d4a8b47429ce571a2d65970cf796775b08058b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sikora?= Date: Fri, 23 Oct 2020 21:21:46 +0200 Subject: [PATCH] Accept builder in constructor of ChuckerInterceptor This type of builder will ensure that library is binary compatible even if we add more default fields. --- CHANGELOG.md | 4 +- .../chucker/api/ChuckerInterceptor.kt | 15 +-- .../chucker/api/ChuckerInterceptor.kt | 101 +++++------------- .../chucker/ChuckerInterceptorDelegate.kt | 15 ++- .../chucker/sample/HttpBinClient.kt | 11 +- 5 files changed, 51 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d01955b65..2f18f6f5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,9 +19,9 @@ Please add your entries according to this format. * Fixed memory leak in MainActivity [#465]. * Fixed build failure for projects with new `kotlin-parcelize` plugin [#480]. -### Deprecated +### Removed -* `ChuckerInterceptor` constructor is now deprecated. Unless `Context` is the only parameter that you pass into the constructor you should migrate to builder. +* Removed parametrized `ChuckerInterceptor` constructor in favour of builder pattern. Constructor that accepts only `Context` is still available. ## Version 3.3.0 *(2020-09-30)* diff --git a/library-no-op/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt b/library-no-op/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt index 95365372d..12c0ee319 100644 --- a/library-no-op/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt +++ b/library-no-op/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt @@ -9,14 +9,15 @@ import kotlin.jvm.Throws /** * No-op implementation. */ -public class ChuckerInterceptor @JvmOverloads constructor( - context: Context, - collector: Any? = null, - maxContentLength: Any? = null, - headersToRedact: Any? = null, - alwaysReadResponseBody: Any? = null, +public class ChuckerInterceptor private constructor( + builder: Builder, ) : Interceptor { + /** + * No-op implementation. + */ + public constructor(context: Context) : this(Builder(context)) + public fun redactHeaders(vararg names: String): ChuckerInterceptor { return this } @@ -41,6 +42,6 @@ public class ChuckerInterceptor @JvmOverloads constructor( public fun alwaysReadResponseBody(enable: Boolean): Builder = this - public fun build(): ChuckerInterceptor = ChuckerInterceptor(context) + public fun build(): ChuckerInterceptor = ChuckerInterceptor(this) } } diff --git a/library/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt b/library/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt index b10fc1a22..4b63bef85 100755 --- a/library/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt +++ b/library/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt @@ -28,73 +28,29 @@ import kotlin.jvm.Throws /** * An OkHttp Interceptor which persists and displays HTTP activity * in your application for later inspection. - * - * @param context An Android [Context] - * @param collector A [ChuckerCollector] to customize data retention - * @param maxContentLength The maximum length for request and response content - * before their truncation. Warning: setting this value too high may cause unexpected - * results. - * @param cacheDirectoryProvider Provider of [File] where Chucker will save temporary responses - * before processing them. - * @param alwaysReadResponseBody If set to `true` Chucker will read full content of response - * bodies even in case of parsing errors or closing the response body without reading it. - * @param headersToRedact a [Set] of headers you want to redact. They will be replaced - * with a `**` in the Chucker UI. */ -public class ChuckerInterceptor internal constructor( - private val context: Context, - private val collector: ChuckerCollector = ChuckerCollector(context), - private val maxContentLength: Long = 250000L, - private val cacheDirectoryProvider: CacheDirectoryProvider, - private val alwaysReadResponseBody: Boolean = false, - headersToRedact: Set = emptySet(), +public class ChuckerInterceptor private constructor( + builder: Builder, ) : Interceptor { /** * An OkHttp Interceptor which persists and displays HTTP activity * in your application for later inspection. * + * This constructor is a shorthand for `ChuckerInterceptor.Builder(context).build()`. + * * @param context An Android [Context] - * @param collector A [ChuckerCollector] to customize data retention - * @param maxContentLength The maximum length for request and response content - * before their truncation. Warning: setting this value too high may cause unexpected - * results. - * @param alwaysReadResponseBody If set to `true` Chucker will read full content of response - * bodies even in case of parsing errors or closing the response body without reading it. - * @param headersToRedact a [Set] of headers you want to redact. They will be replaced - * with a `**` in the Chucker UI. + * @see ChuckerInterceptor.Builder */ - @JvmOverloads - @Deprecated( - message = "" + - "Customisation of ChuckerInterceptor should be replaced with a builder pattern " + - "unless you pass only Context.", - replaceWith = ReplaceWith( - "ChuckerInterceptor.Builder(context)\n" + - ".collector(collector)\n" + - ".maxContentLength(maxContentLength)\n" + - ".redactHeaders(headersToRedact)\n" + - ".alwaysReadResponseBody(alwaysReadResponseBody)\n" + - ".build()" - ) - ) - public constructor( - context: Context, - collector: ChuckerCollector = ChuckerCollector(context), - maxContentLength: Long = 250000L, - headersToRedact: Set = emptySet(), - alwaysReadResponseBody: Boolean = false, - ) : this( - context = context, - collector = collector, - maxContentLength = maxContentLength, - cacheDirectoryProvider = { context.cacheDir }, - alwaysReadResponseBody = alwaysReadResponseBody, - headersToRedact = headersToRedact, - ) - - private val io: IOUtils = IOUtils(context) - private val headersToRedact: MutableSet = headersToRedact.toMutableSet() + public constructor(context: Context) : this(Builder(context)) + + private val context = builder.context + private val collector = builder.collector ?: ChuckerCollector(context) + private val maxContentLength = builder.maxContentLength + private val cacheDirectoryProvider = builder.cacheDirectoryProvider ?: CacheDirectoryProvider { context.filesDir } + private val alwaysReadResponseBody = builder.alwaysReadResponseBody + private val io = IOUtils(builder.context) + private val headersToRedact = builder.headersToRedact.toMutableSet() /** Adds [headerName] into [headersToRedact] */ public fun redactHeader(vararg headerName: String) { @@ -308,12 +264,12 @@ public class ChuckerInterceptor internal constructor( * * @param context An Android [Context]. */ - public class Builder(private var context: Context) { - private var collector: ChuckerCollector? = null - private var maxContentLength = MAX_CONTENT_LENGTH - private var cacheDirectoryProvider: CacheDirectoryProvider? = null - private var alwaysReadResponseBody = false - private var headersToRedact = emptySet() + public class Builder(internal var context: Context) { + internal var collector: ChuckerCollector? = null + internal var maxContentLength = MAX_CONTENT_LENGTH + internal var cacheDirectoryProvider: CacheDirectoryProvider? = null + internal var alwaysReadResponseBody = false + internal var headersToRedact = emptySet() /** * Sets the [ChuckerCollector] to customize data retention. @@ -358,17 +314,18 @@ public class ChuckerInterceptor internal constructor( this.alwaysReadResponseBody = enable } + /** + * Sets provider of a directory where Chucker will save temporary responses + * before processing them. + */ + internal fun cacheDirectorProvider(provider: CacheDirectoryProvider): Builder = apply { + this.cacheDirectoryProvider = provider + } + /** * Creates a new [ChuckerInterceptor] instance with values defined in this builder. */ - public fun build(): ChuckerInterceptor = ChuckerInterceptor( - context = context, - collector = collector ?: ChuckerCollector(context), - maxContentLength = maxContentLength, - cacheDirectoryProvider = cacheDirectoryProvider ?: CacheDirectoryProvider { context.filesDir }, - alwaysReadResponseBody = alwaysReadResponseBody, - headersToRedact = headersToRedact, - ) + public fun build(): ChuckerInterceptor = ChuckerInterceptor(this) } private companion object { diff --git a/library/src/test/java/com/chuckerteam/chucker/ChuckerInterceptorDelegate.kt b/library/src/test/java/com/chuckerteam/chucker/ChuckerInterceptorDelegate.kt index 090ad80b2..726f55327 100644 --- a/library/src/test/java/com/chuckerteam/chucker/ChuckerInterceptorDelegate.kt +++ b/library/src/test/java/com/chuckerteam/chucker/ChuckerInterceptorDelegate.kt @@ -33,14 +33,13 @@ internal class ChuckerInterceptorDelegate( } } - private val chucker = ChuckerInterceptor( - context = mockContext, - collector = mockCollector, - maxContentLength = maxContentLength, - headersToRedact = headersToRedact, - cacheDirectoryProvider = cacheDirectoryProvider, - alwaysReadResponseBody = alwaysReadResponseBody, - ) + private val chucker = ChuckerInterceptor.Builder(context = mockContext) + .collector(mockCollector) + .maxContentLength(maxContentLength) + .redactHeaders(headersToRedact) + .alwaysReadResponseBody(alwaysReadResponseBody) + .cacheDirectorProvider(cacheDirectoryProvider) + .build() internal fun expectTransaction(): HttpTransaction { if (transactions.isEmpty()) { diff --git a/sample/src/main/java/com/chuckerteam/chucker/sample/HttpBinClient.kt b/sample/src/main/java/com/chuckerteam/chucker/sample/HttpBinClient.kt index 58d9da5ad..4e76d40fd 100644 --- a/sample/src/main/java/com/chuckerteam/chucker/sample/HttpBinClient.kt +++ b/sample/src/main/java/com/chuckerteam/chucker/sample/HttpBinClient.kt @@ -31,12 +31,11 @@ class HttpBinClient( retentionPeriod = RetentionManager.Period.ONE_HOUR ) - private val chuckerInterceptor = ChuckerInterceptor( - context = context, - collector = collector, - maxContentLength = 250000L, - headersToRedact = emptySet() - ) + private val chuckerInterceptor = ChuckerInterceptor.Builder(context) + .collector(collector) + .maxContentLength(250000L) + .redactHeaders(emptySet()) + .build() private val httpClient = OkHttpClient.Builder()