Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored the Variant Loader to a General Parser #95

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* The class handles loading and merging of JSON Data by utilizing the {@link JSONLoader} and {@link JSONMerger} classes. <br>
* To load the Variants it loops through all resources in a folder and merges them into a single {@link JsonObject}. <br>
* The merged JSON data is then parsed into {} instances and stored in {@link #AllVariants}. <br>
* Purpose: This class handles the loading and parsing of entity variants from JSON files.<br>
* When: The variants are loaded when the {@link #loadVariants(String, MinecraftServer, String)} method is called.<br>
* Where: The variants are stored in a static map and can be accessed globally.<br>
* Additional Info: This class extends {@link JSONParser} to utilize its JSON parsing capabilities.
* </p>
* Key Methods:
* <ul>
* <li>{@link #loadVariants(String, MinecraftServer, String)} - Loads and merges variant data by looping thru all resources in a folder.</li>
* <li>{@link #loadVariants(String, MinecraftServer, String)} - Loads variants from a specified folder path.</li>
* <li>{@link #parseVariants(String, JsonObject)} - Parses the loaded JSON data and stores the variants.</li>
* </ul>
*
* @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.
* <p>
* 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.<br>
* When: Populated when the {@link #loadVariants(String, MinecraftServer, String)} method is called.<br>
* Where: Used globally to access the loaded variants.<br>
* Additional Info: The map is static to allow global access.
* </p>
* <br>
* <strong>We don't recommend using this field directly unless you know what you are doing.</strong>
*
* @see #loadVariants(String, MinecraftServer, String)
* @see #parseVariants(String, JsonObject)
* @since 1.3.0
*/
public static Map<String, JsonObject> AllVariants = new HashMap<>();
public static final Map<String, JsonObject> 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.
* <p>
* 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.<br>
* When: Initialized when the class is loaded.<br>
* Where: Used internally within the class methods.<br>
* Additional Info: Ensures only one instance of VariantLoader is used.
* </p>
*
* @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.
* <p>
* The method loops through all resources in the folder and merges them into a single {@link JsonObject}. <br>
* The merged JSON data is then parsed into {@link JsonObject} instances and stored in {@link #AllVariants}. <br>
* Purpose: This method loads JSON data from the specified folder path and parses the variants.<br>
* When: Called when variants need to be loaded for a specific entity.<br>
* Where: Typically invoked during server initialization or entity configuration.<br>
* Additional Info: The loaded variants are stored in the {@link #AllVariants} map.
* </p>
*
* @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<ResourceLocation> 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.
* <p>
* 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.<br>
* When: Called internally after loading the JSON data.<br>
* Where: Invoked within the {@link #loadVariants(String, MinecraftServer, String)} method.<br>
* Additional Info: The parsed variants are logged for debugging purposes.
* </p>
*
* @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) {
Expand Down
173 changes: 173 additions & 0 deletions common/src/main/java/software/bluelib/json/JSONParser.java
Original file line number Diff line number Diff line change
@@ -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.
* <p>
* Purpose: This class provides methods to load and merge JSON data from specified folder paths.<br>
* When: The JSON data is loaded and merged when the {@link #loadData(String, MinecraftServer)} method is called.<br>
* Where: The JSON data is loaded from the specified folder path and merged into a single {@link JsonObject}.<br>
* Additional Info: This class uses {@link JSONLoader} to load JSON data and {@link JSONMerger} to merge JSON objects.
* </p>
* Key Methods:
* <ul>
* <li>{@link #loadData(String, MinecraftServer)} - Loads and merges JSON data from the specified folder path.</li>
* <li>{@link #getDataMap()} - Returns the data map containing JSON data.</li>
* <li>{@link #getMergedJsonObject()} - Returns the merged JSON object.</li>
* </ul>
*
* @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.
* <p>
* Purpose: This map holds the JSON data loaded from the specified folder path.<br>
* When: The map is populated when the {@link #loadData(String, MinecraftServer)} method is called.<br>
* Where: The map is used to store JSON data with their corresponding keys.<br>
* Additional Info: The keys are the resource locations of the JSON files.
* </p>
*
* @since 1.7.0
*/
protected Map<String, JsonObject> dataMap = new HashMap<>();

/**
* A static instance of JSONLoader to load JSON data.
* <p>
* Purpose: This instance is used to load JSON data from the specified folder path.<br>
* When: The instance is used when the {@link #loadData(String, MinecraftServer)} method is called.<br>
* Where: The instance is used to load JSON data from the specified folder path.<br>
* Additional Info: The JSONLoader class provides methods to load JSON data from resource locations.
* </p>
*
* @see JSONLoader
* @since 1.7.0
*/
protected static final JSONLoader jsonLoader = new JSONLoader();

/**
* A static instance of JSONMerger to merge JSON objects.
* <p>
* Purpose: This instance is used to merge JSON objects loaded from the specified folder path.<br>
* When: The instance is used when the {@link #loadData(String, MinecraftServer)} method is called.<br>
* Where: The instance is used to merge JSON objects loaded from the specified folder path.<br>
* Additional Info: The JSONMerger class provides methods to merge JSON objects.
* </p>
*
* @see JSONMerger
* @since 1.7.0
*/
protected static final JSONMerger jsonMerger = new JSONMerger();

/**
* A JsonObject to store the merged JSON data.
* <p>
* Purpose: This object holds the merged JSON data from the specified folder path.<br>
* When: The object is populated when the {@link #loadData(String, MinecraftServer)} method is called.<br>
* Where: The object is used to store the merged JSON data.<br>
* Additional Info: The merged JSON data is a combination of all JSON files loaded from the specified folder path.
* </p>
*
* @since 1.7.0
*/
protected JsonObject mergedJsonObject;

/**
* Loads JSON data from the specified folder path and merges them.
* <p>
* Purpose: This method loads JSON data from the specified folder path and merges them into a single {@link JsonObject}.<br>
* When: The method is called to load and merge JSON data.<br>
* Where: The method is called whenever JSON data needs to be loaded and merged.<br>
* Additional Info: The method uses {@link JSONLoader} to load JSON data and {@link JSONMerger} to merge JSON objects.
* </p>
*
* @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<ResourceLocation> 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.
* <p>
* Purpose: This method returns the data map containing JSON data loaded from the specified folder path.<br>
* When: The method is called to retrieve the data map.<br>
* Where: The method is called from any class or method.<br>
* Additional Info: The data map contains JSON data with their corresponding keys.
* </p>
*
* @return The data map.
* @since 1.7.0
* @author MeAlam
* @see JsonObject
* @see Map
*/
public Map<String, JsonObject> getDataMap() {
return dataMap;
}

/**
* Returns the merged JSON object.
* <p>
* Purpose: This method returns the merged JSON object containing data from all JSON files loaded from the specified folder path.<br>
* When: The method is called to retrieve the merged JSON object.<br>
* Where: The method is called from any class or method.<br>
* Additional Info: The merged JSON object is a combination of all JSON files loaded from the specified folder path.
* </p>
*
* @return The merged JSON object.
* @since 1.7.0
* @author MeAlam
* @see JsonObject
*/
public JsonObject getMergedJsonObject() {
return mergedJsonObject;
}
}
Loading