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