优化 JsonUtils (#4161)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Glavo 2025-07-31 20:41:27 +08:00 committed by GitHub
parent d5fa232704
commit 3eddfa23b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 83 additions and 73 deletions

View File

@ -158,6 +158,8 @@ public class HMCLGameRepository extends DefaultGameRepository {
blackList.add("saves");
if (Files.exists(dstDir)) throw new IOException("Version exists");
Files.createDirectories(dstDir);
FileUtils.copyDirectory(srcDir, dstDir, path -> Modpack.acceptFile(path, blackList, null));
Path fromJson = srcDir.resolve(srcId + ".json");
@ -170,7 +172,7 @@ public class HMCLGameRepository extends DefaultGameRepository {
}
Files.copy(fromJson, toJson);
FileUtils.writeText(toJson, JsonUtils.GSON.toJson(fromVersion.setId(dstId)));
JsonUtils.writeToJsonFile(toJson, fromVersion.setId(dstId));
VersionSetting oldVersionSetting = getVersionSetting(srcId).clone();
GameDirectoryType originalGameDirType = oldVersionSetting.getGameDirType();

View File

@ -31,7 +31,6 @@ import org.jackhuang.hmcl.util.io.CompressingUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -66,7 +65,7 @@ public final class HMCLModpackInstallTask extends Task<Void> {
ModpackConfiguration<Modpack> config = null;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(Modpack.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(Modpack.class));
if (!HMCLModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a HMCL modpack. Cannot update this version.");

View File

@ -140,7 +140,7 @@ public final class ModpackHelper {
throw new FileNotFoundException(file.getPath());
else
try {
return JsonUtils.GSON.fromJson(Files.readString(file.toPath()), ModpackConfiguration.class);
return JsonUtils.fromJsonFile(file.toPath(), ModpackConfiguration.class);
} catch (JsonParseException e) {
throw new IOException("Malformed modpack configuration");
}

View File

@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.platform.Platform;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
import java.util.*;
@ -116,11 +115,7 @@ public final class HMCLJavaRepository implements JavaRepository {
}
if (Files.isDirectory(javaDir)) {
JavaManifest manifest;
try (InputStream input = Files.newInputStream(file)) {
manifest = JsonUtils.fromJsonFully(input, JavaManifest.class);
}
JavaManifest manifest = JsonUtils.fromJsonFile(file, JavaManifest.class);
list.add(JavaRuntime.of(executable, manifest.getInfo(), isManaged));
}
}
@ -191,7 +186,7 @@ public final class HMCLJavaRepository implements JavaRepository {
});
JavaManifest manifest = new JavaManifest(info, update, files);
FileUtils.writeText(getManifestFile(platform, gameJavaVersion), JsonUtils.GSON.toJson(manifest));
JsonUtils.writeToJsonFile(getManifestFile(platform, gameJavaVersion), manifest);
return JavaRuntime.of(executable, info, true);
});
}
@ -203,7 +198,7 @@ public final class HMCLJavaRepository implements JavaRepository {
throw new IOException("Platform is mismatch: expected " + platform + " but got " + result.getInfo().getPlatform());
Path executable = javaDir.resolve("bin").resolve(platform.getOperatingSystem().getJavaExecutable()).toRealPath();
FileUtils.writeText(getManifestFile(platform, name), JsonUtils.GSON.toJson(result));
JsonUtils.writeToJsonFile(getManifestFile(platform, name), result);
return JavaRuntime.of(executable, result.getInfo(), true);
});
}

View File

