Nullability refinements and related polishing

This commit is contained in:
Juergen Hoeller
2019-07-31 13:45:48 +02:00
parent cca32a56a4
commit e6f86c5c75
12 changed files with 147 additions and 149 deletions

View File

@@ -142,20 +142,31 @@ public class MessageMappingMessageHandler extends AbstractMethodMessageHandler<C
* efficiency consider using the {@code PathPatternRouteMatcher} from
* {@code spring-web} instead.
*/
public void setRouteMatcher(RouteMatcher routeMatcher) {
Assert.notNull(routeMatcher, "RouteMatcher must not be null");
public void setRouteMatcher(@Nullable RouteMatcher routeMatcher) {
this.routeMatcher = routeMatcher;
}
/**
* Return the {@code RouteMatcher} used to map messages to handlers.
* May be {@code null} before component is initialized.
* May be {@code null} before the component is initialized.
*/
@Nullable
public RouteMatcher getRouteMatcher() {
return this.routeMatcher;
}
/**
* Obtain the {@code RouteMatcher} for actual use.
* @return the RouteMatcher (never {@code null})
* @throws IllegalStateException in case of no RouteMatcher set
* @since 5.0
*/
protected RouteMatcher obtainRouteMatcher() {
RouteMatcher routeMatcher = getRouteMatcher();
Assert.state(routeMatcher != null, "No RouteMatcher set");
return routeMatcher;
}
/**
* Configure a {@link ConversionService} to use for type conversion of
* String based values, e.g. in destination variables or headers.
@@ -245,13 +256,13 @@ public class MessageMappingMessageHandler extends AbstractMethodMessageHandler<C
*/
@Nullable
protected CompositeMessageCondition getCondition(AnnotatedElement element) {
MessageMapping annot = AnnotatedElementUtils.findMergedAnnotation(element, MessageMapping.class);
if (annot == null || annot.value().length == 0) {
MessageMapping ann = AnnotatedElementUtils.findMergedAnnotation(element, MessageMapping.class);
if (ann == null || ann.value().length == 0) {
return null;
}
String[] patterns = processDestinations(annot.value());
String[] patterns = processDestinations(ann.value());
return new CompositeMessageCondition(
new DestinationPatternsMessageCondition(patterns, this.routeMatcher));
new DestinationPatternsMessageCondition(patterns, obtainRouteMatcher()));
}
/**
@@ -272,7 +283,7 @@ public class MessageMappingMessageHandler extends AbstractMethodMessageHandler<C
protected Set<String> getDirectLookupMappings(CompositeMessageCondition mapping) {
Set<String> result = new LinkedHashSet<>();
for (String pattern : mapping.getCondition(DestinationPatternsMessageCondition.class).getPatterns()) {
if (!this.routeMatcher.isPattern(pattern)) {
if (!obtainRouteMatcher().isPattern(pattern)) {
result.add(pattern);
}
}
@@ -309,7 +320,7 @@ public class MessageMappingMessageHandler extends AbstractMethodMessageHandler<C
String pattern = patterns.iterator().next();
RouteMatcher.Route destination = getDestination(message);
Assert.state(destination != null, "Missing destination header");
Map<String, String> vars = getRouteMatcher().matchAndExtract(pattern, destination);
Map<String, String> vars = obtainRouteMatcher().matchAndExtract(pattern, destination);
if (!CollectionUtils.isEmpty(vars)) {
MessageHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class);
Assert.state(mha != null && mha.isMutable(), "Mutable MessageHeaderAccessor required");

View File

@@ -56,23 +56,23 @@ final class DefaultRSocketStrategies implements RSocketStrategies {
private final RouteMatcher routeMatcher;
private final MetadataExtractor metadataExtractor;
private final ReactiveAdapterRegistry adapterRegistry;
private final DataBufferFactory bufferFactory;
private final ReactiveAdapterRegistry adapterRegistry;
private final MetadataExtractor metadataExtractor;
private DefaultRSocketStrategies(List<Encoder<?>> encoders, List<Decoder<?>> decoders,
RouteMatcher routeMatcher, MetadataExtractor metadataExtractor,
DataBufferFactory bufferFactory, ReactiveAdapterRegistry adapterRegistry) {
RouteMatcher routeMatcher, ReactiveAdapterRegistry adapterRegistry,
DataBufferFactory bufferFactory, MetadataExtractor metadataExtractor) {
this.encoders = Collections.unmodifiableList(encoders);
this.decoders = Collections.unmodifiableList(decoders);
this.routeMatcher = routeMatcher;
this.metadataExtractor = metadataExtractor;
this.bufferFactory = bufferFactory;
this.adapterRegistry = adapterRegistry;
this.bufferFactory = bufferFactory;
this.metadataExtractor = metadataExtractor;
}
@@ -92,8 +92,8 @@ final class DefaultRSocketStrategies implements RSocketStrategies {
}
@Override
public MetadataExtractor metadataExtractor() {
return this.metadataExtractor;
public ReactiveAdapterRegistry reactiveAdapterRegistry() {
return this.adapterRegistry;
}
@Override
@@ -102,8 +102,8 @@ final class DefaultRSocketStrategies implements RSocketStrategies {
}
@Override
public ReactiveAdapterRegistry reactiveAdapterRegistry() {
return this.adapterRegistry;
public MetadataExtractor metadataExtractor() {
return this.metadataExtractor;
}
@@ -119,39 +119,36 @@ final class DefaultRSocketStrategies implements RSocketStrategies {
@Nullable
private RouteMatcher routeMatcher;
@Nullable
private MetadataExtractor metadataExtractor;
@Nullable
private ReactiveAdapterRegistry adapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
@Nullable
private DataBufferFactory bufferFactory;
@Nullable
private MetadataExtractor metadataExtractor;
DefaultRSocketStrategiesBuilder() {
// Order of decoders may be significant for default data MimeType
// selection in RSocketRequester.Builder
this.decoders.add(StringDecoder.allMimeTypes());
this.decoders.add(new ByteBufferDecoder());
this.decoders.add(new ByteArrayDecoder());
this.decoders.add(new DataBufferDecoder());
this.encoders.add(CharSequenceEncoder.allMimeTypes());
this.encoders.add(new ByteBufferEncoder());
this.encoders.add(new ByteArrayEncoder());
this.encoders.add(new DataBufferEncoder());
// Order of decoders may be significant for default data MimeType
// selection in RSocketRequester.Builder
this.decoders.add(StringDecoder.allMimeTypes());
this.decoders.add(new ByteBufferDecoder());
this.decoders.add(new ByteArrayDecoder());
this.decoders.add(new DataBufferDecoder());
}
DefaultRSocketStrategiesBuilder(RSocketStrategies other) {
this.encoders.addAll(other.encoders());
this.decoders.addAll(other.decoders());
this.routeMatcher = other.routeMatcher();
this.metadataExtractor = other.metadataExtractor();
this.adapterRegistry = other.reactiveAdapterRegistry();
this.bufferFactory = other.dataBufferFactory();
this.metadataExtractor = other.metadataExtractor();
}
@@ -185,12 +182,6 @@ final class DefaultRSocketStrategies implements RSocketStrategies {
return this;
}
@Override
public Builder metadataExtractor(@Nullable MetadataExtractor metadataExtractor) {
this.metadataExtractor = metadataExtractor;
return this;
}
@Override
public Builder reactiveAdapterStrategy(@Nullable ReactiveAdapterRegistry registry) {
this.adapterRegistry = registry;
@@ -203,22 +194,27 @@ final class DefaultRSocketStrategies implements RSocketStrategies {
return this;
}
@Override
public Builder metadataExtractor(@Nullable MetadataExtractor metadataExtractor) {
this.metadataExtractor = metadataExtractor;
return this;
}
@Override
public RSocketStrategies build() {
RouteMatcher matcher = (this.routeMatcher != null ? this.routeMatcher : initRouteMatcher());
RouteMatcher matcher = this.routeMatcher != null ? this.routeMatcher : initRouteMatcher();
ReactiveAdapterRegistry registry = (this.adapterRegistry != null ?
this.adapterRegistry : ReactiveAdapterRegistry.getSharedInstance());
MetadataExtractor extractor = this.metadataExtractor != null ?
this.metadataExtractor : new DefaultMetadataExtractor(this.decoders);
DataBufferFactory factory = (this.bufferFactory != null ?
this.bufferFactory : new NettyDataBufferFactory(PooledByteBufAllocator.DEFAULT));
DataBufferFactory factory = this.bufferFactory != null ?
this.bufferFactory : new NettyDataBufferFactory(PooledByteBufAllocator.DEFAULT);
ReactiveAdapterRegistry registry = this.adapterRegistry != null ?
this.adapterRegistry : ReactiveAdapterRegistry.getSharedInstance();
MetadataExtractor extractor = (this.metadataExtractor != null ?
this.metadataExtractor : new DefaultMetadataExtractor(this.decoders));
return new DefaultRSocketStrategies(
this.encoders, this.decoders, matcher, extractor, factory, registry);
this.encoders, this.decoders, matcher, registry, factory, extractor);
}
private RouteMatcher initRouteMatcher() {

View File

@@ -98,9 +98,10 @@ public interface RSocketStrategies {
RouteMatcher routeMatcher();
/**
* Return the configured {@link Builder#metadataExtractor(MetadataExtractor)}.
* Return the configured
* {@link Builder#reactiveAdapterStrategy(ReactiveAdapterRegistry) reactiveAdapterRegistry}.
*/
MetadataExtractor metadataExtractor();
ReactiveAdapterRegistry reactiveAdapterRegistry();
/**
* Return the configured
@@ -109,10 +110,9 @@ public interface RSocketStrategies {
DataBufferFactory dataBufferFactory();
/**
* Return the configured
* {@link Builder#reactiveAdapterStrategy(ReactiveAdapterRegistry) reactiveAdapterRegistry}.
* Return the configured {@link Builder#metadataExtractor(MetadataExtractor)}.
*/
ReactiveAdapterRegistry reactiveAdapterRegistry();
MetadataExtractor metadataExtractor();
/**
* Return a builder to create a new {@link RSocketStrategies} instance
@@ -184,16 +184,6 @@ public interface RSocketStrategies {
*/
Builder routeMatcher(@Nullable RouteMatcher routeMatcher);
/**
* Configure a {@link MetadataExtractor} to extract the route along with
* other metadata. This option is applicable to client or server
* responders.
* <p>By default this is {@link DefaultMetadataExtractor} created with
* the {@link #decoder(Decoder[]) configured} decoders and extracting a
* route from {@code "message/x.rsocket.routing.v0"} metadata.
*/
Builder metadataExtractor(@Nullable MetadataExtractor metadataExtractor);
/**
* Configure the registry for reactive type support. This can be used to
* to adapt to, and/or determine the semantics of a given
@@ -219,6 +209,16 @@ public interface RSocketStrategies {
*/
Builder dataBufferFactory(@Nullable DataBufferFactory bufferFactory);
/**
* Configure a {@link MetadataExtractor} to extract the route along with
* other metadata. This option is applicable to client or server
* responders.
* <p>By default this is {@link DefaultMetadataExtractor} created with
* the {@link #decoder(Decoder[]) configured} decoders and extracting a
* route from {@code "message/x.rsocket.routing.v0"} metadata.
*/
Builder metadataExtractor(@Nullable MetadataExtractor metadataExtractor);
/**
* Build the {@code RSocketStrategies} instance.
*/

View File

@@ -77,15 +77,15 @@ class MessagingRSocket extends AbstractRSocket {
MessagingRSocket(MimeType dataMimeType, MimeType metadataMimeType, MetadataExtractor metadataExtractor,
RSocketRequester requester, ReactiveMessageHandler messageHandler,
RouteMatcher routeMatcher, RSocketStrategies strategies) {
RSocketRequester requester, ReactiveMessageHandler messageHandler, RouteMatcher routeMatcher,
RSocketStrategies strategies) {
Assert.notNull(dataMimeType, "'dataMimeType' is required");
Assert.notNull(metadataMimeType, "'metadataMimeType' is required");
Assert.notNull(metadataExtractor, "'metadataExtractor' is required");
Assert.notNull(requester, "'requester' is required");
Assert.notNull(messageHandler, "'messageHandler' is required");
Assert.notNull(routeMatcher, "'routeMatcher' is required");
Assert.notNull(metadataExtractor, "MetadataExtractor is required");
Assert.notNull(requester, "RSocketRequester is required");
Assert.notNull(messageHandler, "ReactiveMessageHandler is required");
Assert.notNull(routeMatcher, "RouteMatcher is required");
Assert.notNull(strategies, "RSocketStrategies is required");
this.dataMimeType = dataMimeType;

View File

@@ -73,9 +73,7 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
private final List<Encoder<?>> encoders = new ArrayList<>();
private MetadataExtractor metadataExtractor;
private RSocketStrategies strategies;
private RSocketStrategies strategies = RSocketStrategies.create();
@Nullable
private MimeType defaultDataMimeType;
@@ -84,29 +82,9 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
public RSocketMessageHandler() {
setRSocketStrategies(RSocketStrategies.create());
setRSocketStrategies(this.strategies);
}
/**
* {@inheritDoc}
* <p>When {@link #setRSocketStrategies(RSocketStrategies) rsocketStrategies}
* is set, this property is re-initialized with the decoders in it, and
* likewise when this property is set the {@code RSocketStrategies} are
* mutated to change the decoders in them.
* <p>By default this is set to the
* {@link RSocketStrategies.Builder#decoder(Decoder[]) defaults} from
* {@code RSocketStrategies}.
*/
@Override
public void setDecoders(List<? extends Decoder<?>> decoders) {
super.setDecoders(decoders);
this.strategies = this.strategies.mutate()
.decoders(list -> {
list.clear();
list.addAll(decoders);
})
.build();
}
/**
* Configure the encoders to use for encoding handler method return values.
@@ -136,6 +114,27 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
return this.encoders;
}
/**
* {@inheritDoc}
* <p>When {@link #setRSocketStrategies(RSocketStrategies) rsocketStrategies}
* is set, this property is re-initialized with the decoders in it, and
* likewise when this property is set the {@code RSocketStrategies} are
* mutated to change the decoders in them.
* <p>By default this is set to the
* {@link RSocketStrategies.Builder#decoder(Decoder[]) defaults} from
* {@code RSocketStrategies}.
*/
@Override
public void setDecoders(List<? extends Decoder<?>> decoders) {
super.setDecoders(decoders);
this.strategies = this.strategies.mutate()
.decoders(list -> {
list.clear();
list.addAll(decoders);
})
.build();
}
/**
* {@inheritDoc}
* <p>When {@link #setRSocketStrategies(RSocketStrategies) rsocketStrategies}
@@ -147,7 +146,7 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
* from {@code RSocketStrategies}.
*/
@Override
public void setRouteMatcher(RouteMatcher routeMatcher) {
public void setRouteMatcher(@Nullable RouteMatcher routeMatcher) {
super.setRouteMatcher(routeMatcher);
this.strategies = this.strategies.mutate().routeMatcher(routeMatcher).build();
}
@@ -181,17 +180,14 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
* @param extractor the extractor to use
*/
public void setMetadataExtractor(MetadataExtractor extractor) {
this.metadataExtractor = extractor;
this.strategies = this.strategies.mutate().metadataExtractor(this.metadataExtractor).build();
this.strategies = this.strategies.mutate().metadataExtractor(extractor).build();
}
/**
* Return the configured {@link #setMetadataExtractor MetadataExtractor}.
* This may be {@code null} before {@link #afterPropertiesSet()}.
*/
@Nullable
public MetadataExtractor getMetadataExtractor() {
return this.metadataExtractor;
return this.strategies.metadataExtractor();
}
/**
@@ -210,11 +206,11 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
*/
public void setRSocketStrategies(RSocketStrategies rsocketStrategies) {
this.strategies = rsocketStrategies;
setDecoders(this.strategies.decoders());
setEncoders(this.strategies.encoders());
setRouteMatcher(this.strategies.routeMatcher());
setMetadataExtractor(this.strategies.metadataExtractor());
setReactiveAdapterRegistry(this.strategies.reactiveAdapterRegistry());
this.encoders.clear();
this.encoders.addAll(this.strategies.encoders());
super.setDecoders(this.strategies.decoders());
super.setRouteMatcher(this.strategies.routeMatcher());
super.setReactiveAdapterRegistry(this.strategies.reactiveAdapterRegistry());
}
/**
@@ -284,19 +280,19 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
@Override
@Nullable
protected CompositeMessageCondition getCondition(AnnotatedElement element) {
MessageMapping annot1 = AnnotatedElementUtils.findMergedAnnotation(element, MessageMapping.class);
if (annot1 != null && annot1.value().length > 0) {
String[] patterns = processDestinations(annot1.value());
MessageMapping ann1 = AnnotatedElementUtils.findMergedAnnotation(element, MessageMapping.class);
if (ann1 != null && ann1.value().length > 0) {
String[] patterns = processDestinations(ann1.value());
return new CompositeMessageCondition(
RSocketFrameTypeMessageCondition.REQUEST_CONDITION,
new DestinationPatternsMessageCondition(patterns, getRouteMatcher()));
new DestinationPatternsMessageCondition(patterns, obtainRouteMatcher()));
}
ConnectMapping annot2 = AnnotatedElementUtils.findMergedAnnotation(element, ConnectMapping.class);
if (annot2 != null) {
String[] patterns = processDestinations(annot2.value());
ConnectMapping ann2 = AnnotatedElementUtils.findMergedAnnotation(element, ConnectMapping.class);
if (ann2 != null) {
String[] patterns = processDestinations(ann2.value());
return new CompositeMessageCondition(
RSocketFrameTypeMessageCondition.CONNECT_CONDITION,
new DestinationPatternsMessageCondition(patterns, getRouteMatcher()));
new DestinationPatternsMessageCondition(patterns, obtainRouteMatcher()));
}
return null;
}
@@ -362,22 +358,18 @@ public class RSocketMessageHandler extends MessageMappingMessageHandler {
}
private MessagingRSocket createResponder(ConnectionSetupPayload setupPayload, RSocket rsocket) {
String s = setupPayload.dataMimeType();
MimeType dataMimeType = StringUtils.hasText(s) ? MimeTypeUtils.parseMimeType(s) : this.defaultDataMimeType;
String str = setupPayload.dataMimeType();
MimeType dataMimeType = StringUtils.hasText(str) ? MimeTypeUtils.parseMimeType(str) : this.defaultDataMimeType;
Assert.notNull(dataMimeType, "No `dataMimeType` in ConnectionSetupPayload and no default value");
Assert.isTrue(isDataMimeTypeSupported(dataMimeType), "Data MimeType '" + dataMimeType + "' not supported");
s = setupPayload.metadataMimeType();
MimeType metaMimeType = StringUtils.hasText(s) ? MimeTypeUtils.parseMimeType(s) : this.defaultMetadataMimeType;
str = setupPayload.metadataMimeType();
MimeType metaMimeType = StringUtils.hasText(str) ? MimeTypeUtils.parseMimeType(str) : this.defaultMetadataMimeType;
Assert.notNull(metaMimeType, "No `metadataMimeType` in ConnectionSetupPayload and no default value");
RSocketRequester requester = RSocketRequester.wrap(
rsocket, dataMimeType, metaMimeType, this.strategies);
Assert.state(getRouteMatcher() != null, () -> "No RouteMatcher. Was afterPropertiesSet not called?");
return new MessagingRSocket(dataMimeType, metaMimeType, this.metadataExtractor,
requester, this, getRouteMatcher(), this.strategies);
RSocketRequester requester = RSocketRequester.wrap(rsocket, dataMimeType, metaMimeType, this.strategies);
return new MessagingRSocket(dataMimeType, metaMimeType, getMetadataExtractor(),
requester, this, obtainRouteMatcher(), this.strategies);
}
private boolean isDataMimeTypeSupported(MimeType dataMimeType) {