diff --git a/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt b/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt index 468e3bdf2..1d6a9d345 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt @@ -68,7 +68,7 @@ object BookSourceController { fun deleteSources(postData: String?): ReturnData { kotlin.runCatching { - GSON.fromJsonArray(postData).getOrThrow()?.let { + GSON.fromJsonArray(postData).getOrThrow().let { it.forEach { source -> appDb.bookSourceDao.delete(source) SourceConfig.removeSource(source.bookSourceUrl) diff --git a/app/src/main/java/io/legado/app/data/entities/RssSource.kt b/app/src/main/java/io/legado/app/data/entities/RssSource.kt index 86e5d84ab..6ea441d1f 100644 --- a/app/src/main/java/io/legado/app/data/entities/RssSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/RssSource.kt @@ -3,10 +3,13 @@ package io.legado.app.data.entities import android.os.Parcelable import android.text.TextUtils import androidx.room.* -import com.jayway.jsonpath.DocumentContext +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonDeserializer +import com.google.gson.JsonElement import io.legado.app.constant.AppPattern import io.legado.app.utils.* import kotlinx.parcelize.Parcelize +import java.lang.reflect.Type @Parcelize @Entity(tableName = "rssSources", indices = [(Index(value = ["sourceUrl"], unique = false))]) @@ -171,65 +174,35 @@ data class RssSource( @Suppress("MemberVisibilityCanBePrivate") companion object { - - fun fromJsonDoc(doc: DocumentContext): Result { - return kotlin.runCatching { - val loginUi = doc.read("$.loginUi") - RssSource( - sourceUrl = doc.readString("$.sourceUrl")!!, - sourceName = doc.readString("$.sourceName")!!, - sourceIcon = doc.readString("$.sourceIcon") ?: "", - sourceGroup = doc.readString("$.sourceGroup"), - sourceComment = doc.readString("$.sourceComment"), - enabled = doc.readBool("$.enabled") ?: true, - concurrentRate = doc.readString("$.concurrentRate"), - header = doc.readString("$.header"), - loginUrl = doc.readString("$.loginUrl"), - loginUi = if (loginUi is List<*>) GSON.toJson(loginUi) else loginUi?.toString(), - loginCheckJs = doc.readString("$.loginCheckJs"), - sortUrl = doc.readString("$.sortUrl"), - singleUrl = doc.readBool("$.singleUrl") ?: false, - articleStyle = doc.readInt("$.articleStyle") ?: 0, - ruleArticles = doc.readString("$.ruleArticles"), - ruleNextPage = doc.readString("$.ruleNextPage"), - ruleTitle = doc.readString("$.ruleTitle"), - rulePubDate = doc.readString("$.rulePubDate"), - ruleDescription = doc.readString("$.ruleDescription"), - ruleImage = doc.readString("$.ruleImage"), - ruleLink = doc.readString("$.ruleLink"), - ruleContent = doc.readString("$.ruleContent"), - style = doc.readString("$.style"), - injectJs = doc.readString("$.injectJs"), - enableJs = doc.readBool("$.enableJs") ?: true, - loadWithBaseUrl = doc.readBool("$.loadWithBaseUrl") ?: true, - enabledCookieJar = doc.readBool("$.enabledCookieJar") ?: false, - customOrder = doc.readInt("$.customOrder") ?: 0, - lastUpdateTime = doc.readLong("$.lastUpdateTime") ?: 0L, - coverDecodeJs = doc.readString("$.coverDecodeJs"), - variableComment = doc.readString("$.variableComment"), - contentBlacklist = doc.readString("$.contentBlacklist"), - contentWhitelist = doc.readString("$.contentWhitelist") - ) - } + private val gson by lazy { + GSON.newBuilder() + .registerTypeAdapter(String::class.java, RssJsonDeserializer()) + .create() } fun fromJson(json: String): Result { - return fromJsonDoc(jsonPath.parse(json)) + return gson.fromJsonObject(json) } - fun fromJsonArray(jsonArray: String): Result> { - return kotlin.runCatching { - val sources = arrayListOf() - val doc = jsonPath.parse(jsonArray).read>("$") - doc.forEach { - val jsonItem = jsonPath.parse(it) - fromJsonDoc(jsonItem).getOrThrow().let { source -> - sources.add(source) - } - } - sources - } + fun fromJsonArray(jsonArray: String): Result> { + return gson.fromJsonArray(jsonArray) } } + class RssJsonDeserializer : JsonDeserializer { + + override fun deserialize( + json: JsonElement, + typeOfT: Type?, + context: JsonDeserializationContext? + ): String? { + return when { + json.isJsonPrimitive -> json.asString + json.isJsonNull -> null + else -> json.toString() + } + } + + } + } diff --git a/app/src/main/java/io/legado/app/help/DefaultData.kt b/app/src/main/java/io/legado/app/help/DefaultData.kt index e5e99431b..1d3079668 100644 --- a/app/src/main/java/io/legado/app/help/DefaultData.kt +++ b/app/src/main/java/io/legado/app/help/DefaultData.kt @@ -87,7 +87,7 @@ object DefaultData { appCtx.assets.open("defaultData${File.separator}coverRule.json") .readBytes() ) - GSON.fromJsonObject(json).getOrThrow()!! + GSON.fromJsonObject(json).getOrThrow() } val dictRules: List by lazy { @@ -95,7 +95,7 @@ object DefaultData { appCtx.assets.open("defaultData${File.separator}dictRules.json") .readBytes() ) - GSON.fromJsonArray(json).getOrThrow()!! + GSON.fromJsonArray(json).getOrThrow() } val keyboardAssists: List by lazy { @@ -103,7 +103,7 @@ object DefaultData { appCtx.assets.open("defaultData${File.separator}keyboardAssists.json") .readBytes() ) - GSON.fromJsonArray(json).getOrNull()!! + GSON.fromJsonArray(json).getOrThrow() } fun importDefaultHttpTTS() { diff --git a/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt b/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt index a94f30581..3f4910d77 100644 --- a/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt +++ b/app/src/main/java/io/legado/app/help/source/BookSourceExtensions.kt @@ -50,7 +50,7 @@ suspend fun BookSource.exploreKinds(): List { } } if (ruleStr.isJsonArray()) { - GSON.fromJsonArray(ruleStr).getOrThrow()?.let { + GSON.fromJsonArray(ruleStr).getOrThrow().let { kinds.addAll(it.filterNotNull()) } } else { diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt index 17720bebd..9148d3e6c 100644 --- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt +++ b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt @@ -218,7 +218,7 @@ object LocalBook { SimpleBindings().also { it["src"] = tempFileName } ).toString() val bookMess = GSON.fromJsonObject>(jsonStr) - .getOrThrow() ?: HashMap() + .getOrThrow() name = bookMess["name"] ?: tempFileName author = bookMess["author"]?.takeIf { it.length != tempFileName.length } ?: "" } catch (e: Exception) { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt index 5f5161030..90a8eaa4b 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt @@ -71,11 +71,11 @@ class ImportDictRuleViewModel(app: Application) : BaseViewModel(app) { private suspend fun importSourceAwait(text: String) { when { text.isJsonObject() -> { - GSON.fromJsonObject(text).getOrThrow()?.let { + GSON.fromJsonObject(text).getOrThrow().let { allSources.add(it) } } - text.isJsonArray() -> GSON.fromJsonArray(text).getOrThrow()?.let { items -> + text.isJsonArray() -> GSON.fromJsonArray(text).getOrThrow().let { items -> allSources.addAll(items) } text.isAbsUrl() -> { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt index 0afd3d6a7..51e421ab1 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt @@ -104,12 +104,8 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { } } mText.isJsonArray() -> { - val items: List> = jsonPath.parse(mText).read("$") - for (item in items) { - val jsonItem = jsonPath.parse(item) - RssSource.fromJsonDoc(jsonItem).getOrThrow().let { - allSources.add(it) - } + RssSource.fromJsonArray(mText).getOrThrow().let { + allSources.addAll(it) } } mText.isAbsUrl() -> { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt index a2d23156c..fad8f27f7 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt @@ -68,12 +68,12 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) { private suspend fun importSourceAwait(text: String) { when { text.isJsonObject() -> { - GSON.fromJsonObject(text).getOrThrow()?.let { + GSON.fromJsonObject(text).getOrThrow().let { allSources.add(it) } } text.isJsonArray() -> GSON.fromJsonArray(text).getOrThrow() - ?.let { items -> + .let { items -> allSources.addAll(items) } text.isAbsUrl() -> { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt index 3332ddefc..df481a4e8 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt @@ -71,12 +71,12 @@ class ImportTxtTocRuleViewModel(app: Application) : BaseViewModel(app) { private suspend fun importSourceAwait(text: String) { when { text.isJsonObject() -> { - GSON.fromJsonObject(text).getOrThrow()?.let { + GSON.fromJsonObject(text).getOrThrow().let { allSources.add(it) } } text.isJsonArray() -> GSON.fromJsonArray(text).getOrThrow() - ?.let { items -> + .let { items -> allSources.addAll(items) } text.isAbsUrl() -> { diff --git a/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt index 3eeecdb17..c4fa6d6b3 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt @@ -3,7 +3,6 @@ package io.legado.app.ui.book.toc.rule import android.app.Application import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb -import io.legado.app.data.entities.DictRule import io.legado.app.data.entities.TxtTocRule import io.legado.app.help.DefaultData import io.legado.app.help.http.newCallResponseBody @@ -43,7 +42,7 @@ class TxtTocRuleViewModel(app: Application) : BaseViewModel(app) { okHttpClient.newCallResponseBody { url(url) }.text("utf-8").let { json -> - GSON.fromJsonArray(json).getOrThrow()?.let { + GSON.fromJsonArray(json).getOrThrow().let { appDb.txtTocRuleDao.insert(*it.toTypedArray()) } } diff --git a/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleEditDialog.kt b/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleEditDialog.kt index b2c34102c..5b5c987ee 100644 --- a/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/dict/rule/DictRuleEditDialog.kt @@ -109,7 +109,7 @@ class DictRuleEditDialog() : BaseDialogFragment(R.layout.dialog_dict_rule_edit, return } execute { - GSON.fromJsonObject(text).getOrThrow()!! + GSON.fromJsonObject(text).getOrThrow() }.onSuccess { success.invoke(it) }.onError { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 42c4f5194..31f8ef7d1 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -125,7 +125,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) private fun importBookshelfByJson(json: String, groupId: Long) { execute { val bookSources = appDb.bookSourceDao.allEnabled - GSON.fromJsonArray>(json).getOrThrow()?.forEach { bookInfo -> + GSON.fromJsonArray>(json).getOrThrow().forEach { bookInfo -> if (!isActive) return@execute val name = bookInfo["name"] ?: "" val author = bookInfo["author"] ?: "" diff --git a/app/src/main/java/io/legado/app/utils/GsonExtensions.kt b/app/src/main/java/io/legado/app/utils/GsonExtensions.kt index 9329613e3..1b5af4ca7 100644 --- a/app/src/main/java/io/legado/app/utils/GsonExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/GsonExtensions.kt @@ -27,29 +27,41 @@ val GSON: Gson by lazy { inline fun genericType(): Type = object : TypeToken() {}.type -inline fun Gson.fromJsonObject(json: String?): Result { +inline fun Gson.fromJsonObject(json: String?): Result { return kotlin.runCatching { - fromJson(json, genericType()) as? T + if (json == null) { + throw JsonSyntaxException("解析字符串为空") + } + fromJson(json, genericType()) as T } } -inline fun Gson.fromJsonArray(json: String?): Result?> { +inline fun Gson.fromJsonArray(json: String?): Result> { return kotlin.runCatching { - fromJson(json, ParameterizedTypeImpl(T::class.java)) as? List + if (json == null) { + throw JsonSyntaxException("解析字符串为空") + } + fromJson(json, ParameterizedTypeImpl(T::class.java)) as List } } -inline fun Gson.fromJsonObject(inputStream: InputStream?): Result { +inline fun Gson.fromJsonObject(inputStream: InputStream?): Result { return kotlin.runCatching { + if (inputStream == null) { + throw JsonSyntaxException("解析流为空") + } val reader = InputStreamReader(inputStream) - fromJson(reader, genericType()) as? T + fromJson(reader, genericType()) as T } } -inline fun Gson.fromJsonArray(inputStream: InputStream?): Result?> { +inline fun Gson.fromJsonArray(inputStream: InputStream?): Result> { return kotlin.runCatching { + if (inputStream == null) { + throw JsonSyntaxException("解析流为空") + } val reader = InputStreamReader(inputStream) - fromJson(reader, ParameterizedTypeImpl(T::class.java)) as? List + fromJson(reader, ParameterizedTypeImpl(T::class.java)) as List } }