Skip to content

Commit 12e9e22

Browse files
committed
Add notification api + sample usage
Add notification api + sample usage
1 parent 3d50af8 commit 12e9e22

12 files changed

+149
-15
lines changed

.classpath

-11
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,13 @@
66
<attribute name="maven.pomderived" value="true"/>
77
</attributes>
88
</classpathentry>
9-
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
10-
<attributes>
11-
<attribute name="maven.pomderived" value="true"/>
12-
</attributes>
13-
</classpathentry>
149
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
1510
<attributes>
1611
<attribute name="optional" value="true"/>
1712
<attribute name="maven.pomderived" value="true"/>
1813
<attribute name="test" value="true"/>
1914
</attributes>
2015
</classpathentry>
21-
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
22-
<attributes>
23-
<attribute name="maven.pomderived" value="true"/>
24-
<attribute name="test" value="true"/>
25-
</attributes>
26-
</classpathentry>
2716
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
2817
<attributes>
2918
<attribute name="maven.pomderived" value="true"/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package shortbus;
2+
3+
import java.util.List;
4+
5+
public class AggregateException extends Exception {
6+
7+
private static final long serialVersionUID = 1L;
8+
private List<Exception> exceptions;
9+
10+
public AggregateException(List<Exception> exceptions) {
11+
this.exceptions = exceptions;
12+
}
13+
14+
public List<Exception> getExceptions() {
15+
return exceptions;
16+
}
17+
18+
}

src/main/java/shortbus/Mediator.java

+7
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,11 @@ public interface Mediator {
1111
* @return Response object
1212
*/
1313
public <T> Response<T> request(Request<T> request);
14+
15+
/**
16+
* Send a notification to all handler.
17+
* @param notification
18+
* @return
19+
*/
20+
public Response<Void> notify(Notification notification);
1421
}

src/main/java/shortbus/MediatorImpl.java

+52-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.lang.reflect.Method;
55
import java.lang.reflect.ParameterizedType;
66
import java.lang.reflect.Type;
7+
import java.util.ArrayList;
8+
import java.util.List;
79
import java.util.Map;
810
import java.util.Map.Entry;
911