@ -72,8 +72,7 @@ public final class AuthlibInjectorServers implements Validation {
if (ConfigHolder.isNewlyCreated() && Files.exists(configLocation)) {
AuthlibInjectorServers configInstance;
try {
String content = Files.readString(configLocation);
configInstance = JsonUtils.GSON.fromJson(content, AuthlibInjectorServers.class);
configInstance = JsonUtils.fromJsonFile(configLocation, AuthlibInjectorServers.class);
} catch (IOException | JsonParseException e) {
LOG.warning("Malformed authlib-injectors.json", e);
return;

View File

@ -34,9 +34,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
@ -117,8 +114,8 @@ public final class AboutPage extends StackPane {
return componentList;
}
try (Reader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) {
JsonArray array = JsonUtils.GSON.fromJson(reader, JsonArray.class);
try {
JsonArray array = JsonUtils.fromJsonFully(input, JsonArray.class);
for (JsonElement element : array) {
JsonObject obj = element.getAsJsonObject();

View File

@ -200,7 +200,8 @@ public class DefaultCacheRepository extends CacheRepository {
private void saveIndex() {
if (indexFile == null || index == null) return;
try {
FileUtils.writeText(indexFile, JsonUtils.GSON.toJson(index));
Files.createDirectories(indexFile.getParent());
JsonUtils.writeToJsonFile(indexFile, index);
} catch (IOException e) {
LOG.error("Unable to save index.json", e);
}

View File

@ -21,9 +21,9 @@ import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* This task is to save the version json.
@ -51,7 +51,8 @@ public final class VersionJsonSaveTask extends Task<Version> {
@Override
public void execute() throws Exception {
File json = repository.getVersionJson(version.getId()).getAbsoluteFile();
FileUtils.writeText(json, JsonUtils.GSON.toJson(version));
Path json = repository.getVersionJson(version.getId()).toPath().toAbsolutePath();
Files.createDirectories(json.getParent());
JsonUtils.writeToJsonFile(json, version);
}
}

View File

@ -219,8 +219,9 @@ public class DefaultGameRepository implements GameRepository {
// fix inheritsFrom of versions that inherits from version [from].
for (Version version : getVersions()) {
if (from.equals(version.getInheritsFrom())) {
File json = getVersionJson(version.getId()).getAbsoluteFile();
FileUtils.writeText(json, JsonUtils.GSON.toJson(version.setInheritsFrom(to)));
Path targetPath = getVersionJson(version.getId()).toPath();
Files.createDirectories(targetPath.getParent());
JsonUtils.writeToJsonFile(targetPath, version.setInheritsFrom(to));
}
}
return true;
@ -384,7 +385,7 @@ public class DefaultGameRepository implements GameRepository {
@Override
public AssetIndex getAssetIndex(String version, String assetId) throws IOException {
try {
return Objects.requireNonNull(JsonUtils.GSON.fromJson(Files.readString(getIndexFile(version, assetId)), AssetIndex.class));
return Objects.requireNonNull(JsonUtils.fromJsonFile(getIndexFile(version, assetId), AssetIndex.class));
} catch (JsonParseException | NullPointerException e) {
throw new IOException("Asset index file malformed", e);
}
@ -445,8 +446,7 @@ public class DefaultGameRepository implements GameRepository {
if (!Files.isRegularFile(indexFile))
return assetsDir;
String assetIndexContent = Files.readString(indexFile);
AssetIndex index = JsonUtils.GSON.fromJson(assetIndexContent, AssetIndex.class);
AssetIndex index = JsonUtils.fromJsonFile(indexFile, AssetIndex.class);
if (index == null)
return assetsDir;
@ -455,7 +455,7 @@ public class DefaultGameRepository implements GameRepository {
Path resourcesDir = getRunDirectory(version).toPath().resolve("resources");
int cnt = 0;
int tot = index.getObjects().entrySet().size();
int tot = index.getObjects().size();
for (Map.Entry<String, AssetObject> entry : index.getObjects().entrySet()) {
Path target = virtualRoot.resolve(entry.getKey());
Path original = getAssetObject(version, assetsDir, entry.getValue());
@ -512,7 +512,7 @@ public class DefaultGameRepository implements GameRepository {
if (!hasVersion(version)) throw new VersionNotFoundException(version);
File file = getModpackConfiguration(version);
if (!file.exists()) return null;
return JsonUtils.GSON.fromJson(Files.readString(file.toPath()), ModpackConfiguration.class);
return JsonUtils.fromJsonFile(file.toPath(), ModpackConfiguration.class);
}
public boolean isModpack(String version) {

View File

@ -75,7 +75,9 @@ public final class MinecraftInstanceTask<T> extends Task<ModpackConfiguration<T>
}
ModpackConfiguration<T> configuration = new ModpackConfiguration<>(manifest, type, name, version, overrides);
FileUtils.writeText(jsonFile, JsonUtils.GSON.toJson(configuration));
Path jsonPath = jsonFile.toPath();
Files.createDirectories(jsonPath.getParent());
JsonUtils.writeToJsonFile(jsonPath, configuration);
setResult(configuration);
}
}

View File

@ -27,12 +27,10 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@ -88,7 +86,7 @@ public final class CurseCompletionTask extends Task<Void> {
try {
File manifestFile = new File(repository.getVersionRoot(version), "manifest.json");
if (manifestFile.exists())
this.manifest = JsonUtils.GSON.fromJson(Files.readString(manifestFile.toPath()), CurseManifest.class);
this.manifest = JsonUtils.fromJsonFile(manifestFile.toPath(), CurseManifest.class);
} catch (Exception e) {
LOG.warning("Unable to read CurseForge modpack manifest.json", e);
}
@ -137,7 +135,7 @@ public final class CurseCompletionTask extends Task<Void> {
}
})
.collect(Collectors.toList()));
FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(newManifest));
JsonUtils.writeToJsonFile(root.toPath().resolve("manifest.json"), newManifest);
File versionRoot = repository.getVersionRoot(modManager.getVersion());
File resourcePacksRoot = new File(versionRoot, "resourcepacks"), shaderPacksRoot = new File(versionRoot, "shaderpacks");

View File

@ -25,11 +25,11 @@ import org.jackhuang.hmcl.mod.*;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -60,7 +60,6 @@ public final class CurseInstallTask extends Task<Void> {
* @param zipFile the CurseForge modpack file.
* @param manifest The manifest content of given CurseForge modpack.
* @param name the new version name
* @see CurseManifest#readCurseForgeModpackManifest
*/
public CurseInstallTask(DefaultDependencyManager dependencyManager, File zipFile, Modpack modpack, CurseManifest manifest, String name) {
this.dependencyManager = dependencyManager;
@ -99,7 +98,7 @@ public final class CurseInstallTask extends Task<Void> {
ModpackConfiguration<CurseManifest> config = null;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(CurseManifest.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(CurseManifest.class));
if (!CurseModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a Curse modpack. Cannot update this version.");
@ -137,7 +136,8 @@ public final class CurseInstallTask extends Task<Void> {
}
}
File root = repository.getVersionRoot(name);
FileUtils.writeText(new File(root, "manifest.json"), JsonUtils.GSON.toJson(manifest));
Path root = repository.getVersionRoot(name).toPath();
Files.createDirectories(root);
JsonUtils.writeToJsonFile(root.resolve("manifest.json"), manifest);
}
}

View File

@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.*;
import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -113,6 +112,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
}
Path rootPath = repository.getVersionRoot(version).toPath();
Files.createDirectories(rootPath);
Map<McbbsModpackManifest.File, McbbsModpackManifest.File> localFiles = manifest.getFiles().stream().collect(Collectors.toMap(Function.identity(), Function.identity()));
@ -173,15 +173,15 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
manifest = remoteManifest.setFiles(newFiles);
return executor.all(tasks.stream().filter(Objects::nonNull).collect(Collectors.toList()));
})).thenAcceptAsync(wrapConsumer(unused1 -> {
File manifestFile = repository.getModpackConfiguration(version);
FileUtils.writeText(manifestFile, JsonUtils.GSON.toJson(
Path manifestFile = repository.getModpackConfiguration(version).toPath();
JsonUtils.writeToJsonFile(manifestFile,
new ModpackConfiguration<>(manifest, this.configuration.getType(), this.manifest.getName(), this.manifest.getVersion(),
this.manifest.getFiles().stream()
.flatMap(file -> file instanceof McbbsModpackManifest.AddonFile
? Stream.of((McbbsModpackManifest.AddonFile) file)
: Stream.empty())
.map(file -> new ModpackConfiguration.FileInformation(file.getPath(), file.getHash()))
.collect(Collectors.toList()))));
.collect(Collectors.toList())));
})));
}).thenComposeAsync(unused -> {
AtomicBoolean allNameKnown = new AtomicBoolean(true);
@ -240,7 +240,7 @@ public class McbbsModpackCompletionTask extends CompletableFutureTask<Void> {
manifest = newManifest;
configuration = configuration.setManifest(newManifest);
FileUtils.writeText(configurationFile, JsonUtils.GSON.toJson(configuration));
JsonUtils.writeToJsonFile(configurationFile.toPath(), configuration);
for (McbbsModpackManifest.File file : newManifest.getFiles())
if (file instanceof McbbsModpackManifest.CurseFile) {

View File

@ -31,7 +31,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -79,7 +78,7 @@ public class McbbsModpackLocalInstallTask extends Task<Void> {
ModpackConfiguration<McbbsModpackManifest> config = null;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(McbbsModpackManifest.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(McbbsModpackManifest.class));
if (!McbbsModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a Mcbbs modpack. Cannot update this version.");

View File

@ -27,7 +27,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -62,10 +61,10 @@ public class McbbsModpackRemoteInstallTask extends Task<Void> {
repository.removeVersionFromDisk(name);
});
ModpackConfiguration<McbbsModpackManifest> config = null;
ModpackConfiguration<McbbsModpackManifest> config;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(McbbsModpackManifest.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(McbbsModpackManifest.class));
if (!MODPACK_TYPE.equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a Mcbbs modpack. Cannot update this version.");

View File

@ -125,7 +125,7 @@ public final class ForgeOldModMetadata {
Path mcmod = fs.getPath("mcmod.info");
if (Files.notExists(mcmod))
throw new IOException("File " + modFile + " is not a Forge mod.");
List<ForgeOldModMetadata> modList = JsonUtils.GSON.fromJson(Files.readString(mcmod), listTypeOf(ForgeOldModMetadata.class));
List<ForgeOldModMetadata> modList = JsonUtils.fromJsonFile(mcmod, listTypeOf(ForgeOldModMetadata.class));
if (modList == null || modList.isEmpty())
throw new IOException("Mod " + modFile + " `mcmod.info` is malformed..");
ForgeOldModMetadata metadata = modList.get(0);

View File

@ -26,7 +26,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
@ -78,9 +77,9 @@ public class ModrinthCompletionTask extends Task<Void> {
if (manifest == null)
try {
File manifestFile = new File(repository.getVersionRoot(version), "modrinth.index.json");
if (manifestFile.exists())
this.manifest = JsonUtils.GSON.fromJson(Files.readString(manifestFile.toPath()), ModrinthManifest.class);
Path manifestFile = repository.getVersionRoot(version).toPath().resolve("modrinth.index.json");
if (Files.exists(manifestFile))
this.manifest = JsonUtils.fromJsonFile(manifestFile, ModrinthManifest.class);
} catch (Exception e) {
LOG.warning("Unable to read Modrinth modpack manifest.json", e);
}

View File

@ -24,7 +24,6 @@ import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.mod.*;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.IOException;
@ -93,7 +92,7 @@ public class ModrinthInstallTask extends Task<Void> {
ModpackConfiguration<ModrinthManifest> config = null;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(ModrinthManifest.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(ModrinthManifest.class));
if (!ModrinthModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a Modrinth modpack. Cannot update this version.");
@ -132,7 +131,8 @@ public class ModrinthInstallTask extends Task<Void> {
}
}
File root = repository.getVersionRoot(name);
FileUtils.writeText(new File(root, "modrinth.index.json"), JsonUtils.GSON.toJson(manifest));
Path root = repository.getVersionRoot(name).toPath();
Files.createDirectories(root);
JsonUtils.writeToJsonFile(root.resolve("modrinth.index.json"), manifest);
}
}

View File

@ -110,7 +110,7 @@ public final class MultiMCModpackInstallTask extends Task<MultiMCInstancePatch.R
ModpackConfiguration<MultiMCInstanceConfiguration> config = null;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(MultiMCInstanceConfiguration.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(MultiMCInstanceConfiguration.class));
if (!MultiMCModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a MultiMC modpack. Cannot update this version.");

View File

@ -28,7 +28,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.DigestUtils;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import java.io.File;
@ -65,7 +64,7 @@ public class ServerModpackCompletionTask extends Task<Void> {
try {
File manifestFile = repository.getModpackConfiguration(version);
if (manifestFile.exists()) {
this.manifest = JsonUtils.GSON.fromJson(Files.readString(manifestFile.toPath()), ModpackConfiguration.typeOf(ServerModpackManifest.class));
this.manifest = JsonUtils.fromJsonFile(manifestFile.toPath(), ModpackConfiguration.typeOf(ServerModpackManifest.class));
}
} catch (Exception e) {
LOG.warning("Unable to read Server modpack manifest.json", e);
@ -179,7 +178,8 @@ public class ServerModpackCompletionTask extends Task<Void> {
@Override
public void postExecute() throws Exception {
if (manifest == null || StringUtils.isBlank(manifest.getManifest().getFileApi())) return;
File manifestFile = repository.getModpackConfiguration(version);
FileUtils.writeText(manifestFile, JsonUtils.GSON.toJson(new ModpackConfiguration<>(remoteManifest, this.manifest.getType(), this.manifest.getName(), this.manifest.getVersion(), remoteManifest.getFiles())));
Path manifestFile = repository.getModpackConfiguration(version).toPath();
Files.createDirectories(manifestFile.getParent());
JsonUtils.writeToJsonFile(manifestFile, new ModpackConfiguration<>(remoteManifest, this.manifest.getType(), this.manifest.getName(), this.manifest.getVersion(), remoteManifest.getFiles()));
}
}

View File

@ -30,7 +30,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -71,7 +70,7 @@ public class ServerModpackLocalInstallTask extends Task<Void> {
ModpackConfiguration<ServerModpackManifest> config = null;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(ServerModpackManifest.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(ServerModpackManifest.class));
if (!ServerModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a Server modpack. Cannot update this version.");

View File

@ -27,7 +27,6 @@ import org.jackhuang.hmcl.util.gson.JsonUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -65,7 +64,7 @@ public class ServerModpackRemoteInstallTask extends Task<Void> {
ModpackConfiguration<ServerModpackManifest> config;
try {
if (json.exists()) {
config = JsonUtils.GSON.fromJson(Files.readString(json.toPath()), ModpackConfiguration.typeOf(ServerModpackManifest.class));
config = JsonUtils.fromJsonFile(json.toPath(), ModpackConfiguration.typeOf(ServerModpackManifest.class));
if (!MODPACK_TYPE.equals(config.getType()))
throw new IllegalArgumentException("Version " + name + " is not a Server modpack. Cannot update this version.");

View File

@ -20,6 +20,7 @@ package org.jackhuang.hmcl.util;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;
import org.jackhuang.hmcl.util.function.ExceptionalSupplier;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.FileNotFoundException;
@ -44,7 +45,9 @@ import java.util.function.BiFunction;
import java.util.stream.Stream;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.jackhuang.hmcl.util.gson.JsonUtils.*;
import static org.jackhuang.hmcl.util.gson.JsonUtils.fromMaybeMalformedJson;
import static org.jackhuang.hmcl.util.gson.JsonUtils.fromNonNullJson;
import static org.jackhuang.hmcl.util.gson.JsonUtils.mapTypeOf;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class CacheRepository {
@ -67,7 +70,7 @@ public class CacheRepository {
}
if (Files.isRegularFile(indexFile)) {
ETagIndex raw = GSON.fromJson(Files.readString(indexFile), ETagIndex.class);
ETagIndex raw = JsonUtils.fromJsonFile(indexFile, ETagIndex.class);
if (raw == null)
index = new HashMap<>();
else
@ -289,7 +292,7 @@ public class CacheRepository {
ETagIndex indexOnDisk = fromMaybeMalformedJson(new String(Channels.newInputStream(channel).readAllBytes(), UTF_8), ETagIndex.class);
Map<String, ETagItem> newIndex = joinETagIndexes(indexOnDisk == null ? null : indexOnDisk.eTag, index.values());
channel.truncate(0);
ByteBuffer writeTo = ByteBuffer.wrap(GSON.toJson(new ETagIndex(newIndex.values())).getBytes(UTF_8));
ByteBuffer writeTo = ByteBuffer.wrap(JsonUtils.GSON.toJson(new ETagIndex(newIndex.values())).getBytes(UTF_8));
while (writeTo.hasRemaining()) {
if (channel.write(writeTo) == 0) {
throw new IOException("No value is written");
@ -427,7 +430,7 @@ public class CacheRepository {
indexOnDisk.putAll(storage);
channel.truncate(0);
ByteBuffer writeTo = ByteBuffer.wrap(GSON.toJson(storage).getBytes(UTF_8));
ByteBuffer writeTo = ByteBuffer.wrap(JsonUtils.GSON.toJson(storage).getBytes(UTF_8));
while (writeTo.hasRemaining()) {
if (channel.write(writeTo) == 0) {
throw new IOException("No value is written");

View File

@ -28,6 +28,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
import java.util.Map;
@ -66,6 +68,16 @@ public final class JsonUtils {
return (TypeToken<Map<K, V>>) TypeToken.getParameterized(Map.class, keyType, valueType.getType());
}
public static <T> T fromJsonFile(Path file, Class<T> classOfT) throws IOException {
return fromJsonFile(file, TypeToken.get(classOfT));
}
public static <T> T fromJsonFile(Path file, TypeToken<T> type) throws IOException {
try (var reader = Files.newBufferedReader(file)) {
return GSON.fromJson(reader, type.getType());
}
}
public static <T> T fromJsonFully(InputStream json, Class<T> classOfT) throws IOException, JsonParseException {
try (InputStreamReader reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
return GSON.fromJson(reader, classOfT);
@ -126,6 +138,12 @@ public final class JsonUtils {
}
}
public static void writeToJsonFile(Path file, Object value) throws IOException {
try (var writer = Files.newBufferedWriter(file)) {
GSON.toJson(value, writer);
}
}
public static GsonBuilder defaultGsonBuilder() {
return new GsonBuilder()
.enableComplexMapKeySerialization()