[FEATURE] Version comparing

This commit is contained in:
Gravita 2021-04-06 22:36:43 +07:00
parent f1331b6d5d
commit 6c37dd6ed2
7 changed files with 115 additions and 11 deletions

View file

@ -64,7 +64,7 @@ public static void prepare() throws Throwable {
launchServer = builder.build(); launchServer = builder.build();
} }
@Test @Test
public static void reloadTest() throws Exception { public void reloadTest() throws Exception {
AuthProvider provider = new AuthProvider() { AuthProvider provider = new AuthProvider() {
@Override @Override
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception { public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {

View file

@ -1,14 +1,24 @@
package pro.gravit.launcher.modules; package pro.gravit.launcher.modules;
import pro.gravit.launcher.LauncherTrustManager; import pro.gravit.launcher.LauncherTrustManager;
import pro.gravit.utils.Version;
import java.util.HashMap; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class LauncherModule { public abstract class LauncherModule {
protected final LauncherModuleInfo moduleInfo; protected final LauncherModuleInfo moduleInfo;
@SuppressWarnings("rawtypes") private final static class EventEntity<T extends Event> {
private final Map<Class<? extends Event>, EventHandler> eventMap = new HashMap<>(); final Class<T> clazz;
final EventHandler<T> handler;
private EventEntity(EventHandler<T> handler, Class<T> clazz) {
this.clazz = clazz;
this.handler = handler;
}
}
private final List<EventEntity<? extends Event>> eventList = new ArrayList<>(4);
protected LauncherModulesManager modulesManager; protected LauncherModulesManager modulesManager;
protected ModulesConfigManager modulesConfigManager; protected ModulesConfigManager modulesConfigManager;
protected InitStatus initStatus = InitStatus.CREATED; protected InitStatus initStatus = InitStatus.CREATED;
@ -23,7 +33,7 @@ protected LauncherModule(LauncherModuleInfo info) {
moduleInfo = info; moduleInfo = info;
} }
public LauncherModuleInfo getModuleInfo() { public final LauncherModuleInfo getModuleInfo() {
return moduleInfo; return moduleInfo;
} }
@ -60,6 +70,27 @@ public final LauncherTrustManager.CheckClassResult getCheckResult() {
return new LauncherTrustManager.CheckClassResult(this.checkResult); return new LauncherTrustManager.CheckClassResult(this.checkResult);
} }
protected final LauncherModule requireModule(String name, Version minVersion) {
if(context == null) throw new IllegalStateException("requireModule must be used in init() phase");
LauncherModule module = context.getModulesManager().getModule(name);
requireModule(module, minVersion, name);
return module;
}
protected final <T extends LauncherModule> T requireModule(Class<? extends T> clazz, Version minVersion) {
if(context == null) throw new IllegalStateException("requireModule must be used in init() phase");
T module = context.getModulesManager().getModule(clazz);
requireModule(module, minVersion, clazz.getName());
return module;
}
private void requireModule(LauncherModule module, Version minVersion, String requiredModuleName) {
if(module == null)
throw new RuntimeException(String.format("Module %s required %s v%s or higher", moduleInfo.name, requiredModuleName, minVersion.getVersionString()));
else if(module.moduleInfo.version.isLowerThan(minVersion))
throw new RuntimeException(String.format("Module %s required %s v%s or higher (current version %s)", moduleInfo.name, requiredModuleName, minVersion.getVersionString(), module.moduleInfo.version.getVersionString()));
}
/** /**
* The internal method used by the ModuleManager * The internal method used by the ModuleManager
* DO NOT TOUCH * DO NOT TOUCH
@ -86,7 +117,7 @@ public void preInitAction() {
//NOP //NOP
} }
public LauncherModule preInit() { public final LauncherModule preInit() {
if (!initStatus.equals(InitStatus.PRE_INIT_WAIT)) if (!initStatus.equals(InitStatus.PRE_INIT_WAIT))
throw new IllegalStateException("PreInit not allowed in current state"); throw new IllegalStateException("PreInit not allowed in current state");
initStatus = InitStatus.PRE_INIT; initStatus = InitStatus.PRE_INIT;
@ -121,7 +152,8 @@ public LauncherModule preInit() {
* @return true if adding a handler was successful * @return true if adding a handler was successful
*/ */
protected <T extends Event> boolean registerEvent(EventHandler<T> handle, Class<T> tClass) { protected <T extends Event> boolean registerEvent(EventHandler<T> handle, Class<T> tClass) {
eventMap.put(tClass, handle); EventEntity<T> eventEntity = new EventEntity<T>(handle, tClass);
eventList.add(eventEntity);
return true; return true;
} }
@ -134,10 +166,11 @@ protected <T extends Event> boolean registerEvent(EventHandler<T> handle, Class<
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final <T extends Event> void callEvent(T event) { public final <T extends Event> void callEvent(T event) {
Class<? extends Event> tClass = event.getClass(); Class<? extends Event> tClass = event.getClass();
for (@SuppressWarnings("rawtypes") Map.Entry<Class<? extends Event>, EventHandler> e : eventMap.entrySet()) { for (EventEntity<? extends Event> entity : eventList) {
if (e.getKey().isAssignableFrom(tClass)) { if (entity.clazz.isAssignableFrom(tClass)) {
e.getValue().event(event); //noinspection RedundantCast
((EventEntity<T>)entity).handler.event(event);
if (event.isCancel()) return; if (event.isCancel()) return;
} }
} }

View file

@ -37,6 +37,8 @@ default <T extends LauncherModule> boolean containsModule(Class<? extends T> cla
<T extends LauncherModule> T findModule(Class<? extends T> clazz, Predicate<Version> versionPredicate); <T extends LauncherModule> T findModule(Class<? extends T> clazz, Predicate<Version> versionPredicate);
LauncherModule findModule(String name, Predicate<Version> versionPredicate);
/** /**
* Invoke event processing for all modules. * Invoke event processing for all modules.
* Event processing is carried out in the order of the modules in the list (sorted by priority) * Event processing is carried out in the order of the modules in the list (sorted by priority)

View file

@ -266,6 +266,16 @@ public <T extends LauncherModule> T findModule(Class<? extends T> clazz, Predica
return null; return null;
} }
@Override
public LauncherModule findModule(String name, Predicate<Version> versionPredicate) {
for (LauncherModule module : modules) {
LauncherModuleInfo info = module.getModuleInfo();
if (!versionPredicate.test(info.version)) continue;
if (name.equals(info.name)) return module;
}
return null;
}
@Override @Override
public <T extends LauncherModule.Event> void invokeEvent(T event) { public <T extends LauncherModule.Event> void invokeEvent(T event) {
for (LauncherModule module : modules) { for (LauncherModule module : modules) {

View file

@ -1,8 +1,10 @@
package pro.gravit.launcher.impl; package pro.gravit.launcher.impl;
import org.junit.jupiter.api.Assertions;
import pro.gravit.launcher.modules.LauncherInitContext; import pro.gravit.launcher.modules.LauncherInitContext;
import pro.gravit.launcher.modules.LauncherModule; import pro.gravit.launcher.modules.LauncherModule;
import pro.gravit.launcher.modules.LauncherModuleInfo; import pro.gravit.launcher.modules.LauncherModuleInfo;
import pro.gravit.utils.Version;
public class Depend2Module extends LauncherModule { public class Depend2Module extends LauncherModule {
public Depend2Module() { public Depend2Module() {
@ -17,5 +19,18 @@ public void preInitAction() {
@Override @Override
public void init(LauncherInitContext initContext) { public void init(LauncherInitContext initContext) {
requireModule("depend1", new Version(1,0,0));
try {
requireModule("dependNotFound", new Version(1,0,0));
Assertions.fail("dependNotFound");
} catch (RuntimeException ignored) {
}
try {
requireModule("depend1", new Version(10,0,0));
Assertions.fail("depend1 high version");
} catch (RuntimeException ignored) {
}
} }
} }

View file

@ -2,7 +2,7 @@
import java.util.*; import java.util.*;
public final class Version { public final class Version implements Comparable<Version> {
public static final int MAJOR = 5; public static final int MAJOR = 5;
public static final int MINOR = 2; public static final int MINOR = 2;
@ -24,6 +24,18 @@ public Version(int major, int minor, int patch) {
release = Type.UNKNOWN; release = Type.UNKNOWN;
} }
public static Version of(int major, int minor, int patch) {
return new Version(major, minor, patch);
}
public static Version of(int major, int minor, int patch, int build) {
return new Version(major, minor, patch, build);
}
public static Version of(int major, int minor, int patch, int build, Type release) {
return new Version(major, minor, patch, build, release);
}
public Version(int major, int minor, int patch, int build) { public Version(int major, int minor, int patch, int build) {
this.major = major; this.major = major;
@ -81,6 +93,22 @@ public String toString() {
return String.format("%d.%d.%d-%d %s", major, minor, patch, build, getReleaseStatus()); return String.format("%d.%d.%d-%d %s", major, minor, patch, build, getReleaseStatus());
} }
@Override
public int compareTo(Version version) {
if(version.major != major) return Integer.compare(major, version.major);
if(version.minor != minor) return Integer.compare(minor, version.minor);
if(version.patch != patch) return Integer.compare(patch, version.patch);
return 0;
}
public boolean isUpperThan(Version version) {
return this.compareTo(version) > 0;
}
public boolean isLowerThan(Version version) {
return this.compareTo(version) < 0;
}
public enum Type { public enum Type {
LTS, LTS,

View file

@ -0,0 +1,16 @@
package pro.gravit.launcher;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import pro.gravit.utils.Version;
public class VersionCompareTest {
@Test
public void compareTest() {
Assertions.assertTrue(new Version(1,0,0).compareTo(new Version(1,1,0)) < 0);
Assertions.assertTrue(new Version(1,1,0).compareTo(new Version(1,0,0)) > 0);
Assertions.assertTrue(new Version(1,0,0).isLowerThan(new Version(1,1,0)));
Assertions.assertTrue(new Version(1,0,1).isUpperThan(new Version(1,0,0)));
}
}