Skip to content

Commit c51947a

Browse files
Improve code layout of handler method classes.
1 parent dbbdabd commit c51947a

File tree

7 files changed

+102
-33
lines changed

7 files changed

+102
-33
lines changed

server/src/main/java/org/spine3/server/aggregate/Aggregate.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
package org.spine3.server.aggregate;
2121

2222
import com.google.common.annotations.VisibleForTesting;
23-
import com.google.common.base.Predicate;
2423
import com.google.common.collect.ImmutableList;
2524
import com.google.common.collect.ImmutableSet;
2625
import com.google.common.collect.Lists;
@@ -94,10 +93,6 @@ public abstract class Aggregate<I, S extends Message, B extends Message.Builder>
9493
extends Entity<I, S>
9594
implements CommandHandler {
9695

97-
/* package */ static final Predicate<Method> IS_AGGREGATE_COMMAND_HANDLER = CommandHandlerMethod.PREDICATE;
98-
99-
/* package */ static final Predicate<Method> IS_EVENT_APPLIER = new EventApplier.FilterPredicate();
100-
10196
/**
10297
* The builder for the aggregate state.
10398
*
@@ -160,8 +155,7 @@ public Aggregate(I id) {
160155
*/
161156
@CheckReturnValue
162157
/* package */ static ImmutableSet<Class<? extends Message>> getCommandClasses(Class<? extends Aggregate> clazz) {
163-
final ImmutableSet<Class<? extends Message>> classes = Classes.getHandledMessageClasses(clazz, IS_AGGREGATE_COMMAND_HANDLER);
164-
return classes;
158+
return Classes.getHandledMessageClasses(clazz, CommandHandlerMethod.PREDICATE);
165159
}
166160

167161
/**
@@ -171,8 +165,7 @@ public Aggregate(I id) {
171165
* @return immutable set of event classes
172166
*/
173167
/* package */ static ImmutableSet<Class<? extends Message>> getEventClasses(Class<? extends Aggregate> clazz) {
174-
final ImmutableSet<Class<? extends Message>> classes = Classes.getHandledMessageClasses(clazz, IS_EVENT_APPLIER);
175-
return classes;
168+
return Classes.getHandledMessageClasses(clazz, EventApplier.PREDICATE);
176169
}
177170

178171
/**
@@ -233,7 +226,9 @@ protected B getBuilder() {
233226
* Updates the aggregate state and closes the update phase of the aggregate.
234227
*/
235228
private void updateState() {
236-
@SuppressWarnings("unchecked") // It is safe to cast as we checked compatibility in init();
229+
@SuppressWarnings("unchecked") // It is safe to assume that correct builder type is passed to aggregate,
230+
// because otherwise it won't be possible to write the code of applier methods that make sense to the
231+
// aggregate.
237232
final S newState = (S) getBuilder().build();
238233
setState(newState, getVersion(), whenModified());
239234

server/src/main/java/org/spine3/server/aggregate/EventApplier.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,11 @@
2323
import com.google.common.base.Predicate;
2424
import com.google.protobuf.Message;
2525
import org.spine3.server.internal.MessageHandlerMethod;
26-
import org.spine3.server.reflect.MethodMap;
27-
import org.spine3.server.reflect.Methods;
2826

2927
import javax.annotation.Nullable;
3028
import java.lang.reflect.InvocationTargetException;
3129
import java.lang.reflect.Method;
3230
import java.lang.reflect.Modifier;
33-
import java.util.Map;
3431

3532
import static com.google.common.base.Preconditions.checkNotNull;
3633

@@ -41,6 +38,11 @@
4138
*/
4239
/* package */ class EventApplier extends MessageHandlerMethod<Aggregate, Void> {
4340

41+
/**
42+
* The instance of the predicate to filter event applier methods of an aggregate class.
43+
*/
44+
/* package */ static final Predicate<Method> PREDICATE = new FilterPredicate();
45+
4446
/**
4547
* Creates a new instance to wrap {@code method} on {@code target}.
4648
*
@@ -65,21 +67,19 @@ protected <R> R invoke(Message message) throws InvocationTargetException {
6567
* @param methods the map of methods to check
6668
* @see MessageHandlerMethod#log()
6769
*/
68-
public static void checkModifiers(MethodMap methods) {
69-
for (Map.Entry<Class<? extends Message>, Method> entry : methods.entrySet()) {
70-
final Method method = entry.getValue();
70+
/* package */ static void checkModifiers(Iterable<Method> methods) {
71+
for (Method method : methods) {
7172
final boolean isPrivate = Modifier.isPrivate(method.getModifiers());
7273
if (!isPrivate) {
73-
log().warn(String.format("Event applier method %s must be declared 'private'.",
74-
Methods.getFullMethodName(method)));
74+
warnOnWrongModifier("Event applier method {} must be declared 'private'.", method);
7575
}
7676
}
7777
}
7878

7979
/**
8080
* The predicate for filtering event applier methods.
8181
*/
82-
/* package */ static class FilterPredicate implements Predicate<Method> {
82+
private static class FilterPredicate implements Predicate<Method> {
8383

8484
private static final int EVENT_PARAM_INDEX = 0;
8585

@@ -98,8 +98,8 @@ public static boolean isEventApplier(Method method) {
9898
}
9999

100100
final Class<?>[] parameterTypes = method.getParameterTypes();
101-
final boolean hasOneParam = parameterTypes.length == NUMBER_OF_PARAMS;
102-
if (!hasOneParam) {
101+
final boolean paramCountValid = parameterTypes.length == NUMBER_OF_PARAMS;
102+
if (!paramCountValid) {
103103
return false;
104104
}
105105

server/src/main/java/org/spine3/server/aggregate/Registry.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@
2020

2121
package org.spine3.server.aggregate;
2222

23+
import org.spine3.server.internal.CommandHandlerMethod;
2324
import org.spine3.server.reflect.MethodMap;
2425

2526
import javax.annotation.CheckReturnValue;
2627

27-
import static org.spine3.server.internal.CommandHandlerMethod.checkModifiers;
28-
2928
/**
3029
* The registry of method maps for all aggregate classes.
3130
*
@@ -41,11 +40,11 @@
4140
private final MethodMap.Registry<Aggregate> eventAppliers = new MethodMap.Registry<>();
4241

4342
/* package */ void register(Class<? extends Aggregate> clazz) {
44-
commandHandlers.register(clazz, Aggregate.IS_AGGREGATE_COMMAND_HANDLER);
45-
checkModifiers(commandHandlers.get(clazz).values());
43+
commandHandlers.register(clazz, CommandHandlerMethod.PREDICATE);
44+
CommandHandlerMethod.checkModifiers(commandHandlers.get(clazz).values());
4645

47-
eventAppliers.register(clazz, Aggregate.IS_EVENT_APPLIER);
48-
EventApplier.checkModifiers(eventAppliers.get(clazz));
46+
eventAppliers.register(clazz, EventApplier.PREDICATE);
47+
EventApplier.checkModifiers(eventAppliers.get(clazz).values());
4948
}
5049

5150
@CheckReturnValue

server/src/main/java/org/spine3/server/internal/CommandHandlerMethod.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.spine3.server.Assign;
2828
import org.spine3.server.CommandHandler;
2929
import org.spine3.server.reflect.MethodMap;
30-
import org.spine3.server.reflect.Methods;
3130
import org.spine3.type.CommandClass;
3231

3332
import javax.annotation.CheckReturnValue;
@@ -148,8 +147,7 @@ public static void checkModifiers(Iterable<Method> methods) {
148147
for (Method method : methods) {
149148
final boolean isPublic = Modifier.isPublic(method.getModifiers());
150149
if (!isPublic) {
151-
final String fullMethodName = Methods.getFullMethodName(method);
152-
log().warn(String.format("Command handler method %s should be declared 'public'.", fullMethodName));
150+
warnOnWrongModifier("Command handler method {} should be declared 'public'.", method);
153151
}
154152
}
155153
}

server/src/main/java/org/spine3/server/internal/EventHandlerMethod.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.spine3.base.EventContext;
2727
import org.spine3.server.Subscribe;
2828
import org.spine3.server.reflect.MethodMap;
29-
import org.spine3.server.reflect.Methods;
3029
import org.spine3.type.EventClass;
3130

3231
import javax.annotation.CheckReturnValue;
@@ -99,8 +98,7 @@ public static void checkModifiers(Iterable<Method> methods) {
9998
for (Method method : methods) {
10099
final boolean isPublic = Modifier.isPublic(method.getModifiers());
101100
if (!isPublic) {
102-
log().warn(String.format("Event handler %s must be declared 'public'",
103-
Methods.getFullMethodName(method)));
101+
warnOnWrongModifier("Event handler {} must be declared 'public'", method);
104102
}
105103
}
106104
}

server/src/main/java/org/spine3/server/internal/MessageHandlerMethod.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ protected MessageHandlerMethod(T target, Method method) {
7070
method.setAccessible(true);
7171
}
7272

73+
protected static void warnOnWrongModifier(String messageFormat, Method method) {
74+
log().warn(messageFormat, Methods.getFullMethodName(method));
75+
}
76+
7377
/**
7478
* @return the target object on which the method call is made
7579
*/
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2016, TeamDev Ltd. All rights reserved.
3+
*
4+
* Redistribution and use in source and/or binary forms, with or without
5+
* modification, must retain the above copyright notice and the following
6+
* disclaimer.
7+
*
8+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
10+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
11+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
12+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
13+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
14+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
18+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19+
*/
20+
21+
package org.spine3.server.aggregate;
22+
23+
import com.google.common.collect.ImmutableSet;
24+
import com.google.protobuf.Message;
25+
import org.junit.Test;
26+
import org.spine3.base.EventContext;
27+
import org.spine3.test.project.Project;
28+
import org.spine3.test.project.event.ProjectCreated;
29+
30+
import static org.junit.Assert.assertTrue;
31+
import static org.spine3.test.Verify.assertContains;
32+
33+
@SuppressWarnings("InstanceMethodNamingConvention")
34+
public class EventApplierShould {
35+
36+
private static class AggregateWithTwoMethodsApplier extends Aggregate<Long, Project, Project.Builder> {
37+
38+
public AggregateWithTwoMethodsApplier(Long id) {
39+
super(id);
40+
}
41+
42+
@Apply
43+
private void apply(ProjectCreated event, EventContext context) {
44+
// Do nothing.
45+
}
46+
}
47+
48+
@Test
49+
public void do_not_accept_methods_with_two_parameters() {
50+
assertTrue(Aggregate.getEventClasses(AggregateWithTwoMethodsApplier.class)
51+
.isEmpty());
52+
}
53+
54+
private static class AggregateWithNonPrivateApplier extends Aggregate<Long, Project, Project.Builder> {
55+
56+
public AggregateWithNonPrivateApplier(Long id) {
57+
super(id);
58+
}
59+
60+
@Apply
61+
public void apply(ProjectCreated event) {
62+
// Do nothing.
63+
}
64+
}
65+
66+
@Test
67+
public void accept_non_private_appliers() {
68+
final ImmutableSet<Class<? extends Message>> eventClasses = Aggregate.getEventClasses(
69+
AggregateWithNonPrivateApplier.class);
70+
71+
// The method is counted and the event is present.
72+
assertContains(ProjectCreated.class, eventClasses);
73+
}
74+
75+
}

0 commit comments

Comments
 (0)