|
|
@@ -1,13 +1,16 @@
|
|
|
package me.lethunderhawk.fluxapi.profile.representation;
|
|
|
|
|
|
+import me.lethunderhawk.fluxapi.profile.AnnotatedProfileCategory;
|
|
|
import me.lethunderhawk.fluxapi.profile.event.FluxProfileLoadEvent;
|
|
|
import me.lethunderhawk.fluxapi.profile.event.FluxProfileUpdateEvent;
|
|
|
import org.bukkit.Bukkit;
|
|
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
|
|
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
+import org.jspecify.annotations.NonNull;
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
@@ -17,7 +20,7 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
/* Static Registry */
|
|
|
/* ------------------------------------------------ */
|
|
|
|
|
|
- private static final Map<String, Class<? extends ConfigurationSerializable>> REGISTERED_TYPES = new ConcurrentHashMap<>();
|
|
|
+ private static final Map<String, Class<? extends AnnotatedProfileCategory>> REGISTERED_TYPES = new ConcurrentHashMap<>();
|
|
|
private static final Map<String, SubProfileFactory<?>> DEFAULT_FACTORIES = new HashMap<>();
|
|
|
/**
|
|
|
* Register a sub profile type.
|
|
|
@@ -27,11 +30,10 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
*/
|
|
|
public static void registerSubProfile(
|
|
|
@NotNull String id,
|
|
|
- @NotNull Class<? extends ConfigurationSerializable> clazz
|
|
|
+ @NotNull Class<? extends AnnotatedProfileCategory> clazz
|
|
|
) {
|
|
|
REGISTERED_TYPES.put(id, clazz);
|
|
|
ConfigurationSerialization.registerClass(clazz);
|
|
|
-
|
|
|
}
|
|
|
/**
|
|
|
* Register a sub profile type with a default Object.
|
|
|
@@ -40,11 +42,22 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
* @param clazz The serializable class
|
|
|
* @param factory The default factory used to create a subConfig if there is nothing saved yet
|
|
|
*/
|
|
|
- public static <T extends ConfigurationSerializable> void registerSubProfile(
|
|
|
+ public static <T extends AnnotatedProfileCategory> void registerSubProfile(
|
|
|
@NotNull String id,
|
|
|
@NotNull Class<T> clazz,
|
|
|
@NotNull SubProfileFactory<T> factory
|
|
|
) {
|
|
|
+ try {
|
|
|
+ clazz.getDeclaredMethod("deserialize", Map.class);
|
|
|
+ } catch (NoSuchMethodException e) {
|
|
|
+ throw new IllegalArgumentException(
|
|
|
+ clazz.getSimpleName() + " must declare a static deserialize(Map) method. " +
|
|
|
+ "Add: public static " + clazz.getSimpleName() +
|
|
|
+ " deserialize(Map<String, Object> map) { " +
|
|
|
+ "return AnnotatedProfileCategory.deserialize(" + clazz.getSimpleName() +
|
|
|
+ ".class, map); }"
|
|
|
+ );
|
|
|
+ }
|
|
|
REGISTERED_TYPES.put(id, clazz);
|
|
|
DEFAULT_FACTORIES.put(id, factory);
|
|
|
ConfigurationSerialization.registerClass(clazz);
|
|
|
@@ -53,12 +66,10 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
/* ------------------------------------------------ */
|
|
|
/* Instance Data */
|
|
|
/* ------------------------------------------------ */
|
|
|
-
|
|
|
private final String playerUUID;
|
|
|
- private boolean dirty = false;
|
|
|
|
|
|
// Fully deserialized objects
|
|
|
- private final Map<String, ConfigurationSerializable> subProfiles = new HashMap<>();
|
|
|
+ private final Map<String, AnnotatedProfileCategory> subProfiles = new HashMap<>();
|
|
|
|
|
|
// Raw maps (used if plugin not yet registered)
|
|
|
private final Map<String, Map<String, Object>> unresolvedData = new HashMap<>();
|
|
|
@@ -85,19 +96,15 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
|
|
|
|
|
String key = entry.getKey();
|
|
|
-
|
|
|
if (key.equals("uuid")) continue;
|
|
|
|
|
|
Object value = entry.getValue();
|
|
|
|
|
|
- // CASE 1: Already deserialized by Bukkit
|
|
|
- if (value instanceof ConfigurationSerializable serializable) {
|
|
|
-
|
|
|
+ if (value instanceof AnnotatedProfileCategory serializable) {
|
|
|
subProfiles.put(key, serializable);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // CASE 2: Raw map (class not registered yet)
|
|
|
if (value instanceof Map<?, ?> rawMap) {
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
@@ -111,13 +118,14 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
try {
|
|
|
Class<?> clazz = Class.forName(className);
|
|
|
|
|
|
- if (ConfigurationSerializable.class.isAssignableFrom(clazz)) {
|
|
|
+ if (AnnotatedProfileCategory.class.isAssignableFrom(clazz)) {
|
|
|
|
|
|
- ConfigurationSerializable obj =
|
|
|
- ConfigurationSerialization.deserializeObject(
|
|
|
- section,
|
|
|
- clazz.asSubclass(ConfigurationSerializable.class)
|
|
|
- );
|
|
|
+ AnnotatedProfileCategory obj =
|
|
|
+ (AnnotatedProfileCategory)
|
|
|
+ ConfigurationSerialization.deserializeObject(
|
|
|
+ section,
|
|
|
+ clazz.asSubclass(AnnotatedProfileCategory.class)
|
|
|
+ );
|
|
|
|
|
|
subProfiles.put(key, obj);
|
|
|
continue;
|
|
|
@@ -128,8 +136,6 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
|
|
|
unresolvedData.put(key, section);
|
|
|
}
|
|
|
-
|
|
|
- System.out.println("Loaded key: " + key + " type: " + value.getClass().getName());
|
|
|
}
|
|
|
|
|
|
Bukkit.getPluginManager().callEvent(new FluxProfileLoadEvent(this));
|
|
|
@@ -150,7 +156,7 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
*/
|
|
|
public void addSubProfile(
|
|
|
@NotNull String id,
|
|
|
- @NotNull ConfigurationSerializable profile
|
|
|
+ @NotNull AnnotatedProfileCategory profile
|
|
|
) {
|
|
|
subProfiles.put(id, profile);
|
|
|
|
|
|
@@ -164,12 +170,12 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
* Automatically resolves unresolved raw data if class gets registered later.
|
|
|
*/
|
|
|
@SuppressWarnings("unchecked")
|
|
|
- public synchronized <T extends ConfigurationSerializable> T getSubProfile(
|
|
|
+ public synchronized <T extends AnnotatedProfileCategory> T getSubProfile(
|
|
|
@NotNull String id,
|
|
|
@NotNull Class<T> expectedType
|
|
|
) {
|
|
|
// Already deserialized
|
|
|
- ConfigurationSerializable existing = subProfiles.get(id);
|
|
|
+ AnnotatedProfileCategory existing = subProfiles.get(id);
|
|
|
if (existing != null) {
|
|
|
return expectedType.cast(existing);
|
|
|
}
|
|
|
@@ -178,11 +184,11 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
Map<String, Object> raw = unresolvedData.remove(id);
|
|
|
if (raw != null) {
|
|
|
|
|
|
- Class<? extends ConfigurationSerializable> clazz = REGISTERED_TYPES.get(id);
|
|
|
+ Class<? extends AnnotatedProfileCategory> clazz = REGISTERED_TYPES.get(id);
|
|
|
|
|
|
if (clazz != null) {
|
|
|
- ConfigurationSerializable obj =
|
|
|
- ConfigurationSerialization.deserializeObject(raw, clazz);
|
|
|
+ AnnotatedProfileCategory obj =
|
|
|
+ (AnnotatedProfileCategory) ConfigurationSerialization.deserializeObject(raw, clazz);
|
|
|
|
|
|
subProfiles.put(id, obj);
|
|
|
return expectedType.cast(obj);
|
|
|
@@ -204,27 +210,18 @@ public class FluxProfile implements ConfigurationSerializable {
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
- /* ------------------------------------------------ */
|
|
|
- /* Serialization */
|
|
|
- /* ------------------------------------------------ */
|
|
|
-
|
|
|
@Override
|
|
|
- public @NotNull Map<String, Object> serialize() {
|
|
|
+ public @NonNull Map<String, Object> serialize() {
|
|
|
|
|
|
- Map<String, Object> data = new HashMap<>();
|
|
|
- data.put("uuid", playerUUID);
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
|
|
|
- // Store resolved profiles
|
|
|
- data.putAll(subProfiles);
|
|
|
+ result.put("uuid", playerUUID);
|
|
|
|
|
|
- // Preserve unresolved raw data
|
|
|
- data.putAll(unresolvedData);
|
|
|
+ result.putAll(subProfiles);
|
|
|
|
|
|
- return data;
|
|
|
- }
|
|
|
+ // Preserve unresolved data
|
|
|
+ result.putAll(unresolvedData);
|
|
|
|
|
|
- public static FluxProfile deserialize(Map<String, Object> map) {
|
|
|
- return new FluxProfile(map);
|
|
|
+ return result;
|
|
|
}
|
|
|
}
|