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); } }