diff --git a/src/main/java/fucoin/Main.java b/src/main/java/fucoin/Main.java index 2b491c8ba39ad8f2c2a13262a961cb2f82377665..2a6e947a169ad4b78333d4dd8519b55b49a02a9b 100644 --- a/src/main/java/fucoin/Main.java +++ b/src/main/java/fucoin/Main.java @@ -1,13 +1,18 @@ package fucoin; import akka.actor.ActorSystem; +import akka.actor.Props; +import com.google.common.collect.Sets; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import fucoin.configurations.AbstractConfiguration; +import fucoin.configurations.internal.ConfigurationSelection; import fucoin.setup.NetworkInterfaceReader; +import org.reflections.ReflectionUtils; import org.reflections.Reflections; import org.reflections.scanners.ResourcesScanner; import org.reflections.scanners.SubTypesScanner; +import org.reflections.scanners.TypeElementsScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import org.reflections.util.FilterBuilder; @@ -15,10 +20,7 @@ import org.reflections.util.FilterBuilder; import javax.swing.*; import java.io.File; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; +import java.util.*; public class Main { @@ -43,42 +45,42 @@ public class Main { } public static void main(String[] args) throws InterruptedException, IllegalAccessException, InstantiationException { - List<AbstractConfiguration> configurations = getAbstractConfigurations(); + List<ConfigurationSelection> configurations = getAbstractConfigurations(); - AbstractConfiguration[] configs = new AbstractConfiguration[configurations.size()]; + ConfigurationSelection[] configs = new ConfigurationSelection[configurations.size()]; configurations.toArray(configs); - AbstractConfiguration selectedConfig = (AbstractConfiguration) JOptionPane.showInputDialog(null, "Select a configuration to run", "Configuration Selection", JOptionPane.QUESTION_MESSAGE, null, configs, configurations.get(0)); + ConfigurationSelection selectedConfig = (ConfigurationSelection) JOptionPane.showInputDialog(null, "Select a configuration to run", "Configuration Selection", JOptionPane.QUESTION_MESSAGE, null, configs, configurations.get(0)); if (selectedConfig != null) { - selectedConfig.setSystem(cSystem); - selectedConfig.run(); + Props theProps = AbstractConfiguration.props(selectedConfig.getConfigurationClass()); + + cSystem.actorOf(theProps, "Configuration"); } else { cSystem.terminate(); } } - private static List<AbstractConfiguration> getAbstractConfigurations() throws InstantiationException, IllegalAccessException { + private static List<ConfigurationSelection> getAbstractConfigurations() throws InstantiationException, IllegalAccessException { List<ClassLoader> classLoadersList = new LinkedList<>(); classLoadersList.add(ClasspathHelper.contextClassLoader()); classLoadersList.add(ClasspathHelper.staticClassLoader()); Reflections reflections = new Reflections(new ConfigurationBuilder() - .setScanners(new SubTypesScanner(false), new ResourcesScanner()) + .setScanners(new SubTypesScanner(false), new ResourcesScanner(), new TypeElementsScanner()) .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))) .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("fucoin.configurations")))); - Set<Class<? extends Object>> allClasses = - reflections.getSubTypesOf(Object.class); + Set<String> typeSet = reflections.getStore().get("TypeElementsScanner").keySet(); + HashSet<Class<?>> allClasses = Sets.newHashSet(ReflectionUtils.forNames(typeSet, reflections + .getConfiguration().getClassLoaders())); - List<AbstractConfiguration> configurations = new ArrayList<>(); + List<ConfigurationSelection> configurations = new ArrayList<>(); + + allClasses.stream().filter(oneClass -> !Modifier.isAbstract(oneClass.getModifiers()) && AbstractConfiguration.class.isAssignableFrom(oneClass)).forEach(oneClass -> { + ConfigurationSelection cfg = new ConfigurationSelection((Class<AbstractConfiguration>) oneClass); + configurations.add(cfg); + }); - for (Class<? extends Object> oneClass: allClasses){ - if (!Modifier.isAbstract(oneClass.getModifiers())) { - AbstractConfiguration cfg = (AbstractConfiguration)oneClass.newInstance(); - cfg.setSystem(cSystem); - configurations.add(cfg); - } - } return configurations; } } diff --git a/src/main/java/fucoin/actions/control/ActionWalletSendMoney.java b/src/main/java/fucoin/actions/control/ActionWalletSendMoney.java new file mode 100644 index 0000000000000000000000000000000000000000..1480d1666f28b11c6c33e8beab2c4adc8841c338 --- /dev/null +++ b/src/main/java/fucoin/actions/control/ActionWalletSendMoney.java @@ -0,0 +1,25 @@ +package fucoin.actions.control; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.actions.ClientAction; +import fucoin.wallet.AbstractWallet; + +/** + * + */ +public class ActionWalletSendMoney extends ClientAction { + + protected String address; + protected int amount; + + public ActionWalletSendMoney(String address, int amount) { + this.address = address; + this.amount = amount; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, AbstractWallet abstractNode) { + abstractNode.send(address, amount); + } +} diff --git a/src/main/java/fucoin/configurations/AbstractConfiguration.java b/src/main/java/fucoin/configurations/AbstractConfiguration.java index 649ef96d1ea5a1ce851bcb919c4947974f044950..2bb74bd14a1816e26820d8e8875b5bfed9cf894d 100644 --- a/src/main/java/fucoin/configurations/AbstractConfiguration.java +++ b/src/main/java/fucoin/configurations/AbstractConfiguration.java @@ -1,27 +1,29 @@ package fucoin.configurations; import akka.actor.ActorRef; -import akka.actor.ActorSystem; import akka.actor.Props; +import fucoin.AbstractNode; import fucoin.actions.join.ActionTellSupervisor; +import fucoin.configurations.internal.ConfigurationCreator; import fucoin.supervisor.SuperVisorImpl; import fucoin.wallet.WalletImpl; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ThreadLocalRandom; /** * */ -public abstract class AbstractConfiguration { +public abstract class AbstractConfiguration extends AbstractNode { - protected ActorSystem cSystem; protected ActorRef superVisor; protected final List<ActorRef> activeActors = new ArrayList<>(); - public void setSystem(ActorSystem system) { - cSystem = system; + public static Props props(Class configurationClass) { + + return Props.create(new ConfigurationCreator(configurationClass)); } public ActorRef spawnWallet(String name, boolean createGUI) { @@ -33,7 +35,7 @@ public abstract class AbstractConfiguration { props = WalletImpl.props(activeActors.get(numOfWallets - 1), name, createGUI); } - ActorRef actorRef = cSystem.actorOf(props, name); + ActorRef actorRef = context().actorOf(props, name); activeActors.add(actorRef); @@ -52,8 +54,12 @@ public abstract class AbstractConfiguration { } } + public ActorRef getRandomWallet() { + return activeActors.get(ThreadLocalRandom.current().nextInt(activeActors.size())); + } + public ActorRef initSupervisor() { - superVisor = cSystem.actorOf(SuperVisorImpl.props(), "SuperVisorImpl"); + superVisor = context().actorOf(SuperVisorImpl.props(), "SuperVisorImpl"); // Don't ask. try { @@ -64,6 +70,13 @@ public abstract class AbstractConfiguration { return superVisor; } + @Override + public void preStart() throws Exception { + super.preStart(); + + this.run(); + } + public abstract void run(); public abstract String getName(); diff --git a/src/main/java/fucoin/configurations/DefaultConfiguration.java b/src/main/java/fucoin/configurations/DefaultConfiguration.java index f3dd28afde014790af9af61a776592b83ced271e..924739084beef7a092174c9e98449e283c1c7f70 100644 --- a/src/main/java/fucoin/configurations/DefaultConfiguration.java +++ b/src/main/java/fucoin/configurations/DefaultConfiguration.java @@ -1,18 +1,39 @@ package fucoin.configurations; +import akka.actor.ActorRef; +import fucoin.actions.control.ActionWalletSendMoney; +import fucoin.configurations.internal.ConfigurationName; + /** * */ +@ConfigurationName("Default Configuration") public class DefaultConfiguration extends AbstractConfiguration { @Override public void run() { initSupervisor(); - spawnWallets(2, true); + + ActorRef wallet1 = spawnWallet("Wallet0", false); + ActorRef wallet2 = spawnWallet("Wallet1", false); + + // TODO: this should be solved differently + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + wallet1.tell(new ActionWalletSendMoney("Wallet1", 50), wallet1); } @Override public String getName() { return "Default Configuration"; } + + @Override + public void onReceive(Object message) { + + } } diff --git a/src/main/java/fucoin/configurations/MassWalletConfiguration.java b/src/main/java/fucoin/configurations/MassWalletConfiguration.java index f4c3587315c45041bf19f6fb3f9bcc4bb6a6dbe7..625c34bc83828d1e4266065aeb3d3d534ac158af 100644 --- a/src/main/java/fucoin/configurations/MassWalletConfiguration.java +++ b/src/main/java/fucoin/configurations/MassWalletConfiguration.java @@ -14,4 +14,9 @@ public class MassWalletConfiguration extends AbstractConfiguration { public String getName() { return "Lots of wallets"; } + + @Override + public void onReceive(Object message) { + + } } diff --git a/src/main/java/fucoin/configurations/internal/ConfigurationCreator.java b/src/main/java/fucoin/configurations/internal/ConfigurationCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..423e495c35ba1457b9563f4450a058f8b065fbaa --- /dev/null +++ b/src/main/java/fucoin/configurations/internal/ConfigurationCreator.java @@ -0,0 +1,22 @@ +package fucoin.configurations.internal; + +import akka.japi.Creator; +import fucoin.configurations.AbstractConfiguration; + +/** + * + */ +public class ConfigurationCreator implements Creator<AbstractConfiguration> { + + private Class configurationClass; + + public ConfigurationCreator(Class configurationClass) { + + this.configurationClass = configurationClass; + } + + @Override + public AbstractConfiguration create() throws Exception { + return (AbstractConfiguration) this.configurationClass.newInstance(); + } +} diff --git a/src/main/java/fucoin/configurations/internal/ConfigurationName.java b/src/main/java/fucoin/configurations/internal/ConfigurationName.java new file mode 100644 index 0000000000000000000000000000000000000000..c822acb2543e430c1224185f453f31ffc08602ae --- /dev/null +++ b/src/main/java/fucoin/configurations/internal/ConfigurationName.java @@ -0,0 +1,8 @@ +package fucoin.configurations.internal; + +/** + * + */ +public @interface ConfigurationName { + String value(); +} diff --git a/src/main/java/fucoin/configurations/internal/ConfigurationSelection.java b/src/main/java/fucoin/configurations/internal/ConfigurationSelection.java new file mode 100644 index 0000000000000000000000000000000000000000..e019f4a4ea5a8d6780946581458e8dd5a4984826 --- /dev/null +++ b/src/main/java/fucoin/configurations/internal/ConfigurationSelection.java @@ -0,0 +1,26 @@ +package fucoin.configurations.internal; + +import fucoin.configurations.AbstractConfiguration; + +import java.util.Arrays; + +/** + * + */ +public class ConfigurationSelection { + private Class<AbstractConfiguration> configurationClass; + + public ConfigurationSelection(Class<AbstractConfiguration> configurationClass) { + this.configurationClass = configurationClass; + } + + public Class<AbstractConfiguration> getConfigurationClass() { + return configurationClass; + } + + @Override + public String toString() { + System.out.println(configurationClass.isAnnotationPresent(ConfigurationName.class)); + return configurationClass.getSimpleName(); + } +}