diff --git a/Plan/api/build.gradle b/Plan/api/build.gradle
index bd3e76ee4..c79e42946 100644
--- a/Plan/api/build.gradle
+++ b/Plan/api/build.gradle
@@ -2,7 +2,7 @@ plugins {
id "com.jfrog.bintray" version "1.8.1"
}
-ext.apiVersion = '0.0.3'
+ext.apiVersion = '0.0.4'
bintray {
user = System.getenv('BINTRAY_USER')
diff --git a/Plan/api/src/main/java/com/djrapitops/plan/capability/Capability.java b/Plan/api/src/main/java/com/djrapitops/plan/capability/Capability.java
new file mode 100644
index 000000000..fa7576d18
--- /dev/null
+++ b/Plan/api/src/main/java/com/djrapitops/plan/capability/Capability.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.capability;
+
+import java.util.Optional;
+
+/**
+ * List of different capabilities current version provides.
+ *
+ * The enum is package private to restrict direct access. This is to avoid NoClassDefFoundError in case
+ * a wanted Capability is not provided in an earlier version.
+ *
+ * Use {@link CapabilityService#hasCapability(String)} with name of a Capability to figure out if an API is available.
+ * Example usage: {@code CapabilityService.getInstance().hasCapability("DATA_EXTENSION_VALUES")}.
+ *
+ * If a capability is not available, attempting to use the capability might lead to exceptions.
+ *
+ * @author Rsl1122
+ */
+enum Capability {
+
+ /**
+ * ExtensionService, DataExtension API base package, PluginInfo, Conditional, Tab, TabInfo, TabOrder and BooleanProvider, DoubleProvider, PercentageProvider, NumberProvider, StringProvider annotations.
+ */
+ DATA_EXTENSION_VALUES;
+
+ static Optional getByName(String name) {
+ try {
+ return Optional.of(valueOf(name));
+ } catch (IllegalArgumentException e) {
+ return Optional.empty();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java b/Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java
new file mode 100644
index 000000000..cd5ed969f
--- /dev/null
+++ b/Plan/api/src/main/java/com/djrapitops/plan/capability/CapabilityService.java
@@ -0,0 +1,76 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.capability;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * Service for figuring out provided API capabilities.
+ *
+ * {@link CapabilityService#registerEnableListener(Consumer)} to be notified of Plan reloads
+ * {@link CapabilityService#hasCapability(String)} to check if a capability is available.
+ *
+ * See {@link Capability} for list of capabilities provided by the current version.
+ *
+ * @author Rsl1122
+ */
+public interface CapabilityService {
+
+ /**
+ * Obtain instance of CapabilityService.
+ *
+ * @return CapabilityService implementation.
+ * @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed.
+ * @throws IllegalStateException If Plan is installed, but not enabled.
+ */
+ static CapabilityService getInstance() {
+ return Optional.ofNullable(CapabilityServiceHolder.service)
+ .orElseThrow(() -> new IllegalStateException("CapabilityService has not been initialised yet."));
+ }
+
+ /**
+ * Register a method to be called when Plan reloads.
+ *
+ * @param isEnabledListener The boolean given to the method tells if Plan has enabled successfully.
+ */
+ void registerEnableListener(Consumer isEnabledListener);
+
+ /**
+ * Check if the API on the current version provides a capability.
+ *
+ * @param capabilityName Name of a capability
+ * @return true if the capability is available.
+ * @see Capability for different capabilityNames.
+ */
+ default boolean hasCapability(String capabilityName) {
+ return Capability.getByName(capabilityName).isPresent();
+ }
+
+ class CapabilityServiceHolder {
+ static CapabilityService service;
+
+ private CapabilityServiceHolder() {
+ /* Static variable holder */
+ }
+
+ static void set(CapabilityService service) {
+ CapabilityServiceHolder.service = service;
+ }
+ }
+
+}
diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java
index 693dfc3ba..6a00fe207 100644
--- a/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java
+++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java
@@ -19,6 +19,7 @@ package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.events.PlanBukkitEnableEvent;
+import com.djrapitops.plan.capability.CapabilityServiceImplementation;
import com.djrapitops.plan.system.listeners.bukkit.*;
import com.djrapitops.plan.system.status.Status;
import org.bukkit.Bukkit;
@@ -83,7 +84,9 @@ public class BukkitListenerSystem extends ListenerSystem {
@Override
public void callEnableEvent(PlanPlugin plugin) {
- PlanBukkitEnableEvent event = new PlanBukkitEnableEvent(plugin.isSystemEnabled());
+ boolean isEnabled = plugin.isSystemEnabled();
+ PlanBukkitEnableEvent event = new PlanBukkitEnableEvent(isEnabled);
Bukkit.getServer().getPluginManager().callEvent(event);
+ CapabilityServiceImplementation.notifyAboutEnable(isEnabled);
}
}
diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java
index b4fba6aa4..722ed46dd 100644
--- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java
+++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java
@@ -19,6 +19,7 @@ package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.events.PlanBungeeEnableEvent;
+import com.djrapitops.plan.capability.CapabilityServiceImplementation;
import com.djrapitops.plan.system.listeners.bungee.PlayerOnlineListener;
import javax.inject.Inject;
@@ -46,7 +47,9 @@ public class BungeeListenerSystem extends ListenerSystem {
@Override
public void callEnableEvent(PlanPlugin plugin) {
- PlanBungeeEnableEvent event = new PlanBungeeEnableEvent(plugin.isSystemEnabled());
+ boolean isEnabled = plugin.isSystemEnabled();
+ PlanBungeeEnableEvent event = new PlanBungeeEnableEvent(isEnabled);
((PlanBungee) plugin).getProxy().getPluginManager().callEvent(event);
+ CapabilityServiceImplementation.notifyAboutEnable(isEnabled);
}
}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java b/Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java
new file mode 100644
index 000000000..cc9abd850
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/capability/CapabilityServiceImplementation.java
@@ -0,0 +1,58 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.capability;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Singleton instance implementation for {@link CapabilityService}.
+ *
+ * Only one instance exists per runtime in order to notify others when the plugin enables.
+ *
+ * @author Rsl1122
+ */
+public class CapabilityServiceImplementation implements CapabilityService {
+
+ private List> enableListeners;
+
+ private CapabilityServiceImplementation() {
+ /* Inject required for dagger */
+ CapabilityServiceHolder.set(this);
+ enableListeners = new ArrayList<>();
+ }
+
+ private static CapabilityServiceImplementation get() {
+ CapabilityService instance = CapabilityService.getInstance();
+ if (instance == null) {
+ return new CapabilityServiceImplementation();
+ }
+ return (CapabilityServiceImplementation) instance;
+ }
+
+ public static void notifyAboutEnable(boolean isEnabled) {
+ for (Consumer enableListener : get().enableListeners) {
+ enableListener.accept(isEnabled);
+ }
+ }
+
+ @Override
+ public void registerEnableListener(Consumer enableListener) {
+ enableListeners.add(enableListener);
+ }
+}
\ No newline at end of file
diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java b/Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java
index 8bd6187f7..64c00f5fa 100644
--- a/Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java
+++ b/Plan/sponge/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java
@@ -20,6 +20,7 @@ import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.PlanSponge;
import com.djrapitops.plan.SpongeServerShutdownSave;
import com.djrapitops.plan.api.events.PlanSpongeEnableEvent;
+import com.djrapitops.plan.capability.CapabilityServiceImplementation;
import com.djrapitops.plan.system.listeners.sponge.*;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.event.Event;
@@ -94,5 +95,6 @@ public class SpongeListenerSystem extends ListenerSystem {
} catch (IllegalStateException ignore) {
/* Ignore, Sponge is not initialized */
}
+ CapabilityServiceImplementation.notifyAboutEnable(plugin.isSystemEnabled());
}
}
diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java b/Plan/velocity/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java
index a31984e2a..710555c51 100644
--- a/Plan/velocity/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java
+++ b/Plan/velocity/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java
@@ -19,6 +19,7 @@ package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.PlanVelocity;
import com.djrapitops.plan.api.events.PlanVelocityEnableEvent;
+import com.djrapitops.plan.capability.CapabilityServiceImplementation;
import com.djrapitops.plan.system.listeners.velocity.PlayerOnlineListener;
import javax.inject.Inject;
@@ -52,7 +53,9 @@ public class VelocityListenerSystem extends ListenerSystem {
@Override
public void callEnableEvent(PlanPlugin plugin) {
- PlanVelocityEnableEvent event = new PlanVelocityEnableEvent(plugin.isSystemEnabled());
+ boolean isEnabled = plugin.isSystemEnabled();
+ PlanVelocityEnableEvent event = new PlanVelocityEnableEvent(isEnabled);
((PlanVelocity) plugin).getProxy().getEventManager().fireAndForget(event);
+ CapabilityServiceImplementation.notifyAboutEnable(isEnabled);
}
}