Add method to ignore source for a peer
[jFCPlib.git] / src / main / java / net / pterodactylus / fcp / quelaton / ModifyPeerCommandImpl.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
10 import net.pterodactylus.fcp.ModifyPeer;
11 import net.pterodactylus.fcp.Peer;
12 import net.pterodactylus.fcp.UnknownNodeIdentifier;
13
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.ListeningExecutorService;
16 import com.google.common.util.concurrent.MoreExecutors;
17
18 /**
19  * Default {@link ModifyPeerCommand} implementation based on {@link FcpDialog}.
20  *
21  * @author <a href="mailto:bombe@freenetproject.org">David ‘Bombe’ Roden</a>
22  */
23 public class ModifyPeerCommandImpl implements ModifyPeerCommand {
24
25         private final ListeningExecutorService threadPool;
26         private final ConnectionSupplier connectionSupplier;
27         private final AtomicReference<String> nodeIdentifier = new AtomicReference<>();
28         private final AtomicReference<Boolean> enabled = new AtomicReference<>();
29         private final AtomicReference<Boolean> allowLocalAddresses = new AtomicReference<>();
30         private final AtomicReference<Boolean> burstOnly = new AtomicReference<>();
31         private final AtomicReference<Boolean> listenOnly = new AtomicReference<>();
32         private final AtomicReference<Boolean> ignoreSource = new AtomicReference<>();
33
34         public ModifyPeerCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier) {
35                 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
36                 this.connectionSupplier = connectionSupplier;
37         }
38
39         @Override
40         public ModifyPeerCommand enable() {
41                 enabled.set(true);
42                 return this;
43         }
44
45         @Override
46         public ModifyPeerCommand disable() {
47                 enabled.set(false);
48                 return this;
49         }
50
51         @Override
52         public ModifyPeerCommand allowLocalAddresses() {
53                 allowLocalAddresses.set(true);
54                 return this;
55         }
56
57         @Override
58         public ModifyPeerCommand disallowLocalAddresses() {
59                 allowLocalAddresses.set(false);
60                 return this;
61         }
62
63         @Override
64         public ModifyPeerCommand setBurstOnly() {
65                 burstOnly.set(true);
66                 return this;
67         }
68
69         @Override
70         public ModifyPeerCommand clearBurstOnly() {
71                 burstOnly.set(false);
72                 return this;
73         }
74
75         @Override
76         public ModifyPeerCommand setListenOnly() {
77                 listenOnly.set(true);
78                 return this;
79         }
80
81         @Override
82         public ModifyPeerCommand clearListenOnly() {
83                 listenOnly.set(false);
84                 return this;
85         }
86
87         @Override
88         public ModifyPeerCommand ignoreSource() {
89                 ignoreSource.set(true);
90                 return this;
91         }
92
93         @Override
94         public Executable<Optional<Peer>> byName(String name) {
95                 nodeIdentifier.set(name);
96                 return this::execute;
97         }
98
99         @Override
100         public Executable<Optional<Peer>> byIdentity(String nodeIdentity) {
101                 nodeIdentifier.set(nodeIdentity);
102                 return this::execute;
103         }
104
105         @Override
106         public Executable<Optional<Peer>> byHostAndPort(String host, int port) {
107                 nodeIdentifier.set(String.format("%s:%d", host, port));
108                 return this::execute;
109         }
110
111         private ListenableFuture<Optional<Peer>> execute() {
112                 return threadPool.submit(this::executeSequence);
113         }
114
115         private Optional<Peer> executeSequence() throws IOException, ExecutionException, InterruptedException {
116                 ModifyPeer modifyPeer = new ModifyPeer(new RandomIdentifierGenerator().generate(), nodeIdentifier.get());
117                 Optional.ofNullable(enabled.get()).ifPresent(enabled -> modifyPeer.setEnabled(enabled));
118                 Optional.ofNullable(allowLocalAddresses.get()).ifPresent(allowed -> modifyPeer.setAllowLocalAddresses(allowed));
119                 Optional.ofNullable(burstOnly.get()).ifPresent(burstOnly -> modifyPeer.setBurstOnly(burstOnly));
120                 Optional.ofNullable(listenOnly.get()).ifPresent(listenOnly -> modifyPeer.setListenOnly(listenOnly));
121                 Optional.ofNullable(ignoreSource.get()).ifPresent(ignoreSource -> modifyPeer.setIgnoreSource(ignoreSource));
122                 try (ModifyPeerDialog modifyPeerDialog = new ModifyPeerDialog()) {
123                         return modifyPeerDialog.send(modifyPeer).get();
124                 }
125         }
126
127         private class ModifyPeerDialog extends FcpDialog<Optional<Peer>> {
128
129                 private final AtomicBoolean finished = new AtomicBoolean();
130                 private final AtomicReference<Peer> peer = new AtomicReference<>();
131
132                 public ModifyPeerDialog() throws IOException {
133                         super(threadPool, connectionSupplier.get());
134                 }
135
136                 @Override
137                 protected boolean isFinished() {
138                         return finished.get();
139                 }
140
141                 @Override
142                 protected Optional<Peer> getResult() {
143                         return Optional.ofNullable(peer.get());
144                 }
145
146                 @Override
147                 protected void consumePeer(Peer peer) {
148                         this.peer.set(peer);
149                         finished.set(true);
150                 }
151
152                 @Override
153                 protected void consumeUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
154                         finished.set(true);
155                 }
156
157         }
158
159 }