Skip to content
Merged
9 changes: 2 additions & 7 deletions apis/src/main/kotlin/org/yapp/apis/auth/util/IsbnConverter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,8 @@ object IsbnConverter {

fun toIsbn13(isbn10: String?): String? {
val sanitized = isbn10?.replace("-", "")?.uppercase()

if (sanitized.isNullOrBlank() || sanitized.length != ISBN10_LENGTH) {
return null
}
if (!sanitized.matches(Regex(RegexUtils.ISBN10_PATTERN))) {
return null
}
?.takeIf { it.length == ISBN10_LENGTH && it.matches(Regex(RegexUtils.ISBN10_PATTERN)) }
?: return null

val stem = ISBN13_PREFIX + sanitized.substring(0, ISBN10_LENGTH - 1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ data class BookDetailResponse private constructor(

companion object {
private const val DEFAULT_MAX_PAGE_COUNT = 4032

fun from(response: AladinBookDetailResponse, userBookStatus: BookStatus = BookStatus.BEFORE_REGISTRATION): BookDetailResponse {
val item = response.item.firstOrNull()
?: throw IllegalArgumentException("No book item found in detail response.")

val isbn13 = item.isbn13?.takeIf { it.isNotBlank() }
?: IsbnConverter.toIsbn13(item.isbn?.takeIf { it.isNotBlank() })
?: throw IllegalArgumentException("Either isbn13 or isbn must be provided")

return BookDetailResponse(
version = response.version,
title = item.title,
Expand All @@ -39,7 +43,7 @@ data class BookDetailResponse private constructor(
pubDate = item.pubDate ?: "",
description = item.description ?: "",
mallType = item.mallType,
isbn13 = item.isbn13 ?: IsbnConverter.toIsbn13(item.isbn) ?: throw IllegalArgumentException("Either isbn13 or isbn must be provided"),
isbn13 = isbn13,
coverImageUrl = item.cover,
categoryName = item.categoryName,
publisher = item.publisher ?: "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import org.yapp.apis.book.dto.response.BookDetailResponse
import org.yapp.apis.book.dto.response.BookSearchResponse
import org.yapp.apis.book.exception.BookErrorCode
import org.yapp.apis.book.exception.BookException
import org.yapp.apis.util.IsbnConverter
import org.yapp.globalutils.validator.IsbnValidator
import org.yapp.infra.external.aladin.AladinApi
import org.yapp.infra.external.aladin.request.AladinBookLookupRequest
import org.yapp.infra.external.aladin.request.AladinBookSearchRequest
Expand Down Expand Up @@ -42,7 +44,31 @@ class AladinBookQueryService(
log.error("Failed to call Aladin search API for request: '$request'", exception)
throw BookException(BookErrorCode.ALADIN_API_SEARCH_FAILED, exception.message)
}
return BookSearchResponse.from(response)

val filteredItems = response.item.filter { item ->
val isbn13 = item.isbn13?.takeIf { it.isNotBlank() }
?: item.isbn?.let { IsbnConverter.toIsbn13(it) }

isbn13?.let {
IsbnValidator.isValidIsbn(it) && !it.startsWith("K", ignoreCase = true)
} ?: false
}

val filteredResponse = AladinSearchResponse(
version = response.version,
title = response.title,
link = response.link,
pubDate = response.pubDate,
totalResults = filteredItems.size,
startIndex = response.startIndex,
itemsPerPage = response.itemsPerPage,
query = response.query,
searchCategoryId = response.searchCategoryId,
searchCategoryName = response.searchCategoryName,
item = filteredItems
)

return BookSearchResponse.from(filteredResponse)
}

override fun getBookDetail(@Valid request: BookDetailRequest): BookDetailResponse {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package org.yapp.globalutils.validator

import org.yapp.globalutils.util.RegexUtils

object IsbnValidator {
private val ISBN_REGEX = Regex("^(.{10}|.{13})$")
private val ISBN10_REGEX = Regex(RegexUtils.ISBN10_PATTERN)
private val ISBN13_REGEX = Regex(RegexUtils.ISBN13_PATTERN)

fun isValidIsbn(isbn: String): Boolean {
return isbn.matches(ISBN_REGEX)
return isbn.matches(ISBN10_REGEX) || isbn.matches(ISBN13_REGEX)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
import java.math.BigDecimal

@JsonIgnoreProperties(ignoreUnknown = true)
data class AladinSearchResponse internal constructor(
data class AladinSearchResponse(
@JsonProperty("version") val version: String?,
@JsonProperty("title") val title: String?,
@JsonProperty("link") val link: String?,
Expand All @@ -20,7 +20,7 @@ data class AladinSearchResponse internal constructor(
)

@JsonIgnoreProperties(ignoreUnknown = true)
data class AladinSearchItem internal constructor(
data class AladinSearchItem(
@JsonProperty("title") val title: String,
@JsonProperty("link") val link: String,
@JsonProperty("author") val author: String?,
Expand Down