Add subscription cancelling
[jFCPlib.git] / src / main / java / net / pterodactylus / fcp / quelaton / ActiveSubscriptions.java
1 package net.pterodactylus.fcp.quelaton;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.concurrent.ExecutionException;
9 import java.util.function.Consumer;
10 import java.util.function.Supplier;
11
12 import net.pterodactylus.fcp.FcpAdapter;
13 import net.pterodactylus.fcp.FcpConnection;
14 import net.pterodactylus.fcp.FcpListener;
15 import net.pterodactylus.fcp.Priority;
16 import net.pterodactylus.fcp.SubscribeUSK;
17 import net.pterodactylus.fcp.SubscribedUSKUpdate;
18
19 /**
20  * Maintains a record of active subscriptions.
21  *
22  * @author <a href="mailto:bombe@freenetproject.org">David ‘Bombe’ Roden</a>
23  */
24 public class ActiveSubscriptions {
25
26         private final Supplier<UnsubscribeUskCommand> unsubscribeUskCommandSupplier;
27         private final Map<String, RemoteUskSubscription> subscriptions = Collections.synchronizedMap(new HashMap<>());
28
29         public ActiveSubscriptions(Supplier<UnsubscribeUskCommand> unsubscribeUskCommandSupplier) {
30                 this.unsubscribeUskCommandSupplier = unsubscribeUskCommandSupplier;
31         }
32
33         public void renew(Consumer<FcpListener> fcpEventSender, Supplier<SubscribeUskCommand> subscribeUskCommandSupplier)
34         throws ExecutionException, InterruptedException {
35                 fcpEventSender.accept(createFcpListener());
36                 for (UskSubscription uskSubscription : subscriptions.values()) {
37                         subscribeUskCommandSupplier.get().uri(uskSubscription.getUri()).execute().get();
38                 }
39         }
40
41         private FcpListener createFcpListener() {
42                 return new FcpAdapter() {
43                         @Override
44                         public void receivedSubscribedUSKUpdate(
45                                 FcpConnection fcpConnection, SubscribedUSKUpdate subscribedUSKUpdate) {
46                                 String identifier = subscribedUSKUpdate.getIdentifier();
47                                 RemoteUskSubscription uskSubscription = subscriptions.get(identifier);
48                                 if (uskSubscription == null) {
49                                         /* TODO - log warning? */
50                                         return;
51                                 }
52                                 uskSubscription.foundUpdate(subscribedUSKUpdate.getEdition());
53                         }
54                 };
55         }
56
57         public UskSubscription createUskSubscription(SubscribeUSK subscribeUSK) {
58                 RemoteUskSubscription remoteUskSubscription =
59                         new RemoteUskSubscription(subscribeUSK.getIdentifier(), subscribeUSK.getUri(), subscribeUSK.isActive(),
60                                 subscribeUSK.isSparse(), subscribeUSK.getPriority(), subscribeUSK.getActivePriority(),
61                                 subscribeUSK.isRealTime(), subscribeUSK.isIgnoreDateHints());
62                 subscriptions.put(subscribeUSK.getIdentifier(), remoteUskSubscription);
63                 return remoteUskSubscription;
64         }
65
66         private class RemoteUskSubscription implements UskSubscription {
67
68                 private final String identifier;
69                 private final String uri;
70                 private final boolean active;
71                 private final boolean sparse;
72                 private final Priority priority;
73                 private final Priority activePriority;
74                 private final boolean realTime;
75                 private final boolean ignoreDateHints;
76                 private final List<UskUpdater> uskUpdaters = Collections.synchronizedList(new ArrayList<>());
77
78                 private RemoteUskSubscription(
79                         String identifier, String uri, boolean active, boolean sparse, Priority priority, Priority activePriority,
80                         boolean realTime, boolean ignoreDateHints) {
81                         this.identifier = identifier;
82                         this.uri = uri;
83                         this.active = active;
84                         this.sparse = sparse;
85                         this.priority = priority;
86                         this.activePriority = activePriority;
87                         this.realTime = realTime;
88                         this.ignoreDateHints = ignoreDateHints;
89                 }
90
91                 @Override
92                 public String getUri() {
93                         return uri;
94                 }
95
96                 @Override
97                 public void onUpdate(UskUpdater uskUpdater) {
98                         uskUpdaters.add(uskUpdater);
99                 }
100
101                 private void foundUpdate(int edition) {
102                         for (UskUpdater uskUpdater : uskUpdaters) {
103                                 uskUpdater.uskUpdated(edition);
104                         }
105                 }
106
107                 public void cancel() throws ExecutionException, InterruptedException {
108                         unsubscribeUskCommandSupplier.get().identifier(identifier).execute().get();
109                         subscriptions.remove(identifier);
110                 }
111
112         }
113
114 }