From 490b5c77fc7bc504a03792f5690189c3429b4ff0 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Wed, 1 Nov 2023 10:49:43 +0800 Subject: [PATCH] Use switch expression where feasible --- .../DefaultListableBeanFactoryBenchmark.java | 24 ++--- .../AbstractNestablePropertyAccessor.java | 9 +- .../beans/PropertyAccessorUtils.java | 8 +- .../LoadTimeWeavingConfiguration.java | 12 +-- .../format/datetime/DateFormatter.java | 16 ++-- .../core/SerializableTypeWrapper.java | 9 +- .../util/xml/ListBasedXMLEventReader.java | 20 ++--- .../core/io/ResourceTests.java | 11 ++- .../common/TemplateAwareExpressionParser.java | 17 ++-- .../jdbc/core/JdbcTemplate.java | 52 +++++------ .../LazyConnectionDataSourceProxy.java | 63 ++++++++------ .../SingleConnectionDataSource.java | 42 ++++----- .../TransactionAwareDataSourceProxy.java | 23 +++-- .../connection/SingleConnectionFactory.java | 87 +++++++++++-------- ...ransactionAwareConnectionFactoryProxy.java | 43 +++++---- .../user/DefaultUserDestinationResolver.java | 12 ++- .../orm/hibernate5/HibernateTemplate.java | 50 +++++------ .../LocalSessionFactoryBuilder.java | 35 ++++---- .../jpa/AbstractEntityManagerFactoryBean.java | 10 ++- .../orm/jpa/ExtendedEntityManagerCreator.java | 32 ++++--- .../orm/jpa/SharedEntityManagerCreator.java | 45 ++++++---- .../connection/SingleConnectionFactory.java | 33 ++++--- ...ransactionAwareConnectionFactoryProxy.java | 40 ++++----- .../r2dbc/core/DefaultDatabaseClient.java | 33 ++++--- .../JtaAfterCompletionSynchronization.java | 11 +-- .../util/HtmlCharacterEntityReferences.java | 20 ++--- .../client/WebClientResponseException.java | 53 ++++------- .../annotation/MvcUriComponentsBuilder.java | 40 +++++---- 28 files changed, 423 insertions(+), 427 deletions(-) diff --git a/spring-beans/src/jmh/java/org/springframework/beans/factory/DefaultListableBeanFactoryBenchmark.java b/spring-beans/src/jmh/java/org/springframework/beans/factory/DefaultListableBeanFactoryBenchmark.java index ec828fb185b..4679dd17de3 100644 --- a/spring-beans/src/jmh/java/org/springframework/beans/factory/DefaultListableBeanFactoryBenchmark.java +++ b/spring-beans/src/jmh/java/org/springframework/beans/factory/DefaultListableBeanFactoryBenchmark.java @@ -55,30 +55,30 @@ public class DefaultListableBeanFactoryBenchmark { RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class); switch (this.mode) { - case "simple": - break; - case "dependencyCheck": + case "simple" -> { + } + case "dependencyCheck" -> { rbd = new RootBeanDefinition(LifecycleBean.class); rbd.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_OBJECTS); this.beanFactory.addBeanPostProcessor(new LifecycleBean.PostProcessor()); - break; - case "constructor": + } + case "constructor" -> { rbd.getConstructorArgumentValues().addGenericArgumentValue("juergen"); rbd.getConstructorArgumentValues().addGenericArgumentValue("99"); - break; - case "constructorArgument": + } + case "constructorArgument" -> { rbd.getConstructorArgumentValues().addGenericArgumentValue(new RuntimeBeanReference("spouse")); this.beanFactory.registerBeanDefinition("test", rbd); this.beanFactory.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class)); - break; - case "properties": + } + case "properties" -> { rbd.getPropertyValues().add("name", "juergen"); rbd.getPropertyValues().add("age", "99"); - break; - case "resolvedProperties": + } + case "resolvedProperties" -> { rbd.getPropertyValues().add("spouse", new RuntimeBeanReference("spouse")); this.beanFactory.registerBeanDefinition("spouse", new RootBeanDefinition(TestBean.class)); - break; + } } rbd.setScope(BeanDefinition.SCOPE_PROTOTYPE); this.beanFactory.registerBeanDefinition("test", rbd); diff --git a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java index fcb43011290..eaef7f706ec 100644 --- a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java @@ -976,11 +976,11 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA int length = propertyName.length(); for (int i = startIndex; i < length; i++) { switch (propertyName.charAt(i)) { - case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR: + case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR -> { // The property name contains opening prefix(es)... unclosedPrefixes++; - break; - case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR: + } + case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR -> { if (unclosedPrefixes == 0) { // No unclosed prefix(es) in the property name (left) -> // this is the suffix we are looking for. @@ -991,13 +991,12 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA // just one that occurred within the property name. unclosedPrefixes--; } - break; + } } } return -1; } - @Override public String toString() { String className = getClass().getName(); diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java b/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java index 564194e2f0a..c3583927f5d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyAccessorUtils.java @@ -91,14 +91,14 @@ public abstract class PropertyAccessorUtils { int i = (last ? length - 1 : 0); while (last ? i >= 0 : i < length) { switch (propertyPath.charAt(i)) { - case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR: - case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR: + case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR, PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR -> { inKey = !inKey; - break; - case PropertyAccessor.NESTED_PROPERTY_SEPARATOR_CHAR: + } + case PropertyAccessor.NESTED_PROPERTY_SEPARATOR_CHAR -> { if (!inKey) { return i; } + } } if (last) { i--; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java b/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java index 477de756a8c..c08dd42b244 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/LoadTimeWeavingConfiguration.java @@ -94,20 +94,20 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade if (this.enableLTW != null) { AspectJWeaving aspectJWeaving = this.enableLTW.getEnum("aspectjWeaving"); switch (aspectJWeaving) { - case DISABLED: + case DISABLED -> { // AJ weaving is disabled -> do nothing - break; - case AUTODETECT: + } + case AUTODETECT -> { if (this.beanClassLoader.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) == null) { // No aop.xml present on the classpath -> treat as 'disabled' break; } // aop.xml is present on the classpath -> enable AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader); - break; - case ENABLED: + } + case ENABLED -> { AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader); - break; + } } } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java index 06a95b7bee5..4b909a33247 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java @@ -277,13 +277,15 @@ public class DateFormatter implements Formatter { private int getStylePatternForChar(int index) { if (this.stylePattern != null && this.stylePattern.length() > index) { - switch (this.stylePattern.charAt(index)) { - case 'S': return DateFormat.SHORT; - case 'M': return DateFormat.MEDIUM; - case 'L': return DateFormat.LONG; - case 'F': return DateFormat.FULL; - case '-': return -1; - } + char ch = this.stylePattern.charAt(index); + return switch (ch) { + case 'S' -> DateFormat.SHORT; + case 'M' -> DateFormat.MEDIUM; + case 'L' -> DateFormat.LONG; + case 'F' -> DateFormat.FULL; + case '-' -> -1; + default -> throw new IllegalStateException("Unsupported style pattern '" + this.stylePattern + "'"); + }; } throw new IllegalStateException("Unsupported style pattern '" + this.stylePattern + "'"); } diff --git a/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java b/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java index 01e5a42b5ec..3df50042f43 100644 --- a/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java +++ b/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java @@ -186,17 +186,20 @@ final class SerializableTypeWrapper { @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { switch (method.getName()) { - case "equals": + case "equals" -> { Object other = args[0]; // Unwrap proxies for speed if (other instanceof Type otherType) { other = unwrap(otherType); } return ObjectUtils.nullSafeEquals(this.provider.getType(), other); - case "hashCode": + } + case "hashCode" -> { return ObjectUtils.nullSafeHashCode(this.provider.getType()); - case "getTypeProvider": + } + case "getTypeProvider" -> { return this.provider; + } } if (Type.class == method.getReturnType() && ObjectUtils.isEmpty(args)) { diff --git a/spring-core/src/main/java/org/springframework/util/xml/ListBasedXMLEventReader.java b/spring-core/src/main/java/org/springframework/util/xml/ListBasedXMLEventReader.java index 803139cd6ea..abb303a2361 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/ListBasedXMLEventReader.java +++ b/spring-core/src/main/java/org/springframework/util/xml/ListBasedXMLEventReader.java @@ -112,24 +112,22 @@ class ListBasedXMLEventReader extends AbstractXMLEventReader { while (true) { XMLEvent event = nextEvent(); switch (event.getEventType()) { - case XMLStreamConstants.START_ELEMENT: - case XMLStreamConstants.END_ELEMENT: + case XMLStreamConstants.START_ELEMENT, XMLStreamConstants.END_ELEMENT -> { return event; - case XMLStreamConstants.END_DOCUMENT: + } + case XMLStreamConstants.END_DOCUMENT -> { return null; - case XMLStreamConstants.SPACE: - case XMLStreamConstants.COMMENT: - case XMLStreamConstants.PROCESSING_INSTRUCTION: + } + case XMLStreamConstants.SPACE, XMLStreamConstants.COMMENT, XMLStreamConstants.PROCESSING_INSTRUCTION -> { continue; - case XMLStreamConstants.CDATA: - case XMLStreamConstants.CHARACTERS: + } + case XMLStreamConstants.CDATA, XMLStreamConstants.CHARACTERS -> { if (!event.asCharacters().isWhiteSpace()) { throw new XMLStreamException( "Non-ignorable whitespace CDATA or CHARACTERS event: " + event); } - break; - default: - throw new XMLStreamException("Expected START_ELEMENT or END_ELEMENT: " + event); + } + default -> throw new XMLStreamException("Expected START_ELEMENT or END_ELEMENT: " + event); } } } diff --git a/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java b/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java index 742fa2c925b..9a9ada3124e 100644 --- a/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/ResourceTests.java @@ -438,16 +438,15 @@ class ResourceTests { @Override public MockResponse dispatch(RecordedRequest request) throws InterruptedException { if (request.getPath().equals("/resource")) { - switch (request.getMethod()) { - case "HEAD": - return new MockResponse() + return switch (request.getMethod()) { + case "HEAD" -> new MockResponse() .addHeader("Content-Length", "6"); - case "GET": - return new MockResponse() + case "GET" -> new MockResponse() .addHeader("Content-Length", "6") .addHeader("Content-Type", "text/plain") .setBody("Spring"); - } + default -> new MockResponse().setResponseCode(404); + }; } return new MockResponse().setResponseCode(404); } diff --git a/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java b/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java index 0f5ccbddbd2..e0fb6bc0b41 100644 --- a/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java +++ b/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java @@ -184,14 +184,10 @@ public abstract class TemplateAwareExpressionParser implements ExpressionParser } char ch = expressionString.charAt(pos); switch (ch) { - case '{': - case '[': - case '(': + case '{', '[', '(' -> { stack.push(new Bracket(ch, pos)); - break; - case '}': - case ']': - case ')': + } + case '}', ']', ')' -> { if (stack.isEmpty()) { throw new ParseException(expressionString, pos, "Found closing '" + ch + "' at position " + pos + " without an opening '" + @@ -203,9 +199,8 @@ public abstract class TemplateAwareExpressionParser implements ExpressionParser "' at position " + pos + " but most recent opening is '" + p.bracket + "' at position " + p.pos); } - break; - case '\'': - case '"': + } + case '\'', '"' -> { // jump to the end of the literal int endLiteral = expressionString.indexOf(ch, pos + 1); if (endLiteral == -1) { @@ -213,7 +208,7 @@ public abstract class TemplateAwareExpressionParser implements ExpressionParser "Found non terminating string literal starting at position " + pos); } pos = endLiteral; - break; + } } pos++; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index a57132b08b3..c6979a21c81 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -1655,42 +1655,36 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> (proxy == args[0]); // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of PersistenceManager proxy. - return System.identityHashCode(proxy); - case "close": + case "close" -> null; // Handle close method: suppress, not valid. - return null; - case "isClosed": - return false; - case "getTargetConnection": + case "isClosed" -> false; + case "getTargetConnection" -> this.target; // Handle getTargetConnection method: return underlying Connection. - return this.target; - case "unwrap": - return (((Class) args[0]).isInstance(proxy) ? proxy : this.target.unwrap((Class) args[0])); - case "isWrapperFor": - return (((Class) args[0]).isInstance(proxy) || this.target.isWrapperFor((Class) args[0])); - } + case "unwrap" -> (((Class) args[0]).isInstance(proxy) ? proxy : this.target.unwrap((Class) args[0])); + case "isWrapperFor" -> (((Class) args[0]).isInstance(proxy) || this.target.isWrapperFor((Class) args[0])); + default -> { + // Invoke method on target Connection. + try { + Object retVal = method.invoke(this.target, args); - // Invoke method on target Connection. - try { - Object retVal = method.invoke(this.target, args); + // If return value is a JDBC Statement, apply statement settings + // (fetch size, max rows, transaction timeout). + if (retVal instanceof Statement statement) { + applyStatementSettings(statement); + } - // If return value is a JDBC Statement, apply statement settings - // (fetch size, max rows, transaction timeout). - if (retVal instanceof Statement statement) { - applyStatementSettings(statement); + yield retVal; + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } } - - return retVal; - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + }; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java index ed352bf3885..fec0dd8b454 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java @@ -302,28 +302,31 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource { // Invocation on ConnectionProxy interface coming in... switch (method.getName()) { - case "equals": + case "equals" -> { // We must avoid fetching a target Connection for "equals". // Only consider equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // We must avoid fetching a target Connection for "hashCode", // and we must return the same hash code even when the target // Connection has been fetched: use hashCode of Connection proxy. return System.identityHashCode(proxy); - case "getTargetConnection": + } + case "getTargetConnection" -> { // Handle getTargetConnection method: return underlying connection. return getTargetConnection(method); - case "unwrap": + } + case "unwrap" -> { if (((Class) args[0]).isInstance(proxy)) { return proxy; } - break; - case "isWrapperFor": + } + case "isWrapperFor" -> { if (((Class) args[0]).isInstance(proxy)) { return true; } - break; + } } if (!hasTargetConnection()) { @@ -332,58 +335,68 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource { // a physical JDBC Connection until absolutely necessary. switch (method.getName()) { - case "toString": + case "toString" -> { return "Lazy Connection proxy for target DataSource [" + getTargetDataSource() + "]"; - case "getAutoCommit": + } + case "getAutoCommit" -> { if (this.autoCommit != null) { return this.autoCommit; } // Else fetch actual Connection and check there, // because we didn't have a default specified. - break; - case "setAutoCommit": + } + case "setAutoCommit" -> { this.autoCommit = (Boolean) args[0]; return null; - case "getTransactionIsolation": + } + case "getTransactionIsolation" -> { if (this.transactionIsolation != null) { return this.transactionIsolation; } // Else fetch actual Connection and check there, // because we didn't have a default specified. - break; - case "setTransactionIsolation": + } + case "setTransactionIsolation" -> { this.transactionIsolation = (Integer) args[0]; return null; - case "isReadOnly": + } + case "isReadOnly" -> { return this.readOnly; - case "setReadOnly": + } + case "setReadOnly" -> { this.readOnly = (Boolean) args[0]; return null; - case "getHoldability": + } + case "getHoldability" -> { return this.holdability; - case "setHoldability": + } + case "setHoldability" -> { this.holdability = (Integer) args[0]; return null; - case "commit": - case "rollback": + } + case "commit", "rollback" -> { // Ignore: no statements created yet. return null; - case "getWarnings": - case "clearWarnings": + } + case "getWarnings", "clearWarnings" -> { // Ignore: no warnings to expose yet. return null; - case "close": + } + case "close" -> { // Ignore: no target connection yet. this.closed = true; return null; - case "isClosed": + } + case "isClosed" -> { return this.closed; - default: + } + default -> { if (this.closed) { // Connection proxy closed, without ever having fetched a // physical JDBC Connection: throw corresponding SQLException. throw new SQLException("Illegal operation: connection is closed"); } + } } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java index 17026d8d6fa..59074efea62 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java @@ -349,34 +349,28 @@ public class SingleConnectionDataSource extends DriverManagerDataSource public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> (proxy == args[0]); // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of Connection proxy. - return System.identityHashCode(proxy); - case "close": + case "close" -> null; // Handle close method: don't pass the call on. - return null; - case "isClosed": - return this.target.isClosed(); - case "getTargetConnection": + case "isClosed" -> this.target.isClosed(); + case "getTargetConnection" -> this.target; // Handle getTargetConnection method: return underlying Connection. - return this.target; - case "unwrap": - return (((Class) args[0]).isInstance(proxy) ? proxy : this.target.unwrap((Class) args[0])); - case "isWrapperFor": - return (((Class) args[0]).isInstance(proxy) || this.target.isWrapperFor((Class) args[0])); - } - - // Invoke method on target Connection. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + case "unwrap" -> (((Class) args[0]).isInstance(proxy) ? proxy : this.target.unwrap((Class) args[0])); + case "isWrapperFor" -> (((Class) args[0]).isInstance(proxy) || this.target.isWrapperFor((Class) args[0])); + default -> { + // Invoke method on target Connection. + try { + yield method.invoke(this.target, args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java index 122ceeba185..fadc44283fd 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java @@ -176,13 +176,15 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource { // Invocation on ConnectionProxy interface coming in... switch (method.getName()) { - case "equals": + case "equals" -> { // Only considered as equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // Use hashCode of Connection proxy. return System.identityHashCode(proxy); - case "toString": + } + case "toString" -> { // Allow for differentiating between the proxy and the raw Connection. StringBuilder sb = new StringBuilder("Transaction-aware proxy for target Connection "); if (this.target != null) { @@ -192,23 +194,26 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource { sb.append(" from DataSource [").append(this.targetDataSource).append(']'); } return sb.toString(); - case "close": + } + case "close" -> { // Handle close method: only close if not within a transaction. DataSourceUtils.doReleaseConnection(this.target, this.targetDataSource); this.closed = true; return null; - case "isClosed": + } + case "isClosed" -> { return this.closed; - case "unwrap": + } + case "unwrap" -> { if (((Class) args[0]).isInstance(proxy)) { return proxy; } - break; - case "isWrapperFor": + } + case "isWrapperFor" -> { if (((Class) args[0]).isInstance(proxy)) { return true; } - break; + } } if (this.target == null) { diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java index d85f4033507..763fba93ece 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java @@ -600,35 +600,35 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti @Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> { Object other = args[0]; if (proxy == other) { - return true; + yield true; } if (other == null || !Proxy.isProxyClass(other.getClass())) { - return false; + yield false; } InvocationHandler otherHandler = Proxy.getInvocationHandler(other); - return (otherHandler instanceof SharedConnectionInvocationHandler sharedHandler && + yield (otherHandler instanceof SharedConnectionInvocationHandler sharedHandler && factory() == sharedHandler.factory()); - case "hashCode": + } + case "hashCode" -> System.identityHashCode(factory()); // Use hashCode of containing SingleConnectionFactory. - return System.identityHashCode(factory()); - case "toString": - return "Shared JMS Connection: " + getConnection(); - case "setClientID": + case "toString" -> "Shared JMS Connection: " + getConnection(); + case "setClientID" -> { // Handle setClientID method: throw exception if not compatible. String currentClientId = getConnection().getClientID(); if (currentClientId != null && currentClientId.equals(args[0])) { - return null; + yield null; } else { throw new jakarta.jms.IllegalStateException( "setClientID call not supported on proxy for shared Connection. " + - "Set the 'clientId' property on the SingleConnectionFactory instead."); + "Set the 'clientId' property on the SingleConnectionFactory instead."); } - case "setExceptionListener": + } + case "setExceptionListener" -> { // Handle setExceptionListener method: add to the chain. synchronized (connectionMonitor) { if (aggregatedExceptionListener != null) { @@ -642,32 +642,36 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti } this.localExceptionListener = listener; } - return null; + yield null; } else { throw new jakarta.jms.IllegalStateException( "setExceptionListener call not supported on proxy for shared Connection. " + - "Set the 'exceptionListener' property on the SingleConnectionFactory instead. " + - "Alternatively, activate SingleConnectionFactory's 'reconnectOnException' feature, " + - "which will allow for registering further ExceptionListeners to the recovery chain."); + "Set the 'exceptionListener' property on the SingleConnectionFactory instead. " + + "Alternatively, activate SingleConnectionFactory's 'reconnectOnException' feature, " + + "which will allow for registering further ExceptionListeners to the recovery chain."); } } - case "getExceptionListener": + } + case "getExceptionListener" -> { synchronized (connectionMonitor) { if (this.localExceptionListener != null) { - return this.localExceptionListener; + yield this.localExceptionListener; } else { - return getExceptionListener(); + yield getExceptionListener(); } } - case "start": + } + case "start" -> { localStart(); - return null; - case "stop": + yield null; + } + case "stop" -> { localStop(); - return null; - case "close": + yield null; + } + case "close" -> { localStop(); synchronized (connectionMonitor) { if (this.localExceptionListener != null) { @@ -677,10 +681,9 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti this.localExceptionListener = null; } } - return null; - case "createSession": - case "createQueueSession": - case "createTopicSession": + yield null; + } + case "createSession", "createQueueSession", "createTopicSession" -> { // Default: JMS 2.0 createSession() method Integer mode = Session.AUTO_ACKNOWLEDGE; if (!ObjectUtils.isEmpty(args)) { @@ -707,16 +710,24 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti } throw new jakarta.jms.IllegalStateException(msg); } - return session; + yield session; } - } - - try { - return method.invoke(getConnection(), args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + try { + yield method.invoke(getConnection(), args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + default -> { + try { + yield method.invoke(getConnection(), args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } private void localStart() throws JMSException { diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java b/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java index 1d2abde613c..389026e2511 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java @@ -257,12 +257,14 @@ public class TransactionAwareConnectionFactoryProxy // Invocation on ConnectionProxy interface coming in... switch (method.getName()) { - case "equals": + case "equals" -> { // Only consider equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // Use hashCode of Connection proxy. return System.identityHashCode(proxy); + } } if (Session.class == method.getReturnType()) { @@ -329,32 +331,29 @@ public class TransactionAwareConnectionFactoryProxy public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on SessionProxy interface coming in... - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> (proxy == args[0]); // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of Connection proxy. - return System.identityHashCode(proxy); - case "commit": + case "commit" -> throw new TransactionInProgressException("Commit call not allowed within a managed transaction"); - case "rollback": + case "rollback" -> throw new TransactionInProgressException("Rollback call not allowed within a managed transaction"); - case "close": + case "close" -> null; // Handle close method: not to be closed within a transaction. - return null; - case "getTargetSession": + case "getTargetSession" -> this.target; // Handle getTargetSession method: return underlying Session. - return this.target; - } - - // Invoke method on target Session. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + default -> { + // Invoke method on target Session. + try { + yield method.invoke(this.target, args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java index 0005fed4837..8ff7a092e99 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java @@ -153,13 +153,11 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver { } SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(headers); if (messageType != null) { - switch (messageType) { - case SUBSCRIBE: - case UNSUBSCRIBE: - return parseSubscriptionMessage(message, sourceDestination); - case MESSAGE: - return parseMessage(headers, sourceDestination); - } + return switch (messageType) { + case SUBSCRIBE, UNSUBSCRIBE -> parseSubscriptionMessage(message, sourceDestination); + case MESSAGE -> parseMessage(headers, sourceDestination); + default -> null; + }; } return null; } diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java index 56159333bf3..d5870122f22 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTemplate.java @@ -1150,36 +1150,34 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on Session interface coming in... - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> (proxy == args[0]); // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of Session proxy. - return System.identityHashCode(proxy); - case "close": + case "close" -> null; // Handle close method: suppress, not valid. - return null; - } - - // Invoke method on target Session. - try { - Object retVal = method.invoke(this.target, args); - - // If return value is a Query or Criteria, apply transaction timeout. - // Applies to createQuery, getNamedQuery, createCriteria. - if (retVal instanceof Criteria criteria) { - prepareCriteria(criteria); - } - else if (retVal instanceof Query query) { - prepareQuery(query); + default -> { + // Invoke method on target Session. + try { + Object retVal = method.invoke(this.target, args); + + // If return value is a Query or Criteria, apply transaction timeout. + // Applies to createQuery, getNamedQuery, createCriteria. + if (retVal instanceof Criteria criteria) { + prepareCriteria(criteria); + } + else if (retVal instanceof Query query) { + prepareQuery(query); + } + + yield retVal; + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } } - - return retVal; - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + }; } } diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java index 6f051ac66d4..a931561dbf1 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java @@ -412,28 +412,25 @@ public class LocalSessionFactoryBuilder extends Configuration { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> (proxy == args[0]); // Only consider equal when proxies are identical. - return (proxy == args[0]); - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of EntityManagerFactory proxy. - return System.identityHashCode(proxy); - case "getProperties": - return getProperties(); - case "getWrappedObject": + case "getProperties" -> getProperties(); + case "getWrappedObject" -> getSessionFactory(); // Call coming in through InfrastructureProxy interface... - return getSessionFactory(); - } - - // Regular delegation to the target SessionFactory, - // enforcing its full initialization... - try { - return method.invoke(getSessionFactory(), args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + default -> { + // Regular delegation to the target SessionFactory, + // enforcing its full initialization... + try { + yield method.invoke(getSessionFactory(), args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } private SessionFactory getSessionFactory() { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java index 2460da78eca..1fcd9a58985 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java @@ -711,13 +711,15 @@ public abstract class AbstractEntityManagerFactoryBean implements @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { switch (method.getName()) { - case "equals": + case "equals" -> { // Only consider equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // Use hashCode of EntityManagerFactory proxy. return System.identityHashCode(proxy); - case "unwrap": + } + case "unwrap" -> { // Handle JPA 2.1 unwrap method - could be a proxy match. Class targetClass = (Class) args[0]; if (targetClass == null) { @@ -726,7 +728,7 @@ public abstract class AbstractEntityManagerFactoryBean implements else if (targetClass.isInstance(proxy)) { return proxy; } - break; + } } try { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java index 4554e5131e6..36428552302 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/ExtendedEntityManagerCreator.java @@ -297,16 +297,19 @@ public abstract class ExtendedEntityManagerCreator { // Invocation on EntityManager interface coming in... switch (method.getName()) { - case "equals": + case "equals" -> { // Only consider equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // Use hashCode of EntityManager proxy. return hashCode(); - case "getTargetEntityManager": + } + case "getTargetEntityManager" -> { // Handle EntityManagerProxy interface. return this.target; - case "unwrap": + } + case "unwrap" -> { // Handle JPA 2.0 unwrap method - could be a proxy match. Class targetClass = (Class) args[0]; if (targetClass == null) { @@ -315,13 +318,13 @@ public abstract class ExtendedEntityManagerCreator { else if (targetClass.isInstance(proxy)) { return proxy; } - break; - case "isOpen": + } + case "isOpen" -> { if (this.containerManaged) { return true; } - break; - case "close": + } + case "close" -> { if (this.containerManaged) { throw new IllegalStateException("Invalid usage: Cannot close a container-managed EntityManager"); } @@ -332,22 +335,23 @@ public abstract class ExtendedEntityManagerCreator { synch.closeOnCompletion = true; return null; } - break; - case "getTransaction": + } + case "getTransaction" -> { if (this.synchronizedWithTransaction) { throw new IllegalStateException( "Cannot obtain local EntityTransaction from a transaction-synchronized EntityManager"); } - break; - case "joinTransaction": + } + case "joinTransaction" -> { doJoinTransaction(true); return null; - case "isJoinedToTransaction": + } + case "isJoinedToTransaction" -> { // Handle JPA 2.1 isJoinedToTransaction method for the non-JTA case. if (!this.jta) { return TransactionSynchronizationManager.hasResource(this.target); } - break; + } } // Do automatic joining if required. Excludes toString, equals, hashCode calls. diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java index 4e32abcd399..7c7c0827101 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java @@ -221,20 +221,23 @@ public abstract class SharedEntityManagerCreator { // Invocation on EntityManager interface coming in... switch (method.getName()) { - case "equals": + case "equals" -> { // Only consider equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // Use hashCode of EntityManager proxy. return hashCode(); - case "toString": + } + case "toString" -> { // Deliver toString without touching a target EntityManager. return "Shared EntityManager proxy for target factory [" + this.targetFactory + "]"; - case "getEntityManagerFactory": + } + case "getEntityManagerFactory" -> { // JPA 2.0: return EntityManagerFactory without creating an EntityManager. return this.targetFactory; - case "getCriteriaBuilder": - case "getMetamodel": + } + case "getCriteriaBuilder", "getMetamodel" -> { // JPA 2.0: return EntityManagerFactory's CriteriaBuilder/Metamodel (avoid creation of EntityManager) try { return EntityManagerFactory.class.getMethod(method.getName()).invoke(this.targetFactory); @@ -242,23 +245,27 @@ public abstract class SharedEntityManagerCreator { catch (InvocationTargetException ex) { throw ex.getTargetException(); } - case "unwrap": + } + case "unwrap" -> { // JPA 2.0: handle unwrap method - could be a proxy match. Class targetClass = (Class) args[0]; if (targetClass != null && targetClass.isInstance(proxy)) { return proxy; } - break; - case "isOpen": + } + case "isOpen" -> { // Handle isOpen method: always return true. return true; - case "close": + } + case "close" -> { // Handle close method: suppress, not valid. return null; - case "getTransaction": + } + case "getTransaction" -> { throw new IllegalStateException( "Not allowed to create transaction on shared EntityManager - " + - "use Spring transactions or EJB CMT instead"); + "use Spring transactions or EJB CMT instead"); + } } // Determine current EntityManager: either the transactional one @@ -370,13 +377,15 @@ public abstract class SharedEntityManagerCreator { // Invocation on Query interface coming in... switch (method.getName()) { - case "equals": + case "equals" -> { // Only consider equal when proxies are identical. return (proxy == args[0]); - case "hashCode": + } + case "hashCode" -> { // Use hashCode of EntityManager proxy. return hashCode(); - case "unwrap": + } + case "unwrap" -> { // Handle JPA 2.0 unwrap method - could be a proxy match. Class targetClass = (Class) args[0]; if (targetClass == null) { @@ -385,8 +394,8 @@ public abstract class SharedEntityManagerCreator { else if (targetClass.isInstance(proxy)) { return proxy; } - break; - case "getOutputParameterValue": + } + case "getOutputParameterValue" -> { if (this.entityManager == null) { Object key = args[0]; if (this.outputParameters == null || !this.outputParameters.containsKey(key)) { @@ -398,7 +407,7 @@ public abstract class SharedEntityManagerCreator { } return value; } - break; + } } // Invoke method on actual Query object. diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/SingleConnectionFactory.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/SingleConnectionFactory.java index 527da9d9b00..dfa27270a23 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/SingleConnectionFactory.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/SingleConnectionFactory.java @@ -251,27 +251,24 @@ public class SingleConnectionFactory extends DelegatingConnectionFactory @Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> proxy == args[0]; // Only consider equal when proxies are identical. - return proxy == args[0]; - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of PersistenceManager proxy. - return System.identityHashCode(proxy); - case "unwrap": - return this.target; - case "close": + case "unwrap" -> this.target; + case "close" -> Mono.empty(); // Handle close method: suppress, not valid. - return Mono.empty(); - } - - // Invoke method on target Connection. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + default -> { + // Invoke method on target Connection. + try { + yield method.invoke(this.target, args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } } diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxy.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxy.java index edc61bfb842..a480ff17408 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxy.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxy.java @@ -143,28 +143,26 @@ public class TransactionAwareConnectionFactoryProxy extends DelegatingConnection } } - switch (method.getName()) { - case "unwrap": - return this.connection; - case "close": - // Handle close method: only close if not within a transaction. - return ConnectionFactoryUtils.doReleaseConnection(this.connection, this.targetConnectionFactory) + return switch (method.getName()) { + case "unwrap" -> this.connection; + case "close" -> ConnectionFactoryUtils.doReleaseConnection(this.connection, this.targetConnectionFactory) .doOnSubscribe(n -> this.closed = true); - case "isClosed": - return this.closed; - } - - if (this.closed) { - throw new IllegalStateException("Connection handle already closed"); - } - - // Invoke method on target Connection. - try { - return method.invoke(this.connection, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + // Handle close method: only close if not within a transaction. + case "isClosed" -> this.closed; + default -> { + if (this.closed) { + throw new IllegalStateException("Connection handle already closed"); + } + + // Invoke method on target Connection. + try { + yield method.invoke(this.connection, args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } private String proxyToString(@Nullable Object proxy) { diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java index 465d5f99563..ff1c91ce4a6 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java @@ -519,27 +519,24 @@ final class DefaultDatabaseClient implements DatabaseClient { @Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - switch (method.getName()) { - case "equals": + return switch (method.getName()) { + case "equals" -> proxy == args[0]; // Only consider equal when proxies are identical. - return proxy == args[0]; - case "hashCode": + case "hashCode" -> System.identityHashCode(proxy); // Use hashCode of PersistenceManager proxy. - return System.identityHashCode(proxy); - case "unwrap": - return this.target; - case "close": + case "unwrap" -> this.target; + case "close" -> Mono.error(new UnsupportedOperationException("Close is not supported!")); // Handle close method: suppress, not valid. - return Mono.error(new UnsupportedOperationException("Close is not supported!")); - } - - // Invoke method on target Connection. - try { - return method.invoke(this.target, args); - } - catch (InvocationTargetException ex) { - throw ex.getTargetException(); - } + default -> { + // Invoke method on target Connection. + try { + yield method.invoke(this.target, args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + }; } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java index 15eb93ce505..b037e12ee20 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/JtaAfterCompletionSynchronization.java @@ -57,7 +57,7 @@ public class JtaAfterCompletionSynchronization implements Synchronization { @Override public void afterCompletion(int status) { switch (status) { - case Status.STATUS_COMMITTED: + case Status.STATUS_COMMITTED -> { try { TransactionSynchronizationUtils.invokeAfterCommit(this.synchronizations); } @@ -65,14 +65,15 @@ public class JtaAfterCompletionSynchronization implements Synchronization { TransactionSynchronizationUtils.invokeAfterCompletion( this.synchronizations, TransactionSynchronization.STATUS_COMMITTED); } - break; - case Status.STATUS_ROLLEDBACK: + } + case Status.STATUS_ROLLEDBACK -> { TransactionSynchronizationUtils.invokeAfterCompletion( this.synchronizations, TransactionSynchronization.STATUS_ROLLED_BACK); - break; - default: + } + default -> { TransactionSynchronizationUtils.invokeAfterCompletion( this.synchronizations, TransactionSynchronization.STATUS_UNKNOWN); + } } } } diff --git a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java index 5663b7ddf9f..ef637a96159 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java +++ b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java @@ -134,18 +134,14 @@ class HtmlCharacterEntityReferences { @Nullable public String convertToReference(char character, String encoding) { if (encoding.startsWith("UTF-")){ - switch (character){ - case '<': - return "<"; - case '>': - return ">"; - case '"': - return """; - case '&': - return "&"; - case '\'': - return "'"; - } + return switch (character){ + case '<' -> "<"; + case '>' -> ">"; + case '"' -> """; + case '&' -> "&"; + case '\'' -> "'"; + default -> null; + }; } else if (character < 1000 || (character >= 8000 && character < 10000)) { int index = (character < 1000 ? character : character - 7000); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientResponseException.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientResponseException.java index 80cf9bcc5b5..360adb44baf 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientResponseException.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientResponseException.java @@ -303,40 +303,25 @@ public class WebClientResponseException extends WebClientException { byte[] body, @Nullable Charset charset, @Nullable HttpRequest request) { if (statusCode instanceof HttpStatus httpStatus) { - switch (httpStatus) { - case BAD_REQUEST: - return new WebClientResponseException.BadRequest(statusText, headers, body, charset, request); - case UNAUTHORIZED: - return new WebClientResponseException.Unauthorized(statusText, headers, body, charset, request); - case FORBIDDEN: - return new WebClientResponseException.Forbidden(statusText, headers, body, charset, request); - case NOT_FOUND: - return new WebClientResponseException.NotFound(statusText, headers, body, charset, request); - case METHOD_NOT_ALLOWED: - return new WebClientResponseException.MethodNotAllowed(statusText, headers, body, charset, request); - case NOT_ACCEPTABLE: - return new WebClientResponseException.NotAcceptable(statusText, headers, body, charset, request); - case CONFLICT: - return new WebClientResponseException.Conflict(statusText, headers, body, charset, request); - case GONE: - return new WebClientResponseException.Gone(statusText, headers, body, charset, request); - case UNSUPPORTED_MEDIA_TYPE: - return new WebClientResponseException.UnsupportedMediaType(statusText, headers, body, charset, request); - case TOO_MANY_REQUESTS: - return new WebClientResponseException.TooManyRequests(statusText, headers, body, charset, request); - case UNPROCESSABLE_ENTITY: - return new WebClientResponseException.UnprocessableEntity(statusText, headers, body, charset, request); - case INTERNAL_SERVER_ERROR: - return new WebClientResponseException.InternalServerError(statusText, headers, body, charset, request); - case NOT_IMPLEMENTED: - return new WebClientResponseException.NotImplemented(statusText, headers, body, charset, request); - case BAD_GATEWAY: - return new WebClientResponseException.BadGateway(statusText, headers, body, charset, request); - case SERVICE_UNAVAILABLE: - return new WebClientResponseException.ServiceUnavailable(statusText, headers, body, charset, request); - case GATEWAY_TIMEOUT: - return new WebClientResponseException.GatewayTimeout(statusText, headers, body, charset, request); - } + return switch (httpStatus) { + case BAD_REQUEST -> new WebClientResponseException.BadRequest(statusText, headers, body, charset, request); + case UNAUTHORIZED -> new WebClientResponseException.Unauthorized(statusText, headers, body, charset, request); + case FORBIDDEN -> new WebClientResponseException.Forbidden(statusText, headers, body, charset, request); + case NOT_FOUND -> new WebClientResponseException.NotFound(statusText, headers, body, charset, request); + case METHOD_NOT_ALLOWED -> new WebClientResponseException.MethodNotAllowed(statusText, headers, body, charset, request); + case NOT_ACCEPTABLE -> new WebClientResponseException.NotAcceptable(statusText, headers, body, charset, request); + case CONFLICT -> new WebClientResponseException.Conflict(statusText, headers, body, charset, request); + case GONE -> new WebClientResponseException.Gone(statusText, headers, body, charset, request); + case UNSUPPORTED_MEDIA_TYPE -> new WebClientResponseException.UnsupportedMediaType(statusText, headers, body, charset, request); + case TOO_MANY_REQUESTS -> new WebClientResponseException.TooManyRequests(statusText, headers, body, charset, request); + case UNPROCESSABLE_ENTITY -> new WebClientResponseException.UnprocessableEntity(statusText, headers, body, charset, request); + case INTERNAL_SERVER_ERROR -> new WebClientResponseException.InternalServerError(statusText, headers, body, charset, request); + case NOT_IMPLEMENTED -> new WebClientResponseException.NotImplemented(statusText, headers, body, charset, request); + case BAD_GATEWAY -> new WebClientResponseException.BadGateway(statusText, headers, body, charset, request); + case SERVICE_UNAVAILABLE -> new WebClientResponseException.ServiceUnavailable(statusText, headers, body, charset, request); + case GATEWAY_TIMEOUT -> new WebClientResponseException.GatewayTimeout(statusText, headers, body, charset, request); + default -> new WebClientResponseException(statusCode, statusText, headers, body, charset, request); + }; } return new WebClientResponseException(statusCode, statusText, headers, body, charset, request); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index ecaa081426a..21fc36901bd 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -720,26 +720,28 @@ public class MvcUriComponentsBuilder { @Override @Nullable public Object intercept(@Nullable Object obj, Method method, Object[] args, @Nullable MethodProxy proxy) { - switch (method.getName()) { - case "getControllerType": return this.controllerType; - case "getControllerMethod": return this.controllerMethod; - case "getArgumentValues": return this.argumentValues; - } - if (ReflectionUtils.isObjectMethod(method)) { - return ReflectionUtils.invokeMethod(method, obj, args); - } - else { - this.controllerMethod = method; - this.argumentValues = args; - Class returnType = method.getReturnType(); - try { - return (returnType == void.class ? null : returnType.cast(initProxy(returnType, this))); - } - catch (Throwable ex) { - throw new IllegalStateException( - "Failed to create proxy for controller method return type: " + method, ex); + return switch (method.getName()) { + case "getControllerType" -> this.controllerType; + case "getControllerMethod" -> this.controllerMethod; + case "getArgumentValues" -> this.argumentValues; + default -> { + if (ReflectionUtils.isObjectMethod(method)) { + yield ReflectionUtils.invokeMethod(method, obj, args); + } + else { + this.controllerMethod = method; + this.argumentValues = args; + Class returnType = method.getReturnType(); + try { + yield (returnType == void.class ? null : returnType.cast(initProxy(returnType, this))); + } + catch (Throwable ex) { + throw new IllegalStateException( + "Failed to create proxy for controller method return type: " + method, ex); + } + } } - } + }; } @Override