Skip to content

Commit c9453fc

Browse files
committed
add builder constructors and getters in SpotifyAPI
1 parent 5c6d0af commit c9453fc

File tree

5 files changed

+142
-37
lines changed

5 files changed

+142
-37
lines changed

docs/com/adamratzman/spotify/main/SpotifyAPIKt.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ <h3>Method Summary</h3>
127127
</tr>
128128
<tr id="i0" class="altColor">
129129
<td class="colFirst"><code>static <a href="../../../../com/adamratzman/spotify/main/SpotifyApiBuilder.html" title="type parameter in SpotifyApiBuilder">SpotifyApiBuilder</a></code></td>
130-
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../com/adamratzman/spotify/main/SpotifyAPIKt.html#spotifyApi-block-">spotifyApi</a></span>(kotlin.jvm.functions.Function1&lt;? super com.adamratzman.spotify.SpotifyApiBuilder,kotlin.Unit&gt;&nbsp;block)</code>&nbsp;</td>
130+
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../com/adamratzman/spotify/main/SpotifyAPIKt.html#spotifyApi-block-">spotifyApi</a></span>(kotlin.jvm.functions.Function1&lt;? super com.adamratzman.spotify.SpotifyApiBuilderDsl,kotlin.Unit&gt;&nbsp;block)</code>&nbsp;</td>
131131
</tr>
132132
</table>
133133
</li>
@@ -150,7 +150,7 @@ <h3>Method Detail</h3>
150150
<ul class="blockListLast">
151151
<li class="blockList">
152152
<h4>spotifyApi</h4>
153-
<pre>public static&nbsp;<a href="../../../../com/adamratzman/spotify/main/SpotifyApiBuilder.html" title="type parameter in SpotifyApiBuilder">SpotifyApiBuilder</a>&nbsp;spotifyApi(kotlin.jvm.functions.Function1&lt;? super com.adamratzman.spotify.SpotifyApiBuilder,kotlin.Unit&gt;&nbsp;block)</pre>
153+
<pre>public static&nbsp;<a href="../../../../com/adamratzman/spotify/main/SpotifyApiBuilder.html" title="type parameter in SpotifyApiBuilder">SpotifyApiBuilder</a>&nbsp;spotifyApi(kotlin.jvm.functions.Function1&lt;? super com.adamratzman.spotify.SpotifyApiBuilderDsl,kotlin.Unit&gt;&nbsp;block)</pre>
154154
</li>
155155
</ul>
156156
</li>

docs/com/adamratzman/spotify/main/SpotifyApiBuilder.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
77
<title>SpotifyApiBuilder</title>
88
<meta name="date" content="2019-05-03">
9-
<meta name="keywords" content="com.adamratzman.spotify.SpotifyApiBuilder class">
9+
<meta name="keywords" content="com.adamratzman.spotify.SpotifyApiBuilderDsl class">
1010
<meta name="keywords" content="getUseCache()">
1111
<meta name="keywords" content="setUseCache()">
1212
<meta name="keywords" content="credentials()">
@@ -107,7 +107,7 @@ <h2 title="Class SpotifyApiBuilder" class="title">Class SpotifyApiBuilder</h2>
107107
</div>
108108
<div class="contentContainer">
109109
<ul class="inheritance">
110-
<li>com.adamratzman.spotify.SpotifyApiBuilder</li>
110+
<li>com.adamratzman.spotify.SpotifyApiBuilderDsl</li>
111111
</ul>
112112
<div class="description">
113113
<ul class="blockList">

docs/com/adamratzman/spotify/main/SpotifyApiBuilderJava.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
77
<title>SpotifyApiBuilderJava</title>
88
<meta name="date" content="2019-05-03">
9-
<meta name="keywords" content="com.adamratzman.spotify.SpotifyApiBuilderJava class">
9+
<meta name="keywords" content="com.adamratzman.spotify.SpotifyApiBuilder class">
1010
<meta name="keywords" content="getRedirectUri()">
1111
<meta name="keywords" content="setRedirectUri()">
1212
<meta name="keywords" content="getAuthorizationCode()">
@@ -117,7 +117,7 @@ <h2 title="Class SpotifyApiBuilderJava" class="title">Class SpotifyApiBuilderJav
117117
</div>
118118
<div class="contentContainer">
119119
<ul class="inheritance">
120-
<li>com.adamratzman.spotify.SpotifyApiBuilderJava</li>
120+
<li>com.adamratzman.spotify.SpotifyApiBuilder</li>
121121
</ul>
122122
<div class="description">
123123
<ul class="blockList">

