diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index fb7f4a8..ecb5347 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,10 @@
-
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index cfd3ca8..a3aaadd 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -21,5 +21,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 1af7969..85918c8 100644
--- a/README.md
+++ b/README.md
@@ -99,6 +99,21 @@ lang: "en"
```
- View more [examples](https://github.com/ethauvin/jokeapi/blob/master/src/test/kotlin/net/thauvin/erik/jokeapi/GetRawJokeTest.kt)...
+## Java
+
+To make it easier to use the library with Java, a configuration builder is also available:
+
+```java
+var config = new JokeConfig.Builder()
+ .type(Type.SINGLE)
+ .safe(true)
+ .build();
+var joke = JokeApi.getJoke(config);
+for (String j : joke.getJoke()) {
+ System.out.println(j);
+}
+```
+
## Extending
A generic `apiCall()` function is available to access other [JokeAPI endpoints](https://v2.jokeapi.dev/#endpoints).
diff --git a/detekt-baseline.xml b/detekt-baseline.xml
index 997bf2d..19fd5a3 100644
--- a/detekt-baseline.xml
+++ b/detekt-baseline.xml
@@ -2,9 +2,10 @@
- ComplexMethod:JokeApi.kt$JokeApi.Companion$@JvmStatic @JvmOverloads @Throws(HttpErrorException::class, IOException::class) fun getRawJoke( categories: Set<Category> = setOf(Category.ANY), language: Language = Language.ENGLISH, flags: Set<Flag> = emptySet(), type: Type = Type.ALL, format: Format = Format.JSON, search: String = "", idRange: IdRange = IdRange(), amount: Int = 1, safe: Boolean = false, ): String
+ ComplexMethod:JokeApi.kt$JokeApi.Companion$@JvmStatic @Throws(HttpErrorException::class, IOException::class) fun getRawJoke( categories: Set<Category> = setOf(Category.ANY), language: Language = Language.ENGLISH, flags: Set<Flag> = emptySet(), type: Type = Type.ALL, format: Format = Format.JSON, search: String = "", idRange: IdRange = IdRange(), amount: Int = 1, safe: Boolean = false, ): StringLongParameterList:JokeApi.kt$JokeApi.Companion$( categories: Set<Category> = setOf(Category.ANY), language: Language = Language.ENGLISH, flags: Set<Flag> = emptySet(), type: Type = Type.ALL, format: Format = Format.JSON, search: String = "", idRange: IdRange = IdRange(), amount: Int = 1, safe: Boolean = false, )LongParameterList:JokeApi.kt$JokeApi.Companion$( categories: Set<Category> = setOf(Category.ANY), language: Language = Language.ENGLISH, flags: Set<Flag> = emptySet(), type: Type = Type.ALL, search: String = "", idRange: IdRange = IdRange(), safe: Boolean = false, splitNewLine: Boolean = true )
+ LongParameterList:JokeConfig.kt$JokeConfig$( val categories: Set<Category>, val language: Language, val flags: Set<Flag>, val type: Type, val format: Format, val search: String, val idRange: IdRange, val amount: Int = 1, val safe: Boolean, val splitNewLine: Boolean, )LongParameterList:JokeException.kt$JokeException$( val error: Boolean, val internalError: Boolean, val code: Int, message: String, val causedBy: List<String>, val additionalInfo: String, val timestamp: Long, cause: Throwable? = null )MagicNumber:JokeApi.kt$JokeApi.Companion$10MagicNumber:JokeApi.kt$JokeApi.Companion$200
@@ -17,6 +18,7 @@
MagicNumber:JokeApi.kt$JokeApi.Companion$429MagicNumber:JokeApi.kt$JokeApi.Companion$500MagicNumber:JokeApi.kt$JokeApi.Companion$523
+ TooManyFunctions:JokeConfig.kt$JokeConfig$BuilderUtilityClassWithPublicConstructor:JokeApi.kt$JokeApi
diff --git a/src/main/kotlin/net/thauvin/erik/jokeapi/JokeApi.kt b/src/main/kotlin/net/thauvin/erik/jokeapi/JokeApi.kt
index 2c02488..cc5ea74 100644
--- a/src/main/kotlin/net/thauvin/erik/jokeapi/JokeApi.kt
+++ b/src/main/kotlin/net/thauvin/erik/jokeapi/JokeApi.kt
@@ -94,7 +94,6 @@ class JokeApi {
}
@JvmStatic
- @JvmOverloads
@Throws(HttpErrorException::class, IOException::class)
fun getRawJoke(
categories: Set = setOf(Category.ANY),
@@ -171,6 +170,22 @@ class JokeApi {
return apiCall(JOKE_ENDPOINT, path, params)
}
+ @JvmStatic
+ @Throws(HttpErrorException::class, IOException::class)
+ fun getRawJoke(config: JokeConfig): String {
+ return getRawJoke(
+ categories = config.categories,
+ language = config.language,
+ flags = config.flags,
+ type = config.type,
+ format = config.format,
+ search = config.search,
+ idRange = config.idRange,
+ amount = config.amount,
+ safe = config.safe
+ )
+ }
+
@Throws(HttpErrorException::class, IOException::class)
internal fun fetchUrl(url: String): String {
if (logger.isLoggable(Level.FINE)) {
@@ -251,7 +266,6 @@ class JokeApi {
}
@JvmStatic
- @JvmOverloads
@Throws(JokeException::class, HttpErrorException::class, IOException::class)
fun getJoke(
categories: Set = setOf(Category.ANY),
@@ -312,5 +326,20 @@ class JokeApi {
)
}
}
+
+ @JvmStatic
+ @Throws(JokeException::class, HttpErrorException::class, IOException::class)
+ fun getJoke(config: JokeConfig): Joke {
+ return getJoke(
+ categories = config.categories,
+ language = config.language,
+ flags = config.flags,
+ type = config.type,
+ search = config.search,
+ idRange = config.idRange,
+ safe = config.safe,
+ splitNewLine = config.splitNewLine
+ )
+ }
}
}
diff --git a/src/main/kotlin/net/thauvin/erik/jokeapi/JokeConfig.kt b/src/main/kotlin/net/thauvin/erik/jokeapi/JokeConfig.kt
new file mode 100644
index 0000000..1461f32
--- /dev/null
+++ b/src/main/kotlin/net/thauvin/erik/jokeapi/JokeConfig.kt
@@ -0,0 +1,81 @@
+/*
+ * Configuration.kt
+ *
+ * Copyright (c) 2022, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of this project nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.jokeapi
+
+import net.thauvin.erik.jokeapi.models.Category
+import net.thauvin.erik.jokeapi.models.Flag
+import net.thauvin.erik.jokeapi.models.Format
+import net.thauvin.erik.jokeapi.models.IdRange
+import net.thauvin.erik.jokeapi.models.Language
+import net.thauvin.erik.jokeapi.models.Type
+
+class JokeConfig private constructor(
+ val categories: Set,
+ val language: Language,
+ val flags: Set,
+ val type: Type,
+ val format: Format,
+ val search: String,
+ val idRange: IdRange,
+ val amount: Int = 1,
+ val safe: Boolean,
+ val splitNewLine: Boolean,
+) {
+ data class Builder(
+ var categories: Set = setOf(Category.ANY),
+ var language: Language = Language.ENGLISH,
+ var flags: Set = emptySet(),
+ var type: Type = Type.ALL,
+ var format: Format = Format.JSON,
+ var search: String = "",
+ var idRange: IdRange = IdRange(),
+ var amount: Int = 1,
+ var safe: Boolean = false,
+ var splitNewLine: Boolean = true
+ ) {
+ fun categories(categories: Set) = apply { this.categories = categories }
+ fun language(language: Language) = apply { this.language = language }
+ fun flags(flags: Set) = apply { this.flags = flags }
+ fun type(type: Type) = apply { this.type = type }
+ fun format(format: Format) = apply { this.format = format }
+ fun search(search: String) = apply { this.search = search }
+ fun idRange(idRange: IdRange) = apply { this.idRange = idRange }
+ fun amount(amount: Int) = apply { this.amount = amount }
+ fun safe(safe: Boolean) = apply { this.safe = safe }
+ fun splitNewLine(splitNewLine: Boolean) = apply { this.splitNewLine = splitNewLine }
+
+ fun build() = JokeConfig(
+ categories, language, flags, type, format, search, idRange, amount, safe, splitNewLine
+ )
+ }
+}
diff --git a/src/test/kotlin/net/thauvin/erik/jokeapi/GetJokeTest.kt b/src/test/kotlin/net/thauvin/erik/jokeapi/GetJokeTest.kt
index bc2b62c..908e80b 100644
--- a/src/test/kotlin/net/thauvin/erik/jokeapi/GetJokeTest.kt
+++ b/src/test/kotlin/net/thauvin/erik/jokeapi/GetJokeTest.kt
@@ -32,10 +32,8 @@
package net.thauvin.erik.jokeapi
-import net.thauvin.erik.jokeapi.JokeApi.Companion.fetchUrl
import net.thauvin.erik.jokeapi.JokeApi.Companion.getJoke
import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
-import net.thauvin.erik.jokeapi.exceptions.HttpErrorException
import net.thauvin.erik.jokeapi.exceptions.JokeException
import net.thauvin.erik.jokeapi.models.Category
import net.thauvin.erik.jokeapi.models.Flag
diff --git a/src/test/kotlin/net/thauvin/erik/jokeapi/JokeConfigTest.kt b/src/test/kotlin/net/thauvin/erik/jokeapi/JokeConfigTest.kt
new file mode 100644
index 0000000..b11e943
--- /dev/null
+++ b/src/test/kotlin/net/thauvin/erik/jokeapi/JokeConfigTest.kt
@@ -0,0 +1,101 @@
+/*
+ * JokeConfigTest.kt
+ *
+ * Copyright (c) 2022, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of this project nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.thauvin.erik.jokeapi
+
+import net.thauvin.erik.jokeapi.JokeApi.Companion.getJoke
+import net.thauvin.erik.jokeapi.JokeApi.Companion.getRawJoke
+import net.thauvin.erik.jokeapi.JokeApi.Companion.logger
+import net.thauvin.erik.jokeapi.models.Category
+import net.thauvin.erik.jokeapi.models.Flag
+import net.thauvin.erik.jokeapi.models.Format
+import net.thauvin.erik.jokeapi.models.IdRange
+import net.thauvin.erik.jokeapi.models.Language
+import net.thauvin.erik.jokeapi.models.Type
+import org.junit.jupiter.api.Assertions.assertAll
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.junit.jupiter.api.BeforeAll
+import org.junit.jupiter.api.Test
+import java.util.logging.ConsoleHandler
+import java.util.logging.Level
+
+class JokeConfigTest {
+ @Test
+ fun `Get Joke with Builder`() {
+ val id = 266
+ val config = JokeConfig.Builder().apply {
+ categories(setOf(Category.PROGRAMMING))
+ language(Language.EN)
+ flags(setOf(Flag.ALL))
+ type(Type.TWOPART)
+ idRange(IdRange(id - 2, id + 2))
+ safe(true)
+ splitNewLine(false)
+ }.build()
+ val joke = getJoke(config)
+ logger.fine(joke.toString())
+ assertAll("Two-Parts Joke",
+ { assertEquals(Type.TWOPART, joke.type, "type should be two-part") },
+ { assertEquals(joke.category, Category.PROGRAMMING) { "category should be ${Category.PROGRAMMING}" } },
+ { assertEquals(joke.joke.size, 2, "should have two lines") },
+ { assertEquals(joke.language, Language.EN, "language should be english") },
+ { assertTrue(joke.flags.isEmpty(), "flags should empty") },
+ { assertTrue(joke.id in id - 2..id + 2) { "id should be $id +- 2" } })
+ }
+
+ @Test
+ fun `Get Raw Joke with Builder`() {
+ val config = JokeConfig.Builder().apply {
+ categories(setOf(Category.PROGRAMMING))
+ format(Format.TEXT)
+ search("bar")
+ amount(2)
+ safe(true)
+ }.build()
+ val joke = getRawJoke(config)
+ assertTrue(
+ joke.contains("----------------------------------------------"), "should contain -- delimiter"
+ )
+ }
+
+ companion object {
+ @JvmStatic
+ @BeforeAll
+ fun beforeAll() {
+ with(logger) {
+ addHandler(ConsoleHandler().apply { level = Level.FINE })
+ level = Level.FINE
+ }
+ }
+ }
+}