]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/MultiAccountManagerImpl.java
Use modern switch syntax
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / MultiAccountManagerImpl.java
1 package org.asamk.signal.manager;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5
6 import java.io.IOException;
7 import java.net.URI;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15 import java.util.concurrent.TimeoutException;
16 import java.util.function.Consumer;
17
18 class MultiAccountManagerImpl implements MultiAccountManager {
19
20 private final static Logger logger = LoggerFactory.getLogger(MultiAccountManagerImpl.class);
21
22 private final Set<Consumer<Manager>> onManagerAddedHandlers = new HashSet<>();
23 private final Set<Consumer<Manager>> onManagerRemovedHandlers = new HashSet<>();
24 private final Set<Manager> managers = new HashSet<>();
25 private final Map<URI, ProvisioningManager> provisioningManagers = new HashMap<>();
26 private final SignalAccountFiles signalAccountFiles;
27
28 public MultiAccountManagerImpl(final Collection<Manager> managers, final SignalAccountFiles signalAccountFiles) {
29 this.signalAccountFiles = signalAccountFiles;
30 this.managers.addAll(managers);
31 managers.forEach(m -> m.addClosedListener(() -> this.removeManager(m)));
32 }
33
34 @Override
35 public List<String> getAccountNumbers() {
36 synchronized (managers) {
37 return managers.stream().map(Manager::getSelfNumber).toList();
38 }
39 }
40
41 @Override
42 public List<Manager> getManagers() {
43 synchronized (managers) {
44 return new ArrayList<>(managers);
45 }
46 }
47
48 void addManager(final Manager m) {
49 synchronized (managers) {
50 if (managers.contains(m)) {
51 return;
52 }
53 managers.add(m);
54 m.addClosedListener(() -> this.removeManager(m));
55 }
56 synchronized (onManagerAddedHandlers) {
57 for (final var handler : onManagerAddedHandlers) {
58 handler.accept(m);
59 }
60 }
61 }
62
63 @Override
64 public void addOnManagerAddedHandler(final Consumer<Manager> handler) {
65 synchronized (onManagerAddedHandlers) {
66 onManagerAddedHandlers.add(handler);
67 }
68 }
69
70 void removeManager(final Manager m) {
71 synchronized (managers) {
72 if (!managers.remove(m)) {
73 return;
74 }
75 }
76 synchronized (onManagerRemovedHandlers) {
77 for (final var handler : onManagerRemovedHandlers) {
78 handler.accept(m);
79 }
80 }
81 }
82
83 @Override
84 public void addOnManagerRemovedHandler(final Consumer<Manager> handler) {
85 synchronized (onManagerRemovedHandlers) {
86 onManagerRemovedHandlers.add(handler);
87 }
88 }
89
90 @Override
91 public Manager getManager(final String number) {
92 synchronized (managers) {
93 return managers.stream().filter(m -> m.getSelfNumber().equals(number)).findFirst().orElse(null);
94 }
95 }
96
97 @Override
98 public URI getNewProvisioningDeviceLinkUri() throws TimeoutException, IOException {
99 final var provisioningManager = getNewProvisioningManager();
100 final var deviceLinkUri = provisioningManager.getDeviceLinkUri();
101 provisioningManagers.put(deviceLinkUri, provisioningManager);
102 return deviceLinkUri;
103 }
104
105 @Override
106 public ProvisioningManager getProvisioningManagerFor(final URI deviceLinkUri) {
107 return provisioningManagers.remove(deviceLinkUri);
108 }
109
110 private ProvisioningManager getNewProvisioningManager() {
111 return signalAccountFiles.initProvisioningManager(this::addManager);
112 }
113
114 @Override
115 public RegistrationManager getNewRegistrationManager(String number) throws IOException {
116 return signalAccountFiles.initRegistrationManager(number, this::addManager);
117 }
118
119 @Override
120 public void close() {
121 synchronized (managers) {
122 for (var m : new ArrayList<>(managers)) {
123 try {
124 m.close();
125 } catch (IOException e) {
126 logger.warn("Cleanup failed", e);
127 }
128 }
129 managers.clear();
130 }
131 }
132 }