From 8c7579eba8cd13cb24ec2228e4a26f41cbba8e89 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 20 Nov 2018 22:06:44 +0100 Subject: [PATCH] Polishing --- .../annotation/EnableAsyncTests.java | 2 +- .../mock/jndi/ExpectedLookupTemplate.java | 26 ++++++------ .../tests/mock/jndi/SimpleNamingContext.java | 14 ++++--- .../mock/jndi/SimpleNamingContextBuilder.java | 41 +++++++++---------- .../org/springframework/util/ObjectUtils.java | 14 +++---- .../util/FastByteArrayOutputStreamTests.java | 18 +++----- .../util/ObjectUtilsTests.java | 6 ++- .../mock/jndi/SimpleNamingContextBuilder.java | 4 +- 8 files changed, 60 insertions(+), 65 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java index ade13b7441..48f99a6633 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java @@ -217,7 +217,7 @@ public class EnableAsyncTests { } @Test - public void customExecutorConfig() throws InterruptedException { + public void customExecutorConfig() { // Arrange AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(CustomExecutorConfig.class); diff --git a/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java b/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java index aef52f3801..58286310dd 100644 --- a/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java +++ b/spring-context/src/test/java/org/springframework/tests/mock/jndi/ExpectedLookupTemplate.java @@ -23,28 +23,29 @@ import javax.naming.NamingException; import org.springframework.jndi.JndiTemplate; /** - * Simple extension of the JndiTemplate class that always returns - * a given object. Very useful for testing. Effectively a mock object. + * Simple extension of the JndiTemplate class that always returns a given object. + * + *

Very useful for testing. Effectively a mock object. * * @author Rod Johnson * @author Juergen Hoeller */ public class ExpectedLookupTemplate extends JndiTemplate { - private final Map jndiObjects = new ConcurrentHashMap<>(); + private final Map jndiObjects = new ConcurrentHashMap<>(16); /** - * Construct a new JndiTemplate that will always return given objects - * for given names. To be populated through {@code addObject} calls. + * Construct a new JndiTemplate that will always return given objects for + * given names. To be populated through {@code addObject} calls. * @see #addObject(String, Object) */ public ExpectedLookupTemplate() { } /** - * Construct a new JndiTemplate that will always return the - * given object, but honour only requests for the given name. + * Construct a new JndiTemplate that will always return the given object, + * but honour only requests for the given name. * @param name the name the client is expected to look up * @param object the object that will be returned */ @@ -52,10 +53,8 @@ public class ExpectedLookupTemplate extends JndiTemplate { addObject(name, object); } - /** - * Add the given object to the list of JNDI objects that this - * template will expose. + * Add the given object to the list of JNDI objects that this template will expose. * @param name the name the client is expected to look up * @param object the object that will be returned */ @@ -63,11 +62,10 @@ public class ExpectedLookupTemplate extends JndiTemplate { this.jndiObjects.put(name, object); } - /** - * If the name is the expected name specified in the constructor, - * return the object provided in the constructor. If the name is - * unexpected, a respective NamingException gets thrown. + * If the name is the expected name specified in the constructor, return the + * object provided in the constructor. If the name is unexpected, a + * respective NamingException gets thrown. */ @Override public Object lookup(String name) throws NamingException { diff --git a/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContext.java b/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContext.java index c4ba15c217..ef0d414b59 100644 --- a/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContext.java +++ b/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -33,6 +33,7 @@ import javax.naming.OperationNotSupportedException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -80,7 +81,9 @@ public class SimpleNamingContext implements Context { * Create a new naming context with the given naming root, * the given name/object map, and the JNDI environment entries. */ - public SimpleNamingContext(String root, Hashtable boundObjects, Hashtable env) { + public SimpleNamingContext( + String root, Hashtable boundObjects, @Nullable Hashtable env) { + this.root = root; this.boundObjects = boundObjects; if (env != null) { @@ -206,6 +209,7 @@ public class SimpleNamingContext implements Context { } @Override + @Nullable public Object addToEnvironment(String propName, Object propVal) { return this.environment.put(propName, propVal); } @@ -293,7 +297,7 @@ public class SimpleNamingContext implements Context { } - private static abstract class AbstractNamingEnumeration implements NamingEnumeration { + private abstract static class AbstractNamingEnumeration implements NamingEnumeration { private Iterator iterator; @@ -353,7 +357,7 @@ public class SimpleNamingContext implements Context { } - private static class NameClassPairEnumeration extends AbstractNamingEnumeration { + private static final class NameClassPairEnumeration extends AbstractNamingEnumeration { private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException { super(context, root); @@ -366,7 +370,7 @@ public class SimpleNamingContext implements Context { } - private static class BindingEnumeration extends AbstractNamingEnumeration { + private static final class BindingEnumeration extends AbstractNamingEnumeration { private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException { super(context, root); diff --git a/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java b/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java index 56fc6e802b..6c3a3d7780 100644 --- a/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java +++ b/spring-context/src/test/java/org/springframework/tests/mock/jndi/SimpleNamingContextBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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,10 @@ import javax.naming.spi.NamingManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; /** * Simple implementation of a JNDI naming context builder. @@ -42,7 +45,7 @@ import org.springframework.util.ClassUtils; *

* *

Typical usage in bootstrap code: @@ -80,7 +83,8 @@ import org.springframework.util.ClassUtils; */ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder { - /** An instance of this class bound to JNDI */ + /** An instance of this class bound to JNDI. */ + @Nullable private static volatile SimpleNamingContextBuilder activated; private static boolean initialized = false; @@ -93,13 +97,14 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder * @return the current SimpleNamingContextBuilder instance, * or {@code null} if none */ + @Nullable public static SimpleNamingContextBuilder getCurrentContextBuilder() { return activated; } /** * If no SimpleNamingContextBuilder is already configuring JNDI, - * create and activate one. Otherwise take the existing activate + * create and activate one. Otherwise take the existing activated * SimpleNamingContextBuilder, clear it and return it. *

This is mainly intended for test suites that want to * reinitialize JNDI bindings from scratch repeatedly. @@ -107,17 +112,18 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder * to control JNDI bindings */ public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException { - if (activated != null) { + SimpleNamingContextBuilder builder = activated; + if (builder != null) { // Clear already activated context builder. - activated.clear(); + builder.clear(); } else { // Create and activate new context builder. - SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); + builder = new SimpleNamingContextBuilder(); // The activate() call will cause an assignment to the activated variable. builder.activate(); } - return activated; + return builder; } @@ -138,12 +144,10 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder logger.info("Activating simple JNDI environment"); synchronized (initializationLock) { if (!initialized) { - if (NamingManager.hasInitialContextFactoryBuilder()) { - throw new IllegalStateException( + Assert.state(!NamingManager.hasInitialContextFactoryBuilder(), "Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " + "Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " + "with no reset option. As a consequence, a JNDI provider must only be registered once per JVM."); - } NamingManager.setInitialContextFactoryBuilder(this); initialized = true; } @@ -192,7 +196,8 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder * @see SimpleNamingContext */ @Override - public InitialContextFactory createInitialContextFactory(Hashtable environment) { + @SuppressWarnings("unchecked") + public InitialContextFactory createInitialContextFactory(@Nullable Hashtable environment) { if (activated == null && environment != null) { Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY); if (icf != null) { @@ -212,22 +217,16 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder "Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf); } try { - return (InitialContextFactory) icfClass.newInstance(); + return (InitialContextFactory) ReflectionUtils.accessibleConstructor(icfClass).newInstance(); } catch (Throwable ex) { - throw new IllegalStateException("Cannot instantiate specified InitialContextFactory: " + icf, ex); + throw new IllegalStateException("Unable to instantiate specified InitialContextFactory: " + icf, ex); } } } // Default case... - return new InitialContextFactory() { - @Override - @SuppressWarnings("unchecked") - public Context getInitialContext(Hashtable environment) { - return new SimpleNamingContext("", boundObjects, (Hashtable) environment); - } - }; + return env -> new SimpleNamingContext("", this.boundObjects, (Hashtable) env); } } diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index e48de23acf..2511858a97 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -199,7 +199,7 @@ public abstract class ObjectUtils { /** * Check whether the given array of enum constants contains a constant with the given name, * ignoring case when determining a match. - * @param enumValues the enum values to check, typically the product of a call to MyEnum.values() + * @param enumValues the enum values to check, typically obtained via {@code MyEnum.values()} * @param constant the constant name to find (must not be null or empty string) * @return whether the constant has been found in the given array */ @@ -209,15 +209,14 @@ public abstract class ObjectUtils { /** * Check whether the given array of enum constants contains a constant with the given name. - * @param enumValues the enum values to check, typically the product of a call to MyEnum.values() + * @param enumValues the enum values to check, typically obtained via {@code MyEnum.values()} * @param constant the constant name to find (must not be null or empty string) * @param caseSensitive whether case is significant in determining a match * @return whether the constant has been found in the given array */ public static boolean containsConstant(Enum[] enumValues, String constant, boolean caseSensitive) { for (Enum candidate : enumValues) { - if (caseSensitive ? - candidate.toString().equals(constant) : + if (caseSensitive ? candidate.toString().equals(constant) : candidate.toString().equalsIgnoreCase(constant)) { return true; } @@ -228,7 +227,7 @@ public abstract class ObjectUtils { /** * Case insensitive alternative to {@link Enum#valueOf(Class, String)}. * @param the concrete Enum type - * @param enumValues the array of all Enum constants in question, usually per Enum.values() + * @param enumValues the array of all Enum constants in question, usually per {@code Enum.values()} * @param constant the constant to get the enum value of * @throws IllegalArgumentException if the given constant is not found in the given array * of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to avoid this exception. @@ -239,9 +238,8 @@ public abstract class ObjectUtils { return candidate; } } - throw new IllegalArgumentException( - String.format("constant [%s] does not exist in enum type %s", - constant, enumValues.getClass().getComponentType().getName())); + throw new IllegalArgumentException("Constant [" + constant + "] does not exist in enum type " + + enumValues.getClass().getComponentType().getName()); } /** diff --git a/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java b/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java index ae96ba6b6d..8cebce793f 100644 --- a/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java +++ b/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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,30 +20,24 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; -import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; /** - * Test suite for {@link FastByteArrayOutputStream} + * Test suite for {@link FastByteArrayOutputStream}. + * * @author Craig Andrews */ public class FastByteArrayOutputStreamTests { private static final int INITIAL_CAPACITY = 256; - private FastByteArrayOutputStream os; - - private byte[] helloBytes; + private final FastByteArrayOutputStream os = new FastByteArrayOutputStream(INITIAL_CAPACITY);; - - @Before - public void setUp() throws Exception { - this.os = new FastByteArrayOutputStream(INITIAL_CAPACITY); - this.helloBytes = "Hello World".getBytes("UTF-8"); - } + private final byte[] helloBytes = "Hello World".getBytes(StandardCharsets.UTF_8);; @Test diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index 2a7835ad0e..7054937975 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -45,6 +45,7 @@ public class ObjectUtilsTests { @Rule public final ExpectedException exception = ExpectedException.none(); + @Test public void isCheckedException() { assertTrue(ObjectUtils.isCheckedException(new Exception())); @@ -807,7 +808,8 @@ public class ObjectUtilsTests { assertThat(ObjectUtils.caseInsensitiveValueOf(Tropes.values(), "BAR"), is(Tropes.BAR)); exception.expect(IllegalArgumentException.class); - exception.expectMessage(is("constant [bogus] does not exist in enum type org.springframework.util.ObjectUtilsTests$Tropes")); + exception.expectMessage( + is("Constant [bogus] does not exist in enum type org.springframework.util.ObjectUtilsTests$Tropes")); ObjectUtils.caseInsensitiveValueOf(Tropes.values(), "bogus"); } @@ -818,6 +820,6 @@ public class ObjectUtilsTests { } - enum Tropes { FOO, BAR, baz } + enum Tropes {FOO, BAR, baz} } diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java b/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java index 959f1ab241..833d73cb6e 100644 --- a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java +++ b/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java @@ -104,7 +104,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder /** * If no SimpleNamingContextBuilder is already configuring JNDI, - * create and activate one. Otherwise take the existing activate + * create and activate one. Otherwise take the existing activated * SimpleNamingContextBuilder, clear it and return it. *

This is mainly intended for test suites that want to * reinitialize JNDI bindings from scratch repeatedly. @@ -226,7 +226,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder } // Default case... - return environment1 -> new SimpleNamingContext("", this.boundObjects, (Hashtable) environment1); + return env -> new SimpleNamingContext("", this.boundObjects, (Hashtable) env); } }