Compare commits

...

43 Commits

Author SHA1 Message Date
Spring Builds e0f56e7d80 Release v5.3.20 2022-05-11 06:55:19 +00:00
Juergen Hoeller 83186b689f Refine CachedIntrospectionResults property introspection
Closes gh-28445
2022-05-11 08:32:06 +02:00
rstoyanchev dc2947c52d Ignore invalid connect frame
Closes gh-28443
2022-05-11 07:22:22 +01:00
Arjen Poutsma e4ec376075 Disabling Undertow server in CoroutinesIntegrationTests 2022-05-10 15:55:00 +02:00
Juergen Hoeller c81e11d537 Polishing 2022-05-10 13:07:00 +02:00
Juergen Hoeller de6180b093 Upgrade to Reactor 2020.0.19
Includes Netty 4.1.77 and RxJava 3.1.4.

Closes gh-28437
2022-05-10 13:05:56 +02:00
Sam Brannen 1c10cdd1e8 Update copyright dates
See gh-28433
2022-05-10 11:33:32 +02:00
evgeny.bovykin 941b92cbed Make inner classes static when feasible
A static nested class does not keep an implicit reference to its
enclosing instance.

This prevents a common cause of memory leaks and uses less memory per
instance of the class.

Closes gh-28433
2022-05-10 11:32:37 +02:00
Sam Brannen e26d8839b3 Stop referring to features as Java 6/7 features where unnecessary 2022-05-09 19:09:06 +02:00
Sam Brannen a1c7380398 Add test for value attribute in @ModelAttribute in WebFlux
This complements the previous commit which tested only the `name`
attribute.

See gh-28423
2022-05-09 15:22:22 +02:00
Sam Brannen 7dd622bdb2 Support name attribute in @ModelAttribute in WebFlux
Prior to this commit, the `name` attribute in @ModelAttribute was not
supported when using WebFlux. This is because MethodParameter was used
instead of SynthesizingMethodParameter when retrieving the
@ModelAttribute annotation. In other words, @AliasFor was not honored
because the annotation was not synthesized. Consequently, only the
`value` attribute was supported in WebFlux when specifying a custom name
via @ModelAttribute.

This commit fixes this by using SynthesizingMethodParameter to retrieve
the @ModelAttribute annotation.

Closes gh-28423
2022-05-07 17:16:26 +02:00
Sam Brannen 64c96c579d Polish contribution
See gh-28422
2022-05-07 16:18:47 +02:00
Carlos Bouzón García 39e3876301 Fix BindingResult error when ModelAttribute has custom name in WebFlux
Closes gh-28422
2022-05-07 16:18:04 +02:00
Juergen Hoeller f771603789 Polishing 2022-05-05 18:04:54 +02:00
Juergen Hoeller e441832e99 Accept WritableResource as required dependency type as well
Closes gh-15284
2022-05-05 18:04:13 +02:00
Juergen Hoeller f963fc5f98 Check that nullable annotations are from org.springframework.lang
Closes gh-28410
2022-05-05 18:02:27 +02:00
Juergen Hoeller b55eee1b0d Upgrade to ASM 9.3
Closes gh-28390
2022-05-05 18:01:53 +02:00
Juergen Hoeller 28742171fd Upgrade to Netty 4.1.76, Mockito 4.5.1, HtmlUnit 2.61 2022-05-05 18:01:31 +02:00
Lee, Kyutae 7a75b94556 Fix typo in reference docs regarding RequestMappingHandlerAdapter
Closes gh-28370
2022-05-05 16:31:40 +02:00
Sam Brannen ab71ff93bb Polish package-info for org.springframework.util
See gh-28411
2022-05-05 16:22:52 +02:00
neals cf30327740 Remove Log4J configurer from package-info.java in spring-core
Closes gh-28411
2022-05-05 16:16:49 +02:00
neals e22a038725 Remove Log4J initialization from package-info.java
Closes gh-28420
2022-05-05 16:10:59 +02:00
Brian Clozel 7aedb9ee33 Build CI image using oci-build-task resource 2022-05-03 15:50:29 +02:00
Brian Clozel 5b1719cd77 Upgrade CI to concourse-release-scripts 0.3.4 2022-05-03 15:09:23 +02:00
Brian Clozel c056b81753 Upgrade JDK and Ubuntu versions in CI image 2022-05-03 15:08:14 +02:00
Brian Clozel dbdd67ec62 Remove outdated docker-image resource from CI
The docker-image resource is now replaced by the registry-image
resource.
2022-05-03 15:05:58 +02:00
Sam Brannen 4fcfa5b991 Update and simplify ArrayConstructorTests 2022-05-03 14:27:48 +02:00
Sam Brannen ed06a6de26 Convert SimpleFormController example to @Controller in reference manual
This change is necessary since the SimpleFormController class no longer
exists.
2022-05-03 12:03:04 +02:00
Sam Brannen afa799b4f0 Suppress warning in test 2022-05-03 11:46:47 +02:00
rstoyanchev f0d149b330 Polishing contribution
Closes gh-27830
2022-04-28 11:26:50 +01:00
binchoo caaf83b8e6 Add tests for binding to a Part field
See gh-27830
2022-04-28 10:45:09 +01:00
rstoyanchev b30f4d7bb7 Exposes all root causes to ExceptionHandler methods
Closes gh-28155
2022-04-28 04:04:57 +01:00
Arjen Poutsma b6b03f38d7 Updated .sdkmanrc 2022-04-26 11:54:02 +02:00
Stephane Nicoll 46b0d7dc03 Merge pull request #28369 from izeye
* pr/28369:
  Add Javadoc since for GraphQL constants

Closes gh-28369
2022-04-24 10:05:28 +02:00
izeye fcf64798b5 Add Javadoc since for GraphQL constants
See gh-28369
2022-04-24 09:58:50 +02:00
Stephane Nicoll 94ed07d9cb Merge pull request #28372 from zhangmingqi09
* pr/28372:
  Update copyright year of changed file
  Fix github issue reference in RequestMappingHandlerMapping

Closes gh-28372
2022-04-24 09:57:02 +02:00
Stephane Nicoll b81c62d064 Update copyright year of changed file
See gh-28372
2022-04-24 09:56:39 +02:00
zhangmingqi09 ca1a11acac Fix github issue reference in RequestMappingHandlerMapping
See gh-28372
2022-04-24 09:55:20 +02:00
Stephane Nicoll c261d40610 Merge pull request #28340 from koenpunt
* pr/28340:
  Update copyright year of changed file
  Fix method reference in Kotlin documentation

