Skip to content

Commit 8535b6e

Browse files
committed
Using with calls in companion
1 parent a4998cf commit 8535b6e

14 files changed

+118
-85
lines changed

src/main/kotlin/at/bitfire/dav4jvm/DavResource.kt

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ open class DavResource @JvmOverloads constructor(
215215
/* Multiple resources were to be affected by the MOVE, but errors on some
216216
of them prevented the operation from taking place.
217217
[_] (RFC 4918 9.9.4. Status Codes for MOVE Method) */
218-
throw HttpException(response)
218+
throw HttpException.fromHttpResponse(response)
219219

220220
// update location
221221
location.resolve(response.header("Location") ?: destination.toString())?.let {
@@ -258,7 +258,7 @@ open class DavResource @JvmOverloads constructor(
258258
/* Multiple resources were to be affected by the COPY, but errors on some
259259
of them prevented the operation from taking place.
260260
[_] (RFC 4918 9.8.5. Status Codes for COPY Method) */
261-
throw HttpException(response)
261+
throw HttpException.fromHttpResponse(response)
262262

263263
callback.onResponse(response)
264264
}
@@ -549,7 +549,7 @@ open class DavResource @JvmOverloads constructor(
549549
/* If an error occurs deleting a member resource (a resource other than
550550
the resource identified in the Request-URI), then the response can be
551551
a 207 (Multi-Status). […] (RFC 4918 9.6.1. DELETE for Collections) */
552-
throw HttpException(response)
552+
throw HttpException.fromHttpResponse(response)
553553

554554
callback.onResponse(response)
555555
}
@@ -680,20 +680,15 @@ open class DavResource @JvmOverloads constructor(
680680
return
681681

682682
throw when (code) {
683-
HttpURLConnection.HTTP_UNAUTHORIZED ->
684-
if (response != null) UnauthorizedException(response) else UnauthorizedException(message)
685-
HttpURLConnection.HTTP_FORBIDDEN ->
686-
if (response != null) ForbiddenException(response) else ForbiddenException(message)
687-
HttpURLConnection.HTTP_NOT_FOUND ->
688-
if (response != null) NotFoundException(response) else NotFoundException(message)
689-
HttpURLConnection.HTTP_CONFLICT ->
690-
if (response != null) ConflictException(response) else ConflictException(message)
691-
HttpURLConnection.HTTP_PRECON_FAILED ->
692-
if (response != null) PreconditionFailedException(response) else PreconditionFailedException(message)
693-
HttpURLConnection.HTTP_UNAVAILABLE ->
694-
if (response != null) ServiceUnavailableException(response) else ServiceUnavailableException(message)
695-
else ->
696-
if (response != null) HttpException(response) else HttpException(code, message)
683+
HttpURLConnection.HTTP_UNAUTHORIZED -> UnauthorizedException
684+
HttpURLConnection.HTTP_FORBIDDEN -> ForbiddenException
685+
HttpURLConnection.HTTP_NOT_FOUND -> NotFoundException
686+
HttpURLConnection.HTTP_CONFLICT -> ConflictException
687+
HttpURLConnection.HTTP_PRECON_FAILED -> PreconditionFailedException
688+
HttpURLConnection.HTTP_UNAVAILABLE -> ServiceUnavailableException
689+
else -> HttpException
690+
}.let { exceptionClass ->
691+
if (response != null) exceptionClass.fromHttpResponse(response) else exceptionClass.fromMessage(message)
697692
}
698693
}
699694

@@ -739,7 +734,7 @@ open class DavResource @JvmOverloads constructor(
739734
*/
740735
fun assertMultiStatus(response: Response) {
741736
if (response.code != HTTP_MULTISTATUS)
742-
throw DavException("Expected 207 Multi-Status, got ${response.code} ${response.message}").populateHttpResponse(response)
737+
throw DavException.fromHttpResponse("Expected 207 Multi-Status, got ${response.code} ${response.message}", httpResponse = response)
743738

744739
response.peekBody(XML_SIGNATURE.size.toLong()).use { body ->
745740
body.contentType()?.let { mimeType ->
@@ -760,7 +755,7 @@ open class DavResource @JvmOverloads constructor(
760755
logger.log(Level.WARNING, "Couldn't scan for XML signature", e)
761756
}
762757

763-
throw DavException("Received non-XML 207 Multi-Status").populateHttpResponse(response)
758+
throw DavException.fromHttpResponse("Received non-XML 207 Multi-Status", httpResponse = response)
764759
}
765760
} ?: logger.warning("Received 207 Multi-Status without Content-Type, assuming XML")
766761
}

src/main/kotlin/at/bitfire/dav4jvm/exception/ConflictException.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import java.net.HttpURLConnection
1515

1616
class ConflictException: HttpException {
1717

18-
constructor(response: Response): super(response)
18+
companion object: DavExceptionCompanion<ConflictException> {
19+
override fun constructor(message: String?): ConflictException = ConflictException(message)
20+
}
21+
1922
constructor(message: String?): super(HttpURLConnection.HTTP_CONFLICT, message)
2023

2124
}

src/main/kotlin/at/bitfire/dav4jvm/exception/DavException.kt

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ open class DavException @JvmOverloads constructor(
4545
type.type == "text" ||
4646
(type.type == "application" && type.subtype in arrayOf("html", "xml"))
4747

48+
fun fromHttpResponse(message: String, ex: Throwable? = null, httpResponse: Response?): DavException {
49+
return DavException(message, ex).apply { populateHttpResponse(httpResponse) }
50+
}
51+
4852
}
4953

5054
private val logger
@@ -76,21 +80,12 @@ open class DavException @JvmOverloads constructor(
7680
var errors: List<Error> = listOf()
7781
private set
7882

79-
/**
80-
* Initializes the [DavException] and populates [request], [requestBody], [response], [responseBody] and [errors] with the contents of [httpResponse].
81-
*
82-
* The whole response body may be loaded, so this function should be called in blocking-sensitive contexts.
83-
*/
84-
constructor(message: String, httpResponse: Response?, ex: Throwable? = null): this(message, ex) {
85-
populateHttpResponse(httpResponse)
86-
}
87-
8883
/**
8984
* Fills [request], [requestBody], [response], [responseBody] and [errors] according to the given [httpResponse].
9085
*
9186
* The whole response body may be loaded, so this function should be called in blocking-sensitive contexts.
9287
*/
93-
private fun populateHttpResponse(httpResponse: Response?): DavException {
88+
fun populateHttpResponse(httpResponse: Response?) {
9489
if (httpResponse != null) {
9590
response = httpResponse.toString()
9691

@@ -153,8 +148,6 @@ open class DavException @JvmOverloads constructor(
153148
} else {
154149
response = null
155150
}
156-
157-
return this
158151
}
159152

160153
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* SPDX-License-Identifier: MPL-2.0
9+
*/
10+
11+
package at.bitfire.dav4jvm.exception
12+
13+
import okhttp3.Response
14+
15+
interface DavExceptionCompanion<CL: DavException> {
16+
fun constructor(message: String?): CL
17+
18+
fun fromHttpResponse(httpResponse: Response): CL {
19+
return constructor(httpResponse.message).apply { populateHttpResponse(httpResponse) }
20+
}
21+
22+
fun fromMessage(message: String?): CL = constructor(message)
23+
}

src/main/kotlin/at/bitfire/dav4jvm/exception/ForbiddenException.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import java.net.HttpURLConnection
1515

1616
class ForbiddenException: HttpException {
1717

18-
constructor(response: Response): super(response)
18+
companion object: DavExceptionCompanion<ForbiddenException> {
19+
override fun constructor(message: String?): ForbiddenException = ForbiddenException(message)
20+
}
21+
1922
constructor(message: String?): super(HttpURLConnection.HTTP_FORBIDDEN, message)
2023

2124
}

src/main/kotlin/at/bitfire/dav4jvm/exception/GoneException.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import java.net.HttpURLConnection
1515

1616
class GoneException: HttpException {
1717

18-
constructor(response: Response): super(response)
18+
companion object: DavExceptionCompanion<GoneException> {
19+
override fun constructor(message: String?): GoneException = GoneException(message)
20+
}
21+
1922
constructor(message: String?): super(HttpURLConnection.HTTP_GONE, message)
2023

2124
}

src/main/kotlin/at/bitfire/dav4jvm/exception/HttpException.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ import okhttp3.Response
1717
*/
1818
open class HttpException: DavException {
1919

20-
var code: Int
20+
companion object: DavExceptionCompanion<HttpException> {
21+
override fun constructor(message: String?): HttpException = HttpException(-1, message)
2122

22-
constructor(response: Response): super(
23-
"HTTP ${response.code} ${response.message}",
24-
httpResponse = response
25-
) {
26-
code = response.code
23+
override fun fromHttpResponse(httpResponse: Response): HttpException {
24+
return HttpException(httpResponse.code, httpResponse.message).apply { populateHttpResponse(httpResponse) }
25+
}
2726
}
2827

28+
var code: Int
29+
2930
constructor(code: Int, message: String?): super("HTTP $code $message") {
3031
this.code = code
3132
}

src/main/kotlin/at/bitfire/dav4jvm/exception/NotFoundException.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import java.net.HttpURLConnection
1515

1616
class NotFoundException: HttpException {
1717

18-
constructor(response: Response): super(response)
18+
companion object: DavExceptionCompanion<NotFoundException> {
19+
override fun constructor(message: String?): NotFoundException = NotFoundException(message)
20+
}
21+
1922
constructor(message: String?): super(HttpURLConnection.HTTP_NOT_FOUND, message)
2023

2124
}

src/main/kotlin/at/bitfire/dav4jvm/exception/PreconditionFailedException.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import java.net.HttpURLConnection
1515

1616
class PreconditionFailedException: HttpException {
1717

18-
constructor(response: Response): super(response)
18+
companion object: DavExceptionCompanion<PreconditionFailedException> {
19+
override fun constructor(message: String?): PreconditionFailedException = PreconditionFailedException(message)
20+
}
21+
1922
constructor(message: String?): super(HttpURLConnection.HTTP_PRECON_FAILED, message)
2023

2124
}

src/main/kotlin/at/bitfire/dav4jvm/exception/ServiceUnavailableException.kt

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,10 @@ import java.util.logging.Logger
2222

2323
class ServiceUnavailableException : HttpException {
2424

25-
private val logger
26-
get() = Logger.getLogger(javaClass.name)
27-
2825
val retryAfter: Instant?
2926

30-
constructor(message: String?) : super(HttpURLConnection.HTTP_UNAVAILABLE, message) {
31-
retryAfter = null
32-
}
33-
34-
constructor(response: Response) : super(response) {
35-
// Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
36-
// HTTP-date = rfc1123-date | rfc850-date | asctime-date
37-
38-
var retryAfterValue: Instant? = null
39-
response.header("Retry-After")?.let { after ->
40-
retryAfterValue = HttpUtils.parseDate(after) ?:
41-
// not a HTTP-date, must be delta-seconds
42-
try {
43-
val seconds = after.toLong()
44-
Instant.now().plusSeconds(seconds)
45-
} catch (e: NumberFormatException) {
46-
logger.log(Level.WARNING, "Received Retry-After which was not a HTTP-date nor delta-seconds: $after", e)
47-
null
48-
}
49-
}
50-
51-
retryAfter = retryAfterValue
27+
constructor(message: String?, retryAfter: Instant? = null) : super(HttpURLConnection.HTTP_UNAVAILABLE, message) {
28+
this.retryAfter = retryAfter
5229
}
5330

5431

@@ -75,13 +52,38 @@ class ServiceUnavailableException : HttpException {
7552
}
7653

7754

78-
companion object {
55+
companion object: DavExceptionCompanion<ServiceUnavailableException> {
7956

8057
// default values for getDelayUntil
8158
const val DELAY_UNTIL_DEFAULT = 15 * 60L // 15 min
8259
const val DELAY_UNTIL_MIN = 1 * 60L // 1 min
8360
const val DELAY_UNTIL_MAX = 2 * 60 * 60L // 2 hours
8461

62+
private val logger
63+
get() = Logger.getLogger(this::javaClass.name)
64+
65+
override fun constructor(message: String?): ServiceUnavailableException = ServiceUnavailableException(message)
66+
67+
override fun fromHttpResponse(httpResponse: Response): ServiceUnavailableException = ServiceUnavailableException(
68+
message = httpResponse.message,
69+
retryAfter = httpResponse.let { response ->
70+
// Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
71+
// HTTP-date = rfc1123-date | rfc850-date | asctime-date
72+
73+
response.header("Retry-After")?.let { after ->
74+
HttpUtils.parseDate(after) ?:
75+
// not a HTTP-date, must be delta-seconds
76+
try {
77+
val seconds = after.toLong()
78+
Instant.now().plusSeconds(seconds)
79+
} catch (e: NumberFormatException) {
80+
logger.log(Level.WARNING, "Received Retry-After which was not a HTTP-date nor delta-seconds: $after", e)
81+
null
82+
}
83+
}
84+
}
85+
)
86+
8587
}
8688

8789
}

0 commit comments

Comments
 (0)