First of all, I am absolutely surprised that this code even works. Originally what I did was create a version checking system for Minecraft plugins (specifically Bukkit, Craftbukkit, & Spigot).What I wanted to do was refactor my Version class in order to make it platform independent (where it doesn't depend or provide functionality for only Minecraft servers and plugins).So instead of the constructors accepting Bukkit classes, I changed it to accept a generic String that would represent the version. Then I made Builder methods, which I deleted and move into a factory: VersionFactory (this makes it easier for end-users to construct Version objects specific to Bukkit servers).So, the main methods of Version.java are isCompatible() and isSupported(). However, the first thing these methods did was perform an isEnabled() check on the Version object because any compatibility checks should fail (as intended) if the target plugin isn't even installed on the server.However, any such checks on specific Bukkit classes and objects would restrict the use of my Version checking system to only Bukkit. And I wanted to make it platform independent.So what I did was create a functional interface called Tester, and asked for it in the constructor of Version (along with the object under test). The primary intent is to allow plugin.isEnabled() to be run and return true or false BEFORE isCompatible() or isSupported() is executed. However, it does allow ANY custom test() to be performed.What is surprising is that I can pass type Object into the constructor, which gets assigned to a field, and ultimately gets passed to tester.isEnabled() which is able to call a plugin specific method on a generic Object type!Version.javapackage mc.euro.version;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * The Version object: Capable of asking the important questions:. <br/><br/> *  * Is the version that's currently installed on the server compatible/supported with a specified version ? <br/><br/> *  * isCompatible(): Is the installed version greater than or equal to the minimum required version ? <br/><br/> *  * isSupported(): Is the installed version less than or equal to the maximum required version ? <br/><br/> *  * @author Europia79, BigTeddy98, Tux2, DSH105 */public class Version implements Comparable<Version> {    /**     * The Predicate tester preforms the job of checking if the plugin isEnabled(). <br/><br/>     *      * Because, if the plugin is disabled, then our compatibility check should fail.     */    Tester tester;    Object object;    final String version;    String separator = [_.-];    /**     * VersionFactory methods getPluginVersion(), getServerVersion(), getNmsVersion() available for convenience. <br/>     * @param version The version of the plugin, server, or application that is currently running in the JVM. <br/>     */    public Version(String version) {        this.version = version;        this.tester = TesterFactory.getDefaultTester();        this.object = new Object();    }    /**     * VersionFactory methods getPluginVersion(), getServerVersion(), getNmsVersion() available for convenience. <br/>     * @param version The version of the plugin, server, or application that is currently running in the JVM. <br/>     * @param tester isCompatible() & isSupported() will ask the tester if the object isEnabled() before proceeding. <br/>     * @param object The object to be tested. <br/>     */    public Version(String version, Tester tester, Object object) {        this.version = version;        this.tester = tester;        this.object = object;    }    public boolean isEnabled() {        return tester.isEnabled(object);    }    /**     * @param minVersion - The absolute minimum version that's required to achieve compatibility.     * @return Return true, if the currently running/installed version is greater than or equal to minVersion.     */    public boolean isCompatible(String minVersion) {        if (!this.isEnabled()) return false;        int x = compareTo(new Version(minVersion));        if (x >= 0) {            return true;        }         return false;    }    /**     * @param maxVersion - The absolute maximum version that's supported.     * @return Return true, if the currently running/installed version is less than or equal to maxVersion.     */    public boolean isSupported(String maxVersion) {        if (!this.isEnabled()) return false;        int x = compareTo(new Version(maxVersion));        if (x <= 0) {            return true;        }        return false;    }    @Override    public int compareTo(Version whichVersion) {        int[] currentVersion = parseVersion(this.version);        int[] otherVersion = parseVersion(whichVersion.toString());        int length = (currentVersion.length >= otherVersion.length) ? currentVersion.length : otherVersion.length;        for (int index = 0; index <= (length - 1); index = index + 1) {            try {                if (currentVersion[index] != otherVersion[index]) {                    return currentVersion[index] - otherVersion[index];                }            } catch (IndexOutOfBoundsException ex) {                if (currentVersion.length > otherVersion.length) {                    return currentVersion[index] - 0;                } else if (currentVersion.length < otherVersion.length) {                    return 0 - otherVersion[index];                }            }        }        return 0;    }    /**     * A typical version of 1.2.3.4-b567 will be broken down into an array. <br/><br/>     *      * [1] [2] [3] [4] [567]     */    private int[] parseVersion(String version) {        String[] stringArray = version.split(separator);        int[] temp = new int[stringArray.length];        for (int index = 0; index <= (stringArray.length - 1); index = index + 1) {            String t = stringArray[index].replaceAll(\\D, );            try {                temp[index] = Integer.valueOf(t);            } catch(NumberFormatException ex) {                temp[index] = 0;            }        }        return temp;    }    public Version setSeparator(String regex) {        this.separator = regex;        return this;    }    /**     * search() for possible Development builds.     */    public boolean search(String regex) {        if (version == null) return false;        Pattern pattern = Pattern.compile(regex);        Matcher matcher = pattern.matcher(this.version);        if (matcher.find()) {            return true;        }        return false;    }    /**     * Used to get a Sub-Version (or Development build). <br/><br/>     * @param regex      * @return A completely new Version object.     */    public Version getSubVersion(String regex) {        if (version == null) return this;        Pattern pattern = Pattern.compile(regex);        Matcher matcher = pattern.matcher(this.version);        String dev = this.version;        if (matcher.find()) {            dev = matcher.group();        }        return new Version(dev);    }    @Override    public String toString() {        String v = (this.version == null) ?  : this.version;        return v;    }}Examples of using itpublic class SomePlugin extends JavaPlugin {    private Version server;    public static final String MAX = 1.7.10-R9.9-SNAPSHOT;    public static final String MIN = 1.2.5;    public static final String NMS = VersionFactory.getNmsVersion().toString();    @Override    public void onEnable() {        server = VersionFactory.getServerVersion();        if (!server.isSupported(MAX) || !server.isCompatible(MIN)) {            getLogger().info(This plugin is not compatible with your server.);            getLogger().info(The maximum supported version is  + MAX);            getLogger().info(The minimum capatible version is  + MIN);            Bukkit.getServer().getPluginManager().disablePlugin(this);            return;        }        // ...        Version HD = VersionFactory.getPluginVersion(HolographicDisplays);        Version Holoapi = VersionFactory.getPluginVersion(HoloAPI);        debug.log(HolographicDisplays version =  + HD.toString());        debug.log(HoloAPI version =  + Holoapi.toString());        if (ShowHolograms && HD.isCompatible(1.8.5)) {            this.holograms = new HolographicDisplay(this);            debug.log(HolographicDisplays support is enabled.);        } else if (ShowHolograms && Holoapi.isEnabled()) {            this.holograms = new HolographicAPI(this);            debug.log(HoloAPI support is enabled.);        } else {            this.holograms = new HologramsOff();            debug.log(Hologram support is disabled.);            debug.log(Please download HoloAPI or HolographicDisplays to enable Hologram support.);        }    }    public static Class<?> getNmsClass(String clazz) throws Exception {        return Class.forName(com.yourdomain.yourproject.compat. + NMS + . + clazz);    }}VersionFactory.javapackage mc.euro.version;import org.bukkit.Bukkit;import org.bukkit.plugin.Plugin;/** * Handles the construction of new Version objects specific to Craftbukkit. * @author Nikolai */public class VersionFactory {    /**     * Factory method used when you want to construct a Version object via a Plugin object. <br/>     */    public static Version getPluginVersion(Plugin plugin) {        String version = (plugin == null) ? null : plugin.getDescription().getVersion();        Tester tester = TesterFactory.getNewTester(plugin);        return new Version(version, tester, plugin);    }    /**     * Factory method used when you want to construct a Version object via pluginName. <br/>     */    public static Version getPluginVersion(String pluginName) {        Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);        String version = (plugin == null) ? null : plugin.getDescription().getVersion();        Tester tester = TesterFactory.getNewTester(plugin);        return new Version(version, tester, plugin);    }    /**     * Factory method to conveniently construct a Version object of the server. <br/>     */    public static Version getServerVersion() {        String version = Bukkit.getServer().getBukkitVersion();        return new Version(version);    }    /**     * Factory method to conveniently construct a Version object of net.minecraft.server.v1_X_RY package. <br/>     */    public static Version getNmsVersion() {        String NMS = null;            try {                NMS = Bukkit.getServer().getClass().getPackage().getName().replace(., ,).split(,)[3];            } catch (ArrayIndexOutOfBoundsException ex) {                NMS = pre;            }        return new Version(NMS);    }}TesterFactory.javapackage mc.euro.version;import org.bukkit.plugin.Plugin;/** * Provides less typing for the construction of Plugin Testers. <br/><br/> *  * @author Nikolai */public class TesterFactory {    public static Tester getNewTester(Plugin plugin) {        if (plugin == null) {            return new Tester<Plugin>() {                @Override                public boolean isEnabled(Plugin t) {                    return false;                }            };        } else {            return new Tester<Plugin>() {                @Override                public boolean isEnabled(Plugin t) {                    return t.isEnabled();                }            };        }    }    public static Tester getDefaultTester() {        return new Tester() {            @Override            public boolean isEnabled(Object t) {                return true;            }        };    }}Tester.javapackage mc.euro.version;/** * The Tester interface is used to optionally pass an additional isEnabled() check to the Version object. <br/><br/> *  * Notice that if the test returns false, then the compatibility check will stop, (as intended)  * because if the plugin is not enabled, then it's not compatible. *  * @author Nikolai */public interface Tester<T> {    public boolean isEnabled(T t);}All the code is hereThe build tests are hereThe javadocs are here
Functional interface uses uncheck or unsafe operations
java;generics;interface