Merge branch '5.2.x'

# Conflicts:
#	build.gradle
#	src/docs/asciidoc/core/core-aop-api.adoc
This commit is contained in:
Juergen Hoeller 2020-09-14 22:22:02 +02:00
commit 07b3e92bae
9 changed files with 69 additions and 50 deletions

View File

@ -334,7 +334,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.36"
toolVersion = "8.36.1"
configDirectory.set(rootProject.file("src/checkstyle"))
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -159,8 +159,6 @@ public class MimeMessageHelper {
private static final String HEADER_PRIORITY = "X-Priority";
private static final String HEADER_CONTENT_ID = "Content-ID";
private final MimeMessage mimeMessage;
@ -175,6 +173,8 @@ public class MimeMessageHelper {
private FileTypeMap fileTypeMap;
private boolean encodeFilenames = true;
private boolean validateAddresses = false;
@ -464,7 +464,7 @@ public class MimeMessageHelper {
* Set the Java Activation Framework {@code FileTypeMap} to use
* for determining the content type of inline content and attachments
* that get added to the message.
* <p>Default is the {@code FileTypeMap} that the underlying
* <p>The default is the {@code FileTypeMap} that the underlying
* MimeMessage carries, if any, or the Activation Framework's default
* {@code FileTypeMap} instance else.
* @see #addInline
@ -480,18 +480,40 @@ public class MimeMessageHelper {
/**
* Return the {@code FileTypeMap} used by this MimeMessageHelper.
* @see #setFileTypeMap
*/
public FileTypeMap getFileTypeMap() {
return this.fileTypeMap;
}
/**
* Set whether to encode attachment filenames passed to this helper's
* {@code #addAttachment} methods.
* <p>The default is {@code true} for compatibility with older email clients;
* turn this to {@code false} for standard MIME behavior. On a related note,
* check out JavaMail's {@code mail.mime.encodefilename} system property.
* @since 5.2.9
* @see #addAttachment(String, DataSource)
* @see MimeBodyPart#setFileName(String)
*/
public void setEncodeFilenames(boolean encodeFilenames) {
this.encodeFilenames = encodeFilenames;
}
/**
* Return whether to encode attachment filenames passed to this helper's
* {@code #addAttachment} methods.
* @since 5.2.9
* @see #setEncodeFilenames
*/
public boolean isEncodeFilenames() {
return this.encodeFilenames;
}
/**
* Set whether to validate all addresses which get passed to this helper.
* Default is "false".
* <p>Note that this is by default just available for JavaMail >= 1.3.
* You can override the default {@code validateAddress method} for
* validation on older JavaMail versions (or for custom validation).
* <p>The default is {@code false}.
* @see #validateAddress
*/
public void setValidateAddresses(boolean validateAddresses) {
@ -500,6 +522,7 @@ public class MimeMessageHelper {
/**
* Return whether this helper will validate all addresses passed to it.
* @see #setValidateAddresses
*/
public boolean isValidateAddresses() {
return this.validateAddresses;
@ -508,10 +531,8 @@ public class MimeMessageHelper {
/**
* Validate the given mail address.
* Called by all of MimeMessageHelper's address setters and adders.
* <p>Default implementation invokes {@code InternetAddress.validate()},
* <p>The default implementation invokes {@link InternetAddress#validate()},
* provided that address validation is activated for the helper instance.
* <p>Note that this method will just work on JavaMail >= 1.3. You can override
* it for validation on older JavaMail versions or for custom validation.
* @param address the address to validate
* @throws AddressException if validation failed
* @see #isValidateAddresses()
@ -525,7 +546,8 @@ public class MimeMessageHelper {
/**
* Validate all given mail addresses.
* Default implementation simply delegates to validateAddress for each address.
* <p>The default implementation simply delegates to {@link #validateAddress}
* for each address.
* @param addresses the addresses to validate
* @throws AddressException if validation failed
* @see #validateAddress(InternetAddress)
@ -885,9 +907,7 @@ public class MimeMessageHelper {
Assert.notNull(dataSource, "DataSource must not be null");
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDisposition(MimeBodyPart.INLINE);
// We're using setHeader here to remain compatible with JavaMail 1.2,
// rather than JavaMail 1.3's setContentID.
mimeBodyPart.setHeader(HEADER_CONTENT_ID, "<" + contentId + ">");
mimeBodyPart.setContentID("<" + contentId + ">");
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
getMimeMultipart().addBodyPart(mimeBodyPart);
}
@ -997,7 +1017,8 @@ public class MimeMessageHelper {
try {
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename));
mimeBodyPart.setFileName(isEncodeFilenames() ?
MimeUtility.encodeText(attachmentFilename) : attachmentFilename);
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
getRootMimeMultipart().addBodyPart(mimeBodyPart);
}

View File

@ -103,6 +103,7 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
return this.defaultCharset;
}
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
return (elementType.resolve() == String.class && super.canDecode(elementType, mimeType));
@ -167,7 +168,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
/**
* Finds the first match and longest delimiter, {@link EndFrameBuffer} just after it.
*
* @param dataBuffer the buffer to find delimiters in
* @param matcher used to find the first delimiters
* @return a flux of buffers, containing {@link EndFrameBuffer} after each delimiter that was
@ -221,7 +221,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
}
DataBuffer result = dataBuffers.get(0).factory().join(dataBuffers);
if (stripDelimiter && matchingDelimiter != null) {
result.writePosition(result.writePosition() - matchingDelimiter.length);
}
@ -229,8 +228,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
}
/**
* Create a {@code StringDecoder} for {@code "text/plain"}.
* @param stripDelimiter this flag is ignored
@ -293,8 +290,7 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
private static final DataBuffer BUFFER = DefaultDataBufferFactory.sharedInstance.wrap(new byte[0]);
private byte[] delimiter;
private final byte[] delimiter;
public EndFrameBuffer(byte[] delimiter) {
super(BUFFER);
@ -304,7 +300,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
public byte[] delimiter() {
return this.delimiter;
}
}
@ -313,7 +308,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final LimitedDataBufferList list;
LimitChecker(int maxInMemorySize) {
this.list = new LimitedDataBufferList(maxInMemorySize);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,9 +30,9 @@ import org.springframework.core.convert.converter.Converter;
*/
final class StringToBooleanConverter implements Converter<String, Boolean> {
private static final Set<String> trueValues = new HashSet<>(4);
private static final Set<String> trueValues = new HashSet<>(8);
private static final Set<String> falseValues = new HashSet<>(4);
private static final Set<String> falseValues = new HashSet<>(8);
static {
trueValues.add("true");
@ -46,6 +46,7 @@ final class StringToBooleanConverter implements Converter<String, Boolean> {
falseValues.add("0");
}
@Override
public Boolean convert(String source) {
String value = source.trim();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.core.convert.support;
import java.util.UUID;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@ -31,6 +32,7 @@ import org.springframework.util.StringUtils;
final class StringToUUIDConverter implements Converter<String, UUID> {
@Override
@Nullable
public UUID convert(String source) {
return (StringUtils.hasText(source) ? UUID.fromString(source.trim()) : null);
}

View File

@ -562,7 +562,7 @@ public final class ContentDisposition {
private static class BuilderImpl implements Builder {
private String type;
private final String type;
@Nullable
private String name;

View File

@ -861,7 +861,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
public void setContentDispositionFormData(String name, @Nullable String filename) {
Assert.notNull(name, "Name must not be null");
ContentDisposition.Builder disposition = ContentDisposition.builder("form-data").name(name);
if (filename != null) {
if (StringUtils.hasText(filename)) {
disposition.filename(filename);
}
setContentDisposition(disposition.build());
@ -888,7 +888,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
*/
public ContentDisposition getContentDisposition() {
String contentDisposition = getFirst(CONTENT_DISPOSITION);
if (contentDisposition != null) {
if (StringUtils.hasText(contentDisposition)) {
return ContentDisposition.parse(contentDisposition);
}
return ContentDisposition.empty();

View File

@ -103,13 +103,13 @@ The `MethodMatcher` interface is normally more important. The complete interface
The `matches(Method, Class)` method is used to test whether this pointcut ever
matches a given method on a target class. This evaluation can be performed when an AOP
proxy is created to avoid the need for a test on every method invocation. If the
two-argument `matches` method returns `true` for a given method, and the `isRuntime()` method
for the MethodMatcher returns `true`, the three-argument matches method is invoked on
every method invocation. This lets a pointcut look at the arguments passed to the
method invocation immediately before the target advice starts.
two-argument `matches` method returns `true` for a given method, and the `isRuntime()`
method for the MethodMatcher returns `true`, the three-argument matches method is
invoked on every method invocation. This lets a pointcut look at the arguments passed
to the method invocation immediately before the target advice starts.
Most `MethodMatcher` implementations are static, meaning that their `isRuntime()` method returns `false`.
In this case, the three-argument `matches` method is never invoked.
Most `MethodMatcher` implementations are static, meaning that their `isRuntime()` method
returns `false`. In this case, the three-argument `matches` method is never invoked.
TIP: If possible, try to make pointcuts static, allowing the AOP framework to cache the
results of pointcut evaluation when an AOP proxy is created.
@ -145,20 +145,20 @@ See the <<aop, previous chapter>> for a discussion of supported AspectJ pointcut
[[aop-api-pointcuts-impls]]
=== Convenience Pointcut Implementations
Spring provides several convenient pointcut implementations. You can use some of them directly.
Others are intended to be subclassed in application-specific pointcuts.
Spring provides several convenient pointcut implementations. You can use some of them
directly; others are intended to be subclassed in application-specific pointcuts.
[[aop-api-pointcuts-static]]
==== Static Pointcuts
Static pointcuts are based on the method and the target class and cannot take into account the
method's arguments. Static pointcuts suffice -- and are best -- for most usages.
Spring can evaluate a static pointcut only once, when a method is first
invoked. After that, there is no need to evaluate the pointcut again with each method
invocation.
Static pointcuts are based on the method and the target class and cannot take into account
the method's arguments. Static pointcuts suffice -- and are best -- for most usages.
Spring can evaluate a static pointcut only once, when a method is first invoked.
After that, there is no need to evaluate the pointcut again with each method invocation.
The rest of this section describes some of the static pointcut implementations that are included with Spring.
The rest of this section describes some of the static pointcut implementations that are
included with Spring.
[[aop-api-pointcuts-regex]]
===== Regular Expression Pointcuts
@ -168,9 +168,9 @@ frameworks besides Spring make this possible.
`org.springframework.aop.support.JdkRegexpMethodPointcut` is a generic regular
expression pointcut that uses the regular expression support in the JDK.
With the `JdkRegexpMethodPointcut` class, you can provide a list of pattern strings. If
any of these is a match, the pointcut evaluates to `true`. (So, the result is
effectively the union of these patterns.)
With the `JdkRegexpMethodPointcut` class, you can provide a list of pattern strings.
If any of these is a match, the pointcut evaluates to `true`. (As a consequence,
the resulting pointcut is effectively the union of the specified patterns.)
The following example shows how to use `JdkRegexpMethodPointcut`:

View File

@ -4424,7 +4424,8 @@ which these `BeanFactoryPostProcessor` instances run by setting the `order` prop
However, you can only set this property if the `BeanFactoryPostProcessor` implements the
`Ordered` interface. If you write your own `BeanFactoryPostProcessor`, you should
consider implementing the `Ordered` interface, too. See the javadoc of the
{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`] and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.
{api-spring-framework}/beans/factory/config/BeanFactoryPostProcessor.html[`BeanFactoryPostProcessor`]
and {api-spring-framework}/core/Ordered.html[`Ordered`] interfaces for more details.
[NOTE]
====