Skip to content

Package: TransportProxy

TransportProxy

nameinstructionbranchcomplexitylinemethod
TransportProxy(Transport, Executor)
M: 14 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
attach()
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
checkClosed()
M: 9 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
close()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
detach()
M: 13 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
fireEvent(boolean, Set)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
handleChange(boolean)
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
isAttached()
M: 7 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$fireEvent$2(Set, boolean)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
lambda$listen$0(Transport.Listener)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$null$1(boolean, Transport.Listener)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
listen(Transport.Listener)
M: 26 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
proxy(Transport, Executor)
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
removeListener(Transport.Listener)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2017, 2022 Red Hat Inc and others.
3: *
4: * This program and the accompanying materials are made
5: * available under the terms of the Eclipse Public License 2.0
6: * which is available at https://www.eclipse.org/legal/epl-2.0/
7: *
8: * SPDX-License-Identifier: EPL-2.0
9: *
10: * Contributors:
11: * Red Hat Inc - initial API and implementation
12: *******************************************************************************/
13: package org.eclipse.kapua.client.gateway.spi.util;
14:
15: import java.util.Collections;
16: import java.util.Objects;
17: import java.util.Set;
18: import java.util.concurrent.CopyOnWriteArraySet;
19: import java.util.concurrent.Executor;
20:
21: import org.eclipse.kapua.client.gateway.Transport;
22:
23: public final class TransportProxy implements Transport, AutoCloseable {
24:
25: private final Transport transport;
26: private final Executor executor;
27: private boolean closed;
28:
29: private final Set<Listener> listeners = new CopyOnWriteArraySet<>();
30:
31: private ListenerHandle handle;
32:
33: private boolean lastKnownState;
34:
35: private TransportProxy(final Transport transport, final Executor executor) {
36: this.transport = transport;
37: this.executor = executor;
38: }
39:
40: @Override
41: public void close() {
42: detach();
43: }
44:
45: @Override
46: public synchronized ListenerHandle listen(final Listener listener) {
47: Objects.requireNonNull(listener);
48:
49: checkClosed();
50:
51: // add before calling into attach()
52:
53: listeners.add(listener);
54:
55: // already attached?
56:
57:• if (isAttached()) {
58:
59: // simply fire last known state
60:
61: fireEvent(lastKnownState, Collections.singleton(listener));
62:
63: } else {
64:
65: // attach, will implicitly call listener
66:
67: attach();
68: }
69:
70: return () -> removeListener(listener);
71: }
72:
73: private void checkClosed() {
74:• if (closed) {
75: throw new IllegalStateException("TransportProxy instance is already closed");
76: }
77: }
78:
79: private boolean isAttached() {
80:• return handle != null;
81: }
82:
83: /**
84: * Remove a listener from the internal set
85: * <p>
86: * If the proxy instance is already closed, this method will <b>not</b> throw any exception
87: * </p>
88: *
89: * @param listener
90: * the listener to remove
91: */
92: private synchronized void removeListener(final Listener listener) {
93:
94: // simply remove listener
95:
96: listeners.remove(listener);
97: }
98:
99: private synchronized void handleChange(final boolean state) {
100: lastKnownState = state;
101: fireEvent(state, new CopyOnWriteArraySet<>(listeners));
102: }
103:
104: private void fireEvent(final boolean state, final Set<Listener> listeners) {
105: executor.execute(() -> {
106: listeners.stream().forEach(l -> l.stateChange(state));
107: });
108: }
109:
110: private void attach() {
111: handle = transport.listen(this::handleChange);
112: }
113:
114: private synchronized void detach() {
115:
116: // mark closed
117:
118: closed = true;
119:
120: // check for a listener handle
121:
122:• if (handle != null) {
123:
124: // and close it
125:
126: handle.close();
127: handle = null;
128: }
129: }
130:
131: /**
132: *
133: * @param transport
134: * @param executor
135: * @return
136: */
137: public static TransportProxy proxy(final Transport transport, final Executor executor) {
138: Objects.requireNonNull(transport);
139: Objects.requireNonNull(executor);
140:
141: return new TransportProxy(transport, executor);
142: }
143: }