Skip to content

Commit 3b96690

Browse files
committed
Add missing RestOperations extensions
Issue: SPR-16229
1 parent 01a82b5 commit 3b96690

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

spring-web/src/main/kotlin/org/springframework/web/client/RestOperationsExtensions.kt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ inline fun <reified T: Any> RestOperations.getForObject(url: String, uriVariable
5959
inline fun <reified T: Any> RestOperations.getForObject(url: URI): T? =
6060
getForObject(url, T::class.java)
6161

62+
/**
63+
* Extension for [RestOperations.getForEntity] avoiding requiring the type parameter
64+
* thanks to Kotlin reified type parameters.
65+
*
66+
* @author Sebastien Deleuze
67+
* @since 5.0.2
68+
*/
69+
@Throws(RestClientException::class)
70+
inline fun <reified T: Any> RestOperations.getForEntity(url: URI): ResponseEntity<T> =
71+
getForEntity(url, T::class.java)
72+
6273
/**
6374
* Extension for [RestOperations.getForEntity] avoiding requiring the type parameter
6475
* thanks to Kotlin reified type parameters.
@@ -71,6 +82,50 @@ inline fun <reified T: Any> RestOperations.getForObject(url: URI): T? =
7182
inline fun <reified T: Any> RestOperations.getForEntity(url: String, vararg uriVariables: Any): ResponseEntity<T> =
7283
getForEntity(url, T::class.java, *uriVariables)
7384

85+
/**
86+
* Extension for [RestOperations.getForEntity] avoiding requiring the type parameter
87+
* thanks to Kotlin reified type parameters.
88+
*
89+
* @author Sebastien Deleuze
90+
* @since 5.0.2
91+
*/
92+
@Throws(RestClientException::class)
93+
inline fun <reified T: Any> RestOperations.getForEntity(url: String, uriVariables: Map<String, *>): ResponseEntity<T> =
94+
getForEntity(url, T::class.java, uriVariables)
95+
96+
/**
97+
* Extension for [RestOperations.patchForObject] avoiding specifying the type parameter
98+
* thanks to Kotlin reified type parameters.
99+
*
100+
* @author Sebastien Deleuze
101+
* @since 5.0.2
102+
*/
103+
@Throws(RestClientException::class)
104+
inline fun <reified T: Any> RestOperations.patchForObject(url: String, request: Any, vararg uriVariables: Any): T? =
105+
patchForObject(url, request, T::class.java, *uriVariables)
106+
107+
/**
108+
* Extension for [RestOperations.patchForObject] avoiding specifying the type parameter
109+
* thanks to Kotlin reified type parameters.
110+
*
111+
* @author Sebastien Deleuze
112+
* @since 5.0.2
113+
*/
114+
@Throws(RestClientException::class)
115+
inline fun <reified T: Any> RestOperations.patchForObject(url: String, request: Any, uriVariables: Map<String, *>): T? =
116+
patchForObject(url, request, T::class.java, uriVariables)
117+
118+
/**
119+
* Extension for [RestOperations.patchForObject] avoiding specifying the type parameter
120+
* thanks to Kotlin reified type parameters.
121+
*
122+
* @author Sebastien Deleuze
123+
* @since 5.0.2
124+
*/
125+
@Throws(RestClientException::class)
126+
inline fun <reified T: Any> RestOperations.patchForObject(url: URI, request: Any): T? =
127+
patchForObject(url, request, T::class.java)
128+
74129
/**
75130
* Extension for [RestOperations.postForObject] avoiding specifying the type parameter
76131
* thanks to Kotlin reified type parameters.

spring-web/src/test/kotlin/org/springframework/web/client/RestOperationsExtensionsTests.kt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.web.client
1818

1919
import com.nhaarman.mockito_kotlin.mock
20+
import org.junit.Assert
2021
import org.junit.Test
2122
import org.junit.runner.RunWith
2223
import org.mockito.Answers
@@ -27,7 +28,10 @@ import org.springframework.core.ParameterizedTypeReference
2728
import org.springframework.http.HttpEntity
2829
import org.springframework.http.HttpMethod
2930
import org.springframework.http.RequestEntity
31+
import org.springframework.util.ReflectionUtils
3032
import java.net.URI
33+
import kotlin.reflect.full.createType
34+
import kotlin.reflect.jvm.kotlinFunction
3135

3236
/**
3337
* Mock object based tests for [RestOperations] Kotlin extensions.
@@ -64,6 +68,13 @@ class RestOperationsExtensionsTests {
6468
verify(template, times(1)).getForObject(url, Foo::class.java)
6569
}
6670

71+
@Test
72+
fun `getForEntity with reified type parameters, String and URI`() {
73+
val url = URI("https://spring.io")
74+
template.getForEntity<Foo>(url)
75+
verify(template, times(1)).getForEntity(url, Foo::class.java)
76+
}
77+
6778
@Test
6879
fun `getForEntity with reified type parameters, String and varargs`() {
6980
val url = "https://spring.io"
@@ -73,6 +84,41 @@ class RestOperationsExtensionsTests {
7384
verify(template, times(1)).getForEntity(url, Foo::class.java, var1, var2)
7485
}
7586

87+
@Test
88+
fun `getForEntity with reified type parameters and Map`() {
89+
val url = "https://spring.io"
90+
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
91+
template.getForEntity<Foo>(url, vars)
92+
verify(template, times(1)).getForEntity(url, Foo::class.java, vars)
93+
}
94+
95+
@Test
96+
fun `patchForObject with reified type parameters, String and varargs`() {
97+
val url = "https://spring.io"
98+
val body: Any = "body"
99+
val var1 = "var1"
100+
val var2 = "var2"
101+
template.patchForObject<Foo>(url, body, var1, var2)
102+
verify(template, times(1)).patchForObject(url, body, Foo::class.java, var1, var2)
103+
}
104+
105+
@Test
106+
fun `patchForObject with reified type parameters, String and Map`() {
107+
val url = "https://spring.io"
108+
val body: Any = "body"
109+
val vars = mapOf(Pair("key1", "value1"), Pair("key2", "value2"))
110+
template.patchForObject<Foo>(url, body, vars)
111+
verify(template, times(1)).patchForObject(url, body, Foo::class.java, vars)
112+
}
113+
114+
@Test
115+
fun `patchForObject with reified type parameters`() {
116+
val url = "https://spring.io"
117+
val body: Any = "body"
118+
template.patchForObject<Foo>(url, body)
119+
verify(template, times(1)).patchForObject(url, body, Foo::class.java)
120+
}
121+
76122
@Test
77123
fun `postForObject with reified type parameters, String and varargs`() {
78124
val url = "https://spring.io"
@@ -168,6 +214,21 @@ class RestOperationsExtensionsTests {
168214
object : ParameterizedTypeReference<List<Foo>>() {})
169215
}
170216

217+
@Test
218+
fun `RestOperations are available`() {
219+
val extensions = Class.forName("org.springframework.web.client.RestOperationsExtensionsKt")
220+
ReflectionUtils.doWithMethods(RestOperations::class.java) { method ->
221+
arrayOf(ParameterizedTypeReference::class, Class::class).forEach { kClass ->
222+
if (method.parameterTypes.contains(kClass.java)) {
223+
val parameters = mutableListOf<Class<*>>(RestOperations::class.java).apply { addAll(method.parameterTypes.filter { it != kClass.java }) }
224+
val f = extensions.getDeclaredMethod(method.name, *parameters.toTypedArray()).kotlinFunction!!
225+
Assert.assertEquals(1, f.typeParameters.size)
226+
Assert.assertEquals(listOf(Any::class.createType()), f.typeParameters[0].upperBounds)
227+
}
228+
}
229+
}
230+
}
231+
171232
class Foo
172233

173234
}

0 commit comments

Comments
 (0)