Polishing

This commit is contained in:
Juergen Hoeller
2018-11-20 22:06:44 +01:00
parent a3d763d137
commit 8c7579eba8
8 changed files with 60 additions and 65 deletions

View File

@@ -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);

View File

@@ -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.
*
* <p>Very useful for testing. Effectively a mock object.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class ExpectedLookupTemplate extends JndiTemplate {
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<>();
private final Map<String, Object> 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 {

View File

@@ -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<String, Object> boundObjects, Hashtable<String, Object> env) {
public SimpleNamingContext(
String root, Hashtable<String, Object> boundObjects, @Nullable Hashtable<String, Object> 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<T> implements NamingEnumeration<T> {
private abstract static class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
private Iterator<T> iterator;
@@ -353,7 +357,7 @@ public class SimpleNamingContext implements Context {
}
private static class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
private static final class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
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<Binding> {
private static final class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);

View File

@@ -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;
* <ul>
* <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls)
* <li>{@code DriverManagerDataSource} (creating a new Connection on each getConnection call)
* <li>Apache's Jakarta Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
* <li>Apache's Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
* </ul>
*
* <p>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.
* <p>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<String, Object>) environment);
}
};
return env -> new SimpleNamingContext("", this.boundObjects, (Hashtable<String, Object>) env);
}
}