1 package net.pterodactylus.fcp.quelaton;
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.ArrayList;
7 import java.util.Optional;
8 import java.util.concurrent.ExecutionException;
9 import java.util.concurrent.ExecutorService;
10 import java.util.function.Consumer;
11 import java.util.function.Supplier;
13 import net.pterodactylus.fcp.AllData;
14 import net.pterodactylus.fcp.ClientGet;
15 import net.pterodactylus.fcp.FcpUtils.TempInputStream;
16 import net.pterodactylus.fcp.GetFailed;
17 import net.pterodactylus.fcp.Priority;
18 import net.pterodactylus.fcp.ReturnType;
20 import com.google.common.util.concurrent.ListeningExecutorService;
21 import com.google.common.util.concurrent.MoreExecutors;
24 * Implementation of the {@link ClientGetCommand}.
26 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
28 class ClientGetCommandImpl implements ClientGetCommand {
30 private final ListeningExecutorService threadPool;
31 private final ConnectionSupplier connectionSupplier;
32 private final Supplier<String> identifierGenerator;
33 private final List<Consumer<String>> onRedirects = new ArrayList<>();
35 private boolean ignoreDataStore;
36 private boolean dataStoreOnly;
38 private Priority priority;
39 private boolean realTime;
40 private boolean global;
42 public ClientGetCommandImpl(ExecutorService threadPool, ConnectionSupplier connectionSupplier, Supplier<String> identifierGenerator) {
43 this.threadPool = MoreExecutors.listeningDecorator(threadPool);
44 this.connectionSupplier = connectionSupplier;
45 this.identifierGenerator = identifierGenerator;
49 public ClientGetCommand onRedirect(Consumer<String> onRedirect) {
50 onRedirects.add(onRedirect);
55 public ClientGetCommand ignoreDataStore() {
56 ignoreDataStore = true;
61 public ClientGetCommand dataStoreOnly() {
67 public ClientGetCommand maxSize(long maxSize) {
68 this.maxSize = maxSize;
73 public ClientGetCommand priority(Priority priority) {
74 this.priority = priority;
79 public ClientGetCommand realTime() {
85 public ClientGetCommand global() {
91 public Executable<Optional<Data>> uri(String uri) {
92 return () -> threadPool.submit(() -> execute(uri));
95 private Optional<Data> execute(String uri) throws InterruptedException, ExecutionException, IOException {
96 ClientGet clientGet = createClientGetCommand(identifierGenerator.get(), uri);
97 try (ClientGetDialog clientGetDialog = new ClientGetDialog()) {
98 return clientGetDialog.send(clientGet).get();
102 private ClientGet createClientGetCommand(String identifier, String uri) {
103 ClientGet clientGet = new ClientGet(uri, identifier, ReturnType.direct);
104 if (ignoreDataStore) {
105 clientGet.setIgnoreDataStore(true);
108 clientGet.setDataStoreOnly(true);
110 if (maxSize != null) {
111 clientGet.setMaxSize(maxSize);
113 if (priority != null) {
114 clientGet.setPriority(priority);
117 clientGet.setRealTimeFlag(true);
120 clientGet.setGlobal(true);
125 private class ClientGetDialog extends FcpDialog<Optional<Data>> {
127 public ClientGetDialog() throws IOException {
128 super(ClientGetCommandImpl.this.threadPool, ClientGetCommandImpl.this.connectionSupplier.get(),
129 Optional.<Data>empty());
133 protected void consumeAllData(AllData allData) {
134 synchronized (this) {
135 String contentType = allData.getContentType();
136 long dataLength = allData.getDataLength();
138 InputStream payload = new TempInputStream(allData.getPayloadInputStream(), dataLength);
139 setResult(Optional.of(createData(contentType, dataLength, payload)));
140 } catch (IOException e) {
147 private Data createData(String contentType, long dataLength, InputStream payload) {
150 public String getMimeType() {
160 public InputStream getInputStream() {
167 protected void consumeGetFailed(GetFailed getFailed) {
168 if (getFailed.getCode() == 27) {
169 onRedirects.forEach(onRedirect -> onRedirect.accept(getFailed.getRedirectURI()));
170 sendMessage(createClientGetCommand(getIdentifier(), getFailed.getRedirectURI()));