From 0b2b5b063a4b509a1d708fd0872362ff4bd12342 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Sat, 28 Dec 2024 10:05:39 -0600 Subject: [PATCH] Refactored ScenarioType parsing logic Replaced `valueOf` with `parseFromString` in `ScenarioType` to enhance input validation and error handling. Included logging for parsing failures and ensured fallback to `NONE` for invalid inputs. This improves resilience and maintainability of scenario type handling. --- .../src/mekhq/campaign/mission/Scenario.java | 2 +- .../campaign/mission/enums/ScenarioType.java | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index 0fc79061c5..6e3a19ba08 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -1014,7 +1014,7 @@ public static Scenario generateInstanceFromXML(Node wn, Campaign c, Version vers if (wn2.getNodeName().equalsIgnoreCase("name")) { retVal.setName(wn2.getTextContent()); } else if (wn2.getNodeName().equalsIgnoreCase("stratConScenarioType")) { - retVal.setStratConScenarioType(ScenarioType.valueOf(wn2.getTextContent().trim().toUpperCase())); + retVal.setStratConScenarioType(ScenarioType.parseFromString(wn2.getTextContent())); } else if (wn2.getNodeName().equalsIgnoreCase("status")) { retVal.setStatus(ScenarioStatus.parseFromString(wn2.getTextContent().trim())); } else if (wn2.getNodeName().equalsIgnoreCase("id")) { diff --git a/MekHQ/src/mekhq/campaign/mission/enums/ScenarioType.java b/MekHQ/src/mekhq/campaign/mission/enums/ScenarioType.java index 80aa834474..9b0f8ae4b6 100644 --- a/MekHQ/src/mekhq/campaign/mission/enums/ScenarioType.java +++ b/MekHQ/src/mekhq/campaign/mission/enums/ScenarioType.java @@ -18,6 +18,25 @@ */ package mekhq.campaign.mission.enums; +import megamek.logging.MMLogger; + +/** + * Represents the type of scenario within MekHQ. + * + *

This enum defines specific scenario types that can occur in the game. It provides utility + * methods to distinguish between various types and supports parsing from string representations, + * with graceful error handling.

+ * + *

Currently available scenario types:

+ * + * + *

This enum also supports utility methods to determine if a scenario is of a specific + * type, such as {@link #isLosTech()} and {@link #isResupply()}.

+ */ public enum ScenarioType { NONE, SPECIAL_LOSTECH, @@ -36,4 +55,46 @@ public boolean isLosTech() { public boolean isResupply() { return this == SPECIAL_RESUPPLY; } + + /** + * Parses a {@code ScenarioType} from a string input. + * + *

This method attempts to interpret the given string as either:

+ *
    + *
  1. An integer index corresponding to the scenario type values, retrieved using {@link #values()}.
  2. + *
  3. A string matching the name of a specific {@code ScenarioType} constant, case-sensitive.
  4. + *
+ * + *

If parsing fails for both cases, an error is logged and the method returns the default + * {@code NONE} value.

+ * + *

Parsing Strategy:

+ *
    + *
  1. First, it tries to parse the input as an integer and use it as an index for {@link #values()}.
  2. + *
  3. If that fails, it tries to match the input to a constant name using {@link #valueOf(String)}.
  4. + *
  5. If both attempts fail, it logs an error and returns {@code NONE}.
  6. + *
+ * + *

Note: If the input is invalid (e.g., a non-integer string or out-of-bounds index), the error + * is logged via {@link MMLogger} and the fallback {@code NONE} is returned.

+ * + * @param text the string to be parsed into a {@code ScenarioType}, representing either + * an integer index or the enum constant name. + * @return the parsed {@code ScenarioType}, or {@code NONE} if parsing fails. + */ + public static ScenarioType parseFromString(final String text) { + try { + int value = Integer.parseInt(text.trim()); + return values()[value]; + } catch (Exception ignored) {} + + try { + return valueOf(text.trim().toUpperCase()); + } catch (Exception ignored) {} + + MMLogger.create(ScenarioType.class) + .error("Unable to parse " + text + " into an ScenarioType. Returning NONE."); + + return NONE; + } }