9c9e64e3805c30e1d47d852ec990e5bee76b8bdc
[jFCPlib.git] / src / main / java / net / pterodactylus / fcp / quelaton / LoadPluginCommandImpl.java
1 package net.pterodactylus.fcp.quelaton;
2
3 import java.io.IOException;
4 import java.util.Optional;
5 import java.util.concurrent.ExecutionException;
6 import java.util.concurrent.ExecutorService;
7 import java.util.concurrent.atomic.AtomicBoolean;
8 import java.util.concurrent.atomic.AtomicReference;
9 import java.util.function.Supplier;
10
11 import net.pterodactylus.fcp.LoadPlugin;
12 import net.pterodactylus.fcp.LoadPlugin.OfficialSource;
13 import net.pterodactylus.fcp.LoadPlugin.UrlType;
14 import net.pterodactylus.fcp.PluginInfo;
15 import net.pterodactylus.fcp.ProtocolError;
16
17 import com.google.common.util.concurrent.ListenableFuture;
18 import com.google.common.util.concurrent.ListeningExecutorService;
19 import com.google.common.util.concurrent.MoreExecutors;
20
21 /**
22  * Default {@link LoadPluginCommand} implementation based on {@link FcpDialog}.
23  *
24  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
25  */
26 public class LoadPluginCommandImpl implements LoadPluginCommand {
27
28         private final ListeningExecutorService threadPool;
29         private final ConnectionSupplier connectionSupplier;
30         private final LoadPlugin loadPlugin;
31
32         public LoadPluginCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier, Supplier<String> identifierGenerator) {
33                 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
34                 this.connectionSupplier = connectionSupplier;
35                 loadPlugin = new LoadPlugin(identifierGenerator.get());
36         }
37
38         @Override
39         public LoadPluginCommand addToConfig() {
40                 loadPlugin.setStore(true);
41                 return this;
42         }
43
44         @Override
45         public Executable<Optional<PluginInfo>> officialFromFreenet(String pluginIdentifier) {
46                 loadPlugin.setUrlType(UrlType.OFFICIAL);
47                 loadPlugin.setOfficialSource(OfficialSource.FREENET);
48                 loadPlugin.setPluginUrl(pluginIdentifier);
49                 return this::execute;
50         }
51
52         @Override
53         public Executable<Optional<PluginInfo>> officialFromHttps(String pluginIdentifier) {
54                 loadPlugin.setUrlType(UrlType.OFFICIAL);
55                 loadPlugin.setOfficialSource(OfficialSource.HTTPS);
56                 loadPlugin.setPluginUrl(pluginIdentifier);
57                 return this::execute;
58         }
59
60         @Override
61         public Executable<Optional<PluginInfo>> fromFreenet(String key) {
62                 loadPlugin.setUrlType(UrlType.FREENET);
63                 loadPlugin.setPluginUrl(key);
64                 return this::execute;
65         }
66
67         @Override
68         public Executable<Optional<PluginInfo>> fromFile(String filename) {
69                 loadPlugin.setUrlType(UrlType.FILE);
70                 loadPlugin.setPluginUrl(filename);
71                 return this::execute;
72         }
73
74         @Override
75         public Executable<Optional<PluginInfo>> fromUrl(String url) {
76                 loadPlugin.setUrlType(UrlType.URL);
77                 loadPlugin.setPluginUrl(url);
78                 return this::execute;
79         }
80
81         private ListenableFuture<Optional<PluginInfo>> execute() {
82                 return threadPool.submit(this::executeDialog);
83         }
84
85         private Optional<PluginInfo> executeDialog() throws IOException, ExecutionException, InterruptedException {
86                 try (LoadPluginDialog loadPluginDialog = new LoadPluginDialog()) {
87                         return loadPluginDialog.send(loadPlugin).get();
88                 }
89         }
90
91         private class LoadPluginDialog extends FcpDialog<Optional<PluginInfo>> {
92
93                 private final AtomicBoolean finished = new AtomicBoolean();
94                 private final AtomicReference<PluginInfo> pluginInfo = new AtomicReference<>();
95
96                 public LoadPluginDialog() throws IOException {
97                         super(threadPool, connectionSupplier.get());
98                 }
99
100                 @Override
101                 protected boolean isFinished() {
102                         return finished.get();
103                 }
104
105                 @Override
106                 protected Optional<PluginInfo> getResult() {
107                         return Optional.ofNullable(pluginInfo.get());
108                 }
109
110                 @Override
111                 protected void consumePluginInfo(PluginInfo pluginInfo) {
112                         this.pluginInfo.set(pluginInfo);
113                         finished.set(true);
114                 }
115
116                 @Override
117                 protected void consumeProtocolError(ProtocolError protocolError) {
118                         finished.set(true);
119                 }
120
121         }
122
123 }