src/main/kotlin/com/adamratzman/spotify/Builder.kt

Lines changed: 86 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,108 @@ import com.adamratzman.spotify.models.Token
99
import com.adamratzman.spotify.models.serialization.toObject
1010

1111
// Kotlin DSL builder
12-
fun spotifyApi(block: SpotifyApiBuilder.() -> Unit) = SpotifyApiBuilder().apply(block)
12+
/**
13+
* A builder DSL to create a new [SpotifyAPI]
14+
*/
15+
fun spotifyApi(block: SpotifyApiBuilderDsl.() -> Unit) = SpotifyApiBuilderDsl().apply(block)
1316

1417
// Java-friendly builder
15-
class SpotifyApiBuilderJava(val clientId: String, val clientSecret: String) {
16-
var redirectUri: String? = null
17-
var authorizationCode: String? = null
18-
var tokenString: String? = null
19-
var token: Token? = null
20-
var useCache: Boolean = true
2118

19+
/**
20+
* A builder in the style of traditional Java builders
21+
*/
22+
class SpotifyApiBuilder(
23+
val clientId: String,
24+
val clientSecret: String,
25+
var redirectUri: String? = null,
26+
var authorizationCode: String? = null,
27+
var tokenString: String? = null,
28+
var token: Token? = null,
29+
var useCache: Boolean = true
30+
) {
31+
/**
32+
* Instantiate the builder with the application [clientId] and [clientSecret]
33+
*/
34+
constructor(clientId: String, clientSecret: String) : this(clientId, clientSecret, null)
35+
36+
/**
37+
* Instantiate the builder with the application [clientId], [clientSecret], and whether to use a cache
38+
*/
39+
constructor(clientId: String, clientSecret: String, useCache: Boolean) : this(clientId, clientSecret, null, useCache = useCache)
40+
41+
/**
42+
* Instantiate the builder with the application [clientId], [clientSecret], and application
43+
* [redirectUri]
44+
*/
45+
constructor(clientId: String, clientSecret: String, redirectUri: String) : this(clientId, clientSecret, redirectUri, null)
46+
47+
/**
48+
* Instantiate the builder with the application [clientId], [clientSecret], application
49+
* [redirectUri], and an [authorizationCode]
50+
*/
51+
constructor(clientId: String, clientSecret: String, redirectUri: String?, authorizationCode: String, useCache: Boolean)
52+
: this(clientId, clientSecret, redirectUri, authorizationCode, null, useCache = useCache)
53+
54+
/**
55+
* Instantiate the builder with the application [clientId], [clientSecret], application
56+
* [redirectUri], and an access token string ([tokenString])
57+
*/
58+
constructor(clientId: String, clientSecret: String, redirectUri: String?, tokenString: String)
59+
: this(clientId, clientSecret, redirectUri, null, tokenString)
60+
61+
/**
62+
* Instantiate the builder with the application [clientId], [clientSecret], application
63+
* [redirectUri], and a [token]
64+
*/
65+
constructor(clientId: String, clientSecret: String, redirectUri: String?, token: Token, useCache: Boolean)
66+
: this(clientId, clientSecret, redirectUri, null, null, token, useCache)
67+
68+
/**
69+
* Set whether to cache requests. Default: true
70+
*/
2271
fun useCache(useCache: Boolean) = apply { this.useCache = useCache }
2372

73+
/**
74+
* Set the application [redirect uri](https://developer.spotify.com/documentation/general/guides/authorization-guide/)
75+
*/
2476
fun redirectUri(redirectUri: String?) = apply { this.redirectUri = redirectUri }
2577

78+
/**
79+
* Set a returned [authorization code](https://developer.spotify.com/documentation/general/guides/authorization-guide/)
80+
*/
2681
fun authorizationCode(authorizationCode: String?) = apply { this.authorizationCode = authorizationCode }
2782

83+
/**
84+
* If you only have an access token, the api can be instantiated with it
85+
*/
2886
fun tokenString(tokenString: String?) = apply { this.tokenString = tokenString }
2987

88+
/**
89+
* Set the token to be used with this api instance
90+
*/
3091
fun token(token: Token?) = apply { this.token = token }
3192

3293
fun buildCredentialed() = spotifyApi {
3394
credentials {
34-
clientId = this@SpotifyApiBuilderJava.clientId
35-
clientSecret = this@SpotifyApiBuilderJava.clientSecret
95+
clientId = this@SpotifyApiBuilder.clientId
96+
clientSecret = this@SpotifyApiBuilder.clientSecret
3697
}
3798
authentication {
38-
token = this@SpotifyApiBuilderJava.token
39-
tokenString = this@SpotifyApiBuilderJava.tokenString
99+
token = this@SpotifyApiBuilder.token
100+
tokenString = this@SpotifyApiBuilder.tokenString
40101
}
41102
}.buildCredentialed()
42103

43104
fun buildClient(automaticRefresh: Boolean = false) = spotifyApi {
44105
credentials {
45-
clientId = this@SpotifyApiBuilderJava.clientId
46-
clientSecret = this@SpotifyApiBuilderJava.clientSecret
47-
redirectUri = this@SpotifyApiBuilderJava.redirectUri
106+
clientId = this@SpotifyApiBuilder.clientId
107+
clientSecret = this@SpotifyApiBuilder.clientSecret
108+
redirectUri = this@SpotifyApiBuilder.redirectUri
48109
}
49110
authentication {
50-
authorizationCode = this@SpotifyApiBuilderJava.authorizationCode
51-
tokenString = this@SpotifyApiBuilderJava.tokenString
52-
token = this@SpotifyApiBuilderJava.token
111+
authorizationCode = this@SpotifyApiBuilder.authorizationCode
112+
tokenString = this@SpotifyApiBuilder.tokenString
113+
token = this@SpotifyApiBuilder.token
53114
}
54115
}.buildClient(automaticRefresh)
55116
}
@@ -82,12 +143,12 @@ data class SpotifyCredentials(val clientId: String?, val clientSecret: String?,
82143
* limited time constraint on these before the API automatically refreshes them
83144
*/
84145
class SpotifyUserAuthorizationBuilder(
85-
var authorizationCode: String? = null,
86-
var tokenString: String? = null,
87-
var token: Token? = null
146+
var authorizationCode: String? = null,
147+
var tokenString: String? = null,
148+
var token: Token? = null
88149
)
89150

90-
class SpotifyApiBuilder {
151+
class SpotifyApiBuilderDsl {
91152
private var credentials: SpotifyCredentials = SpotifyCredentials(null, null, null)
92153
private var authentication = SpotifyUserAuthorizationBuilder()
93154
var useCache: Boolean = true
@@ -166,10 +227,10 @@ class SpotifyApiBuilder {
166227
* [authorizationCode] or [token] is provided
167228
*/
168229
private fun buildClient(
169-
authorizationCode: String? = null,
170-
tokenString: String? = null,
171-
token: Token? = null,
172-
automaticRefresh: Boolean = false
230+
authorizationCode: String? = null,
231+
tokenString: String? = null,
232+
token: Token? = null,
233+
automaticRefresh: Boolean = false
173234
): SpotifyClientAPI {
174235
val clientId = credentials.clientId
175236
val clientSecret = credentials.clientSecret

src/main/kotlin/com/adamratzman/spotify/SpotifyAPI.kt

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.adamratzman.spotify.models.serialization.getSavedTrackConverter
2929
import com.adamratzman.spotify.models.serialization.toObjectNullable
3030
import com.beust.klaxon.Klaxon
3131
import java.util.concurrent.Executors
32+
import java.util.concurrent.ScheduledFuture
3233
import java.util.concurrent.TimeUnit
3334

3435
internal val base = "https://api.spotify.com/v1"
@@ -58,8 +59,18 @@ abstract class SpotifyAPI internal constructor(
5859
val clientId: String,
5960
val clientSecret: String,
6061
var token: Token,
61-
var useCache: Boolean
62+
useCache: Boolean
6263
) {
64+
private var refreshFuture: ScheduledFuture<*>? = null
65+
66+
var useCache = useCache
67+
set(value) {
68+
if (!useCache && value) refreshFuture = startCacheRefreshRunnable()
69+
else if (useCache && !value) refreshFuture?.cancel(false)
70+
71+
field = value
72+
}
73+
6374
internal var expireTime = System.currentTimeMillis() + token.expiresIn * 1000
6475
internal val executor = Executors.newScheduledThreadPool(2)
6576

@@ -89,12 +100,22 @@ abstract class SpotifyAPI internal constructor(
89100
*/
90101
abstract fun clearCache()
91102

103+
/**
104+
* Return a new [SpotifyApiBuilder] with the parameters provided to this api instance
105+
*/
106+
abstract fun getApiBuilder(): SpotifyApiBuilder
107+
108+
/**
109+
* Return a new [SpotifyApiBuilderDsl] with the parameters provided to this api instance
110+
*/
111+
abstract fun getApiBuilderDsl(): SpotifyApiBuilderDsl
112+
92113
init {
93-
if (useCache) {
94-
executor.scheduleAtFixedRate(::clearCache, 10, 10, TimeUnit.MINUTES)
95-
}
114+
if (useCache) refreshFuture = startCacheRefreshRunnable()
96115
}
97116

117+
private fun startCacheRefreshRunnable() = executor.scheduleAtFixedRate(::clearCache, 10, 10, TimeUnit.MINUTES)
118+
98119
internal fun clearAllCaches(vararg endpoints: SpotifyEndpoint) {
99120
endpoints.forEach { it.cache.clear() }
100121
}
@@ -180,6 +201,17 @@ class SpotifyAppAPI internal constructor(clientId: String, clientSecret: String,
180201
tracks,
181202
following
182203
)
204+
205+
override fun getApiBuilder() = SpotifyApiBuilder(clientId, clientSecret, useCache)
206+
207+
override fun getApiBuilderDsl() = spotifyApi {
208+
credentials {
209+
clientId = this@SpotifyAppAPI.clientId
210+
clientSecret = this@SpotifyAppAPI.clientSecret
211+
}
212+
213+
useCache = this@SpotifyAppAPI.useCache
214+
}
183215
}
184216

185217
/**
@@ -320,6 +352,18 @@ class SpotifyClientAPI internal constructor(
320352
player
321353
)
322354

355+
override fun getApiBuilder() = SpotifyApiBuilder(clientId, clientSecret, redirectUri, useCache = useCache)
356+
357+
override fun getApiBuilderDsl() = spotifyApi {
358+
credentials {
359+
clientId = this@SpotifyClientAPI.clientId
360+
clientSecret = this@SpotifyClientAPI.clientSecret
361+
redirectUri = this@SpotifyClientAPI.redirectUri
362+
}
363+
364+
useCache = this@SpotifyClientAPI.useCache
365+
}
366+
323367
/**
324368
* Create a Spotify authorization URL from which client access can be obtained
325369
*
@@ -334,14 +378,14 @@ class SpotifyClientAPI internal constructor(
334378
}
335379
}
336380

337-
internal fun getAuthUrlFull(vararg scopes: SpotifyScope, clientId: String, redirectUri: String): String {
381+
fun getAuthUrlFull(vararg scopes: SpotifyScope, clientId: String, redirectUri: String): String {
338382
return "https://accounts.spotify.com/authorize/?client_id=$clientId" +
339383
"&response_type=code" +
340384
"&redirect_uri=$redirectUri" +
341385
if (scopes.isEmpty()) "" else "&scope=${scopes.joinToString("%20") { it.uri }}"
342386
}
343387

344-
internal fun getCredentialedToken(clientId: String, clientSecret: String) =
388+
fun getCredentialedToken(clientId: String, clientSecret: String) =
345389
HttpConnection(
346390
url = "https://accounts.spotify.com/api/token",
347391
method = HttpRequestMethod.POST,

0 commit comments

Comments
 (0)