Skip to content

Commit dda40c1

Browse files
committed
Reactive @MessageMapping
See gh-21987
1 parent 421090c commit dda40c1

File tree

4 files changed

+641
-36
lines changed

4 files changed

+641
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
* Copyright 2002-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.messaging.handler;
17+
18+
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.List;
21+
import java.util.stream.Collectors;
22+
23+
import org.springframework.messaging.Message;
24+
import org.springframework.util.Assert;
25+
26+
/**
27+
* Composite {@link MessageCondition} that delegates to other message conditions.
28+
*
29+
* <p>For {@link #combine} and {@link #compareTo} it is expected that the "other"
30+
* composite contains the same number, type, and order of message conditions.
31+
*
32+
* @author Rossen Stoyanchev
33+
* @since 5.2
34+
*/
35+
public class CompositeMessageCondition implements MessageCondition<CompositeMessageCondition> {
36+
37+
private final List<MessageCondition<?>> messageConditions;
38+
39+
40+
public CompositeMessageCondition(MessageCondition<?>... messageConditions) {
41+
this(Arrays.asList(messageConditions));
42+
}
43+
44+
private CompositeMessageCondition(List<MessageCondition<?>> messageConditions) {
45+
Assert.notEmpty(messageConditions, "No message conditions");
46+
this.messageConditions = messageConditions;
47+
}
48+
49+
50+
public List<MessageCondition<?>> getMessageConditions() {
51+
return this.messageConditions;
52+
}
53+
54+
@SuppressWarnings("unchecked")
55+
public <T extends MessageCondition<T>> T getCondition(Class<T> messageConditionType) {
56+
for (MessageCondition<?> condition : this.messageConditions) {
57+
if (messageConditionType.isAssignableFrom(condition.getClass())) {
58+
return (T) condition;
59+
}
60+
}
61+
throw new IllegalStateException("No condition of type: " + messageConditionType);
62+
}
63+
64+
65+
@Override
66+
public CompositeMessageCondition combine(CompositeMessageCondition other) {
67+
checkCompatible(other);
68+
List<MessageCondition<?>> result = new ArrayList<>(this.messageConditions.size());
69+
for (int i = 0; i < this.messageConditions.size(); i++) {
70+
result.add(combine(getMessageConditions().get(i), other.getMessageConditions().get(i)));
71+
}
72+
return new CompositeMessageCondition(result);
73+
}
74+
75+
@SuppressWarnings("unchecked")
76+
private <T extends MessageCondition<T>> T combine(MessageCondition<?> first, MessageCondition<?> second) {
77+
return ((T) first).combine((T) second);
78+
}
79+
80+
@Override
81+
public CompositeMessageCondition getMatchingCondition(Message<?> message) {
82+
List<MessageCondition<?>> result = new ArrayList<>(this.messageConditions.size());
83+
for (MessageCondition<?> condition : this.messageConditions) {
84+
MessageCondition<?> matchingCondition = (MessageCondition<?>) condition.getMatchingCondition(message);
85+
if (matchingCondition == null) {
86+
return null;
87+
}
88+
result.add(matchingCondition);
89+
}
90+
return new CompositeMessageCondition(result);
91+
}
92+
93+
@Override
94+
public int compareTo(CompositeMessageCondition other, Message<?> message) {
95+
checkCompatible(other);
96+
List<MessageCondition<?>> otherConditions = other.getMessageConditions();
97+
for (int i = 0; i < this.messageConditions.size(); i++) {
98+
int result = compare (this.messageConditions.get(i), otherConditions.get(i), message);
99+
if (result != 0) {
100+
return result;
101+
}
102+
}
103+
return 0;
104+
}
105+
106+
@SuppressWarnings("unchecked")
107+
private <T extends MessageCondition<T>> int compare(
108+
MessageCondition<?> first, MessageCondition<?> second, Message<?> message) {
109+
110+
return ((T) first).compareTo((T) second, message);
111+
}
112+
113+
private void checkCompatible(CompositeMessageCondition other) {
114+
List<MessageCondition<?>> others = other.getMessageConditions();
115+
for (int i = 0; i < this.messageConditions.size(); i++) {
116+
if (i < others.size()) {
117+
if (this.messageConditions.get(i).getClass().equals(others.get(i).getClass())) {
118+
continue;
119+
}
120+
}
121+
throw new IllegalArgumentException("Mismatched CompositeMessageCondition: " +
122+
this.messageConditions + " vs " + others);
123+
}
124+
}
125+
126+
127+
@Override
128+
public boolean equals(Object other) {
129+
if (this == other) {
130+
return true;
131+
}
132+
if (!(other instanceof CompositeMessageCondition)) {
133+
return false;
134+
}
135+
CompositeMessageCondition otherComposite = (CompositeMessageCondition) other;
136+
checkCompatible(otherComposite);
137+
List<MessageCondition<?>> otherConditions = otherComposite.getMessageConditions();
138+
for (int i = 0; i < this.messageConditions.size(); i++) {
139+
if (!this.messageConditions.get(i).equals(otherConditions.get(i))) {
140+
return false;
141+
}
142+
}
143+
return true;
144+
}
145+
146+
@Override
147+
public int hashCode() {
148+
int hashCode = 0;
149+
for (MessageCondition<?> condition : this.messageConditions) {
150+
hashCode += condition.hashCode() * 31;
151+
}
152+
return hashCode;
153+
}
154+
155+
@Override
156+
public String toString() {
157+
return this.messageConditions.stream().map(Object::toString).collect(Collectors.joining(",", "{", "}"));
158+
}
159+
160+
}

0 commit comments

Comments
 (0)