From 2404b2eb3fc8c69a680c30a179cad3e28b1d6a58 Mon Sep 17 00:00:00 2001 From: FalsePattern <30945458+FalsePattern@users.noreply.github.com> Date: Sun, 16 Jul 2023 12:31:04 +0200 Subject: [PATCH] clean up update checker code --- .../impl/updates/UpdateCheckerImpl.java | 229 +++++++++--------- .../lib/updates/ModUpdateInfo.java | 3 + .../lib/updates/UpdateCheckException.java | 4 + .../lib/updates/UpdateChecker.java | 43 ++-- 4 files changed, 147 insertions(+), 132 deletions(-) diff --git a/src/main/java/com/falsepattern/lib/internal/impl/updates/UpdateCheckerImpl.java b/src/main/java/com/falsepattern/lib/internal/impl/updates/UpdateCheckerImpl.java index f7f4754..917aed0 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/updates/UpdateCheckerImpl.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/updates/UpdateCheckerImpl.java @@ -49,6 +49,64 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.atomic.AtomicReference; public final class UpdateCheckerImpl { + public static CompletableFuture> fetchUpdatesAsyncV2(String url) { + return CompletableFuture.supplyAsync(() -> { + try { + return fetchUpdatesV2(url); + } catch (UpdateCheckException e) { + throw new RuntimeException(e); + } + }); + } + + public static List fetchUpdatesV2(String url) throws UpdateCheckException { + try { + val modList = fetchRootListShared(url); + val result = new ArrayList(); + val installedMods = Loader.instance().getIndexedModList(); + for (val node : modList) { + if (!node.isJsonObject()) { + continue; + } + val obj = node.getAsJsonObject(); + if (!obj.has("modid")) { + continue; + } + if (!obj.has("versions")) { + continue; + } + val modid = obj.get("modid").getAsString(); + if (!installedMods.containsKey(modid)) { + continue; + } + val mod = installedMods.get(modid); + var versions = obj.get("versions"); + if (!versions.isJsonArray()) { + if (!versions.isJsonObject()) { + continue; + } + val ver = versions.getAsJsonObject(); + versions = new JsonArray(); + versions.getAsJsonArray().add(ver); + } + val parsedVersions = parseVersionSpecs(versions.getAsJsonArray()).join(); + val latestVersions = new ArrayList(); + for (val version : parsedVersions) { + val versionObj = version.getAsJsonObject(); + latestVersions.add(versionObj.get("version").getAsString()); + } + val currentVersion = mod.getVersion(); + if (latestVersions.contains(currentVersion)) { + continue; + } + val latest = parsedVersions.get(0).getAsJsonObject(); + result.add(new ModUpdateInfo(modid, currentVersion, latest.get("version").getAsString(), latest.get("url").getAsString())); + } + return result; + } catch (Exception e) { + throw new UpdateCheckException("Failed to check for updates!", e); + } + } public static List updateListToChatMessages(String initiator, List updates) { if (updates == null || updates.size() == 0) { return null; @@ -112,118 +170,6 @@ public final class UpdateCheckerImpl { return modList; } - public static CompletableFuture> fetchUpdatesAsync(String url) { - return CompletableFuture.supplyAsync(() -> { - val modList = fetchRootListShared(url); - val result = new ArrayList(); - val installedMods = Loader.instance().getIndexedModList(); - for (val node : modList) { - if (!node.isJsonObject()) { - continue; - } - val obj = node.getAsJsonObject(); - if (!obj.has("modid")) { - continue; - } - if (!obj.has("latestVersion")) { - continue; - } - val modid = obj.get("modid").getAsString(); - if (!installedMods.containsKey(modid)) { - continue; - } - val mod = installedMods.get(modid); - val latestVersionsNode = obj.get("latestVersion"); - List latestVersions; - if (latestVersionsNode.isJsonPrimitive() && (latestVersionsNode.getAsJsonPrimitive().isString())) { - latestVersions = Collections.singletonList(latestVersionsNode.getAsString()); - } else if (latestVersionsNode.isJsonArray()) { - latestVersions = new ArrayList<>(); - for (val version : latestVersionsNode.getAsJsonArray()) { - if (!version.isJsonPrimitive() || !version.getAsJsonPrimitive().isString()) { - continue; - } - latestVersions.add(version.getAsString()); - } - } else { - continue; - } - val currentVersion = mod.getVersion(); - if (latestVersions.contains(currentVersion)) { - continue; - } - val updateURL = obj.has("updateURL") && - obj.get("updateURL").isJsonPrimitive() && - obj.get("updateURL").getAsJsonPrimitive().isString() - ? obj.get("updateURL").getAsString() - : ""; - result.add(new ModUpdateInfo(modid, currentVersion, latestVersions.get(0), updateURL)); - } - return result; - }); - } - - public static List fetchUpdates(String url) throws UpdateCheckException { - try { - return fetchUpdatesAsync(url).join(); - } catch (CompletionException e) { - try { - throw e.getCause(); - } catch (UpdateCheckException e1) { - throw e1; - } catch (Throwable e1) { - throw new UpdateCheckException("Failed to check for updates!", e1); - } - } - } - - public static CompletableFuture> fetchUpdatesAsyncV2(String url) { - return CompletableFuture.supplyAsync(() -> { - val modList = fetchRootListShared(url); - val result = new ArrayList(); - val installedMods = Loader.instance().getIndexedModList(); - for (val node : modList) { - if (!node.isJsonObject()) { - continue; - } - val obj = node.getAsJsonObject(); - if (!obj.has("modid")) { - continue; - } - if (!obj.has("versions")) { - continue; - } - val modid = obj.get("modid").getAsString(); - if (!installedMods.containsKey(modid)) { - continue; - } - val mod = installedMods.get(modid); - var versions = obj.get("versions"); - if (!versions.isJsonArray()) { - if (!versions.isJsonObject()) { - continue; - } - val ver = versions.getAsJsonObject(); - versions = new JsonArray(); - versions.getAsJsonArray().add(ver); - } - val parsedVersions = parseVersionSpecs(versions.getAsJsonArray()).join(); - val latestVersions = new ArrayList(); - for (val version : parsedVersions) { - val versionObj = version.getAsJsonObject(); - latestVersions.add(versionObj.get("version").getAsString()); - } - val currentVersion = mod.getVersion(); - if (latestVersions.contains(currentVersion)) { - continue; - } - val latest = parsedVersions.get(0).getAsJsonObject(); - result.add(new ModUpdateInfo(modid, currentVersion, latest.get("version").getAsString(), latest.get("url").getAsString())); - } - return result; - }); - } - private static String getString(JsonObject object, String entry) { if (!object.has(entry)) { return null; @@ -318,9 +264,63 @@ public final class UpdateCheckerImpl { return result; } - public static List fetchUpdatesV2(String url) throws UpdateCheckException { + //region deprecated + @Deprecated + public static CompletableFuture> fetchUpdatesAsync(String url) { + return CompletableFuture.supplyAsync(() -> { + val modList = fetchRootListShared(url); + val result = new ArrayList(); + val installedMods = Loader.instance().getIndexedModList(); + for (val node : modList) { + if (!node.isJsonObject()) { + continue; + } + val obj = node.getAsJsonObject(); + if (!obj.has("modid")) { + continue; + } + if (!obj.has("latestVersion")) { + continue; + } + val modid = obj.get("modid").getAsString(); + if (!installedMods.containsKey(modid)) { + continue; + } + val mod = installedMods.get(modid); + val latestVersionsNode = obj.get("latestVersion"); + List latestVersions; + if (latestVersionsNode.isJsonPrimitive() && (latestVersionsNode.getAsJsonPrimitive().isString())) { + latestVersions = Collections.singletonList(latestVersionsNode.getAsString()); + } else if (latestVersionsNode.isJsonArray()) { + latestVersions = new ArrayList<>(); + for (val version : latestVersionsNode.getAsJsonArray()) { + if (!version.isJsonPrimitive() || !version.getAsJsonPrimitive().isString()) { + continue; + } + latestVersions.add(version.getAsString()); + } + } else { + continue; + } + val currentVersion = mod.getVersion(); + if (latestVersions.contains(currentVersion)) { + continue; + } + val updateURL = obj.has("updateURL") && + obj.get("updateURL").isJsonPrimitive() && + obj.get("updateURL").getAsJsonPrimitive().isString() + ? obj.get("updateURL").getAsString() + : ""; + result.add(new ModUpdateInfo(modid, currentVersion, latestVersions.get(0), updateURL)); + } + return result; + }); + } + + @Deprecated + public static List fetchUpdates(String url) throws UpdateCheckException { try { - return fetchUpdatesAsyncV2(url).join(); + return fetchUpdatesAsync(url).join(); } catch (CompletionException e) { try { throw e.getCause(); @@ -331,4 +331,5 @@ public final class UpdateCheckerImpl { } } } + //endregion } diff --git a/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java b/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java index e51ae9e..063fcf4 100644 --- a/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java +++ b/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java @@ -25,6 +25,9 @@ import lombok.Data; import lombok.NonNull; import org.apache.logging.log4j.Logger; +/** + * Information about a new version of a mod. + */ @Data @StableAPI(since = "0.8.0") public class ModUpdateInfo { diff --git a/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java b/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java index 6027f44..dec96ff 100644 --- a/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java +++ b/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java @@ -22,6 +22,10 @@ package com.falsepattern.lib.updates; import com.falsepattern.lib.StableAPI; +/** + * Exception only thrown by methods of {@link UpdateChecker}. + * Please don't throw this in your own code, only catch/handle it. + */ @StableAPI(since = "0.8.3") public class UpdateCheckException extends Exception { @StableAPI.Internal diff --git a/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java b/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java index 73e20e6..ef08b4e 100644 --- a/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java +++ b/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.updates; +import com.falsepattern.lib.DeprecationDetails; import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.internal.impl.updates.UpdateCheckerImpl; @@ -30,15 +31,6 @@ import java.util.concurrent.CompletableFuture; @StableAPI(since = "0.8.0") public final class UpdateChecker { - /** - * DEPRECATED: Use the V2 API instead. This is kept for backwards compatibility. - */ - @StableAPI.Expose - @Deprecated - public static CompletableFuture> fetchUpdatesAsync(String url) { - return UpdateCheckerImpl.fetchUpdatesAsync(url); - } - /** * Checks for updates. The URL should be a JSON file that contains a list of mods, each with a mod ID, and one or more * versions. The JSON file must have the following format: @@ -95,15 +87,6 @@ public final class UpdateChecker { return UpdateCheckerImpl.fetchUpdatesAsyncV2(url); } - /** - * DEPRECATED: Use the V2 API instead. This is kept for backwards compatibility. - */ - @StableAPI.Expose - @Deprecated - public static List fetchUpdates(String url) throws UpdateCheckException { - return UpdateCheckerImpl.fetchUpdates(url); - } - /** * Same this as {@link #fetchUpdatesAsyncV2(String)}, but returns the result in a blocking fashion. * @@ -130,4 +113,28 @@ public final class UpdateChecker { public static List updateListToChatMessages(String initiator, List updates) { return UpdateCheckerImpl.updateListToChatMessages(initiator, updates); } + + //region deprecated + /** + * DEPRECATED: Use the V2 API instead. This is kept for backwards compatibility. + */ + @Deprecated + @DeprecationDetails(deprecatedSince = "0.11.0", + replacement = "fetchUpdatesV2") + @StableAPI.Expose + public static List fetchUpdates(String url) throws UpdateCheckException { + return UpdateCheckerImpl.fetchUpdates(url); + } + + /** + * DEPRECATED: Use the V2 API instead. This is kept for backwards compatibility. + */ + @StableAPI.Expose + @Deprecated + @DeprecationDetails(deprecatedSince = "0.11.0", + replacement = "fetchUpdatesAsyncV2") + public static CompletableFuture> fetchUpdatesAsync(String url) { + return UpdateCheckerImpl.fetchUpdatesAsync(url); + } + //endregion }