From 05195d792d21513577002a823af3ac514e71f84d Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 27 Jul 2021 15:01:08 -0700 Subject: [PATCH] Only log error if severe logging level is enabled. --- .idea/bitly-shorten.iml | 9 ++ .idea/modules.xml | 8 + .../kotlin/net/thauvin/erik/bitly/Bitlinks.kt | 143 +++++++++--------- .../kotlin/net/thauvin/erik/bitly/Bitly.kt | 4 +- .../kotlin/net/thauvin/erik/bitly/Utils.kt | 43 ++++-- .../net/thauvin/erik/bitly/BitlyTest.kt | 36 ++--- 6 files changed, 140 insertions(+), 103 deletions(-) create mode 100644 .idea/bitly-shorten.iml create mode 100644 .idea/modules.xml diff --git a/.idea/bitly-shorten.iml b/.idea/bitly-shorten.iml new file mode 100644 index 0000000..3b6f5d8 --- /dev/null +++ b/.idea/bitly-shorten.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..edbcc81 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt b/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt index e43a9b3..58bd057 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Bitlinks.kt @@ -32,6 +32,7 @@ package net.thauvin.erik.bitly +import net.thauvin.erik.bitly.Utils.Companion.isSevereLoggable import net.thauvin.erik.bitly.Utils.Companion.isValidUrl import net.thauvin.erik.bitly.Utils.Companion.removeHttp import net.thauvin.erik.bitly.Utils.Companion.toEndPoint @@ -68,25 +69,25 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun clicks( - bitlink: String, - unit: Units = Units.DAY, - units: Int = -1, - size: Int = 50, - unit_reference: String = Constants.EMPTY, - toJson: Boolean = false + bitlink: String, + unit: Units = Units.DAY, + units: Int = -1, + size: Int = 50, + unit_reference: String = Constants.EMPTY, + toJson: Boolean = false ): String { var clicks = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY if (bitlink.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, - ("/bitlinks/${bitlink.removeHttp()}/clicks/summary").toEndPoint(), - mapOf( - "unit" to unit.toString().lowercase(), - "units" to units.toString(), - "size" to size.toString(), - "unit_reference" to unit_reference - ), - Methods.GET + accessToken, + ("/bitlinks/${bitlink.removeHttp()}/clicks/summary").toEndPoint(), + mapOf( + "unit" to unit.toString().lowercase(), + "units" to units.toString(), + "size" to size.toString(), + "unit_reference" to unit_reference + ), + Methods.GET ) clicks = parseJsonResponse(lastCallResponse, "total_clicks", clicks, toJson) } @@ -107,26 +108,26 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun create( - domain: String = Constants.EMPTY, - title: String = Constants.EMPTY, - group_guid: String = Constants.EMPTY, - tags: Array = emptyArray(), - deeplinks: Array> = emptyArray(), - long_url: String, - toJson: Boolean = false + domain: String = Constants.EMPTY, + title: String = Constants.EMPTY, + group_guid: String = Constants.EMPTY, + tags: Array = emptyArray(), + deeplinks: Array> = emptyArray(), + long_url: String, + toJson: Boolean = false ): String { var link = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY if (long_url.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, - "/bitlinks".toEndPoint(), - mutableMapOf("long_url" to long_url).apply { - if (domain.isNotBlank()) put("domain", domain) - if (title.isNotBlank()) put("title", title) - if (group_guid.isNotBlank()) put("group_guid", group_guid) - if (tags.isNotEmpty()) put("tags", tags) - if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) - } + accessToken, + "/bitlinks".toEndPoint(), + mutableMapOf("long_url" to long_url).apply { + if (domain.isNotBlank()) put("domain", domain) + if (title.isNotBlank()) put("title", title) + if (group_guid.isNotBlank()) put("group_guid", group_guid) + if (tags.isNotEmpty()) put("tags", tags) + if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) + } ) link = parseJsonResponse(lastCallResponse, "link", link, toJson) } @@ -148,9 +149,9 @@ open class Bitlinks(private val accessToken: String) { var longUrl = if (toJson) Constants.EMPTY_JSON else Constants.EMPTY if (bitlink_id.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, - "/expand".toEndPoint(), - mapOf("bitlink_id" to bitlink_id.removeHttp()) + accessToken, + "/expand".toEndPoint(), + mapOf("bitlink_id" to bitlink_id.removeHttp()) ) longUrl = parseJsonResponse(lastCallResponse, "long_url", longUrl, toJson) } @@ -174,7 +175,9 @@ open class Bitlinks(private val accessToken: String) { try { parsed = JSONObject(response.body).getString(key, default) } catch (jse: JSONException) { - Utils.logger.log(Level.SEVERE, "An error occurred parsing the response from Bitly.", jse) + if (Utils.logger.isSevereLoggable()) { + Utils.logger.log(Level.SEVERE, "An error occurred parsing the response from Bitly.", jse) + } } } } @@ -195,14 +198,16 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun shorten( - long_url: String, - group_guid: String = Constants.EMPTY, - domain: String = Constants.EMPTY, - toJson: Boolean = false + long_url: String, + group_guid: String = Constants.EMPTY, + domain: String = Constants.EMPTY, + toJson: Boolean = false ): String { var bitlink = if (toJson) Constants.EMPTY_JSON else long_url if (!long_url.isValidUrl()) { - Utils.logger.severe("Please specify a valid URL to shorten.") + if (Utils.logger.isSevereLoggable()) { + Utils.logger.severe("Please specify a valid URL to shorten.") + } } else { val params = mutableMapOf("long_url" to long_url).apply { if (group_guid.isNotBlank()) put("group_guid", group_guid) @@ -229,39 +234,39 @@ open class Bitlinks(private val accessToken: String) { @Synchronized @JvmOverloads fun update( - bitlink: String, - references: Map = emptyMap(), - archived: Boolean = false, - tags: Array = emptyArray(), - created_at: String = Constants.EMPTY, - title: String = Constants.EMPTY, - deeplinks: Array> = emptyArray(), - created_by: String = Constants.EMPTY, - long_url: String = Constants.EMPTY, - client_id: String = Constants.EMPTY, - custom_bitlinks: Array = emptyArray(), - link: String = Constants.EMPTY, - id: String = Constants.EMPTY, - toJson: Boolean = false + bitlink: String, + references: Map = emptyMap(), + archived: Boolean = false, + tags: Array = emptyArray(), + created_at: String = Constants.EMPTY, + title: String = Constants.EMPTY, + deeplinks: Array> = emptyArray(), + created_by: String = Constants.EMPTY, + long_url: String = Constants.EMPTY, + client_id: String = Constants.EMPTY, + custom_bitlinks: Array = emptyArray(), + link: String = Constants.EMPTY, + id: String = Constants.EMPTY, + toJson: Boolean = false ): String { var result = if (toJson) Constants.EMPTY_JSON else Constants.FALSE if (bitlink.isNotBlank()) { lastCallResponse = Utils.call( - accessToken, "/bitlinks/${bitlink.removeHttp()}".toEndPoint(), mutableMapOf().apply { - if (references.isNotEmpty()) put("references", references) - if (archived) put("archived", archived) - if (tags.isNotEmpty()) put("tags", tags) - if (created_at.isNotBlank()) put("created_at", created_at) - if (title.isNotBlank()) put("title", title) - if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) - if (created_by.isNotBlank()) put("created_by", created_by) - if (long_url.isNotBlank()) put("long_url", long_url) - if (client_id.isNotBlank()) put("client_id", client_id) - if (custom_bitlinks.isNotEmpty()) put("custom_bitlinks", custom_bitlinks) - if (link.isNotBlank()) put("link", link) - if (id.isNotBlank()) put("id", id) - }, - Methods.PATCH + accessToken, "/bitlinks/${bitlink.removeHttp()}".toEndPoint(), mutableMapOf().apply { + if (references.isNotEmpty()) put("references", references) + if (archived) put("archived", archived) + if (tags.isNotEmpty()) put("tags", tags) + if (created_at.isNotBlank()) put("created_at", created_at) + if (title.isNotBlank()) put("title", title) + if (deeplinks.isNotEmpty()) put("deeplinks", deeplinks) + if (created_by.isNotBlank()) put("created_by", created_by) + if (long_url.isNotBlank()) put("long_url", long_url) + if (client_id.isNotBlank()) put("client_id", client_id) + if (custom_bitlinks.isNotEmpty()) put("custom_bitlinks", custom_bitlinks) + if (link.isNotBlank()) put("link", link) + if (id.isNotBlank()) put("id", id) + }, + Methods.PATCH ) if (lastCallResponse.isSuccessful) { diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt b/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt index 731b826..c602867 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Bitly.kt @@ -35,7 +35,7 @@ package net.thauvin.erik.bitly import java.io.File import java.nio.file.Files import java.nio.file.Path -import java.util.Properties +import java.util.* /** * Provides access to the [Bitly API v4](https://dev.bitly.com/api-reference). @@ -49,7 +49,7 @@ open class Bitly() { * [Authentication](https://dev.bitly.com/docs/getting-started/authentication). **/ var accessToken: String = System.getenv(Constants.ENV_ACCESS_TOKEN) - ?: (System.getProperty(Constants.ENV_ACCESS_TOKEN) ?: Constants.EMPTY) + ?: (System.getProperty(Constants.ENV_ACCESS_TOKEN) ?: Constants.EMPTY) /** * Creates a new instance using an [API Access Token][accessToken]. diff --git a/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt b/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt index 12e27cb..98e14c3 100644 --- a/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt +++ b/src/main/kotlin/net/thauvin/erik/bitly/Utils.kt @@ -50,7 +50,7 @@ import java.util.logging.Logger open class Utils private constructor() { companion object { /** The logger instance. */ - val logger: Logger by lazy { Logger.getLogger(Bitly::class.java.simpleName) } + val logger: Logger by lazy { Logger.getLogger(Bitly::class.java.name) } /** * Executes an API call. @@ -122,19 +122,23 @@ open class Utils private constructor() { if (!result.isSuccessful && body.isNotEmpty()) { try { with(JSONObject(body)) { - if (has("message")) { - logger.severe(getString("message") + " (${result.code})") - } - if (has("description")) { - logger.severe(getString("description")) + if (logger.isSevereLoggable()) { + if (has("message")) { + logger.severe(getString("message") + " (${result.code})") + } + if (has("description")) { + logger.severe(getString("description")) + } } } } catch (jse: JSONException) { - logger.log( - Level.SEVERE, - "An error occurred parsing the error response from Bitly. [$endPoint]", - jse - ) + if (logger.isSevereLoggable()) { + logger.log( + Level.SEVERE, + "An error occurred parsing the error response from Bitly. [$endPoint]", + jse + ) + } } } return body @@ -142,6 +146,11 @@ open class Utils private constructor() { return Constants.EMPTY } + /** + * Is [Level.SEVERE] logging enabled. + */ + fun Logger.isSevereLoggable(): Boolean = this.isLoggable(Level.SEVERE) + /** * Validates a URL. */ @@ -151,7 +160,9 @@ open class Utils private constructor() { URL(this) return true } catch (e: MalformedURLException) { - logger.log(Level.FINE, "Invalid URL: $this", e) + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Invalid URL: $this", e) + } } } return false @@ -177,8 +188,12 @@ open class Utils private constructor() { private fun validateCall(accessToken: String, endPoint: String): Boolean { when { - endPoint.isBlank() -> logger.severe("Please specify a valid API endpoint.") - accessToken.isBlank() -> logger.severe("Please specify a valid API access token.") + endPoint.isBlank() -> { + if (logger.isSevereLoggable()) logger.severe("Please specify a valid API endpoint.") + } + accessToken.isBlank() -> { + if (logger.isSevereLoggable()) logger.severe("Please specify a valid API access token.") + } else -> return true } return false diff --git a/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt b/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt index 7c3cf37..d2657b0 100644 --- a/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt +++ b/src/test/kotlin/net/thauvin/erik/bitly/BitlyTest.kt @@ -74,8 +74,8 @@ class BitlyTest { fun `token should be valid`() { val test = Bitly().apply { accessToken = "12345679" } assertEquals( - "{\"message\":\"FORBIDDEN\"}", - test.bitlinks().shorten("https://erik.thauvin.net/blog", toJson = true) + "{\"message\":\"FORBIDDEN\"}", + test.bitlinks().shorten("https://erik.thauvin.net/blog", toJson = true) ) } @@ -108,13 +108,13 @@ class BitlyTest { @Test fun `created by`() { assertEquals( - "ethauvin", - JSONObject( - bitly.call( - "/bitlinks/${shortUrl.removeHttp()}".toEndPoint(), - method = Methods.GET - ).body - ).getString("created_by") + "ethauvin", + JSONObject( + bitly.call( + "/bitlinks/${shortUrl.removeHttp()}".toEndPoint(), + method = Methods.GET + ).body + ).getString("created_by") ) } @@ -155,13 +155,13 @@ class BitlyTest { @Test fun `create bitlink`() { assertEquals( - shortUrl, - bitly.bitlinks().create( - domain = "bit.ly", - title = "Erik's Blog", - tags = arrayOf("erik", "thauvin", "blog", "weblog"), - long_url = longUrl - ) + shortUrl, + bitly.bitlinks().create( + domain = "bit.ly", + title = "Erik's Blog", + tags = arrayOf("erik", "thauvin", "blog", "weblog"), + long_url = longUrl + ) ) } @@ -169,8 +169,8 @@ class BitlyTest { fun `update bitlink`() { val bl = bitly.bitlinks() assertEquals( - Constants.TRUE, - bl.update(shortUrl, title = "Erik's Weblog", tags = arrayOf("blog", "weblog")) + Constants.TRUE, + bl.update(shortUrl, title = "Erik's Weblog", tags = arrayOf("blog", "weblog")) ) bl.update(shortUrl, link = longUrl)