3e9e85062b0a58e26812c2983bd088c6ac636df4
[jFCPlib.git] / src / main / java / net / pterodactylus / fcp / quelaton / GetNodeCommandImpl.java
1 package net.pterodactylus.fcp.quelaton;
2
3 import java.io.IOException;
4 import java.util.concurrent.ExecutionException;
5 import java.util.concurrent.ExecutorService;
6 import java.util.concurrent.atomic.AtomicBoolean;
7 import java.util.concurrent.atomic.AtomicReference;
8
9 import net.pterodactylus.fcp.GetNode;
10 import net.pterodactylus.fcp.NodeData;
11
12 import com.google.common.util.concurrent.ListenableFuture;
13 import com.google.common.util.concurrent.ListeningExecutorService;
14 import com.google.common.util.concurrent.MoreExecutors;
15
16 /**
17  * Default {@link GetNodeCommandImpl} implementation based on {@link FcpDialog}.
18  *
19  * @author <a href="mailto:bombe@freenetproject.org">David ‘Bombe’ Roden</a>
20  */
21 public class GetNodeCommandImpl implements GetNodeCommand {
22
23         private final ListeningExecutorService threadPool;
24         private final ConnectionSupplier connectionSupplier;
25         private final AtomicBoolean giveOpennetRef = new AtomicBoolean(false);
26         private final AtomicBoolean includePrivate = new AtomicBoolean(false);
27         private final AtomicBoolean includeVolatile = new AtomicBoolean(false);
28
29         public GetNodeCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier) {
30                 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
31                 this.connectionSupplier = connectionSupplier;
32         }
33
34         @Override
35         public GetNodeCommand opennetRef() {
36                 giveOpennetRef.set(true);
37                 return this;
38         }
39
40         @Override
41         public GetNodeCommand includePrivate() {
42                 includePrivate.set(true);
43                 return this;
44         }
45
46         @Override
47         public GetNodeCommand includeVolatile() {
48                 includeVolatile.set(true);
49                 return this;
50         }
51
52         @Override
53         public ListenableFuture<NodeData> execute() {
54                 return threadPool.submit(this::executeDialog);
55         }
56
57         private NodeData executeDialog() throws InterruptedException, ExecutionException, IOException {
58                 GetNode getNode = new GetNode(new RandomIdentifierGenerator().generate(), giveOpennetRef.get(),
59                         includePrivate.get(), includeVolatile.get());
60                 try (GetNodeDialog getNodeDialog = new GetNodeDialog()) {
61                         return getNodeDialog.send(getNode).get();
62                 }
63         }
64
65         private class GetNodeDialog extends FcpDialog<NodeData> {
66
67                 private final AtomicReference<NodeData> nodeData = new AtomicReference<>();
68
69                 public GetNodeDialog() throws IOException {
70                         super(threadPool, connectionSupplier.get());
71                 }
72
73                 @Override
74                 protected boolean isFinished() {
75                         return nodeData.get() != null;
76                 }
77
78                 @Override
79                 protected NodeData getResult() {
80                         return nodeData.get();
81                 }
82
83                 @Override
84                 protected void consumeNodeData(NodeData nodeData) {
85                         this.nodeData.set(nodeData);
86                 }
87
88         }
89
90 }