8e1df8c0c5d04aefbadba526c74614be89352994
[jFCPlib.git] / src / main / java / net / pterodactylus / fcp / quelaton / ListPeerNotesCommandImpl.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.EndListPeerNotes;
12 import net.pterodactylus.fcp.ListPeerNotes;
13 import net.pterodactylus.fcp.PeerNote;
14 import net.pterodactylus.fcp.UnknownNodeIdentifier;
15
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.ListeningExecutorService;
18 import com.google.common.util.concurrent.MoreExecutors;
19
20 /**
21  * Default {@link ListPeerNotesCommand} implementation based on {@link FcpDialog}.
22  *
23  * @author <a href="mailto:bombe@freenetproject.org">David ‘Bombe’ Roden</a>
24  */
25 public class ListPeerNotesCommandImpl implements ListPeerNotesCommand {
26
27         private final ListeningExecutorService threadPool;
28         private final ConnectionSupplier connectionSupplier;
29         private final Supplier<String> identifierGenerator;
30         private final AtomicReference<String> nodeIdentifier = new AtomicReference<>();
31
32         public ListPeerNotesCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier, Supplier<String> identifierGenerator) {
33                 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
34                 this.connectionSupplier = connectionSupplier;
35                 this.identifierGenerator = identifierGenerator;
36         }
37
38         @Override
39         public Executable<Optional<PeerNote>> byName(String name) {
40                 nodeIdentifier.set(name);
41                 return this::execute;
42         }
43
44         @Override
45         public Executable<Optional<PeerNote>> byIdentity(String identity) {
46                 nodeIdentifier.set(identity);
47                 return this::execute;
48         }
49
50         @Override
51         public Executable<Optional<PeerNote>> byHostAndPort(String host, int port) {
52                 nodeIdentifier.set(String.format("%s:%d", host, port));
53                 return this::execute;
54         }
55
56         private ListenableFuture<Optional<PeerNote>> execute() {
57                 return threadPool.submit(this::executeDialog);
58         }
59
60         private Optional<PeerNote> executeDialog() throws IOException, ExecutionException, InterruptedException {
61                 ListPeerNotes listPeerNotes = new ListPeerNotes(identifierGenerator.get(), nodeIdentifier.get());
62                 try (ListPeerNotesDialog listPeerNotesDialog = new ListPeerNotesDialog()) {
63                         return listPeerNotesDialog.send(listPeerNotes).get();
64                 }
65         }
66
67         private class ListPeerNotesDialog extends FcpDialog<Optional<PeerNote>> {
68
69                 private final AtomicReference<PeerNote> peerNote = new AtomicReference<>();
70                 private final AtomicBoolean finished = new AtomicBoolean();
71
72                 public ListPeerNotesDialog() throws IOException {
73                         super(threadPool, connectionSupplier.get());
74                 }
75
76                 @Override
77                 protected boolean isFinished() {
78                         return finished.get();
79                 }
80
81                 @Override
82                 protected Optional<PeerNote> getResult() {
83                         return Optional.ofNullable(peerNote.get());
84                 }
85
86                 @Override
87                 protected void consumePeerNote(PeerNote peerNote) {
88                         this.peerNote.set(peerNote);
89                 }
90
91                 @Override
92                 protected void consumeEndListPeerNotes(EndListPeerNotes endListPeerNotes) {
93                         finished.set(true);
94                 }
95
96                 @Override
97                 protected void consumeUnknownNodeIdentifier(UnknownNodeIdentifier unknownNodeIdentifier) {
98                         finished.set(true);
99                 }
100
101         }
102
103 }