Closes gh-28340
2022-04-14 14:11:28 +02:00
Stephane Nicoll 3017955eff Update copyright year of changed file
See gh-28340
2022-04-14 14:09:54 +02:00
Koen Punt 22c82ff206 Fix method reference in Kotlin documentation
See gh-28340
2022-04-14 14:09:02 +02:00
Jerome Prinet f54952481b Update Gradle Enterprise plugin to 3.9
Closes gh-28338
2022-04-14 11:04:22 +02:00
Spring Builds 9e733b09e2 Next development version (v5.3.20-SNAPSHOT) 2022-04-13 09:24:33 +00:00
68 changed files with 646 additions and 506 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.322-librca
java=8.0.332-librca
+6 -6
View File
@@ -28,8 +28,8 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
mavenBom "io.netty:netty-bom:4.1.75.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.18"
mavenBom "io.netty:netty-bom:4.1.77.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.19"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR13"
mavenBom "io.rsocket:rsocket-bom:1.1.2"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.46.v20220331"
@@ -67,7 +67,7 @@ configure(allprojects) { project ->
dependency "io.reactivex:rxjava:1.3.8"
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
dependency "io.reactivex.rxjava3:rxjava:3.1.4"
dependency "io.smallrye.reactive:mutiny:1.4.0"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
@@ -198,7 +198,7 @@ configure(allprojects) { project ->
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '4.4.0') {
dependencySet(group: 'org.mockito', version: '4.5.1') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
@@ -206,10 +206,10 @@ configure(allprojects) { project ->
}
dependency "io.mockk:mockk:1.12.1"
dependency("net.sourceforge.htmlunit:htmlunit:2.60.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.61.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.60.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.61.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
+1 -1
View File
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20220404
FROM ubuntu:focal-20220415
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
+4 -4
View File
@@ -3,16 +3,16 @@ set -e
case "$1" in
java8)
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u332-b09/OpenJDK8U-jdk_x64_linux_hotspot_8u332b09.tar.gz"
;;
java11)
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15%2B10/OpenJDK11U-jdk_x64_linux_hotspot_11.0.15_10.tar.gz"
;;
java17)
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.3%2B7/OpenJDK17U-jdk_x64_linux_hotspot_17.0.3_7.tar.gz"
;;
java18)
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk-18%2B36/OpenJDK18U-jdk_x64_linux_hotspot_18_36.tar.gz"
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk-18.0.1%2B10/OpenJDK18U-jdk_x64_linux_hotspot_18.0.1_10.tar.gz"
;;
*)
echo $"Unknown java version"
-2
View File
@@ -14,8 +14,6 @@ rm -rf /var/lib/apt/lists/*
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
###########################################################
# JAVA
###########################################################
+4
View File
@@ -1,5 +1,6 @@
github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
sonatype-staging-profile: "org.springframework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "5.3.x"
@@ -7,4 +8,7 @@ milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
concourse-url: "https://ci.spring.io"
registry-mirror-host: docker.repo.spring.io
registry-mirror-username: ((artifactory-username))
registry-mirror-password: ((artifactory-password))
task-timeout: 1h00m
+18 -10
View File
@@ -12,7 +12,7 @@ anchors:
SONATYPE_USERNAME: ((sonatype-username))
SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
artifactory-task-params: &artifactory-task-params
ARTIFACTORY_SERVER: ((artifactory-server))
ARTIFACTORY_USERNAME: ((artifactory-username))
@@ -24,6 +24,10 @@ anchors:
username: ((docker-hub-username))
password: ((docker-hub-password))
tag: ((milestone))
registry-mirror-vars: &registry-mirror-vars
registry-mirror-host: ((registry-mirror-host))
registry-mirror-username: ((registry-mirror-username))
registry-mirror-password: ((registry-mirror-password))
slack-fail-params: &slack-fail-params
text: >
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
@@ -92,7 +96,7 @@ resources:
branch: ((branch))
paths: ["ci/images/*"]
- name: ci-image
type: docker-image
type: registry-image
icon: docker
source:
<<: *docker-resource-source
@@ -162,13 +166,20 @@ resources:
jobs:
- name: build-ci-images
plan:
- get: ci-images-git-repo
trigger: true
- in_parallel:
- get: git-repo
- get: ci-images-git-repo
trigger: true
- task: build-ci-image
privileged: true
file: git-repo/ci/tasks/build-ci-image.yml
output_mapping:
image: ci-image
vars:
ci-image-name: ci-image
<<: *registry-mirror-vars
- put: ci-image
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/ci-image/Dockerfile
image: ci-image/image.tar
- name: build
serial: true
public: true
@@ -345,7 +356,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: M
@@ -390,7 +400,6 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RC
@@ -435,7 +444,6 @@ jobs:
download_artifacts: true
save_build_info: true
- task: promote
image: ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RELEASE
+2 -2
View File
@@ -6,11 +6,11 @@ CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
java -jar /opt/concourse-release-scripts.jar \
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
java -jar /opt/concourse-release-scripts.jar \
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
java -jar /opt/concourse-release-scripts.jar syncToCentral "RELEASE" $BUILD_INFO_LOCATION || { exit 1; }
echo "Sync complete"
echo $version > version/version
+31
View File
@@ -0,0 +1,31 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: concourse/oci-build-task
tag: 0.9.1
registry_mirror:
host: ((registry-mirror-host))
username: ((registry-mirror-username))
password: ((registry-mirror-password))
inputs:
- name: ci-images-git-repo
outputs:
- name: image
caches:
- path: ci-image-cache
params:
CONTEXT: ci-images-git-repo/ci/images
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
DOCKER_HUB_AUTH: ((docker-hub-auth))
run:
path: /bin/sh
args:
- "-c"
- |
mkdir -p /root/.docker
cat > /root/.docker/config.json <<EOF
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
EOF
build
+6 -1
View File
@@ -1,5 +1,10 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: springio/concourse-release-scripts
tag: '0.3.4'
inputs:
- name: git-repo
- name: artifactory-repo
@@ -13,6 +18,6 @@ params:
SONATYPE_USER:
SONATYPE_PASSWORD:
SONATYPE_URL:
SONATYPE_STAGING_PROFILE_ID:
SONATYPE_STAGING_PROFILE:
run:
path: git-repo/ci/scripts/promote-version.sh
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.19-SNAPSHOT
version=5.3.20
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
+1 -1
View File
@@ -7,7 +7,7 @@ pluginManagement {
}
plugins {
id "com.gradle.enterprise" version "3.8.1"
id "com.gradle.enterprise" version "3.9"
id "io.spring.ge.conventions" version "0.0.9"
}
@@ -22,6 +22,7 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.HashSet;
@@ -292,10 +293,12 @@ public final class CachedIntrospectionResults {
// Only allow all name variants of Class properties
continue;
}
if (pd.getWriteMethod() == null && pd.getPropertyType() != null &&
(ClassLoader.class.isAssignableFrom(pd.getPropertyType()) ||
ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
// Ignore ClassLoader and ProtectionDomain read-only properties - no need to bind to those
if (URL.class == beanClass && "content".equals(pd.getName())) {
// Only allow URL attribute introspection, not content resolution
continue;
}
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
// Ignore read-only properties such as ClassLoader - no need to bind to those
continue;
}
if (logger.isTraceEnabled()) {
@@ -344,10 +347,8 @@ public final class CachedIntrospectionResults {
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
// against a declared read method, so we prefer read method descriptors here.
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
if (pd.getWriteMethod() == null && pd.getPropertyType() != null &&
(ClassLoader.class.isAssignableFrom(pd.getPropertyType()) ||
ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
// Ignore ClassLoader and ProtectionDomain read-only properties - no need to bind to those
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
// Ignore read-only properties such as ClassLoader - no need to bind to those
continue;
}
this.propertyDescriptors.put(pd.getName(), pd);
@@ -379,8 +380,7 @@ public final class CachedIntrospectionResults {
if (Modifier.isStatic(method.getModifiers()) ||
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
ClassLoader.class.isAssignableFrom(method.getReturnType()) ||
ProtectionDomain.class.isAssignableFrom(method.getReturnType())) {
isInvalidReadOnlyPropertyType(method.getReturnType())) {
return false;
}
try {
@@ -393,6 +393,12 @@ public final class CachedIntrospectionResults {
}
}
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
ClassLoader.class.isAssignableFrom(returnType) ||
ProtectionDomain.class.isAssignableFrom(returnType)));
}
BeanInfo getBeanInfo() {
return this.beanInfo;
@@ -1,5 +1,5 @@
/**
* Support package for the Java 6 ServiceLoader facility.
* Support package for the Java {@link java.util.ServiceLoader} facility.
*/
@NonNullApi
@NonNullFields
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -985,7 +985,7 @@ class ConstructorResolver {
/**
* Delegate for checking Java 6's {@link ConstructorProperties} annotation.
* Delegate for checking Java's {@link ConstructorProperties} annotation.
*/
private static class ConstructorPropertiesChecker {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2022 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.
@@ -43,6 +43,7 @@ import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.WritableResource;
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
import org.springframework.core.io.support.ResourcePatternResolver;
@@ -102,6 +103,7 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, ContextResource.class, baseEditor);
doRegisterEditor(registry, WritableResource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2022 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.
@@ -39,7 +39,7 @@ inline fun <reified T : Any> ListableBeanFactory.getBeansOfType(includeNonSingle
/**
* Extension for [ListableBeanFactory.getBeanNamesForAnnotation] providing a
* `getBeansOfType<Foo>()` variant.
* `getBeanNamesForAnnotation<Foo>()` variant.
*
* @author Sebastien Deleuze
* @since 5.0
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.OverridingClassLoader;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.UrlResource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -153,7 +154,7 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
void propertyDescriptors() {
void propertyDescriptors() throws Exception {
TestBean target = new TestBean();
target.setSpouse(new TestBean());
BeanWrapper accessor = createAccessor(target);
@@ -182,11 +183,29 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
assertThat(accessor.isReadableProperty("class.package")).isFalse();
assertThat(accessor.isReadableProperty("class.module")).isFalse();
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
assertThat(accessor.isReadableProperty("class.name")).isTrue();
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
assertThat(accessor.isReadableProperty("classLoader")).isTrue();
assertThat(accessor.isWritableProperty("classLoader")).isTrue();
OverridingClassLoader ocl = new OverridingClassLoader(getClass().getClassLoader());
accessor.setPropertyValue("classLoader", ocl);
assertThat(accessor.getPropertyValue("classLoader")).isSameAs(ocl);
accessor = createAccessor(new UrlResource("https://spring.io"));
assertThat(accessor.isReadableProperty("class.package")).isFalse();
assertThat(accessor.isReadableProperty("class.module")).isFalse();
assertThat(accessor.isReadableProperty("class.classLoader")).isFalse();
assertThat(accessor.isReadableProperty("class.name")).isTrue();
assertThat(accessor.isReadableProperty("class.simpleName")).isTrue();
assertThat(accessor.isReadableProperty("URL.protocol")).isTrue();
assertThat(accessor.isReadableProperty("URL.host")).isTrue();
assertThat(accessor.isReadableProperty("URL.port")).isTrue();
assertThat(accessor.isReadableProperty("URL.file")).isTrue();
assertThat(accessor.isReadableProperty("URL.content")).isFalse();
assertThat(accessor.isReadableProperty("inputStream")).isFalse();
assertThat(accessor.isReadableProperty("filename")).isTrue();
assertThat(accessor.isReadableProperty("description")).isTrue();
}
@Test
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -22,6 +22,7 @@ import javax.lang.model.element.Element;
/**
* Provide the list of stereotypes that match an {@link Element}.
*
* <p>If an element has one or more stereotypes, it is referenced in the index
* of candidate components and each stereotype can be queried individually.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -762,7 +762,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* <p>The default implementation delegates to {@link JmxUtils#isMBean},
* which checks for {@link javax.management.DynamicMBean} classes as well
* as classes with corresponding "*MBean" interface (Standard MBeans)
* or corresponding "*MXBean" interface (Java 6 MXBeans).
* or corresponding "*MXBean" interface (Java MXBeans).
* @param beanClass the bean class to analyze
* @return whether the class qualifies as an MBean
* @see org.springframework.jmx.support.JmxUtils#isMBean(Class)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -255,7 +255,7 @@ public abstract class JmxUtils {
* Determine whether the given bean class qualifies as an MBean as-is.
* <p>This implementation checks for {@link javax.management.DynamicMBean}
* classes as well as classes with corresponding "*MBean" interface
* (Standard MBeans) or corresponding "*MXBean" interface (Java 6 MXBeans).
* (Standard MBeans) or corresponding "*MXBean" interface (Java MXBeans).
* @param clazz the bean class to analyze
* @return whether the class qualifies as an MBean
* @see org.springframework.jmx.export.MBeanExporter#isMBean(Class)
@@ -289,7 +289,7 @@ public abstract class JmxUtils {
}
/**
* Return the Java 6 MXBean interface exists for the given class, if any
* Return the Java MXBean interface for the given class, if any
* (that is, an interface whose name ends with "MXBean" and/or
* carries an appropriate MXBean annotation).
* @param clazz the class to check
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -36,7 +36,7 @@ import org.springframework.util.StringUtils;
/**
* {@link org.springframework.scripting.ScriptFactory} implementation based
* on the JSR-223 script engine abstraction (as included in Java 6+).
* on the JSR-223 script engine abstraction (as included in Java).
* Supports JavaScript, Groovy, JRuby, and other JSR-223 compliant engines.
*
* <p>Typically used in combination with a
@@ -55,7 +55,7 @@ public abstract class AnnotationVisitor {
* @param api the ASM API version implemented by this visitor. Must be one of the {@code
* ASM}<i>x</i> values in {@link Opcodes}.
*/
public AnnotationVisitor(final int api) {
protected AnnotationVisitor(final int api) {
this(api, null);
}
@@ -67,7 +67,7 @@ public abstract class AnnotationVisitor {
* @param annotationVisitor the annotation visitor to which this visitor must delegate method
* calls. May be {@literal null}.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
protected AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
@@ -65,6 +65,15 @@ public class ByteVector {
this.length = data.length;
}
/**
* Returns the actual number of bytes in this vector.
*
* @return the actual number of bytes in this vector.
*/
public int size() {
return length;
}
/**
* Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
*
@@ -54,7 +54,7 @@ public abstract class ClassVisitor {
* @param api the ASM API version implemented by this visitor. Must be one of the {@code
* ASM}<i>x</i> values in {@link Opcodes}.
*/
public ClassVisitor(final int api) {
protected ClassVisitor(final int api) {
this(api, null);
}
@@ -66,7 +66,7 @@ public abstract class ClassVisitor {
* @param classVisitor the class visitor to which this visitor must delegate method calls. May be
* null.
*/
public ClassVisitor(final int api, final ClassVisitor classVisitor) {
protected ClassVisitor(final int api, final ClassVisitor classVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
@@ -51,7 +51,7 @@ public abstract class FieldVisitor {
* @param api the ASM API version implemented by this visitor. Must be one of the {@code
* ASM}<i>x</i> values in {@link Opcodes}.
*/
public FieldVisitor(final int api) {
protected FieldVisitor(final int api) {
this(api, null);
}
@@ -63,7 +63,7 @@ public abstract class FieldVisitor {
* @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be
* null.
*/
public FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
protected FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
@@ -67,7 +67,7 @@ public abstract class MethodVisitor {
* @param api the ASM API version implemented by this visitor. Must be one of the {@code
* ASM}<i>x</i> values in {@link Opcodes}.
*/
public MethodVisitor(final int api) {
protected MethodVisitor(final int api) {
this(api, null);
}
@@ -79,7 +79,7 @@ public abstract class MethodVisitor {
* @param methodVisitor the method visitor to which this visitor must delegate method calls. May
* be null.
*/
public MethodVisitor(final int api, final MethodVisitor methodVisitor) {
protected MethodVisitor(final int api, final MethodVisitor methodVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
@@ -349,12 +349,12 @@ public abstract class MethodVisitor {
*
* @param opcode the opcode of the local variable instruction to be visited. This opcode is either
* ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* @param var the operand of the instruction to be visited. This operand is the index of a local
* variable.
* @param varIndex the operand of the instruction to be visited. This operand is the index of a
* local variable.
*/
public void visitVarInsn(final int opcode, final int var) {
public void visitVarInsn(final int opcode, final int varIndex) {
if (mv != null) {
mv.visitVarInsn(opcode, var);
mv.visitVarInsn(opcode, varIndex);
}
}
@@ -466,7 +466,8 @@ final class MethodWriter extends MethodVisitor {
/**
* Indicates what must be computed. Must be one of {@link #COMPUTE_ALL_FRAMES}, {@link
* #COMPUTE_INSERTED_FRAMES}, {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_NOTHING}.
* #COMPUTE_INSERTED_FRAMES}, {@link COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link
* #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_NOTHING}.
*/
private final int compute;
@@ -904,26 +905,26 @@ final class MethodWriter extends MethodVisitor {
}
@Override
public void visitVarInsn(final int opcode, final int var) {
public void visitVarInsn(final int opcode, final int varIndex) {
lastBytecodeOffset = code.length;
// Add the instruction to the bytecode of the method.
if (var < 4 && opcode != Opcodes.RET) {
if (varIndex < 4 && opcode != Opcodes.RET) {
int optimizedOpcode;
if (opcode < Opcodes.ISTORE) {
optimizedOpcode = Constants.ILOAD_0 + ((opcode - Opcodes.ILOAD) << 2) + var;
optimizedOpcode = Constants.ILOAD_0 + ((opcode - Opcodes.ILOAD) << 2) + varIndex;
} else {
optimizedOpcode = Constants.ISTORE_0 + ((opcode - Opcodes.ISTORE) << 2) + var;
optimizedOpcode = Constants.ISTORE_0 + ((opcode - Opcodes.ISTORE) << 2) + varIndex;
}
code.putByte(optimizedOpcode);
} else if (var >= 256) {
code.putByte(Constants.WIDE).put12(opcode, var);
} else if (varIndex >= 256) {
code.putByte(Constants.WIDE).put12(opcode, varIndex);
} else {
code.put11(opcode, var);
code.put11(opcode, varIndex);
}
// If needed, update the maximum stack size and number of locals, and stack map frames.
if (currentBasicBlock != null) {
if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
currentBasicBlock.frame.execute(opcode, var, null, null);
currentBasicBlock.frame.execute(opcode, varIndex, null, null);
} else {
if (opcode == Opcodes.RET) {
// No stack size delta.
@@ -945,9 +946,9 @@ final class MethodWriter extends MethodVisitor {
|| opcode == Opcodes.DLOAD
|| opcode == Opcodes.LSTORE
|| opcode == Opcodes.DSTORE) {
currentMaxLocals = var + 2;
currentMaxLocals = varIndex + 2;
} else {
currentMaxLocals = var + 1;
currentMaxLocals = varIndex + 1;
}
if (currentMaxLocals > maxLocals) {
maxLocals = currentMaxLocals;
@@ -1307,21 +1308,21 @@ final class MethodWriter extends MethodVisitor {
}
@Override
public void visitIincInsn(final int var, final int increment) {
public void visitIincInsn(final int varIndex, final int increment) {
lastBytecodeOffset = code.length;
// Add the instruction to the bytecode of the method.
if ((var > 255) || (increment > 127) || (increment < -128)) {
code.putByte(Constants.WIDE).put12(Opcodes.IINC, var).putShort(increment);
if ((varIndex > 255) || (increment > 127) || (increment < -128)) {
code.putByte(Constants.WIDE).put12(Opcodes.IINC, varIndex).putShort(increment);
} else {
code.putByte(Opcodes.IINC).put11(var, increment);
code.putByte(Opcodes.IINC).put11(varIndex, increment);
}
// If needed, update the maximum stack size and number of locals, and stack map frames.
if (currentBasicBlock != null
&& (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES)) {
currentBasicBlock.frame.execute(Opcodes.IINC, var, null, null);
currentBasicBlock.frame.execute(Opcodes.IINC, varIndex, null, null);
}
if (compute != COMPUTE_NOTHING) {
int currentMaxLocals = var + 1;
int currentMaxLocals = varIndex + 1;
if (currentMaxLocals > maxLocals) {
maxLocals = currentMaxLocals;
}
@@ -53,7 +53,7 @@ public abstract class ModuleVisitor {
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
* or {@link Opcodes#ASM7}.
*/
public ModuleVisitor(final int api) {
protected ModuleVisitor(final int api) {
this(api, null);
}
@@ -65,7 +65,7 @@ public abstract class ModuleVisitor {
* @param moduleVisitor the module visitor to which this visitor must delegate method calls. May
* be null.
*/
public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
protected ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
@@ -53,7 +53,7 @@ public abstract class RecordComponentVisitor {
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM8}
* or {@link Opcodes#ASM9}.
*/
public RecordComponentVisitor(final int api) {
protected RecordComponentVisitor(final int api) {
this(api, null);
}
@@ -64,7 +64,7 @@ public abstract class RecordComponentVisitor {
* @param recordComponentVisitor the record component visitor to which this visitor must delegate
* method calls. May be null.
*/
public RecordComponentVisitor(
protected RecordComponentVisitor(
final int api, final RecordComponentVisitor recordComponentVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
@@ -440,7 +440,7 @@ public final class Type {
case '(':
return new Type(METHOD, descriptorBuffer, descriptorBegin, descriptorEnd);
default:
throw new IllegalArgumentException();
throw new IllegalArgumentException("Invalid descriptor: " + descriptorBuffer);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -26,7 +26,7 @@ import org.springframework.util.StringUtils;
* Converts from a String to a {@link java.util.Locale}.
*
* <p>Accepts the classic {@link Locale} String format ({@link Locale#toString()})
* as well as BCP 47 language tags ({@link Locale#forLanguageTag} on Java 7+).
* as well as BCP 47 language tags ({@link Locale#forLanguageTag}.
*
* @author Keith Donald
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2022 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.
@@ -99,14 +99,14 @@ public interface Resource extends InputStreamSource {
/**
* Return a URL handle for this resource.
* @throws IOException if the resource cannot be resolved as URL,
* i.e. if the resource is not available as descriptor
* i.e. if the resource is not available as a descriptor
*/
URL getURL() throws IOException;
/**
* Return a URI handle for this resource.
* @throws IOException if the resource cannot be resolved as URI,
* i.e. if the resource is not available as descriptor
* i.e. if the resource is not available as a descriptor
* @since 2.5
*/
URI getURI() throws IOException;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -35,8 +35,8 @@ import java.util.Properties;
* <p>Loading from and storing to a stream delegates to {@code Properties.load}
* and {@code Properties.store}, respectively, to be fully compatible with
* the Unicode conversion as implemented by the JDK Properties class. As of JDK 6,
* {@code Properties.load/store} will also be used for readers/writers,
* effectively turning this class into a plain backwards compatibility adapter.
* {@code Properties.load/store} is also used for readers/writers, effectively
* turning this class into a plain backwards compatibility adapter.
*
* <p>The persistence code that works with Reader/Writer follows the JDK's parsing
* strategy but does not implement Unicode conversion, because the Reader/Writer
@@ -67,18 +67,20 @@ public abstract class MimeTypeUtils {
/**
* Public constant mime type for {@code application/graphql+json}.
* @since 5.3.19
* @see <a href="https://github.com/graphql/graphql-over-http">GraphQL over HTTP spec</a>
* */
*/
public static final MimeType APPLICATION_GRAPHQL;
/**
* A String equivalent of {@link MimeTypeUtils#APPLICATION_GRAPHQL}.
* @since 5.3.19
*/
public static final String APPLICATION_GRAPHQL_VALUE = "application/graphql+json";
/**
* Public constant mime type for {@code application/json}.
* */
*/
public static final MimeType APPLICATION_JSON;
/**
@@ -804,11 +804,11 @@ public abstract class StringUtils {
/**
* Parse the given {@code String} value into a {@link Locale}, accepting
* the {@link Locale#toString} format as well as BCP 47 language tags.
* the {@link Locale#toString} format as well as BCP 47 language tags as
* specified by {@link Locale#forLanguageTag}.
* @param localeValue the locale value: following either {@code Locale's}
* {@code toString()} format ("en", "en_UK", etc), also accepting spaces as
* separators (as an alternative to underscores), or BCP 47 (e.g. "en-UK")
* as specified by {@link Locale#forLanguageTag} on Java 7+
* @return a corresponding {@code Locale} instance, or {@code null} if none
* @throws IllegalArgumentException in case of an invalid locale specification
* @since 5.0.4
@@ -1,6 +1,6 @@
/**
* Miscellaneous utility classes, such as String manipulation utilities,
* a Log4J configurer, and a state holder for paged lists of objects.
* Miscellaneous utility classes, such as utilities for working with strings,
* classes, collections, reflection, etc.
*/
@NonNullApi
@NonNullFields
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.ObjectUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -27,45 +28,33 @@ import static org.assertj.core.api.Assertions.assertThat;
* Test construction of arrays.
*
* @author Andy Clement
* @author Sam Brannen
*/
public class ArrayConstructorTests extends AbstractExpressionTests {
class ArrayConstructorTests extends AbstractExpressionTests {
@Test
public void simpleArrayWithInitializer() {
evaluateArrayBuildingExpression("new int[]{1,2,3}", "[1,2,3]");
evaluateArrayBuildingExpression("new int[]{}", "[]");
evaluate("new int[]{}.length", "0", Integer.class);
}
@Test
public void conversion() {
void conversion() {
evaluate("new String[]{1,2,3}[0]", "1", String.class);
evaluate("new int[]{'123'}[0]", 123, Integer.class);
}
@Test
public void multidimensionalArrays() {
evaluateAndCheckError("new int[][]{{1,2},{3,4}}", SpelMessage.MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED);
evaluateAndCheckError("new int[3][]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new int[]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new String[]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new int[][1]", SpelMessage.MISSING_ARRAY_DIMENSION);
void primitiveTypeArrayConstructors() {
evaluateArrayBuildingExpression("new int[]{}", "{}");
evaluateArrayBuildingExpression("new int[]{1,2,3,4}", "{1, 2, 3, 4}");
evaluateArrayBuildingExpression("new boolean[]{true,false,true}", "{true, false, true}");
evaluateArrayBuildingExpression("new char[]{'a','b','c'}", "{'a', 'b', 'c'}");
evaluateArrayBuildingExpression("new long[]{1,2,3,4,5}", "{1, 2, 3, 4, 5}");
evaluateArrayBuildingExpression("new short[]{2,3,4,5,6}", "{2, 3, 4, 5, 6}");
evaluateArrayBuildingExpression("new double[]{1d,2d,3d,4d}", "{1.0, 2.0, 3.0, 4.0}");
evaluateArrayBuildingExpression("new float[]{1f,2f,3f,4f}", "{1.0, 2.0, 3.0, 4.0}");
evaluateArrayBuildingExpression("new byte[]{1,2,3,4}", "{1, 2, 3, 4}");
evaluate("new int[]{}.length", "0", Integer.class);
}
@Test
public void primitiveTypeArrayConstructors() {
evaluateArrayBuildingExpression("new int[]{1,2,3,4}", "[1,2,3,4]");
evaluateArrayBuildingExpression("new boolean[]{true,false,true}", "[true,false,true]");
evaluateArrayBuildingExpression("new char[]{'a','b','c'}", "[a,b,c]");
evaluateArrayBuildingExpression("new long[]{1,2,3,4,5}", "[1,2,3,4,5]");
evaluateArrayBuildingExpression("new short[]{2,3,4,5,6}", "[2,3,4,5,6]");
evaluateArrayBuildingExpression("new double[]{1d,2d,3d,4d}", "[1.0,2.0,3.0,4.0]");
evaluateArrayBuildingExpression("new float[]{1f,2f,3f,4f}", "[1.0,2.0,3.0,4.0]");
evaluateArrayBuildingExpression("new byte[]{1,2,3,4}", "[1,2,3,4]");
}
@Test
public void primitiveTypeArrayConstructorsElements() {
void primitiveTypeArrayConstructorsElements() {
evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class);
evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class);
evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class);
@@ -78,15 +67,34 @@ public class ArrayConstructorTests extends AbstractExpressionTests {
}
@Test
public void errorCases() {
void errorCases() {
evaluateAndCheckError("new int[]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new String[]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new int[3][]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new int[][1]", SpelMessage.MISSING_ARRAY_DIMENSION);
evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessage.INITIALIZER_LENGTH_INCORRECT);
evaluateAndCheckError("new char[3]{'a','c','d','e'}", SpelMessage.INITIALIZER_LENGTH_INCORRECT);
evaluateAndCheckError("new int[][]{{1,2},{3,4}}", SpelMessage.MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED);
evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessage.TYPE_CONVERSION_ERROR);
// Could conceivably be a SpelMessage.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, but it appears
// that SpelMessage.INCORRECT_ELEMENT_TYPE_FOR_ARRAY is not actually (no longer?) used
// in the code base.
evaluateAndCheckError("new Integer[3]{'3','ghi','5'}", SpelMessage.TYPE_CONVERSION_ERROR);
evaluateAndCheckError("new String('a','c','d')", SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM);
// Root cause: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
evaluateAndCheckError("new java.util.ArrayList(T(java.lang.Integer).MAX_VALUE)", SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM);
int threshold = 256 * 1024; // ConstructorReference.MAX_ARRAY_ELEMENTS
evaluateAndCheckError("new int[T(java.lang.Integer).MAX_VALUE]", SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, 0, threshold);
evaluateAndCheckError("new int[1024 * 1024][1024 * 1024]", SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, 0, threshold);
}
@Test
public void typeArrayConstructors() {
void typeArrayConstructors() {
evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class);
evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessage.METHOD_NOT_FOUND, 30, "size()",
"java.lang.String[]");
@@ -94,113 +102,25 @@ public class ArrayConstructorTests extends AbstractExpressionTests {
}
@Test
public void basicArray() {
void basicArray() {
evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class);
}
@Test
public void multiDimensionalArray() {
void multiDimensionalArrays() {
evaluate("new String[2][2]", "[Ljava.lang.String;[2]{[2]{null,null},[2]{null,null}}", String[][].class);
evaluate("new String[3][2][1]",
"[[Ljava.lang.String;[3]{[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}},[2]{[1]{null},[1]{null}}}",
String[][][].class);
}
@Test
public void constructorInvocation03() {
evaluateAndCheckError("new String[]", SpelMessage.MISSING_ARRAY_DIMENSION);
}
public void constructorInvocation04() {
evaluateAndCheckError("new Integer[3]{'3','ghi','5'}", SpelMessage.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, 4);
}
private String evaluateArrayBuildingExpression(String expression, String expectedToString) {
private void evaluateArrayBuildingExpression(String expression, String expectedToString) {
SpelExpressionParser parser = new SpelExpressionParser();
Expression e = parser.parseExpression(expression);
Object o = e.getValue();
assertThat(o).isNotNull();
assertThat(o.getClass().isArray()).isTrue();
StringBuilder s = new StringBuilder();
s.append('[');
if (o instanceof int[]) {
int[] array = (int[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof boolean[]) {
boolean[] array = (boolean[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof char[]) {
char[] array = (char[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof long[]) {
long[] array = (long[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof short[]) {
short[] array = (short[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof double[]) {
double[] array = (double[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof float[]) {
float[] array = (float[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else if (o instanceof byte[]) {
byte[] array = (byte[]) o;
for (int i = 0; i < array.length; i++) {
if (i > 0) {
s.append(',');
}
s.append(array[i]);
}
}
else {
throw new IllegalStateException("Not supported " + o.getClass());
}
s.append(']');
assertThat(s.toString()).isEqualTo(expectedToString);
return s.toString();
Object array = e.getValue();
assertThat(array).isNotNull();
assertThat(array.getClass().isArray()).isTrue();
assertThat(ObjectUtils.nullSafeToString(array)).isEqualTo(expectedToString);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -50,9 +50,9 @@ import org.springframework.util.function.SupplierUtils;
* by default. This factory loads a "sql-error-codes.xml" file from the class path,
* defining error code mappings for database names from database meta-data.
* <li>Fallback to a fallback translator. {@link SQLStateSQLExceptionTranslator} is the
* default fallback translator, analyzing the exception's SQL state only. On Java 6
* which introduces its own {@code SQLException} subclass hierarchy, we will
* use {@link SQLExceptionSubclassTranslator} by default, which in turns falls back
* default fallback translator, analyzing the exception's SQL state only. Since Java 6
* which introduces its own {@code SQLException} subclass hierarchy, we use
* {@link SQLExceptionSubclassTranslator} by default, which in turns falls back
* to Spring's own SQL state translation when not encountering specific subclasses.
* </ul>
*
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2022 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.
@@ -53,7 +53,7 @@ import org.springframework.lang.Nullable;
* @author Juergen Hoeller
* @since 2.5
* @see java.sql.SQLTransientException
* @see java.sql.SQLTransientException
* @see java.sql.SQLNonTransientException
* @see java.sql.SQLRecoverableException
*/
public class SQLExceptionSubclassTranslator extends AbstractFallbackSQLExceptionTranslator {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2022 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.
@@ -29,7 +29,7 @@ import java.sql.SQLTransactionRollbackException;
import java.sql.SQLTransientConnectionException;
/**
* Class to generate Java 6 SQLException subclasses for testing purposes.
* Class to generate {@link SQLException} subclasses for testing purposes.
*
* @author Thomas Risberg
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -306,6 +306,12 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
else if (SimpMessageType.CONNECT.equals(messageType)) {
logMessage(message);
if (sessionId != null) {
if (this.sessions.get(sessionId) != null) {
if (logger.isWarnEnabled()) {
logger.warn("Ignoring CONNECT in session " + sessionId + ". Already connected.");
}
return;
}
long[] heartbeatIn = SimpMessageHeaderAccessor.getHeartbeat(headers);
long[] heartbeatOut = getHeartbeatValue();
Principal user = SimpMessageHeaderAccessor.getUser(headers);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -552,6 +552,12 @@ public class StompBrokerRelayMessageHandler extends AbstractBrokerMessageHandler
}
if (StompCommand.CONNECT.equals(command) || StompCommand.STOMP.equals(command)) {
if (this.connectionHandlers.get(sessionId) != null) {
if (logger.isWarnEnabled()) {
logger.warn("Ignoring CONNECT in session " + sessionId + ". Already connected.");
}
return;
}
if (logger.isDebugEnabled()) {
logger.debug(stompAccessor.getShortLogMessage(EMPTY_PAYLOAD));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -260,6 +260,30 @@ class StompBrokerRelayMessageHandlerTests {
assertThat(captor.getValue()).isSameAs(message);
}
@Test
void alreadyConnected() {
this.brokerRelay.start();
Message<byte[]> connect = connectMessage("sess1", "joe");
this.brokerRelay.handleMessage(connect);
assertThat(this.tcpClient.getSentMessages().size()).isEqualTo(2);
StompHeaderAccessor headers1 = this.tcpClient.getSentHeaders(0);
assertThat(headers1.getCommand()).isEqualTo(StompCommand.CONNECT);
assertThat(headers1.getSessionId()).isEqualTo(StompBrokerRelayMessageHandler.SYSTEM_SESSION_ID);
StompHeaderAccessor headers2 = this.tcpClient.getSentHeaders(1);
assertThat(headers2.getCommand()).isEqualTo(StompCommand.CONNECT);
assertThat(headers2.getSessionId()).isEqualTo("sess1");
this.brokerRelay.handleMessage(connect);
assertThat(this.tcpClient.getSentMessages().size()).isEqualTo(2);
assertThat(this.outboundChannel.getMessages()).isEmpty();
}
private Message<byte[]> connectMessage(String sessionId, String user) {
StompHeaderAccessor headers = StompHeaderAccessor.create(StompCommand.CONNECT);
headers.setSessionId(sessionId);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -32,13 +32,17 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.mock.web.MockPart;
import org.springframework.stereotype.Controller;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.ui.Model;
import org.springframework.util.StreamUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@@ -56,19 +60,24 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standal
/**
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Jaebin Joo
*/
public class MultipartControllerTests {
@Test
public void multipartRequestWithSingleFile() throws Exception {
@ParameterizedTest
@ValueSource(strings = {"/multipartfile", "/part"})
public void multipartRequestWithSingleFileOrPart(String url) throws Exception {
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8);
MockMultipartFile filePart = new MockMultipartFile("file", "orig", null, fileContent);
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8);
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json);
MockMultipartHttpServletRequestBuilder requestBuilder = (url.endsWith("file") ?
multipart(url).file(new MockMultipartFile("file", "orig", null, fileContent)) :
multipart(url).part(new MockPart("part", "orig", fileContent)));
standaloneSetup(new MultipartController()).build()
.perform(multipart("/multipartfile").file(filePart).file(jsonPart))
.perform(requestBuilder.file(jsonPart))
.andExpect(status().isFound())
.andExpect(model().attribute("fileContent", fileContent))
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah")));
@@ -225,19 +234,14 @@ public class MultipartControllerTests {
}
@Test
public void multipartRequestWithServletParts() throws Exception {
public void multipartRequestWithDataBindingToFile() throws Exception {
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8);
MockPart filePart = new MockPart("file", "orig", fileContent);
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8);
MockPart jsonPart = new MockPart("json", json);
jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON);
standaloneSetup(new MultipartController()).build()
.perform(multipart("/multipartfile").part(filePart).part(jsonPart))
.perform(multipart("/multipartfilebinding").part(filePart))
.andExpect(status().isFound())
.andExpect(model().attribute("fileContent", fileContent))
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah")));
.andExpect(model().attribute("fileContent", fileContent));
}
@Test // SPR-13317
@@ -343,10 +347,13 @@ public class MultipartControllerTests {
}
@RequestMapping(value = "/part", method = RequestMethod.POST)
public String processPart(@RequestParam Part part,
public String processPart(@RequestPart Part part,
@RequestPart Map<String, String> json, Model model) throws IOException {
model.addAttribute("fileContent", part.getInputStream());
if (part != null) {
byte[] content = StreamUtils.copyToByteArray(part.getInputStream());
model.addAttribute("fileContent", content);
}
model.addAttribute("jsonContent", json);
return "redirect:/index";
@@ -357,6 +364,33 @@ public class MultipartControllerTests {
model.addAttribute("json", json);
return "redirect:/index";
}
@RequestMapping(value = "/multipartfilebinding", method = RequestMethod.POST)
public String processMultipartFileBean(
MultipartFileBean multipartFileBean, Model model, BindingResult bindingResult) throws IOException {
if (!bindingResult.hasErrors()) {
MultipartFile file = multipartFileBean.getFile();
if (file != null) {
model.addAttribute("fileContent", file.getBytes());
}
}
return "redirect:/index";
}
}
private static class MultipartFileBean {
private MultipartFile file;
public MultipartFile getFile() {
return file;
}
@SuppressWarnings("unused")
public void setFile(MultipartFile file) {
this.file = file;
}
}
@@ -97,12 +97,14 @@ public class MediaType extends MimeType implements Serializable {
/**
* Public constant media type for {@code application/graphql+json}.
* @since 5.3.19
* @see <a href="https://github.com/graphql/graphql-over-http">GraphQL over HTTP spec</a>
*/
public static final MediaType APPLICATION_GRAPHQL;
/**
* A String equivalent of {@link MediaType#APPLICATION_GRAPHQL}.
* @since 5.3.19
*/
public static final String APPLICATION_GRAPHQL_VALUE = "application/graphql+json";
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -100,13 +100,12 @@ abstract class DefaultParts {
/**
* Abstract base class.
* Abstract base class for {@link Part} implementations.
*/
private static abstract class AbstractPart implements Part {
private final HttpHeaders headers;
protected AbstractPart(HttpHeaders headers) {
Assert.notNull(headers, "HttpHeaders is required");
this.headers = headers;
@@ -119,7 +118,6 @@ abstract class DefaultParts {
return name;
}
@Override
public HttpHeaders headers() {
return this.headers;
@@ -172,7 +170,6 @@ abstract class DefaultParts {
protected final Content content;
public DefaultPart(HttpHeaders headers, Content content) {
super(headers);
this.content = content;
@@ -198,7 +195,6 @@ abstract class DefaultParts {
return "DefaultPart";
}
}
}
@@ -213,7 +209,7 @@ abstract class DefaultParts {
@Override
public String filename() {
String filename = this.headers().getContentDisposition().getFilename();
String filename = headers().getContentDisposition().getFilename();
Assert.state(filename != null, "No filename found");
return filename;
}
@@ -235,7 +231,6 @@ abstract class DefaultParts {
return "DefaultFilePart{(" + filename + ")}";
}
}
}
@@ -249,9 +244,9 @@ abstract class DefaultParts {
Mono<Void> transferTo(Path dest);
Mono<Void> delete();
}
/**
* {@code Content} implementation based on a flux of data buffers.
*/
@@ -259,12 +254,10 @@ abstract class DefaultParts {
private final Flux<DataBuffer> content;
public FluxContent(Flux<DataBuffer> content) {
this.content = content;
}
@Override
public Flux<DataBuffer> content() {
return this.content;
@@ -279,7 +272,6 @@ abstract class DefaultParts {
public Mono<Void> delete() {
return Mono.empty();
}
}
@@ -292,13 +284,11 @@ abstract class DefaultParts {
private final Scheduler scheduler;
public FileContent(Path file, Scheduler scheduler) {
this.file = file;
this.scheduler = scheduler;
}
@Override
public Flux<DataBuffer> content() {
return DataBufferUtils.readByteChannel(
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -88,7 +88,7 @@ public class UndertowHttpHandlerAdapter implements io.undertow.server.HttpHandle
}
private class HandlerResultSubscriber implements Subscriber<Void> {
private static class HandlerResultSubscriber implements Subscriber<Void> {
private final HttpServerExchange exchange;
@@ -104,11 +104,13 @@ public class ServletRequestDataBinder extends WebDataBinder {
* HTTP parameters: i.e. "uploadedFile" to an "uploadedFile" bean property,
* invoking a "setUploadedFile" setter method.
* <p>The type of the target property for a multipart file can be MultipartFile,
* byte[], or String. The latter two receive the contents of the uploaded file;
* all metadata like original file name, content type, etc are lost in those cases.
* byte[], or String. Servlet Part binding is also supported when the
* request has not been parsed to MultipartRequest via MultipartResolver.
* @param request the request with parameters to bind (can be multipart)
* @see org.springframework.web.multipart.MultipartHttpServletRequest
* @see org.springframework.web.multipart.MultipartRequest
* @see org.springframework.web.multipart.MultipartFile
* @see jakarta.servlet.http.Part
* @see #bind(org.springframework.beans.PropertyValues)
*/
public void bind(ServletRequest request) {
@@ -107,9 +107,9 @@ public class WebRequestDataBinder extends WebDataBinder {
* <p>Multipart files are bound via their parameter name, just like normal
* HTTP parameters: i.e. "uploadedFile" to an "uploadedFile" bean property,
* invoking a "setUploadedFile" setter method.
* <p>The type of the target property for a multipart file can be Part, MultipartFile,
* byte[], or String. The latter two receive the contents of the uploaded file;
* all metadata like original file name, content type, etc are lost in those cases.
* <p>The type of the target property for a multipart file can be MultipartFile,
* byte[], or String. Servlet Part binding is also supported when the
* request has not been parsed to MultipartRequest via MultipartResolver.
* @param request the request with parameters to bind (can be multipart)
* @see org.springframework.web.multipart.MultipartRequest
* @see org.springframework.web.multipart.MultipartFile
@@ -1,6 +1,5 @@
/**
* Miscellaneous web utility classes, such as HTML escaping,
* Log4j initialization, and cookie handling.
* Miscellaneous web utility classes, such as HTML escaping and cookie handling.
*/
@NonNullApi
@NonNullFields
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -236,7 +236,7 @@ public class VersionResourceResolver extends AbstractResourceResolver {
}
private class FileNameVersionedResource extends AbstractResource implements HttpResource {
private static class FileNameVersionedResource extends AbstractResource implements HttpResource {
private final Resource original;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -22,6 +22,7 @@ import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter;
import org.springframework.core.ReactiveAdapter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
@@ -33,10 +34,12 @@ import org.springframework.web.server.ServerWebExchange;
/**
* Resolve {@link Errors} or {@link BindingResult} method arguments.
* An {@code Errors} argument is expected to appear immediately after the
*
* <p>An {@code Errors} argument is expected to appear immediately after the
* model attribute in the method signature.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 5.0
*/
public class ErrorsMethodArgumentResolver extends HandlerMethodArgumentResolverSupport {
@@ -78,7 +81,7 @@ public class ErrorsMethodArgumentResolver extends HandlerMethodArgumentResolverS
"Errors argument must be declared immediately after a model attribute argument");
int index = parameter.getParameterIndex() - 1;
MethodParameter attributeParam = MethodParameter.forExecutable(parameter.getExecutable(), index);
MethodParameter attributeParam = SynthesizingMethodParameter.forExecutable(parameter.getExecutable(), index);
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(attributeParam.getParameterType());
Assert.state(adapter == null, "An @ModelAttribute and an Errors/BindingResult argument " +
@@ -86,9 +89,9 @@ public class ErrorsMethodArgumentResolver extends HandlerMethodArgumentResolverS
"Either declare the @ModelAttribute without an async wrapper type or " +
"handle a WebExchangeBindException error signal through the async type.");
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
String name = (ann != null && StringUtils.hasText(ann.value()) ?
ann.value() : Conventions.getVariableNameForParameter(attributeParam));
ModelAttribute ann = attributeParam.getParameterAnnotation(ModelAttribute.class);
String name = (ann != null && StringUtils.hasText(ann.name()) ? ann.name() :
Conventions.getVariableNameForParameter(attributeParam));
Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);
Assert.state(errors != null, () -> "An Errors/BindingResult argument is expected " +
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -16,6 +16,7 @@
package org.springframework.web.reactive.result.method.annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
@@ -213,21 +214,30 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Application
InvocableHandlerMethod invocable = this.methodResolver.getExceptionHandlerMethod(exception, handlerMethod);
if (invocable != null) {
ArrayList<Throwable> exceptions = new ArrayList<>();
try {
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "Using @ExceptionHandler " + invocable);
}
bindingContext.getModel().asMap().clear();
Throwable cause = exception.getCause();
if (cause != null) {
return invocable.invoke(exchange, bindingContext, exception, cause, handlerMethod);
}
else {
return invocable.invoke(exchange, bindingContext, exception, handlerMethod);
// Expose causes as provided arguments as well
Throwable exToExpose = exception;
while (exToExpose != null) {
exceptions.add(exToExpose);
Throwable cause = exToExpose.getCause();
exToExpose = (cause != exToExpose ? cause : null);
}
Object[] arguments = new Object[exceptions.size() + 1];
exceptions.toArray(arguments); // efficient arraycopy call in ArrayList
arguments[arguments.length - 1] = handlerMethod;
return invocable.invoke(exchange, bindingContext, arguments);
}
catch (Throwable invocationEx) {
if (logger.isWarnEnabled()) {
// Any other than the original exception (or a cause) is unintended here,
// probably an accident (e.g. failed assertion or the like).
if (!exceptions.contains(invocationEx) && logger.isWarnEnabled()) {
logger.warn(exchange.getLogPrefix() + "Failure in @ExceptionHandler " + invocable, invocationEx);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -82,7 +82,7 @@ public class UndertowRequestUpgradeStrategy implements RequestUpgradeStrategy {
}
private class DefaultCallback implements WebSocketConnectionCallback {
private static class DefaultCallback implements WebSocketConnectionCallback {
private final HandshakeInfo handshakeInfo;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -82,9 +82,10 @@ public class ControllerAdviceTests {
@Test
public void resolveExceptionWithAssertionErrorAsRootCause() throws Exception {
AssertionError cause = new AssertionError("argh");
FatalBeanException exception = new FatalBeanException("wrapped", cause);
testException(exception, cause.toString());
AssertionError rootCause = new AssertionError("argh");
FatalBeanException cause = new FatalBeanException("wrapped", rootCause);
Exception exception = new Exception(cause);
testException(exception, rootCause.toString());
}
private void testException(Throwable exception, String expected) throws Exception {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -70,7 +70,7 @@ class ErrorsMethodArgumentResolverTests {
}
@Test
void resolve() {
void resolveWithInferredModelAttributeName() {
BindingResult bindingResult = createBindingResult(new Foo(), "foo");
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "foo", bindingResult);
@@ -81,9 +81,32 @@ class ErrorsMethodArgumentResolverTests {
assertThat(actual).isSameAs(bindingResult);
}
private BindingResult createBindingResult(Foo target, String name) {
DataBinder binder = this.bindingContext.createDataBinder(this.exchange, target, name);
return binder.getBindingResult();
@Test
void resolveWithCustomModelAttributeNameConfiguredViaValueAttribute() {
BindingResult bindingResult = createBindingResult(new Foo(), "custom");
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", bindingResult);
ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handleWithCustomModelAttributeNameViaValueAttribute").build();
MethodParameter parameter = testMethod.arg(Errors.class);
Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
.block(Duration.ofMillis(5000));
assertThat(actual).isSameAs(bindingResult);
}
@Test
void resolveWithCustomModelAttributeNameConfiguredViaNameAttribute() {
BindingResult bindingResult = createBindingResult(new Foo(), "custom");
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", bindingResult);
ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handleWithCustomModelAttributeNameViaNameAttribute").build();
MethodParameter parameter = testMethod.arg(Errors.class);
Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
.block(Duration.ofMillis(5000));
assertThat(actual).isSameAs(bindingResult);
}
@Test
@@ -98,6 +121,20 @@ class ErrorsMethodArgumentResolverTests {
assertThat(actual).isSameAs(bindingResult);
}
@Test
void resolveWithMonoAndCustomModelAttributeNameConfiguredViaValueAttribute() {
BindingResult bindingResult = createBindingResult(new Foo(), "custom");
this.bindingContext.getModel().asMap().put(BindingResult.MODEL_KEY_PREFIX + "custom", Mono.just(bindingResult));
ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handleWithCustomModelAttributeNameViaValueAttribute").build();
MethodParameter parameter = testMethod.arg(Errors.class);
Object actual = this.resolver.resolveArgument(parameter, this.bindingContext, this.exchange)
.block(Duration.ofMillis(5000));
assertThat(actual).isSameAs(bindingResult);
}
@Test
void resolveWithMonoOnBindingResultAndModelAttribute() {
MethodParameter parameter = this.testMethod.arg(BindingResult.class);
@@ -118,6 +155,11 @@ class ErrorsMethodArgumentResolverTests {
"immediately after the @ModelAttribute argument");
}
private BindingResult createBindingResult(Foo target, String name) {
DataBinder binder = this.bindingContext.createDataBinder(this.exchange, target, name);
return binder.getBindingResult();
}
@SuppressWarnings("unused")
private static class Foo {
@@ -150,4 +192,16 @@ class ErrorsMethodArgumentResolverTests {
String string) {
}
@SuppressWarnings("unused")
void handleWithCustomModelAttributeNameViaValueAttribute(
@ModelAttribute("custom") Foo foo,
Errors errors) {
}
@SuppressWarnings("unused")
void handleWithCustomModelAttributeNameViaNameAttribute(
@ModelAttribute(name = "custom") Foo foo,
Errors errors) {
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -138,7 +138,7 @@ class RequestMappingExceptionHandlingIntegrationTests extends AbstractRequestMap
@GetMapping("/thrown-exception-with-cause-to-handle")
public Publisher<String> handleAndThrowExceptionWithCauseToHandle() {
throw new RuntimeException("State", new IOException("IO"));
throw new RuntimeException("State1", new RuntimeException("State2", new IOException("IO")));
}
@GetMapping(path = "/mono-error")
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.jupiter.api.Assumptions.assumeFalse
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.ComponentScan
@@ -36,6 +37,7 @@ import org.springframework.web.bind.annotation.RestController
import org.springframework.web.client.HttpServerErrorException
import org.springframework.web.reactive.config.EnableWebFlux
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer
import org.springframework.web.testfixture.http.server.reactive.bootstrap.UndertowHttpServer
import reactor.core.publisher.Flux
import java.time.Duration
@@ -114,6 +116,8 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
@ParameterizedHttpServerTest
fun `Suspending handler method returning ResponseEntity of Flux `(httpServer: HttpServer) {
assumeFalse(httpServer is UndertowHttpServer, "Undertow currently fails")
startServer(httpServer)
val entity = performGet<String>("/entity-flux", HttpHeaders.EMPTY, String::class.java)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -314,9 +314,9 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte
/**
* Render the given locale as a text value for inclusion in a cookie.
* <p>The default implementation calls {@link Locale#toString()}
* or JDK 7's {@link Locale#toLanguageTag()}, depending on the
* or {@link Locale#toLanguageTag()}, depending on the
* {@link #setLanguageTagCompliant "languageTagCompliant"} configuration property.
* @param locale the locale to stringify
* @param locale the locale to convert to a string
* @return a String representation for the given locale
* @since 4.3
* @see #isLanguageTagCompliant()
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -66,7 +66,7 @@ import org.springframework.web.util.pattern.PathPatternParser;
* mapping and for content negotiation (with similar deprecations in
* {@link org.springframework.web.accept.ContentNegotiationManagerFactoryBean
* ContentNegotiationManagerFactoryBean}). For further context, please read issue
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24719</a>.
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@@ -232,7 +232,7 @@ public class VersionResourceResolver extends AbstractResourceResolver {
}
private class FileNameVersionedResource extends AbstractResource implements HttpResource {
private static class FileNameVersionedResource extends AbstractResource implements HttpResource {
private final Resource original;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -75,7 +75,7 @@ public class XhrStreamingTransportHandler extends AbstractHttpSendingTransportHa
}
private class XhrStreamingSockJsSession extends StreamingSockJsSession {
private static class XhrStreamingSockJsSession extends StreamingSockJsSession {
public XhrStreamingSockJsSession(String sessionId, SockJsServiceConfig config,
WebSocketHandler wsHandler, Map<String, Object> attributes) {
+77 -71
View File
@@ -3,114 +3,120 @@
<suppressions>
<!-- global -->
<suppress files="[\\/]src[\\/](test|testFixtures)[\\/]java[\\/]" checks="AnnotationLocation|AnnotationUseStyle|AtclauseOrder|AvoidNestedBlocks|FinalClass|HideUtilityClassConstructor|InnerTypeLast|JavadocStyle|JavadocType|JavadocVariable|LeftCurly|MultipleVariableDeclarations|NeedBraces|OneTopLevelClass|OuterTypeFilename|RequireThis|SpringCatch|SpringJavadoc|SpringNoThis" />
<suppress files="[\\/]src[\\/](test|testFixtures)[\\/]java[\\/]org[\\/]springframework[\\/].+(Tests|Suite)" checks="IllegalImport" id="bannedJUnitJupiterImports" />
<suppress files="[\\/]src[\\/](test|testFixtures)[\\/]java[\\/]" checks="SpringJUnit5" message="should not be public" />
<suppress files="[\\/]src[\\/](test|testFixtures)[\\/]java[\\/]" checks="AnnotationLocation|AnnotationUseStyle|AtclauseOrder|AvoidNestedBlocks|FinalClass|HideUtilityClassConstructor|InnerTypeLast|JavadocStyle|JavadocType|JavadocVariable|LeftCurly|MultipleVariableDeclarations|NeedBraces|OneTopLevelClass|OuterTypeFilename|RequireThis|SpringCatch|SpringJavadoc|SpringNoThis"/>
<suppress files="[\\/]src[\\/](test|testFixtures)[\\/]java[\\/]org[\\/]springframework[\\/].+(Tests|Suite)" checks="IllegalImport" id="bannedJUnitJupiterImports"/>
<suppress files="[\\/]src[\\/](test|testFixtures)[\\/]java[\\/]" checks="SpringJUnit5" message="should not be public"/>
<!-- generated sources -->
<suppress files="[\\/]build[\\/]generated[\\/]sources[\\/]" checks=".*" />
<suppress files="[\\/]build[\\/]generated[\\/]sources[\\/]" checks=".*"/>
<!-- JMH benchmarks -->
<suppress files="[\\/]src[\\/]jmh[\\/]java[\\/]org[\\/]springframework[\\/]" checks="JavadocVariable|JavadocStyle|InnerTypeLast" />
<suppress files="[\\/]src[\\/]jmh[\\/]java[\\/]org[\\/]springframework[\\/]" checks="JavadocVariable|JavadocStyle|InnerTypeLast"/>
<!-- spring-aop -->
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]aopalliance[\\/]" checks="IllegalImport" id="bannedImports" message="javax"/>
<!-- spring-beans -->
<suppress files="TypeMismatchException" checks="MutableException"/>
<suppress files="BeanCreationException" checks="MutableException"/>
<suppress files="BeanDefinitionParserDelegate" checks="JavadocVariable" />
<suppress files="DefaultBeanDefinitionDocumentReader" checks="JavadocVariable" />
<suppress files="BeanComponentDefinition" checks="EqualsHashCode" />
<suppress files="GenericBeanDefinition" checks="EqualsHashCode" />
<suppress files="RootBeanDefinition" checks="EqualsHashCode" />
<suppress files="BeanDefinitionParserDelegate" checks="JavadocVariable"/>
<suppress files="DefaultBeanDefinitionDocumentReader" checks="JavadocVariable"/>
<suppress files="BeanComponentDefinition" checks="EqualsHashCode"/>
<suppress files="GenericBeanDefinition" checks="EqualsHashCode"/>
<suppress files="RootBeanDefinition" checks="EqualsHashCode"/>
<!-- spring-context -->
<suppress files="SpringAtInjectTckTests" checks="IllegalImportCheck" id="bannedJUnit3Imports" />
<suppress files="SpringAtInjectTckTests" checks="IllegalImportCheck" id="bannedJUnit3Imports"/>
<!-- spring-core -->
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]asm[\\/]" checks=".*" />
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]cglib[\\/]" checks=".*" />
<suppress files="ByteArrayEncoder" checks="SpringLambda" />
<suppress files="SocketUtils" checks="HideUtilityClassConstructor" />
<suppress files="ResolvableType" checks="FinalClass" />
<suppress files="[\\/]src[\\/]testFixtures[\\/]java[\\/].+" checks="IllegalImport" id="bannedJUnitJupiterImports" />
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]asm[\\/]" checks=".*"/>
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]cglib[\\/]" checks=".*"/>
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]lang[\\/]" checks="IllegalImport" id="bannedImports" message="javax"/>
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]core[\\/]annotation[\\/]" checks="IllegalImport" id="bannedImports" message="javax"/>
<suppress files="[\\/]src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]core[\\/]annotation[\\/]" checks="IllegalImport" id="bannedImports" message="javax"/>
<suppress files="ByteArrayEncoder" checks="SpringLambda"/>
<suppress files="SocketUtils" checks="HideUtilityClassConstructor"/>
<suppress files="ResolvableType" checks="FinalClass"/>
<suppress files="[\\/]src[\\/]testFixtures[\\/]java[\\/].+" checks="IllegalImport" id="bannedJUnitJupiterImports"/>
<!-- spring-expression -->
<suppress files="ExpressionException" checks="MutableException" />
<suppress files="SpelMessage" checks="JavadocVariable|JavadocStyle" />
<suppress files="SpelReproTests" checks="InterfaceIsType" />
<suppress files="ExpressionException" checks="MutableException"/>
<suppress files="SpelMessage" checks="JavadocVariable|JavadocStyle"/>
<suppress files="SpelReproTests" checks="InterfaceIsType"/>
<!-- spring-jcl -->
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]apache[\\/]commons[\\/]logging[\\/]" checks="Header|SpringNoThis|IllegalImport" />
<suppress files="[\\/]src[\\/]main[\\/]java[\\/]org[\\/]apache[\\/]commons[\\/]logging[\\/]" checks="Header|SpringNoThis|IllegalImport"/>
<!-- spring-jdbc -->
<suppress files="ResultSetWrappingSqlRowSet" checks="JavadocStyle" />
<suppress files="ResultSetWrappingSqlRowSet" checks="JavadocStyle"/>
<!-- spring-jms -->
<suppress files="JmsHeaderMapper" checks="InterfaceIsType" />
<suppress files="JmsHeaders" checks="InterfaceIsType" />
<suppress files="AbstractJmsListenerContainerFactory" checks="JavadocStyle" />
<suppress files="DefaultJmsListenerContainerFactory" checks="JavadocStyle" />
<suppress files="DefaultJcaListenerContainerFactory" checks="JavadocStyle" />
<suppress files="JmsHeaderMapper" checks="InterfaceIsType"/>
<suppress files="JmsHeaders" checks="InterfaceIsType"/>
<suppress files="AbstractJmsListenerContainerFactory" checks="JavadocStyle"/>
<suppress files="DefaultJmsListenerContainerFactory" checks="JavadocStyle"/>
<suppress files="DefaultJcaListenerContainerFactory" checks="JavadocStyle"/>
<!-- spring-messaging -->
<suppress files="SimpMessageHeaderAccessor" checks="JavadocVariable" />
<suppress files="SimpMessageType" checks="JavadocVariable" />
<suppress files="StompCommand" checks="JavadocVariable" />
<suppress files="StompHeaderAccessor" checks="JavadocVariable" />
<suppress files="StompHeaders" checks="JavadocVariable" />
<suppress files="org[\\/]springframework[\\/]messaging[\\/]handler[\\/]annotation[\\/]ValueConstants" checks="InterfaceIsType" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]messaging[\\/]protobuf[\\/].*" checks=".*" />
<suppress files="SimpMessageHeaderAccessor" checks="JavadocVariable"/>
<suppress files="SimpMessageType" checks="JavadocVariable"/>
<suppress files="StompCommand" checks="JavadocVariable"/>
<suppress files="StompHeaderAccessor" checks="JavadocVariable"/>
<suppress files="StompHeaders" checks="JavadocVariable"/>
<suppress files="org[\\/]springframework[\\/]messaging[\\/]handler[\\/]annotation[\\/]ValueConstants" checks="InterfaceIsType"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]messaging[\\/]protobuf[\\/].*" checks=".*"/>
<!-- spring-orm -->
<suppress files="jpa[\\/]vendor[\\/]Database" checks="JavadocVariable|JavadocStyle"/>
<!-- spring-tx -->
<suppress files="TransactionSystemException" checks="MutableException" />
<suppress files="TransactionTemplate" checks="EqualsHashCode" />
<suppress files="TransactionSystemException" checks="MutableException"/>
<suppress files="TransactionTemplate" checks="EqualsHashCode"/>
<!-- spring-test - main and test -->
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/]junit4[\\/].+" checks="IllegalImport" id="bannedJUnit4Imports" />
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/]junit[\\/]jupiter[\\/].+" checks="IllegalImport" id="bannedJUnitJupiterImports" />
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/]testng[\\/].+" checks="IllegalImport" id="bannedTestNGImports" />
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/]junit4[\\/].+" checks="IllegalImport" id="bannedJUnit4Imports"/>
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/]junit[\\/]jupiter[\\/].+" checks="IllegalImport" id="bannedJUnitJupiterImports"/>
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/]testng[\\/].+" checks="IllegalImport" id="bannedTestNGImports"/>
<!-- spring-test - main -->
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]util[\\/].+Helper" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]client[\\/]match[\\/].+Matchers" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]reactive[\\/]server[\\/].+" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]servlet[\\/]result[\\/].+Matchers" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]util[\\/].+Helper" checks="IllegalImport" id="bannedHamcrestImports"/>
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]client[\\/]match[\\/].+Matchers" checks="IllegalImport" id="bannedHamcrestImports"/>
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]reactive[\\/]server[\\/].+" checks="IllegalImport" id="bannedHamcrestImports"/>
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]servlet[\\/]result[\\/].+Matchers" checks="IllegalImport" id="bannedHamcrestImports"/>
<!-- spring-test - test -->
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/].+TestNGTests" checks="IllegalImport" id="bannedTestNGImports" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]junit[\\/]jupiter[\\/]web[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]util[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/](client|reactive|servlet)[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]junit4" checks="SpringJUnit5" />
<suppress files="ContextHierarchyDirtiesContextTests|ClassLevelDirtiesContextTests|ContextConfigurationWithPropertiesExtendingPropertiesAndInheritedLoaderTests|ContextConfigurationWithPropertiesExtendingPropertiesTests|DirtiesContextInterfaceTests|.+WacTests|JUnit4SpringContextWebTests" checks="SpringJUnit5" />
<suppress files=".+TestSuite|ContextHierarchyDirtiesContextTests|ClassLevelDirtiesContextTests|ContextConfigurationWithPropertiesExtendingPropertiesAndInheritedLoaderTests|ContextConfigurationWithPropertiesExtendingPropertiesTests|DirtiesContextInterfaceTests|.+WacTests|JUnit4SpringContextWebTests" checks="IllegalImport" id="bannedJUnit4Imports" />
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/].+[\\/](ExpectedExceptionSpringRunnerTests|StandardJUnit4FeaturesTests|ProgrammaticTxMgmtTestNGTests)" checks="RegexpSinglelineJava" id="expectedExceptionAnnotation" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/].+TestNGTests" checks="IllegalImport" id="bannedTestNGImports"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]junit[\\/]jupiter[\\/]web[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]util[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/](client|reactive|servlet)[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]junit4" checks="SpringJUnit5"/>
<suppress files="ContextHierarchyDirtiesContextTests|ClassLevelDirtiesContextTests|ContextConfigurationWithPropertiesExtendingPropertiesAndInheritedLoaderTests|ContextConfigurationWithPropertiesExtendingPropertiesTests|DirtiesContextInterfaceTests|.+WacTests|JUnit4SpringContextWebTests" checks="SpringJUnit5"/>
<suppress files=".+TestSuite|ContextHierarchyDirtiesContextTests|ClassLevelDirtiesContextTests|ContextConfigurationWithPropertiesExtendingPropertiesAndInheritedLoaderTests|ContextConfigurationWithPropertiesExtendingPropertiesTests|DirtiesContextInterfaceTests|.+WacTests|JUnit4SpringContextWebTests" checks="IllegalImport" id="bannedJUnit4Imports"/>
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/].+[\\/](ExpectedExceptionSpringRunnerTests|StandardJUnit4FeaturesTests|ProgrammaticTxMgmtTestNGTests)" checks="RegexpSinglelineJava" id="expectedExceptionAnnotation"/>
<!-- spring-web -->
<suppress files="SpringHandlerInstantiator" checks="JavadocStyle" />
<suppress files="org[\\/]springframework[\\/]http[\\/]HttpMethod" checks="JavadocVariable|JavadocStyle" />
<suppress files="org[\\/]springframework[\\/]http[\\/]HttpStatus" checks="JavadocVariable|JavadocStyle" />
<suppress files="org[\\/]springframework[\\/]web[\\/]bind[\\/]annotation[\\/]CrossOrigin" checks="JavadocStyle" />
<suppress files="org[\\/]springframework[\\/]web[\\/]bind[\\/]annotation[\\/]RequestMethod" checks="JavadocVariable" />
<suppress files="org[\\/]springframework[\\/]web[\\/]bind[\\/]annotation[\\/]ValueConstants" checks="InterfaceIsType" />
<suppress files="PatternParseException" checks="JavadocVariable" />
<suppress files="web[\\/]reactive[\\/]socket[\\/]CloseStatus" checks="JavadocStyle" />
<suppress files="SpringHandlerInstantiator" checks="JavadocStyle"/>
<suppress files="org[\\/]springframework[\\/]http[\\/]HttpMethod" checks="JavadocVariable|JavadocStyle"/>
<suppress files="org[\\/]springframework[\\/]http[\\/]HttpStatus" checks="JavadocVariable|JavadocStyle"/>
<suppress files="org[\\/]springframework[\\/]web[\\/]bind[\\/]annotation[\\/]CrossOrigin" checks="JavadocStyle"/>
<suppress files="org[\\/]springframework[\\/]web[\\/]bind[\\/]annotation[\\/]RequestMethod" checks="JavadocVariable"/>
<suppress files="org[\\/]springframework[\\/]web[\\/]bind[\\/]annotation[\\/]ValueConstants" checks="InterfaceIsType"/>
<suppress files="PatternParseException" checks="JavadocVariable"/>
<suppress files="web[\\/]reactive[\\/]socket[\\/]CloseStatus" checks="JavadocStyle"/>
<!-- spring-webflux -->
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]reactive[\\/]resource[\\/]GzipSupport" checks="IllegalImport" id="bannedJUnitJupiterImports" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]reactive[\\/]resource[\\/]GzipSupport" checks="IllegalImport" id="bannedJUnitJupiterImports"/>
<!-- spring-webmvc -->
<suppress files="org[\\/]springframework[\\/]web[\\/]servlet[\\/]tags[\\/]form[\\/].*Tag" checks="JavadocVariable" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]protobuf[\\/].*" checks=".*" />
<suppress files="ExtractingResponseErrorHandlerTests" checks="MutableException" />
<suppress files="ServletAnnotationControllerHandlerMethodTests" checks="InterfaceIsType" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]servlet[\\/]resource[\\/]GzipSupport" checks="IllegalImport" id="bannedJUnitJupiterImports" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]servlet[\\/]handler[\\/]PathPatterns.+" checks="IllegalImport" id="bannedJUnitJupiterImports" />
<suppress files="org[\\/]springframework[\\/]web[\\/]servlet[\\/]tags[\\/]form[\\/].*Tag" checks="JavadocVariable"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]protobuf[\\/].*" checks=".*"/>
<suppress files="ExtractingResponseErrorHandlerTests" checks="MutableException"/>
<suppress files="ServletAnnotationControllerHandlerMethodTests" checks="InterfaceIsType"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]servlet[\\/]resource[\\/]GzipSupport" checks="IllegalImport" id="bannedJUnitJupiterImports"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]servlet[\\/]handler[\\/]PathPatterns.+" checks="IllegalImport" id="bannedJUnitJupiterImports"/>
<!-- spring-websocket -->
<suppress files="web[\\/]socket[\\/]CloseStatus" checks="JavadocStyle" />
<suppress files="web[\\/]socket[\\/]WebSocketHttpHeaders" checks="JavadocVariable" />
<suppress files="sockjs[\\/]frame[\\/]SockJsFrameType" checks="JavadocVariable" />
<suppress files="sockjs[\\/]transport[\\/]TransportType" checks="JavadocVariable" />
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]reactive[\\/]protobuf[\\/].*" checks=".*" />
<suppress files="web[\\/]socket[\\/]CloseStatus" checks="JavadocStyle"/>
<suppress files="web[\\/]socket[\\/]WebSocketHttpHeaders" checks="JavadocVariable"/>
<suppress files="sockjs[\\/]frame[\\/]SockJsFrameType" checks="JavadocVariable"/>
<suppress files="sockjs[\\/]transport[\\/]TransportType" checks="JavadocVariable"/>
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]reactive[\\/]protobuf[\\/].*" checks=".*"/>
</suppressions>
+90 -90
View File
@@ -8,7 +8,7 @@
<!-- Root Checks -->
<module name="io.spring.javaformat.checkstyle.check.SpringHeaderCheck">
<property name="fileExtensions" value="java" />
<property name="fileExtensions" value="java"/>
<property name="headerType" value="apache2"/>
<property name="headerCopyrightPattern" value="20\d\d-20\d\d"/>
<property name="packageInfoHeaderType" value="none"/>
@@ -19,125 +19,125 @@
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
<!-- Annotations -->
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck">
<property name="elementStyle" value="compact" />
<property name="elementStyle" value="compact"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.MissingOverrideCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.PackageAnnotationCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.MissingOverrideCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.PackageAnnotationCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck">
<property name="allowSamelineSingleParameterlessAnnotation"
value="false" />
value="false"/>
</module>
<!-- Block Checks -->
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.EmptyBlockCheck">
<property name="option" value="text" />
<property name="option" value="text"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck">
<property name="option" value="alone" />
<property name="option" value="alone"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.NeedBracesCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.AvoidNestedBlocksCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.NeedBracesCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.AvoidNestedBlocksCheck"/>
<!-- Class Design -->
<module name="com.puppycrawl.tools.checkstyle.checks.design.FinalClassCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.design.InterfaceIsTypeCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.design.FinalClassCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.design.InterfaceIsTypeCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.design.MutableExceptionCheck">
<property name="format" value="^.*Exception$" />
<property name="format" value="^.*Exception$"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.design.InnerTypeLastCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.design.InnerTypeLastCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck"/>
<!-- Type Names -->
<module name="TypeName">
<property name="format" value="^[A-Z][a-zA-Z0-9_$]*(?&lt;!Test)$" />
<property name="tokens" value="CLASS_DEF" />
<property name="format" value="^[A-Z][a-zA-Z0-9_$]*(?&lt;!Test)$"/>
<property name="tokens" value="CLASS_DEF"/>
<message key="name.invalidPattern"
value="Class name ''{0}'' must not end with ''Test'' (checked pattern ''{1}'')." />
value="Class name ''{0}'' must not end with ''Test'' (checked pattern ''{1}'')."/>
</module>
<!-- Coding -->
<module name="com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.EmptyStatementCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.EqualsHashCodeCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanExpressionCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanReturnCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.StringLiteralEqualityCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.EmptyStatementCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.EqualsHashCodeCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanExpressionCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanReturnCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.StringLiteralEqualityCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedForDepthCheck">
<property name="max" value="3" />
<property name="max" value="3"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedIfDepthCheck">
<property name="max" value="5" />
<property name="max" value="5"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedTryDepthCheck">
<property name="max" value="3" />
<property name="max" value="3"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheck"/>
<module name="io.spring.javaformat.checkstyle.filter.RequiresOuterThisFilter" />
<module name="io.spring.javaformat.checkstyle.filter.RequiresOuterThisFilter"/>
<module name="io.spring.javaformat.checkstyle.filter.IdentCheckFilter">
<property name="names" value="logger" />
<property name="names" value="logger"/>
<module
name="com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck">
<property name="checkMethods" value="false" />
<property name="validateOnlyOverlapping" value="false" />
<property name="checkMethods" value="false"/>
<property name="validateOnlyOverlapping" value="false"/>
</module>
</module>
<module name="io.spring.javaformat.checkstyle.check.SpringNoThisCheck">
<property name="names" value="logger" />
<property name="names" value="logger"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck"/>
<!-- Imports -->
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.UnusedImportsCheck">
<property name="processJavadoc" value="true" />
<property name="processJavadoc" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck">
<property name="groups" value="java,javax,*,org.springframework" />
<property name="ordered" value="true" />
<property name="separated" value="true" />
<property name="option" value="bottom" />
<property name="sortStaticImportsAlphabetically" value="true" />
<property name="groups" value="java,javax,*,org.springframework"/>
<property name="ordered" value="true"/>
<property name="separated" value="true"/>
<property name="option" value="bottom"/>
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedImports"/>
<property name="regexp" value="true" />
<property name="regexp" value="true"/>
<property name="illegalClasses"
value="^reactor\.core\.support\.Assert,^org\.slf4j\.LoggerFactory" />
value="^reactor\.core\.support\.Assert,^org\.slf4j\.LoggerFactory,^(?!org\.springframework).*(NonNull|Nonnull|NonNullApi|NonNullFields|Nullable)$"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedJUnit3Imports"/>
<property name="regexp" value="true" />
<property name="illegalClasses" value="^junit\.framework\..+" />
<property name="regexp" value="true"/>
<property name="illegalClasses" value="^junit\.framework\..+"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedJUnit4Imports"/>
<property name="regexp" value="true" />
<property name="regexp" value="true"/>
<property name="illegalClasses"
value="^org\.junit\.(Test|BeforeClass|AfterClass|Before|After|Ignore|FixMethodOrder|Rule|ClassRule|Assert|Assume)$,^org\.junit\.(Assert|Assume)\..+,^org\.junit\.(experimental|internal|matchers|rules|runner|runners|validator)\..+" />
value="^org\.junit\.(Test|BeforeClass|AfterClass|Before|After|Ignore|FixMethodOrder|Rule|ClassRule|Assert|Assume)$,^org\.junit\.(Assert|Assume)\..+,^org\.junit\.(experimental|internal|matchers|rules|runner|runners|validator)\..+"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedJUnitJupiterImports"/>
<property name="regexp" value="true" />
<property name="illegalClasses" value="^org\.junit\.jupiter\..+" />
<property name="regexp" value="true"/>
<property name="illegalClasses" value="^org\.junit\.jupiter\..+"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedTestNGImports"/>
<property name="regexp" value="true" />
<property name="illegalClasses" value="^org\.testng\..+," />
<property name="regexp" value="true"/>
<property name="illegalClasses" value="^org\.testng\..+,"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedHamcrestImports"/>
<property name="regexp" value="true" />
<property name="illegalClasses" value="^org\.hamcrest\..+" />
<property name="regexp" value="true"/>
<property name="illegalClasses" value="^org\.hamcrest\..+"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
<property name="id" value="bannedJetbrainsAnnotationsImports"/>
<property name="regexp" value="true" />
<property name="illegalClasses" value="^org\.jetbrains\.annotations\..+" />
<property name="regexp" value="true"/>
<property name="illegalClasses" value="^org\.jetbrains\.annotations\..+"/>
</module>
<!-- Javadoc Comments -->
@@ -155,7 +155,7 @@
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheck">
<property name="checkEmptyJavadoc" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagContinuationIndentationCheck">
<property name="offset" value="0"/>
</module>
@@ -172,74 +172,74 @@
<module name="com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck">
<property name="tokens" value="BLOCK_COMMENT_BEGIN"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.UpperEllCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.ArrayTypeStyleCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.OuterTypeFilenameCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.UpperEllCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.ArrayTypeStyleCheck"/>
<module name="com.puppycrawl.tools.checkstyle.checks.OuterTypeFilenameCheck"/>
<!-- Regexp -->
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="format" value="^\t* +\t*\S" />
<property name="format" value="^\t* +\t*\S"/>
<property name="message"
value="Line has leading space characters; indentation should be performed with tabs only." />
<property name="ignoreComments" value="true" />
value="Line has leading space characters; indentation should be performed with tabs only."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpCheck">
<property name="format" value="[ \t]+$" />
<property name="illegalPattern" value="true" />
<property name="message" value="Trailing whitespace" />
<property name="format" value="[ \t]+$"/>
<property name="illegalPattern" value="true"/>
<property name="message" value="Trailing whitespace"/>
</module>
<module
name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="maximum" value="0" />
<property name="maximum" value="0"/>
<property name="format"
value="assertThatExceptionOfType\((NullPointerException|IllegalArgumentException|IOException|IllegalStateException)\.class\)" />
value="assertThatExceptionOfType\((NullPointerException|IllegalArgumentException|IOException|IllegalStateException)\.class\)"/>
<property name="message"
value="Please use specialized AssertJ assertThat*Exception method." />
<property name="ignoreComments" value="true" />
value="Please use specialized AssertJ assertThat*Exception method."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="bddMockito"/>
<property name="maximum" value="0"/>
<property name="format" value="org\.mockito\.Mockito\.(when|doThrow|doAnswer)" />
<property name="message" value="Please use BDDMockito." />
<property name="ignoreComments" value="true" />
<property name="format" value="org\.mockito\.Mockito\.(when|doThrow|doAnswer)"/>
<property name="message" value="Please use BDDMockito."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="expectedExceptionAnnotation"/>
<property name="maximum" value="0"/>
<property name="format" value="\@Test\(expected" />
<property name="message" value="Please use AssertJ assertions." />
<property name="ignoreComments" value="true" />
<property name="format" value="\@Test\(expected"/>
<property name="message" value="Please use AssertJ assertions."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="junit4Assertions"/>
<property name="maximum" value="0"/>
<property name="format" value="org\.junit\.Assert\.assert" />
<property name="message" value="Please use AssertJ assertions." />
<property name="ignoreComments" value="true" />
<property name="format" value="org\.junit\.Assert\.assert"/>
<property name="message" value="Please use AssertJ assertions."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="junitJupiterAssertions"/>
<property name="maximum" value="0"/>
<property name="format" value="org\.junit\.jupiter\.api\.Assertions\.assert" />
<property name="message" value="Please use AssertJ assertions." />
<property name="ignoreComments" value="true" />
<property name="format" value="org\.junit\.jupiter\.api\.Assertions\.assert"/>
<property name="message" value="Please use AssertJ assertions."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="testNGAssertions"/>
<property name="maximum" value="0"/>
<!-- should cover org.testng.Assert and org.testng.AssertJUnit -->
<property name="format" value="org\.testng\.Assert(JUnit)?\.assert" />
<property name="message" value="Please use AssertJ assertions." />
<property name="ignoreComments" value="true" />
<property name="format" value="org\.testng\.Assert(JUnit)?\.assert"/>
<property name="message" value="Please use AssertJ assertions."/>
<property name="ignoreComments" value="true"/>
</module>
<!-- Spring Conventions -->
<module name="io.spring.javaformat.checkstyle.check.SpringLambdaCheck">
<property name="singleArgumentParentheses" value="false" />
<property name="singleArgumentParentheses" value="false"/>
</module>
<module name="io.spring.javaformat.checkstyle.check.SpringCatchCheck" />
<module name="io.spring.javaformat.checkstyle.check.SpringJavadocCheck" />
<module name="io.spring.javaformat.checkstyle.check.SpringJUnit5Check" />
<module name="io.spring.javaformat.checkstyle.check.SpringCatchCheck"/>
<module name="io.spring.javaformat.checkstyle.check.SpringJavadocCheck"/>
<module name="io.spring.javaformat.checkstyle.check.SpringJUnit5Check"/>
</module>
</module>
+20 -19
View File
@@ -792,8 +792,8 @@ See also the `org.springframework.beans.support.ResourceEditorRegistrar` for an
`PropertyEditorRegistrar` implementation. Notice how in its implementation of the
`registerCustomEditors(..)` method, it creates new instances of each property editor.
The next example shows how to configure a `CustomEditorConfigurer` and inject an instance of our
`CustomPropertyEditorRegistrar` into it:
The next example shows how to configure a `CustomEditorConfigurer` and inject an instance
of our `CustomPropertyEditorRegistrar` into it:
[source,xml,indent=0,subs="verbatim,quotes"]
----
@@ -809,50 +809,51 @@ The next example shows how to configure a `CustomEditorConfigurer` and inject an
class="com.foo.editors.spring.CustomPropertyEditorRegistrar"/>
----
Finally (and in a bit of a departure from the focus of this chapter for those of you
using <<web.adoc#mvc, Spring's MVC web framework>>), using `PropertyEditorRegistrars` in
conjunction with data-binding `Controllers` (such as `SimpleFormController`) can be very
convenient. The following example uses a `PropertyEditorRegistrar` in the
implementation of an `initBinder(..)` method:
Finally (and in a bit of a departure from the focus of this chapter) for those of you
using <<web.adoc#mvc, Spring's MVC web framework>>, using a `PropertyEditorRegistrar` in
conjunction with data-binding web controllers can be very convenient. The following
example uses a `PropertyEditorRegistrar` in the implementation of an `@InitBinder` method:
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
.Java
----
public final class RegisterUserController extends SimpleFormController {
@Controller
public class RegisterUserController {
private final PropertyEditorRegistrar customPropertyEditorRegistrar;
public RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
this.customPropertyEditorRegistrar = propertyEditorRegistrar;
}
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
@InitBinder
void initBinder(WebDataBinder binder) {
this.customPropertyEditorRegistrar.registerCustomEditors(binder);
}
// other methods to do with registering a User
// other methods related to registering a User
}
----
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
.Kotlin
----
@Controller
class RegisterUserController(
private val customPropertyEditorRegistrar: PropertyEditorRegistrar) : SimpleFormController() {
private val customPropertyEditorRegistrar: PropertyEditorRegistrar) {
protected fun initBinder(request: HttpServletRequest,
binder: ServletRequestDataBinder) {
@InitBinder
fun initBinder(binder: WebDataBinder) {
this.customPropertyEditorRegistrar.registerCustomEditors(binder)
}
// other methods to do with registering a User
// other methods related to registering a User
}
----
This style of `PropertyEditor` registration can lead to concise code (the implementation
of `initBinder(..)` is only one line long) and lets common `PropertyEditor`
registration code be encapsulated in a class and then shared amongst as many
`Controllers` as needed.
of the `@InitBinder` method is only one line long) and lets common `PropertyEditor`
registration code be encapsulated in a class and then shared amongst as many controllers
as needed.
+1 -1
View File
@@ -218,7 +218,7 @@ on the server side (for example, in Spring MVC REST controllers).
Concrete implementations for the main media (MIME) types are provided in the framework
and are, by default, registered with the `RestTemplate` on the client side and with
`RequestMethodHandlerAdapter` on the server side (see
`RequestMappingHandlerAdapter` on the server side (see
<<web.adoc#mvc-config-message-converters, Configuring Message Converters>>).
The implementations of `HttpMessageConverter` are described in the following sections.