diff --git a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/world/PlayerDataStorage.java b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/world/PlayerDataStorage.java index bbacb2d..a17d922 100644 --- a/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/world/PlayerDataStorage.java +++ b/pandalib-paper/src/main/java/fr/pandacube/lib/paper/reflect/wrapper/minecraft/world/PlayerDataStorage.java @@ -16,13 +16,12 @@ public class PlayerDataStorage extends ReflectWrapper { public static final ReflectMethod load = wrapEx(() -> REFLECT.method("load", String.class, String.class)); /** - * @param playerName the name of the player: used for loading error message and of offline UUID generation. - * @param playerId UUID of a player as it is used to name the player data file (UUID.toString()) + * @param playerName the name of the player: used for loading error message and for offline UUID generation. + * @param playerId UUID of a player as it is used to name the player data file (UUID.toString()). */ @SuppressWarnings("unchecked") public Optional load(String playerName, String playerId) { - return ((Optional) wrapReflectEx(() -> load.invoke(__getRuntimeInstance(), playerId))) - .map(o -> wrap(o, CompoundTag.class)); + return wrapOptional((Optional) wrapReflectEx(() -> load.invoke(__getRuntimeInstance(), playerName, playerId)), CompoundTag.class); } diff --git a/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/wrapper/ReflectWrapper.java b/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/wrapper/ReflectWrapper.java index a0478fc..2c94572 100644 --- a/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/wrapper/ReflectWrapper.java +++ b/pandalib-reflect/src/main/java/fr/pandacube/lib/reflect/wrapper/ReflectWrapper.java @@ -7,6 +7,7 @@ import fr.pandacube.lib.reflect.ReflectConstructor; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import static fr.pandacube.lib.util.ThrowableUtil.wrapEx; @@ -98,7 +99,7 @@ public abstract class ReflectWrapper implements ReflectWrapperI { Class runtimeClass = runtimeObj.getClass(); Class expectedRuntimeClass = (expectedWrapperClass == null) ? null : WrapperRegistry.getRuntimeClassOfWrapperClass(expectedWrapperClass); if (expectedRuntimeClass != null && !expectedRuntimeClass.isAssignableFrom(runtimeClass)) { - throw new ClassCastException("Runtime class " + runtimeClass + " is not a sub-class or a sub-interface of expected runtime class " + expectedRuntimeClass + "" + + throw new ClassCastException("Runtime class " + runtimeClass + " is not a sub-class or a sub-interface of expected runtime class " + expectedRuntimeClass + " (expected wrapper class " + expectedWrapperClass + ")."); } Class wrapperClass = WrapperRegistry.getWrapperOfRuntimeClass(runtimeClass); @@ -139,6 +140,27 @@ public abstract class ReflectWrapper implements ReflectWrapperI { } + /** + * Maps the provided {@link Optional} containing a runtime object to the reflection wrapper. + * @param runtimeOptional the object to wrap. + * @param expectedWrapperClass the reflection wrapper class expected to be returned. + * @param the type of the reflection wrapper. + * @throws ClassCastException if the runtime class of the object is not handled by the expected wrapper class or its + * subclasses. + * @throws IllegalArgumentException if the runtime class of the object is not handled by any of the registered + * wrapper classes. + * @implNote Despite that the convention is to not assign null values as Optional, this method properly handles null + * value for parameter runtimeOptional. + * @return an optional of the wrapper. + */ + @SuppressWarnings("OptionalAssignedToNull") + public static Optional wrapOptional(Optional runtimeOptional, Class expectedWrapperClass) { + return runtimeOptional == null ? null : runtimeOptional.map(o -> wrap(o, expectedWrapperClass)); + } + + + +