Skip to content

Package: MessageBusHelper

MessageBusHelper

nameinstructionbranchcomplexitylinemethod
publish(Class, Object)
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%
publish(Object)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
registerMessageListener(Method)
M: 0 C: 25
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
subscribeAll()
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
unsubscribeAll()
M: 0 C: 15
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%

Coverage

1: /*
2: * *************************************************************************************************************************************************************
3: *
4: * TheseFoolishThings: Miscellaneous utilities
5: * http://tidalwave.it/projects/thesefoolishthings
6: *
7: * Copyright (C) 2009 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *************************************************************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12: * You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17: * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18: *
19: * *************************************************************************************************************************************************************
20: *
21: * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
22: * git clone https://github.com/tidalwave-it/thesefoolishthings-src
23: *
24: * *************************************************************************************************************************************************************
25: */
26: package it.tidalwave.messagebus;
27:
28: import java.lang.reflect.Method;
29: import javax.annotation.Nonnull;
30: import java.util.ArrayList;
31: import java.util.List;
32: import it.tidalwave.messagebus.annotation.ListensTo;
33: import it.tidalwave.messagebus.annotation.SimpleMessageSubscriber;
34: import lombok.RequiredArgsConstructor;
35: import lombok.extern.slf4j.Slf4j;
36: import static it.tidalwave.messagebus.spi.ReflectionUtils.*;
37: import static it.tidalwave.messagebus.spi.ReflectionUtils.MethodProcessor.FilterResult.*;
38:
39: /***************************************************************************************************************************************************************
40: *
41: * @author Fabrizio Giudici
42: *
43: **************************************************************************************************************************************************************/
44: @RequiredArgsConstructor @Slf4j
45: public class MessageBusHelper
46: {
47: /***********************************************************************************************************************************************************
48: *
49: **********************************************************************************************************************************************************/
50: public static interface Adapter
51: {
52: @Nonnull
53: public <T> MethodAdapter<T> createMethodAdapter (@Nonnull Object object,
54: @Nonnull Method method,
55: @Nonnull Class<T> topic);
56:
57: public void publish (@Nonnull Object message);
58:
59: public <T> void publish (Class<T> topic, @Nonnull T message);
60: }
61:
62: /***********************************************************************************************************************************************************
63: *
64: **********************************************************************************************************************************************************/
65: public static interface MethodAdapter<T>
66: {
67: public void subscribe();
68:
69: public void unsubscribe();
70: }
71:
72: @Nonnull
73: private final Object owner;
74:
75: @Nonnull
76: private final Adapter methodAdapterFactory;
77:
78: private final List<MethodAdapter<?>> methodAdapters = new ArrayList<>();
79:
80: /***********************************************************************************************************************************************************
81: *
82: **********************************************************************************************************************************************************/
83: public void subscribeAll()
84: {
85: forEachMethodInTopDownHierarchy(owner, new MethodProcessor()
86: {
87: @Override @Nonnull
88: public FilterResult filter (@Nonnull final Class<?> clazz)
89: {
90: return clazz.getAnnotation(SimpleMessageSubscriber.class) != null ? ACCEPT : IGNORE;
91: }
92:
93: @Override
94: public void process (@Nonnull final Method method)
95: {
96: final var parameterAnnotations = method.getParameterAnnotations();
97:
98: if ((parameterAnnotations.length == 1) && containsAnnotation(parameterAnnotations[0], ListensTo.class))
99: {
100: registerMessageListener(method);
101: }
102: }
103: });
104: }
105:
106: /***********************************************************************************************************************************************************
107: *
108: **********************************************************************************************************************************************************/
109: public void unsubscribeAll()
110: {
111:• for (final var methodAdapter : methodAdapters)
112: {
113: methodAdapter.unsubscribe();
114: }
115: }
116:
117: /***********************************************************************************************************************************************************
118: * Publishes a message.
119: *
120: * @param message the message to deliver
121: **********************************************************************************************************************************************************/
122: public void publish (@Nonnull final Object message)
123: {
124: methodAdapterFactory.publish(message);
125: }
126:
127: /***********************************************************************************************************************************************************
128: * Publishes a message.
129: *
130: * @param <T> the static type of the topic
131: * @param topicType the dynamic type of the topic
132: * @param topic the topic
133: **********************************************************************************************************************************************************/
134: public <T> void publish (@Nonnull final Class<T> topicType, @Nonnull final T topic)
135: {
136: methodAdapterFactory.publish(topicType, topic);
137: }
138:
139: /***********************************************************************************************************************************************************
140: *
141: **********************************************************************************************************************************************************/
142: private <T> void registerMessageListener (@Nonnull final Method method)
143: {
144: log.trace("registerMessageListener({})", method);
145:
146: final var topic = (Class<T>)method.getParameterTypes()[0];
147: final var methodAdapter = methodAdapterFactory.createMethodAdapter(owner, method, topic);
148: methodAdapters.add(methodAdapter);
149: methodAdapter.subscribe();
150: }
151: }