11package me .andreasmelone .basicmodinfoparser ;
22
3- import com .google .gson .Gson ;
4- import com .google .gson .JsonArray ;
5- import com .google .gson .JsonObject ;
6- import com .google .gson .JsonSyntaxException ;
7- import org .tomlj .Toml ;
8- import org .tomlj .TomlParseResult ;
9- import org .tomlj .TomlTable ;
3+ import com .google .gson .*;
4+ import me .andreasmelone .basicmodinfoparser .util .ModInfoParseException ;
5+ import me .andreasmelone .basicmodinfoparser .util .ParserUtils ;
6+ import org .tomlj .*;
107
118import java .io .File ;
129import java .io .FileInputStream ;
1310import java .io .IOException ;
1411import java .io .InputStream ;
15- import java .nio .file .Path ;
16- import java .nio .file .Paths ;
1712import java .util .ArrayList ;
1813import java .util .List ;
1914import java .util .jar .JarFile ;
2217import java .util .zip .ZipFile ;
2318import java .util .zip .ZipInputStream ;
2419
20+ import static me .andreasmelone .basicmodinfoparser .util .ParserUtils .*;
21+
2522public enum Platform {
2623 /**
2724 * Legacy Forge platform, which uses the {@code mcmod.info} file containing JSON data.
2825 */
2926 FORGE_LEGACY ((str ) -> {
3027 Gson gson = new Gson ();
31- JsonObject jsonObj = gson .fromJson (str , JsonArray .class ).get (0 ).getAsJsonObject ();
32- String modId = jsonObj .get ("modid" ).getAsString ();
33- String name = jsonObj .get ("name" ).getAsString ();
34- String description = jsonObj .get ("description" ).getAsString ();
35- String version = jsonObj .get ("version" ).getAsString ();
36-
37- return new BasicModInfo (modId , name , version , description );
28+ JsonArray topArray = gson .fromJson (str , JsonArray .class );
29+ if (topArray == null || topArray .size () == 0 || !topArray .get (0 ).isJsonObject ()) {
30+ return BasicModInfo .empty ();
31+ }
32+ return ParserUtils .createModInfoFromJsonObject (topArray .get (0 ).getAsJsonObject (),
33+ "modid" , "name" , "version" , "description" );
3834 }, "mcmod.info" ),
3935 /**
4036 * Forge platform, which uses the {@code mods.toml} file with TOML data.
4137 * It can also be used to parse NeoForge mods.
4238 */
43-
4439 FORGE ((str ) -> {
4540 TomlParseResult result = Toml .parse (str );
46- TomlTable modInfo = result .getArray ("mods" ).getTable (0 );
41+ TomlArray modsArray = result .getArray ("mods" );
42+ if (modsArray == null || modsArray .isEmpty ()) return BasicModInfo .empty ();
43+ TomlTable modInfo = modsArray .getTable (0 );
44+ if (modInfo .isEmpty ()) return BasicModInfo .empty ();
4745
4846 String modId = modInfo .getString ("modId" );
4947 String name = modInfo .getString ("displayName" );
@@ -58,12 +56,9 @@ public enum Platform {
5856 FABRIC ((str ) -> {
5957 Gson gson = new Gson ();
6058 JsonObject jsonObj = gson .fromJson (str , JsonObject .class );
61- String modId = jsonObj .get ("id" ).getAsString ();
62- String name = jsonObj .get ("name" ).getAsString ();
63- String description = jsonObj .get ("description" ).getAsString ();
64- String version = jsonObj .get ("version" ).getAsString ();
65-
66- return new BasicModInfo (modId , name , version , description );
59+ if (jsonObj == null ) return BasicModInfo .empty ();
60+ return ParserUtils .createModInfoFromJsonObject (jsonObj ,
61+ "modId" , "name" , "version" , "description" );
6762 }, "fabric.mod.json" );
6863
6964 private final String [] infoFilePaths ;
@@ -80,15 +75,24 @@ public enum Platform {
8075 * @param toParse The string to parse, expected to be in the format of the specific platform (JSON, TOML, etc.).
8176 * This string must match the format required by the platform; otherwise, parsing will fail.
8277 * @return The {@link BasicModInfo} object containing mod information.
83- * @throws JsonSyntaxException If the string is invalid JSON (for platforms like FABRIC and FORGE_LEGACY) .
84- * @throws IllegalStateException If the string does not match the expected TOML format (for FORGE ).
78+ * @throws IllegalArgumentException If the input string is null .
79+ * @throws ModInfoParseException If an error occurs while parsing the TOML (for Forge) or JSON (for Legacy Forge and Fabric ).
8580 */
8681 public BasicModInfo parse (String toParse ) {
87- return parserFunction .apply (toParse );
82+ if (toParse == null ) {
83+ throw new IllegalArgumentException ("Input string cannot be null" );
84+ }
85+
86+ try {
87+ return parserFunction .apply (toParse );
88+ } catch (TomlParseError | TomlInvalidTypeException | JsonParseException e ) {
89+ throw new ModInfoParseException ("Error parsing the mod info from the given string." , e );
90+ }
8891 }
8992
93+
9094 /**
91- * Reads and returns the content of the platform-specific info file (e.g. ` mcmod.info`, ` mods.toml` , etc.) from a zip archive.
95+ * Reads and returns the content of the platform-specific info file (e.g. {@code mcmod.info}, {@code mods.toml} , etc.) from a zip archive.
9296 *
9397 * @param zip The {@link ZipFile} to search for the platform-specific info file. It is allowed to be a derivative of such, e.g. {@link JarFile}
9498 * @return The content of the info file as a string, or {@code null} if the info file was not found.
@@ -134,39 +138,4 @@ public static Platform[] findModPlatform(File file) throws IOException {
134138
135139 return platforms .toArray (new Platform [0 ]);
136140 }
137-
138- /**
139- * Compares an array of paths to a single path to check if any match after normalisation.<p>
140- * This ensures that two paths are considered equal, even if their string representations differ
141- * (e.g., {@code run/embeddium.jar} and {@code .\run\embeddium.jar}).
142- *
143- * @param paths An array of paths to compare.
144- * @param path2 The path to compare against.
145- * @return {@code true} if any of the provided paths are equal to {@code path2} after normalisation, otherwise {@code false}.
146- */
147- private static boolean comparePaths (String [] paths , String path2 ) {
148- for (String path : paths ) {
149- Path normalizedPath1 = Paths .get (path ).normalize ();
150- Path normalizedPath2 = Paths .get (path2 ).normalize ();
151- if (normalizedPath1 .equals (normalizedPath2 )) return true ;
152- }
153- return false ;
154- }
155-
156- /**
157- * Reads the entire content of an {@link InputStream} and returns it as a string.
158- *
159- * @param in The {@link InputStream} to read from.
160- * @return The content of the InputStream as a string.
161- * @throws IOException If an I/O error occurs during reading.
162- */
163- private static String readEverythingAsString (InputStream in ) throws IOException {
164- StringBuilder sb = new StringBuilder (in .available ());
165- int readBytes ;
166- byte [] buffer = new byte [1024 ];
167- while ((readBytes = in .read (buffer )) > 0 ) {
168- sb .append (new String (buffer , 0 , readBytes ));
169- }
170- return sb .toString ();
171- }
172141}
0 commit comments