From 5ca77713e83638d9dc1aa8df02add57bdaf60bf8 Mon Sep 17 00:00:00 2001 From: Aram Date: Fri, 20 Dec 2024 15:33:43 +0100 Subject: [PATCH] Refactored the Variant Loader to a General Parser (#95) ## Description Refactored the Variant Loader to use a general JSON parser. The parser is now designed to work independently, allowing users to parse and load custom JSON files outside of variants. This improves modularity and reusability across various components. ## Changes - **Change 1**: Extracted the JSON parsing logic into a standalone general parser. - **Change 2**: Updated the Variant Loader to use the general JSON parser for loading variant data. - **Change 3**: Added support for external custom JSONs, allowing users to define and load their own JSON structures. ## Type of Change - [ ] Bug fix - [x] New feature - [x] Cleanup - [ ] Breaking change - [ ] Documentation update ## Checklist - [x] My code follows the style guidelines of this project. [[Contributing](https://github.com/MeAlam1/BlueLib/blob/1.21/CONTRIBUTING.md)](https://github.com/MeAlam1/BlueLib/blob/1.21/CONTRIBUTING.md) - [x] I have performed a self-review of my own code. - [x] I have commented my code following the guidelines. [[Contributing](https://github.com/MeAlam1/BlueLib/blob/1.21/CONTRIBUTING.md)](https://github.com/MeAlam1/BlueLib/blob/1.21/CONTRIBUTING.md) - [x] My changes generate no new warnings. --- .../bluelib/entity/variant/VariantLoader.java | 112 ++++++------ .../software/bluelib/json/JSONParser.java | 173 ++++++++++++++++++ 2 files changed, 229 insertions(+), 56 deletions(-) create mode 100644 common/src/main/java/software/bluelib/json/JSONParser.java diff --git a/common/src/main/java/software/bluelib/entity/variant/VariantLoader.java b/common/src/main/java/software/bluelib/entity/variant/VariantLoader.java index 1c223ae7..c11dde32 100644 --- a/common/src/main/java/software/bluelib/entity/variant/VariantLoader.java +++ b/common/src/main/java/software/bluelib/entity/variant/VariantLoader.java @@ -4,108 +4,108 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import java.util.Collection; import java.util.HashMap; import java.util.Map; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.packs.resources.ResourceManager; -import software.bluelib.interfaces.variant.base.IVariantEntityBase; -import software.bluelib.json.JSONLoader; -import software.bluelib.json.JSONMerger; +import software.bluelib.json.JSONParser; import software.bluelib.utils.logging.BaseLogLevel; import software.bluelib.utils.logging.BaseLogger; import software.bluelib.utils.variant.ParameterUtils; /** - * A {@code public class} that implements the {@link IVariantEntityBase} {@code interface} that manages the loading and storage of entity variants. + * A class for loading and managing entity variants. *

- * The class handles loading and merging of JSON Data by utilizing the {@link JSONLoader} and {@link JSONMerger} classes.
- * To load the Variants it loops through all resources in a folder and merges them into a single {@link JsonObject}.
- * The merged JSON data is then parsed into {} instances and stored in {@link #AllVariants}.
+ * Purpose: This class handles the loading and parsing of entity variants from JSON files.
+ * When: The variants are loaded when the {@link #loadVariants(String, MinecraftServer, String)} method is called.
+ * Where: The variants are stored in a static map and can be accessed globally.
+ * Additional Info: This class extends {@link JSONParser} to utilize its JSON parsing capabilities. *

* Key Methods: * * * @author MeAlam - * @version 1.4.0 + * @version 1.7.0 + * @see JSONParser + * @see ParameterUtils + * @see BaseLogger * @since 1.0.0 */ -public class VariantLoader implements IVariantEntityBase { +public class VariantLoader extends JSONParser { /** - * A {@code public static} {@link Map} that stores all variants of an entity. + * A map to store all loaded variants. *

- * The field is used to store all variants of an entity and is accessed by the {@link ParameterUtils} class. + * Purpose: This map holds all the variants loaded from JSON files, keyed by entity name.
+ * When: Populated when the {@link #loadVariants(String, MinecraftServer, String)} method is called.
+ * Where: Used globally to access the loaded variants.
+ * Additional Info: The map is static to allow global access. *

- *
- * We don't recommend using this field directly unless you know what you are doing. * + * @see #loadVariants(String, MinecraftServer, String) + * @see #parseVariants(String, JsonObject) * @since 1.3.0 */ - public static Map AllVariants = new HashMap<>(); + public static final Map AllVariants = new HashMap<>(); /** - * A {@code private static final} {@link JSONLoader} to load JSON data from resources. - * - * @since 1.0.0 - */ - private static final JSONLoader jsonLoader = new JSONLoader(); - - /** - * A {@code private static final} {@link JSONMerger} to merge JSON data. + * A singleton instance of the VariantLoader. *

- * This {@link JSONMerger} instance is used to merge JSON data into a single {@link JsonObject}. + * Purpose: This instance is used to load and parse JSON data.
+ * When: Initialized when the class is loaded.
+ * Where: Used internally within the class methods.
+ * Additional Info: Ensures only one instance of VariantLoader is used. *

* - * @since 1.0.0 + * @see #loadVariants(String, MinecraftServer, String) + * @since 1.7.0 */ - private static final JSONMerger jsonMerger = new JSONMerger(); + private static final VariantLoader LOADER = new VariantLoader(); /** - * A {@code public static void} that loads and merges variant data from JSON resources in the specified folder path. + * Loads variants from the specified folder path. *

- * The method loops through all resources in the folder and merges them into a single {@link JsonObject}.
- * The merged JSON data is then parsed into {@link JsonObject} instances and stored in {@link #AllVariants}.
+ * Purpose: This method loads JSON data from the specified folder path and parses the variants.
+ * When: Called when variants need to be loaded for a specific entity.
+ * Where: Typically invoked during server initialization or entity configuration.
+ * Additional Info: The loaded variants are stored in the {@link #AllVariants} map. *

* - * @param pFolderPath {@link String} - The path to the folder containing JSON resources. - * @param pServer {@link MinecraftServer} - The {@link MinecraftServer} instance used to access resources. - * @param pEntityName {@link String} - The name of the entity whose variants should be cleared before loading new ones. + * @param pFolderPath The folder path to load JSON data from. + * @param pServer The Minecraft server instance. + * @param pEntityName The name of the entity to load variants for. * @author MeAlam + * @see #AllVariants + * @see #parseVariants(String, JsonObject) + * @see JSONParser#loadData(String, MinecraftServer) + * @see JSONParser#getDataMap() * @since 1.0.0 */ public static void loadVariants(String pFolderPath, MinecraftServer pServer, String pEntityName) { - ResourceManager resourceManager = pServer.getResourceManager(); - JsonObject mergedJsonObject = new JsonObject(); - - Collection collection = resourceManager.listResources(pFolderPath, pFiles -> pFiles.getPath().endsWith(".json")).keySet(); - - BaseLogger.log(BaseLogLevel.INFO, "Found resources: " + collection + " at: " + pFolderPath + " for: " + pEntityName, true); - - for (ResourceLocation resourceLocation : collection) { - try { - BaseLogger.log(BaseLogLevel.INFO, "Loading JSON data from resource: " + resourceLocation.toString(), true); - JsonObject jsonObject = jsonLoader.loadJson(resourceLocation, resourceManager); - jsonMerger.mergeJsonObjects(mergedJsonObject, jsonObject); - } catch (Exception pException) { - BaseLogger.log(BaseLogLevel.ERROR, "Failed to load JSON data from resource: " + resourceLocation.toString(), pException, true); - } - } - parseVariants(pEntityName, mergedJsonObject); + LOADER.loadData(pFolderPath, pServer); + AllVariants.putAll(LOADER.getDataMap()); + parseVariants(pEntityName, LOADER.getMergedJsonObject()); + BaseLogger.log(BaseLogLevel.INFO, "All data of Variants: " + AllVariants, true); } /** - * A {@code private static void} that parses the merged {@link JsonObject} containing variant data. + * Parses the loaded JSON data and stores the variants. *

- * The method parses the merged {@link JsonObject} and stores the data in the {@link #AllVariants} map. - * The map is used to store all variants of an entity. + * Purpose: This method parses the JSON data and stores the variants in the {@link #AllVariants} map.
+ * When: Called internally after loading the JSON data.
+ * Where: Invoked within the {@link #loadVariants(String, MinecraftServer, String)} method.
+ * Additional Info: The parsed variants are logged for debugging purposes. *

* - * @param pJsonObject {@link JsonObject} - The merged {@link JsonObject} containing variant data. + * @param pEntityName The name of the entity to parse variants for. + * @param pJsonObject The JSON object containing the variant data. * @author MeAlam + * @see #AllVariants + * @see #loadVariants(String, MinecraftServer, String) + * @see ParameterUtils#getAllEntities() + * @see ParameterUtils#getVariantsOfEntity(String) * @since 1.0.0 */ private static void parseVariants(String pEntityName, JsonObject pJsonObject) { diff --git a/common/src/main/java/software/bluelib/json/JSONParser.java b/common/src/main/java/software/bluelib/json/JSONParser.java new file mode 100644 index 00000000..963a24e7 --- /dev/null +++ b/common/src/main/java/software/bluelib/json/JSONParser.java @@ -0,0 +1,173 @@ +// Copyright (c) BlueLib. Licensed under the MIT License. + +package software.bluelib.json; + +import com.google.gson.JsonObject; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.packs.resources.ResourceManager; +import software.bluelib.utils.logging.BaseLogLevel; +import software.bluelib.utils.logging.BaseLogger; + +/** + * An abstract class for parsing JSON data. + *

+ * Purpose: This class provides methods to load and merge JSON data from specified folder paths.
+ * When: The JSON data is loaded and merged when the {@link #loadData(String, MinecraftServer)} method is called.
+ * Where: The JSON data is loaded from the specified folder path and merged into a single {@link JsonObject}.
+ * Additional Info: This class uses {@link JSONLoader} to load JSON data and {@link JSONMerger} to merge JSON objects. + *

+ * Key Methods: + *
    + *
  • {@link #loadData(String, MinecraftServer)} - Loads and merges JSON data from the specified folder path.
  • + *
  • {@link #getDataMap()} - Returns the data map containing JSON data.
  • + *
  • {@link #getMergedJsonObject()} - Returns the merged JSON object.
  • + *
+ * + * @see JSONLoader + * @see JSONMerger + * @see MinecraftServer + * @see JsonObject + * @see ResourceManager + * @see ResourceLocation + * @see Collection + * @since 1.7.0 + * @version 1.7.0 + * @author MeAlam + */ +public abstract class JSONParser { + + /** + * A map to store JSON data with their corresponding keys. + *

+ * Purpose: This map holds the JSON data loaded from the specified folder path.
+ * When: The map is populated when the {@link #loadData(String, MinecraftServer)} method is called.
+ * Where: The map is used to store JSON data with their corresponding keys.
+ * Additional Info: The keys are the resource locations of the JSON files. + *

+ * + * @since 1.7.0 + */ + protected Map dataMap = new HashMap<>(); + + /** + * A static instance of JSONLoader to load JSON data. + *

+ * Purpose: This instance is used to load JSON data from the specified folder path.
+ * When: The instance is used when the {@link #loadData(String, MinecraftServer)} method is called.
+ * Where: The instance is used to load JSON data from the specified folder path.
+ * Additional Info: The JSONLoader class provides methods to load JSON data from resource locations. + *

+ * + * @see JSONLoader + * @since 1.7.0 + */ + protected static final JSONLoader jsonLoader = new JSONLoader(); + + /** + * A static instance of JSONMerger to merge JSON objects. + *

+ * Purpose: This instance is used to merge JSON objects loaded from the specified folder path.
+ * When: The instance is used when the {@link #loadData(String, MinecraftServer)} method is called.
+ * Where: The instance is used to merge JSON objects loaded from the specified folder path.
+ * Additional Info: The JSONMerger class provides methods to merge JSON objects. + *

+ * + * @see JSONMerger + * @since 1.7.0 + */ + protected static final JSONMerger jsonMerger = new JSONMerger(); + + /** + * A JsonObject to store the merged JSON data. + *

+ * Purpose: This object holds the merged JSON data from the specified folder path.
+ * When: The object is populated when the {@link #loadData(String, MinecraftServer)} method is called.
+ * Where: The object is used to store the merged JSON data.
+ * Additional Info: The merged JSON data is a combination of all JSON files loaded from the specified folder path. + *

+ * + * @since 1.7.0 + */ + protected JsonObject mergedJsonObject; + + /** + * Loads JSON data from the specified folder path and merges them. + *

+ * Purpose: This method loads JSON data from the specified folder path and merges them into a single {@link JsonObject}.
+ * When: The method is called to load and merge JSON data.
+ * Where: The method is called whenever JSON data needs to be loaded and merged.
+ * Additional Info: The method uses {@link JSONLoader} to load JSON data and {@link JSONMerger} to merge JSON objects. + *

+ * + * @param pFolderPath The folder path to load JSON data from. + * @param pServer The Minecraft server instance. + * @since 1.7.0 + * @author MeAlam + * @see JSONLoader + * @see JSONMerger + * @see MinecraftServer + * @see JsonObject + * @see ResourceManager + * @see ResourceLocation + * @see Collection + */ + public void loadData(String pFolderPath, MinecraftServer pServer) { + ResourceManager resourceManager = pServer.getResourceManager(); + mergedJsonObject = new JsonObject(); + + Collection resources = resourceManager.listResources(pFolderPath, path -> path.getPath().endsWith(".json")).keySet(); + + BaseLogger.log(BaseLogLevel.INFO, "Found resources: " + resources + " at: " + pFolderPath, true); + + for (ResourceLocation resourceLocation : resources) { + try { + BaseLogger.log(BaseLogLevel.INFO, "Loading JSON data from resource: " + resourceLocation, true); + JsonObject jsonObject = jsonLoader.loadJson(resourceLocation, resourceManager); + jsonMerger.mergeJsonObjects(mergedJsonObject, jsonObject); + } catch (Exception exception) { + BaseLogger.log(BaseLogLevel.ERROR, "Failed to load JSON data from resource: " + resourceLocation, exception, true); + } + } + } + + /** + * Returns the data map containing JSON data. + *

+ * Purpose: This method returns the data map containing JSON data loaded from the specified folder path.
+ * When: The method is called to retrieve the data map.
+ * Where: The method is called from any class or method.
+ * Additional Info: The data map contains JSON data with their corresponding keys. + *

+ * + * @return The data map. + * @since 1.7.0 + * @author MeAlam + * @see JsonObject + * @see Map + */ + public Map getDataMap() { + return dataMap; + } + + /** + * Returns the merged JSON object. + *

+ * Purpose: This method returns the merged JSON object containing data from all JSON files loaded from the specified folder path.
+ * When: The method is called to retrieve the merged JSON object.
+ * Where: The method is called from any class or method.
+ * Additional Info: The merged JSON object is a combination of all JSON files loaded from the specified folder path. + *

+ * + * @return The merged JSON object. + * @since 1.7.0 + * @author MeAlam + * @see JsonObject + */ + public JsonObject getMergedJsonObject() { + return mergedJsonObject; + } +}