@@ -19,6 +21,7 @@ public class MediatorImpl implements Mediator {
1921

2022
/**
2123
* Initializes a new instance of Mediator
24+
*
2225
* @param ctx Application context of Spring
2326
*/
2427
public MediatorImpl(ApplicationContext ctx) {
@@ -29,19 +32,45 @@ public MediatorImpl(ApplicationContext ctx) {
2932
public <T> Response<T> request(Request<T> request) {
3033
Response<T> response = new Response<>();
3134
try {
32-
MediatorPlan<T> plan = new MediatorPlan<>(RequestHandler.class, "handle", request.getClass(), ctx);
35+
MediatorPlanRequest<T> plan = new MediatorPlanRequest<>(RequestHandler.class, "handle", request.getClass(),
36+
ctx);
3337
response.data = plan.invoke(request);
3438
} catch (Exception e) {
3539
response.exception = e;
3640
}
3741
return response;
3842
}
3943

40-
class MediatorPlan<T> {
44+
@Override
45+
public Response<Void> notify(Notification notification) {
46+
Response<Void> response = new Response<>();
47+
List<NotificationHandler<Notification>> handlers = MediatorPlanNotify.getInstances(ctx,
48+
notification.getClass());
49+
List<Exception> exceptions = null;
50+
51+
for (NotificationHandler<Notification> handler : handlers) {
52+
try {
53+
handler.handle(notification);
54+
} catch (Exception ex) {
55+
if (exceptions == null)
56+
exceptions = new ArrayList<>();
57+
58+
exceptions.add(ex);
59+
}
60+
}
61+
62+
if (exceptions != null) {
63+
response.exception = new AggregateException(exceptions);
64+
}
65+
66+
return response;
67+
}
68+
69+
class MediatorPlanRequest<T> {
4170
Method handleMethod;
4271
Object handlerInstanceBuilder;
4372

44-
public MediatorPlan(Class<?> handlerType, String handlerMethodName, Class<?> messageType,
73+
public MediatorPlanRequest(Class<?> handlerType, String handlerMethodName, Class<?> messageType,
4574
ApplicationContext context) throws NoSuchMethodException, SecurityException, ClassNotFoundException {
4675
handlerInstanceBuilder = getBean(handlerType, messageType, context);
4776
handleMethod = handlerInstanceBuilder.getClass().getDeclaredMethod(handlerMethodName, messageType);
@@ -70,4 +99,24 @@ public T invoke(Request<T> request)
7099
}
71100
}
72101

102+
static class MediatorPlanNotify {
103+
public static List<NotificationHandler<Notification>> getInstances(ApplicationContext ctx,
104+
Class<?> messageType) {
105+
List<NotificationHandler<Notification>> instances = new ArrayList<>();
106+
107+
Map<String, ?> beans = ctx.getBeansOfType(NotificationHandler.class);
108+
for (Entry<String, ?> entry : beans.entrySet()) {
109+
Class<?> clazz = entry.getValue().getClass();
110+
Type[] interfaces = clazz.getGenericInterfaces();
111+
for (Type interace : interfaces) {
112+
Type parameterType = ((ParameterizedType) interace).getActualTypeArguments()[0];
113+
if (parameterType.equals(messageType)) {
114+
instances.add((NotificationHandler<Notification>) entry.getValue());
115+
}
116+
}
117+
}
118+
119+
return instances;
120+
}
121+
}
73122
}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package shortbus;
2+
3+
/**
4+
* Marker interface to represent a notification.
5+
*
6+
*/
7+
public interface Notification {
8+
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package shortbus;
2+
3+
/**
4+
* Defines a handler for all notification.
5+
*
6+
* @param <T> Notification
7+
*/
8+
public interface NotificationHandler<T> {
9+
/**
10+
* Handles all notification
11+
* @param Object parameter of Notification
12+
*/
13+
public void handle(T notification);
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package shortbus;
2+
3+
public class AnotherNotification implements Notification {
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package shortbus;
2+
3+
public class Bar1Notification implements NotificationHandler<FooNotification> {
4+
5+
@Override
6+
public void handle(FooNotification notification) {
7+
notification.counter++;
8+
}
9+
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package shortbus;
2+
3+
public class Bar2Notification implements NotificationHandler<FooNotification> {
4+
5+
@Override
6+
public void handle(FooNotification notification) {
7+
notification.counter++;
8+
}
9+
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package shortbus;
2+
3+
public class Bar3Notification implements NotificationHandler<AnotherNotification> {
4+
5+
@Override
6+
public void handle(AnotherNotification notification) {
7+
8+
}
9+
10+
}

src/test/java/shortbus/BasicExampleTest.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212
@SpringBootTest
1313
@RunWith(SpringRunner.class)
14-
@ContextConfiguration(classes = { TestSetup.class, Bar.class })
14+
@ContextConfiguration(classes = { TestSetup.class, Bar.class, Bar1Notification.class, Bar2Notification.class,
15+
Bar3Notification.class })
1516
public class BasicExampleTest {
1617

1718
@Autowired
@@ -36,4 +37,11 @@ public void requestResponseVoid() {
3637
Response<Void> response = mediator.request(new FooVoid());
3738
assertThat(response.data).isNull();
3839
}
40+
41+
@Test
42+
public void sendNotification() {
43+
FooNotification notification = new FooNotification();
44+
mediator.notify(notification);
45+
assertThat(notification.counter).isEqualTo(2);
46+
}
3947
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package shortbus;
2+
3+
public class FooNotification implements Notification {
4+
public int counter = 0;
5+
}

0 commit comments

Comments
 (0)