From 8c3760065f4a71bc3b3bfce73bec8a70d951e9e5 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Wed, 13 May 2020 21:51:47 +0300 Subject: [PATCH 01/28] introducing a very simple DI framework --- src/net/azib/ipscan/util/Injector.java | 41 +++++++++++++++++++++ test/net/azib/ipscan/util/InjectorTest.java | 25 +++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/net/azib/ipscan/util/Injector.java create mode 100644 test/net/azib/ipscan/util/InjectorTest.java diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java new file mode 100644 index 00000000..86320b0d --- /dev/null +++ b/src/net/azib/ipscan/util/Injector.java @@ -0,0 +1,41 @@ +package net.azib.ipscan.util; + +import javax.inject.Inject; +import java.lang.reflect.Constructor; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Arrays.stream; + +public class Injector { + private final Map, Object> instances = new HashMap<>(); + + @SuppressWarnings("unchecked") + public T inject(Class type) { + return (T) instances.computeIfAbsent(type, this::createInstance); + } + + @SuppressWarnings("unchecked") + private T createInstance(Class type) { + Constructor constructor = stream(type.getConstructors()).filter(c -> c.isAnnotationPresent(Inject.class)) + .findAny().orElseThrow(() -> new InjectException(type.getName() + " has no constructors annotated with @Inject")); + Object[] deps = stream(constructor.getParameterTypes()).map(this::inject).toArray(); + try { + return (T) constructor.newInstance(deps); + } + catch (Exception e) { + throw new InjectException("Cannot create " + type.getName() + ", depending on " + Arrays.toString(deps), e); + } + } + + public static class InjectException extends RuntimeException { + public InjectException(String message, Exception e) { + super(message, e); + } + + public InjectException(String message) { + super(message); + } + } +} diff --git a/test/net/azib/ipscan/util/InjectorTest.java b/test/net/azib/ipscan/util/InjectorTest.java new file mode 100644 index 00000000..1b112402 --- /dev/null +++ b/test/net/azib/ipscan/util/InjectorTest.java @@ -0,0 +1,25 @@ +package net.azib.ipscan.util; + +import org.junit.Test; + +import javax.inject.Inject; + +import static org.junit.Assert.assertTrue; + +public class InjectorTest { + private Injector injector = new Injector(); + + @Test + public void inject() { + assertTrue(injector.inject(Dummy.class) instanceof Dummy); + assertTrue(injector.inject(WithDeps.class) instanceof WithDeps); + } + + static class Dummy { + @Inject public Dummy() {} + } + + static class WithDeps { + @Inject public WithDeps(Dummy dummy) {} + } +} \ No newline at end of file From 40a807e47682a9a1bbe8d49a0ad83fa13c1e264b Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Wed, 13 May 2020 22:45:44 +0300 Subject: [PATCH 02/28] add support for @Named dependencies --- src/net/azib/ipscan/util/Injector.java | 64 +++++++++++++++++---- test/net/azib/ipscan/util/InjectorTest.java | 15 +++++ 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java index 86320b0d..8b906ce9 100644 --- a/src/net/azib/ipscan/util/Injector.java +++ b/src/net/azib/ipscan/util/Injector.java @@ -1,31 +1,75 @@ package net.azib.ipscan.util; import javax.inject.Inject; +import javax.inject.Named; +import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; import static java.util.Arrays.stream; +import static java.util.stream.IntStream.range; +@SuppressWarnings("unchecked") public class Injector { - private final Map, Object> instances = new HashMap<>(); + private final Map, Object> instances = new HashMap<>(); - @SuppressWarnings("unchecked") - public T inject(Class type) { - return (T) instances.computeIfAbsent(type, this::createInstance); + public void registerNamed(Class type, String name, T impl) { + instances.put(new Key<>(type, name), impl); + } + + public T inject(Key key) { + return (T) instances.computeIfAbsent(key, k -> createInstance(key.type)); + } + + public T inject(Class type) { + return inject(new Key<>(type, null)); } - @SuppressWarnings("unchecked") private T createInstance(Class type) { - Constructor constructor = stream(type.getConstructors()).filter(c -> c.isAnnotationPresent(Inject.class)) - .findAny().orElseThrow(() -> new InjectException(type.getName() + " has no constructors annotated with @Inject")); - Object[] deps = stream(constructor.getParameterTypes()).map(this::inject).toArray(); + Constructor constructor = (Constructor) stream(type.getConstructors()) + .filter(c -> c.isAnnotationPresent(Inject.class)).findAny() + .orElseThrow(() -> new InjectException(type.getName() + " has no constructors annotated with @Inject")); + Object[] deps = depsKeys(constructor).map(this::inject).toArray(); try { - return (T) constructor.newInstance(deps); + return constructor.newInstance(deps); } catch (Exception e) { - throw new InjectException("Cannot create " + type.getName() + ", depending on " + Arrays.toString(deps), e); + throw new InjectException("Cannot create " + type.getName() + ", deps: " + Arrays.toString(deps), e); + } + } + + private Stream> depsKeys(Constructor constructor) { + Class[] types = constructor.getParameterTypes(); + Annotation[][] ans = constructor.getParameterAnnotations(); + return range(0, types.length).mapToObj(i -> new Key<>((Class) types[i], findName(ans[i]))); + } + + private String findName(Annotation[] ans) { + return stream(ans).filter(a -> a.annotationType() == Named.class).findAny().map(a -> ((Named) a).value()).orElse(null); + } + + public static class Key { + final Class type; + final String name; + + public Key(Class type, String name) { + this.type = type; + this.name = name; + } + + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Key key = (Key) o; + return type.equals(key.type) && Objects.equals(name, key.name); + } + + @Override public int hashCode() { + return Objects.hash(type, name); } } diff --git a/test/net/azib/ipscan/util/InjectorTest.java b/test/net/azib/ipscan/util/InjectorTest.java index 1b112402..9be8144f 100644 --- a/test/net/azib/ipscan/util/InjectorTest.java +++ b/test/net/azib/ipscan/util/InjectorTest.java @@ -3,7 +3,9 @@ package net.azib.ipscan.util; import org.junit.Test; import javax.inject.Inject; +import javax.inject.Named; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class InjectorTest { @@ -15,6 +17,12 @@ public class InjectorTest { assertTrue(injector.inject(WithDeps.class) instanceof WithDeps); } + @Test + public void injectWithNamed() { + injector.registerNamed(String.class, "name", "mega-name"); + assertEquals("mega-name", injector.inject(WithNamedDeps.class).name); + } + static class Dummy { @Inject public Dummy() {} } @@ -22,4 +30,11 @@ public class InjectorTest { static class WithDeps { @Inject public WithDeps(Dummy dummy) {} } + + static class WithNamedDeps { + String name; + @Inject public WithNamedDeps(Dummy dummy, @Named("name") String name) { + this.name = name; + } + } } \ No newline at end of file From 37518ec3707f9dccc8bd86ce579f8ed856527a51 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Wed, 13 May 2020 23:20:12 +0300 Subject: [PATCH 03/28] add requireAll() --- src/net/azib/ipscan/util/Injector.java | 26 +++++++++++++-------- test/net/azib/ipscan/util/InjectorTest.java | 21 ++++++++++++----- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java index 8b906ce9..e2fc0b1b 100644 --- a/src/net/azib/ipscan/util/Injector.java +++ b/src/net/azib/ipscan/util/Injector.java @@ -4,36 +4,42 @@ import javax.inject.Inject; import javax.inject.Named; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Stream; import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toList; import static java.util.stream.IntStream.range; @SuppressWarnings("unchecked") public class Injector { - private final Map, Object> instances = new HashMap<>(); + private final Map, Object> instances = new LinkedHashMap<>(); - public void registerNamed(Class type, String name, T impl) { + public void register(Class type, String name, T impl) { instances.put(new Key<>(type, name), impl); } - public T inject(Key key) { + public void register(Class type, T impl) { + register(type, null, impl); + } + + public T require(Key key) { return (T) instances.computeIfAbsent(key, k -> createInstance(key.type)); } - public T inject(Class type) { - return inject(new Key<>(type, null)); + public T require(Class type) { + return require(new Key<>(type, null)); + } + + public List requireAll(Class type) { + return instances.entrySet().stream().filter(e -> e.getKey().type == type).map(e -> (T) e.getValue()).collect(toList()); } private T createInstance(Class type) { Constructor constructor = (Constructor) stream(type.getConstructors()) .filter(c -> c.isAnnotationPresent(Inject.class)).findAny() .orElseThrow(() -> new InjectException(type.getName() + " has no constructors annotated with @Inject")); - Object[] deps = depsKeys(constructor).map(this::inject).toArray(); + Object[] deps = depsKeys(constructor).map(this::require).toArray(); try { return constructor.newInstance(deps); } diff --git a/test/net/azib/ipscan/util/InjectorTest.java b/test/net/azib/ipscan/util/InjectorTest.java index 9be8144f..5f61edf7 100644 --- a/test/net/azib/ipscan/util/InjectorTest.java +++ b/test/net/azib/ipscan/util/InjectorTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import javax.inject.Inject; import javax.inject.Named; +import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -12,15 +13,23 @@ public class InjectorTest { private Injector injector = new Injector(); @Test - public void inject() { - assertTrue(injector.inject(Dummy.class) instanceof Dummy); - assertTrue(injector.inject(WithDeps.class) instanceof WithDeps); + public void require() { + assertTrue(injector.require(Dummy.class) instanceof Dummy); + assertTrue(injector.require(WithDeps.class) instanceof WithDeps); } @Test - public void injectWithNamed() { - injector.registerNamed(String.class, "name", "mega-name"); - assertEquals("mega-name", injector.inject(WithNamedDeps.class).name); + public void namedRequire() { + injector.register(String.class, "name", "mega-name"); + assertEquals("mega-name", injector.require(WithNamedDeps.class).name); + } + + @Test + public void requireAll() { + injector.register(String.class, "name1", "name1"); + injector.register(String.class, "name2", "name2"); + injector.register(String.class, "name3", "name3"); + assertEquals(asList("name1", "name2", "name3"), injector.requireAll(String.class)); } static class Dummy { From 055135407f83b5f90e62ec6e118578667162a8d4 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Wed, 13 May 2020 23:35:34 +0300 Subject: [PATCH 04/28] add support for List deps --- src/net/azib/ipscan/util/Injector.java | 16 ++++++++++------ test/net/azib/ipscan/util/InjectorTest.java | 11 ++++++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java index e2fc0b1b..771af495 100644 --- a/src/net/azib/ipscan/util/Injector.java +++ b/src/net/azib/ipscan/util/Injector.java @@ -4,8 +4,9 @@ import javax.inject.Inject; import javax.inject.Named; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.*; -import java.util.stream.Stream; import static java.util.Arrays.stream; import static java.util.stream.Collectors.toList; @@ -23,7 +24,7 @@ public class Injector { register(type, null, impl); } - public T require(Key key) { + T require(Key key) { return (T) instances.computeIfAbsent(key, k -> createInstance(key.type)); } @@ -39,7 +40,7 @@ public class Injector { Constructor constructor = (Constructor) stream(type.getConstructors()) .filter(c -> c.isAnnotationPresent(Inject.class)).findAny() .orElseThrow(() -> new InjectException(type.getName() + " has no constructors annotated with @Inject")); - Object[] deps = depsKeys(constructor).map(this::require).toArray(); + Object[] deps = deps(constructor); try { return constructor.newInstance(deps); } @@ -48,10 +49,13 @@ public class Injector { } } - private Stream> depsKeys(Constructor constructor) { - Class[] types = constructor.getParameterTypes(); + private Object[] deps(Constructor constructor) { + Type[] types = constructor.getGenericParameterTypes(); Annotation[][] ans = constructor.getParameterAnnotations(); - return range(0, types.length).mapToObj(i -> new Key<>((Class) types[i], findName(ans[i]))); + return range(0, types.length).mapToObj(i -> types[i] instanceof ParameterizedType ? + requireAll((Class) ((ParameterizedType) types[i]).getActualTypeArguments()[0]) : + require(new Key<>((Class) types[i], findName(ans[i]))) + ).toArray(); } private String findName(Annotation[] ans) { diff --git a/test/net/azib/ipscan/util/InjectorTest.java b/test/net/azib/ipscan/util/InjectorTest.java index 5f61edf7..65f7a200 100644 --- a/test/net/azib/ipscan/util/InjectorTest.java +++ b/test/net/azib/ipscan/util/InjectorTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import javax.inject.Inject; import javax.inject.Named; +import java.util.List; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; @@ -30,6 +31,7 @@ public class InjectorTest { injector.register(String.class, "name2", "name2"); injector.register(String.class, "name3", "name3"); assertEquals(asList("name1", "name2", "name3"), injector.requireAll(String.class)); + assertEquals(asList("name1", "name2", "name3"), injector.require(WithListDeps.class).list); } static class Dummy { @@ -46,4 +48,11 @@ public class InjectorTest { this.name = name; } } -} \ No newline at end of file + + static class WithListDeps { + List list; + @Inject public WithListDeps(List list, Dummy dummy) { + this.list = list; + } + } +} From 1f549e772bba322fb1561d20c970aee76c6c21f1 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Thu, 14 May 2020 00:04:19 +0300 Subject: [PATCH 05/28] support for subclasses --- src/net/azib/ipscan/util/Injector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java index 771af495..e2f0260d 100644 --- a/src/net/azib/ipscan/util/Injector.java +++ b/src/net/azib/ipscan/util/Injector.java @@ -33,7 +33,7 @@ public class Injector { } public List requireAll(Class type) { - return instances.entrySet().stream().filter(e -> e.getKey().type == type).map(e -> (T) e.getValue()).collect(toList()); + return instances.entrySet().stream().filter(e -> type.isAssignableFrom(e.getKey().type)).map(e -> (T) e.getValue()).collect(toList()); } private T createInstance(Class type) { From 19acce525bb647a8c0077c970569966e990e7d53 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Thu, 14 May 2020 00:37:50 +0300 Subject: [PATCH 06/28] add support for WildcardType --- src/net/azib/ipscan/util/Injector.java | 12 +++++++++++- test/net/azib/ipscan/util/InjectorTest.java | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java index e2f0260d..0047ef9d 100644 --- a/src/net/azib/ipscan/util/Injector.java +++ b/src/net/azib/ipscan/util/Injector.java @@ -6,6 +6,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; import java.util.*; import static java.util.Arrays.stream; @@ -32,6 +33,10 @@ public class Injector { return require(new Key<>(type, null)); } + public void register(Class ... types) { + stream(types).forEach(this::require); + } + public List requireAll(Class type) { return instances.entrySet().stream().filter(e -> type.isAssignableFrom(e.getKey().type)).map(e -> (T) e.getValue()).collect(toList()); } @@ -53,11 +58,16 @@ public class Injector { Type[] types = constructor.getGenericParameterTypes(); Annotation[][] ans = constructor.getParameterAnnotations(); return range(0, types.length).mapToObj(i -> types[i] instanceof ParameterizedType ? - requireAll((Class) ((ParameterizedType) types[i]).getActualTypeArguments()[0]) : + requireAll(getParamClass((ParameterizedType) types[i])) : require(new Key<>((Class) types[i], findName(ans[i]))) ).toArray(); } + private Class getParamClass(ParameterizedType type) { + Type t = type.getActualTypeArguments()[0]; + return (Class) (t instanceof WildcardType ? ((WildcardType) t).getUpperBounds()[0] : t); + } + private String findName(Annotation[] ans) { return stream(ans).filter(a -> a.annotationType() == Named.class).findAny().map(a -> ((Named) a).value()).orElse(null); } diff --git a/test/net/azib/ipscan/util/InjectorTest.java b/test/net/azib/ipscan/util/InjectorTest.java index 65f7a200..ce727c3d 100644 --- a/test/net/azib/ipscan/util/InjectorTest.java +++ b/test/net/azib/ipscan/util/InjectorTest.java @@ -51,7 +51,7 @@ public class InjectorTest { static class WithListDeps { List list; - @Inject public WithListDeps(List list, Dummy dummy) { + @Inject public WithListDeps(List list, List list2, Dummy dummy) { this.list = list; } } From 12efb9543254e6f3b7ee41f4dcaa20759d95a563 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Sat, 16 May 2020 11:06:59 +0300 Subject: [PATCH 07/28] trying to aut-create all required classes --- .../azib/ipscan/config/ComponentRegistry.java | 35 ++++++++++++++++++- src/net/azib/ipscan/config/ConfigModule.java | 12 +++++++ src/net/azib/ipscan/config/GUIConfig.java | 1 - src/net/azib/ipscan/util/Injector.java | 5 ++- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/net/azib/ipscan/config/ComponentRegistry.java b/src/net/azib/ipscan/config/ComponentRegistry.java index 42543121..f5d526d0 100644 --- a/src/net/azib/ipscan/config/ComponentRegistry.java +++ b/src/net/azib/ipscan/config/ComponentRegistry.java @@ -8,13 +8,16 @@ package net.azib.ipscan.config; import dagger.Module; import dagger.Provides; import net.azib.ipscan.core.Plugin; +import net.azib.ipscan.core.PluginLoader; import net.azib.ipscan.core.state.StateMachine; import net.azib.ipscan.exporters.*; import net.azib.ipscan.feeders.FeederCreator; import net.azib.ipscan.feeders.FeederRegistry; import net.azib.ipscan.fetchers.*; +import net.azib.ipscan.gui.MainWindow; import net.azib.ipscan.gui.SWTAwareStateMachine; import net.azib.ipscan.gui.feeders.*; +import net.azib.ipscan.util.Injector; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; @@ -32,6 +35,36 @@ import static java.util.Arrays.asList; */ @Module public class ComponentRegistry { + public void register(Injector i) { + Display display = Display.getDefault(); + i.register(Display.class, display); + Shell shell = new Shell(); + i.register(Shell.class, shell); + i.register(Menu.class, "mainMenu", new Menu(shell, SWT.BAR)); + i.register(Composite.class, "feederArea", new Composite(shell, SWT.NONE)); + Composite controlsArea = new Composite(shell, SWT.NONE); + i.register(Composite.class, "controlsArea", controlsArea); + i.register(Button.class, "startStopButton", new Button(controlsArea, SWT.NONE)); + i.register(Combo.class, "feederSelectionCombo", new Combo(controlsArea, SWT.READ_ONLY)); + SWTAwareStateMachine stateMachine = new SWTAwareStateMachine(display); + i.register(SWTAwareStateMachine.class, stateMachine); + i.register(StateMachine.class, stateMachine); + i.register(RangeFeederGUI.class, RandomFeederGUI.class, FileFeederGUI.class); + i.register(TXTExporter.class, CSVExporter.class, XMLExporter.class, IPListExporter.class); + i.register(IPFetcher.class, PingFetcher.class, PingTTLFetcher.class, HostnameFetcher.class, PortsFetcher.class, + FilteredPortsFetcher.class, WebDetectFetcher.class, HTTPSenderFetcher.class, CommentFetcher.class, + NetBIOSInfoFetcher.class, PacketLossFetcher.class, HTTPProxyFetcher.class); + i.register(MACFetcher.class, Platform.WINDOWS ? new WinMACFetcher() : new UnixMACFetcher()); + i.register(MACVendorFetcher.class); + } + + public static void main(String[] args) { + Injector i = new Injector(); + new ConfigModule().register(i); + new ComponentRegistry().register(i); + new PluginLoader().getClasses().forEach(i::require); + System.out.println(i.require(MainWindow.class)); + } @Provides @Singleton public Display getDisplay() { return Display.getDefault(); @@ -91,7 +124,7 @@ public class ComponentRegistry { @SuppressWarnings("unchecked") private List addPlugins(List original, Class type, List> classes) { List result = new ArrayList<>(original); - for (Class clazz: classes) { + for (Class clazz: classes) { try { if (type.isAssignableFrom(clazz)) result.add((T)clazz.newInstance()); diff --git a/src/net/azib/ipscan/config/ConfigModule.java b/src/net/azib/ipscan/config/ConfigModule.java index 8619aa32..2f42b2b7 100644 --- a/src/net/azib/ipscan/config/ConfigModule.java +++ b/src/net/azib/ipscan/config/ConfigModule.java @@ -2,11 +2,23 @@ package net.azib.ipscan.config; import dagger.Module; import dagger.Provides; +import net.azib.ipscan.util.Injector; import java.util.prefs.Preferences; @Module public class ConfigModule { + public void register(Injector i) { + Config config = Config.getConfig(); + i.register(Config.class, config); + i.register(Labels.class, Labels.getInstance()); + i.register(Preferences.class, config.getPreferences()); + i.register(ScannerConfig.class, config.forScanner()); + i.register(OpenersConfig.class, config.forOpeners()); + i.register(FavoritesConfig.class, config.forFavorites()); + i.register(GUIConfig.class, config.forGUI()); + } + @Provides Config getConfig() { return Config.getConfig(); } diff --git a/src/net/azib/ipscan/config/GUIConfig.java b/src/net/azib/ipscan/config/GUIConfig.java index 13238f1b..81071a85 100644 --- a/src/net/azib/ipscan/config/GUIConfig.java +++ b/src/net/azib/ipscan/config/GUIConfig.java @@ -36,7 +36,6 @@ public class GUIConfig { public enum DisplayMethod {ALL, ALIVE, PORTS} - // package local constructor GUIConfig(Preferences preferences) { this.preferences = preferences; load(); diff --git a/src/net/azib/ipscan/util/Injector.java b/src/net/azib/ipscan/util/Injector.java index 0047ef9d..e99ce1bf 100644 --- a/src/net/azib/ipscan/util/Injector.java +++ b/src/net/azib/ipscan/util/Injector.java @@ -45,12 +45,11 @@ public class Injector { Constructor constructor = (Constructor) stream(type.getConstructors()) .filter(c -> c.isAnnotationPresent(Inject.class)).findAny() .orElseThrow(() -> new InjectException(type.getName() + " has no constructors annotated with @Inject")); - Object[] deps = deps(constructor); try { - return constructor.newInstance(deps); + return constructor.newInstance(deps(constructor)); } catch (Exception e) { - throw new InjectException("Cannot create " + type.getName() + ", deps: " + Arrays.toString(deps), e); + throw new InjectException("Cannot create " + type.getName() + ", deps: " + Arrays.toString(constructor.getGenericParameterTypes()), e); } } From c591c61891a221878a99cf83efd45f9a076b3d79 Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Sat, 16 May 2020 13:17:59 +0300 Subject: [PATCH 08/28] use constructor injection --- src/net/azib/ipscan/gui/Startup.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/net/azib/ipscan/gui/Startup.java b/src/net/azib/ipscan/gui/Startup.java index 840127d6..6b5377e9 100644 --- a/src/net/azib/ipscan/gui/Startup.java +++ b/src/net/azib/ipscan/gui/Startup.java @@ -4,7 +4,7 @@ import net.azib.ipscan.config.GUIConfig; import net.azib.ipscan.config.Labels; import net.azib.ipscan.config.Platform; import net.azib.ipscan.config.Version; -import net.azib.ipscan.gui.actions.HelpMenuActions; +import net.azib.ipscan.gui.actions.HelpMenuActions.CheckVersion; import net.azib.ipscan.util.GoogleAnalytics; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; @@ -12,11 +12,15 @@ import org.eclipse.swt.widgets.Shell; import javax.inject.Inject; public class Startup { - @Inject Shell shell; - @Inject GUIConfig guiConfig; - @Inject HelpMenuActions.CheckVersion checkVersion; + private Shell shell; + private GUIConfig guiConfig; + private CheckVersion checkVersion; - @Inject public Startup() {} + @Inject public Startup(Shell shell, GUIConfig guiConfig, CheckVersion checkVersion) { + this.shell = shell; + this.guiConfig = guiConfig; + this.checkVersion = checkVersion; + } public void onStart() { if (guiConfig.isFirstRun) { From 35d3710d2c38208c32420ae6084a223891f283ed Mon Sep 17 00:00:00 2001 From: Anton Keks Date: Sat, 16 May 2020 13:19:28 +0300 Subject: [PATCH 09/28] MainWindow can now be created by Injector --- .idea/gradle.xml | 3 ++- .idea/misc.xml | 5 ++++- src/net/azib/ipscan/config/ComponentRegistry.java | 1 + src/net/azib/ipscan/util/Injector.java | 15 +++++++++++++-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index fa5c2d2f..9377824e 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,7 +4,8 @@