Consistent use of @Nullable in spring-test
This commit also removes nullability from two common spots: ResolvableType.getType() and TargetSource.getTarget(), both of which are never effectively null with any regular implementation. For such scenarios, a non-null empty type/target is the cleaner contract. Issue: SPR-15540
This commit is contained in:
parent
ee5fa2633a
commit
fd53d2a51a
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.aop;
|
package org.springframework.aop;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code TargetSource} is used to obtain the current "target" of
|
* A {@code TargetSource} is used to obtain the current "target" of
|
||||||
* an AOP invocation, which will be invoked via reflection if no around
|
* an AOP invocation, which will be invoked via reflection if no around
|
||||||
|
@ -59,7 +57,6 @@ public interface TargetSource extends TargetClassAware {
|
||||||
* @return the target object, which contains the joinpoint
|
* @return the target object, which contains the joinpoint
|
||||||
* @throws Exception if the target object can't be resolved
|
* @throws Exception if the target object can't be resolved
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
Object getTarget() throws Exception;
|
Object getTarget() throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -326,8 +326,12 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
// TODO: small memory optimization here (can skip creation for methods with no advice)
|
// TODO: small memory optimization here (can skip creation for methods with no advice)
|
||||||
for (int x = 0; x < methods.length; x++) {
|
for (int x = 0; x < methods.length; x++) {
|
||||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
|
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
|
||||||
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
|
Object target = this.advised.getTargetSource().getTarget();
|
||||||
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
|
Class<?> targetClass = this.advised.getTargetClass();
|
||||||
|
if (targetClass == null) {
|
||||||
|
targetClass = target.getClass();
|
||||||
|
}
|
||||||
|
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(chain, target, targetClass);
|
||||||
this.fixedInterceptorMap.put(methods[x].toString(), x);
|
this.fixedInterceptorMap.put(methods[x].toString(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +378,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
|
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private static Object processReturnType(Object proxy, @Nullable Object target, Method method, @Nullable Object retVal) {
|
private static Object processReturnType(Object proxy, Object target, Method method, @Nullable Object retVal) {
|
||||||
// Massage return value if necessary
|
// Massage return value if necessary
|
||||||
if (retVal != null && retVal == target &&
|
if (retVal != null && retVal == target &&
|
||||||
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
|
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||||
|
@ -409,7 +413,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
|
|
||||||
private final Object target;
|
private final Object target;
|
||||||
|
|
||||||
public StaticUnadvisedInterceptor(@Nullable Object target) {
|
public StaticUnadvisedInterceptor(Object target) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +434,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
|
|
||||||
private final Object target;
|
private final Object target;
|
||||||
|
|
||||||
public StaticUnadvisedExposedInterceptor(@Nullable Object target) {
|
public StaticUnadvisedExposedInterceptor(Object target) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,9 +476,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
return processReturnType(proxy, target, method, retVal);
|
return processReturnType(proxy, target, method, retVal);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (target != null) {
|
this.targetSource.releaseTarget(target);
|
||||||
this.targetSource.releaseTarget(target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,9 +505,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
AopContext.setCurrentProxy(oldProxy);
|
AopContext.setCurrentProxy(oldProxy);
|
||||||
if (target != null) {
|
this.targetSource.releaseTarget(target);
|
||||||
this.targetSource.releaseTarget(target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -612,9 +612,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
|
|
||||||
private final Class<?> targetClass;
|
private final Class<?> targetClass;
|
||||||
|
|
||||||
public FixedChainStaticTargetInterceptor(
|
public FixedChainStaticTargetInterceptor(List<Object> adviceChain, Object target, Class<?> targetClass) {
|
||||||
List<Object> adviceChain, @Nullable Object target, @Nullable Class<?> targetClass) {
|
|
||||||
|
|
||||||
this.adviceChain = adviceChain;
|
this.adviceChain = adviceChain;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.targetClass = targetClass;
|
this.targetClass = targetClass;
|
||||||
|
@ -650,7 +648,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||||
Object oldProxy = null;
|
Object oldProxy = null;
|
||||||
boolean setProxyContext = false;
|
boolean setProxyContext = false;
|
||||||
Class<?> targetClass = null;
|
|
||||||
Object target = null;
|
Object target = null;
|
||||||
try {
|
try {
|
||||||
if (this.advised.exposeProxy) {
|
if (this.advised.exposeProxy) {
|
||||||
|
@ -658,12 +655,9 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||||
setProxyContext = true;
|
setProxyContext = true;
|
||||||
}
|
}
|
||||||
// May be null. Get as late as possible to minimize the time we
|
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
|
||||||
// "own" the target, in case it comes from a pool...
|
|
||||||
target = getTarget();
|
target = getTarget();
|
||||||
if (target != null) {
|
Class<?> targetClass = target.getClass();
|
||||||
targetClass = target.getClass();
|
|
||||||
}
|
|
||||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||||
Object retVal;
|
Object retVal;
|
||||||
// Check whether we only have one InvokerInterceptor: that is,
|
// Check whether we only have one InvokerInterceptor: that is,
|
||||||
|
@ -709,7 +703,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
return this.advised.hashCode();
|
return this.advised.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
protected Object getTarget() throws Exception {
|
protected Object getTarget() throws Exception {
|
||||||
return this.advised.getTargetSource().getTarget();
|
return this.advised.getTargetSource().getTarget();
|
||||||
}
|
}
|
||||||
|
@ -729,9 +722,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||||
|
|
||||||
private final boolean publicMethod;
|
private final boolean publicMethod;
|
||||||
|
|
||||||
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
|
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
|
||||||
Object[] arguments, @Nullable Class<?> targetClass,
|
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||||
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
|
||||||
|
|
||||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||||
this.methodProxy = methodProxy;
|
this.methodProxy = methodProxy;
|
||||||
|
|
|
@ -159,7 +159,6 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||||
boolean setProxyContext = false;
|
boolean setProxyContext = false;
|
||||||
|
|
||||||
TargetSource targetSource = this.advised.targetSource;
|
TargetSource targetSource = this.advised.targetSource;
|
||||||
Class<?> targetClass = null;
|
|
||||||
Object target = null;
|
Object target = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -189,12 +188,10 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||||
setProxyContext = true;
|
setProxyContext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// May be null. Get as late as possible to minimize the time we "own" the target,
|
// Get as late as possible to minimize the time we "own" the target,
|
||||||
// in case it comes from a pool.
|
// in case it comes from a pool.
|
||||||
target = targetSource.getTarget();
|
target = targetSource.getTarget();
|
||||||
if (target != null) {
|
Class<?> targetClass = target.getClass();
|
||||||
targetClass = target.getClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the interception chain for this method.
|
// Get the interception chain for this method.
|
||||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||||
|
|
|
@ -103,8 +103,8 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||||
* but would complicate the code. And it would work only for static pointcuts.
|
* but would complicate the code. And it would work only for static pointcuts.
|
||||||
*/
|
*/
|
||||||
protected ReflectiveMethodInvocation(
|
protected ReflectiveMethodInvocation(
|
||||||
Object proxy, @Nullable Object target, Method method, Object[] arguments,
|
Object proxy, Object target, Method method, Object[] arguments,
|
||||||
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||||
|
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
|
|
@ -329,7 +329,7 @@ public abstract class AopUtils {
|
||||||
* @throws org.springframework.aop.AopInvocationException in case of a reflection error
|
* @throws org.springframework.aop.AopInvocationException in case of a reflection error
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
|
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
|
|
||||||
// Use reflection to invoke the method.
|
// Use reflection to invoke the method.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -32,6 +32,13 @@ import org.springframework.util.ObjectUtils;
|
||||||
*/
|
*/
|
||||||
public class EmptyTargetSource implements TargetSource, Serializable {
|
public class EmptyTargetSource implements TargetSource, Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The canonical (Singleton) instance of this {@link EmptyTargetSource}.
|
||||||
|
*/
|
||||||
|
public static final EmptyTargetSource INSTANCE = new EmptyTargetSource(null, true);
|
||||||
|
|
||||||
|
private static final Object EMPTY_TARGET = new Object();
|
||||||
|
|
||||||
/** use serialVersionUID from Spring 1.2 for interoperability */
|
/** use serialVersionUID from Spring 1.2 for interoperability */
|
||||||
private static final long serialVersionUID = 3680494563553489691L;
|
private static final long serialVersionUID = 3680494563553489691L;
|
||||||
|
|
||||||
|
@ -40,12 +47,6 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||||
// Static factory methods
|
// Static factory methods
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* The canonical (Singleton) instance of this {@link EmptyTargetSource}.
|
|
||||||
*/
|
|
||||||
public static final EmptyTargetSource INSTANCE = new EmptyTargetSource(null, true);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an EmptyTargetSource for the given target Class.
|
* Return an EmptyTargetSource for the given target Class.
|
||||||
* @param targetClass the target Class (may be {@code null})
|
* @param targetClass the target Class (may be {@code null})
|
||||||
|
@ -87,6 +88,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||||
this.isStatic = isStatic;
|
this.isStatic = isStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always returns the specified target Class, or {@code null} if none.
|
* Always returns the specified target Class, or {@code null} if none.
|
||||||
*/
|
*/
|
||||||
|
@ -104,11 +106,11 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always returns {@code null}.
|
* Always returns {@code DUMMY_TARGET}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object getTarget() {
|
public Object getTarget() {
|
||||||
return null;
|
return EMPTY_TARGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -73,12 +73,9 @@ public abstract aspect AbstractTransactionAspect extends TransactionAspectSuppor
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException | Error ex) {
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
catch (Error err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
catch (Throwable thr) {
|
catch (Throwable thr) {
|
||||||
Rethrower.rethrow(thr);
|
Rethrower.rethrow(thr);
|
||||||
throw new IllegalStateException("Should never get here", thr);
|
throw new IllegalStateException("Should never get here", thr);
|
||||||
|
|
|
@ -141,13 +141,11 @@ public class BeanConfigurerSupport implements BeanFactoryAware, InitializingBean
|
||||||
!this.beanFactory.containsBean(bwi.getBeanName()))) {
|
!this.beanFactory.containsBean(bwi.getBeanName()))) {
|
||||||
// Perform autowiring (also applying standard factory / post-processor callbacks).
|
// Perform autowiring (also applying standard factory / post-processor callbacks).
|
||||||
this.beanFactory.autowireBeanProperties(beanInstance, bwi.getAutowireMode(), bwi.getDependencyCheck());
|
this.beanFactory.autowireBeanProperties(beanInstance, bwi.getAutowireMode(), bwi.getDependencyCheck());
|
||||||
Object result = this.beanFactory.initializeBean(beanInstance, bwi.getBeanName());
|
this.beanFactory.initializeBean(beanInstance, bwi.getBeanName());
|
||||||
checkExposedObject(result, beanInstance);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Perform explicit wiring based on the specified bean definition.
|
// Perform explicit wiring based on the specified bean definition.
|
||||||
Object result = this.beanFactory.configureBean(beanInstance, bwi.getBeanName());
|
this.beanFactory.configureBean(beanInstance, bwi.getBeanName());
|
||||||
checkExposedObject(result, beanInstance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (BeanCreationException ex) {
|
catch (BeanCreationException ex) {
|
||||||
|
@ -168,13 +166,4 @@ public class BeanConfigurerSupport implements BeanFactoryAware, InitializingBean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkExposedObject(@Nullable Object exposedObject, Object originalBeanInstance) {
|
|
||||||
if (exposedObject != originalBeanInstance) {
|
|
||||||
throw new IllegalStateException("Post-processor tried to replace bean instance of type [" +
|
|
||||||
originalBeanInstance.getClass().getName() + "] with (proxy) object of type [" +
|
|
||||||
(exposedObject != null ? exposedObject.getClass().getName() : null) +
|
|
||||||
"] - not supported for aspect-configured classes!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.springframework.core.type.filter.AspectJTypeFilter;
|
||||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||||
import org.springframework.core.type.filter.RegexPatternTypeFilter;
|
import org.springframework.core.type.filter.RegexPatternTypeFilter;
|
||||||
import org.springframework.core.type.filter.TypeFilter;
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
@ -64,7 +63,7 @@ class ComponentScanAnnotationParser {
|
||||||
private final BeanDefinitionRegistry registry;
|
private final BeanDefinitionRegistry registry;
|
||||||
|
|
||||||
|
|
||||||
public ComponentScanAnnotationParser(@Nullable Environment environment, @Nullable ResourceLoader resourceLoader,
|
public ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader,
|
||||||
BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) {
|
BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) {
|
||||||
|
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
|
@ -75,9 +74,6 @@ class ComponentScanAnnotationParser {
|
||||||
|
|
||||||
|
|
||||||
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
|
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
|
||||||
Assert.state(this.environment != null, "Environment must not be null");
|
|
||||||
Assert.state(this.resourceLoader != null, "ResourceLoader must not be null");
|
|
||||||
|
|
||||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
|
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
|
||||||
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
|
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -22,19 +22,19 @@ package org.springframework.jmx;
|
||||||
*/
|
*/
|
||||||
public interface IJmxTestBean {
|
public interface IJmxTestBean {
|
||||||
|
|
||||||
public int add(int x, int y);
|
int add(int x, int y);
|
||||||
|
|
||||||
public long myOperation();
|
long myOperation();
|
||||||
|
|
||||||
public int getAge();
|
int getAge();
|
||||||
|
|
||||||
public void setAge(int age);
|
void setAge(int age);
|
||||||
|
|
||||||
public void setName(String name) throws Exception;
|
void setName(String name) throws Exception;
|
||||||
|
|
||||||
public String getName();
|
String getName();
|
||||||
|
|
||||||
// used to test invalid methods that exist in the proxy interface
|
// used to test invalid methods that exist in the proxy interface
|
||||||
public void dontExposeMe();
|
void dontExposeMe();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -449,24 +449,21 @@ public class RmiSupportTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface IBusinessBean {
|
public interface IBusinessBean {
|
||||||
|
|
||||||
public void setName(String name);
|
|
||||||
|
|
||||||
|
void setName(String name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface IWrongBusinessBean {
|
public interface IWrongBusinessBean {
|
||||||
|
|
||||||
public void setOtherName(String name);
|
|
||||||
|
|
||||||
|
void setOtherName(String name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static interface IRemoteBean extends Remote {
|
public interface IRemoteBean extends Remote {
|
||||||
|
|
||||||
public void setName(String name) throws RemoteException;
|
|
||||||
|
|
||||||
|
void setName(String name) throws RemoteException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class ResolvableType implements Serializable {
|
||||||
* {@code ResolvableType} returned when no value is available. {@code NONE} is used
|
* {@code ResolvableType} returned when no value is available. {@code NONE} is used
|
||||||
* in preference to {@code null} so that multiple method calls can be safely chained.
|
* in preference to {@code null} so that multiple method calls can be safely chained.
|
||||||
*/
|
*/
|
||||||
public static final ResolvableType NONE = new ResolvableType(null, null, null, 0);
|
public static final ResolvableType NONE = new ResolvableType(EmptyType.INSTANCE, null, null, 0);
|
||||||
|
|
||||||
private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0];
|
private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0];
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ public class ResolvableType implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The underlying Java type being managed (only ever {@code null} for {@link #NONE}).
|
* The underlying Java type being managed.
|
||||||
*/
|
*/
|
||||||
private final Type type;
|
private final Type type;
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ public class ResolvableType implements Serializable {
|
||||||
* with upfront resolution and a pre-calculated hash.
|
* with upfront resolution and a pre-calculated hash.
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
private ResolvableType(@Nullable Type type, @Nullable TypeProvider typeProvider,
|
private ResolvableType(Type type, @Nullable TypeProvider typeProvider,
|
||||||
@Nullable VariableResolver variableResolver, Integer hash) {
|
@Nullable VariableResolver variableResolver, Integer hash) {
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -188,10 +188,8 @@ public class ResolvableType implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the underling Java {@link Type} being managed. With the exception of
|
* Return the underling Java {@link Type} being managed.
|
||||||
* the {@link #NONE} constant, this method will never return {@code null}.
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
return SerializableTypeWrapper.unwrap(this.type);
|
return SerializableTypeWrapper.unwrap(this.type);
|
||||||
}
|
}
|
||||||
|
@ -761,7 +759,10 @@ public class ResolvableType implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> resolveClass() {
|
private Class<?> resolveClass() {
|
||||||
if (this.type instanceof Class || this.type == null) {
|
if (this.type == EmptyType.INSTANCE) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (this.type instanceof Class) {
|
||||||
return (Class<?>) this.type;
|
return (Class<?>) this.type;
|
||||||
}
|
}
|
||||||
if (this.type instanceof GenericArrayType) {
|
if (this.type instanceof GenericArrayType) {
|
||||||
|
@ -903,7 +904,7 @@ public class ResolvableType implements Serializable {
|
||||||
* Custom serialization support for {@link #NONE}.
|
* Custom serialization support for {@link #NONE}.
|
||||||
*/
|
*/
|
||||||
private Object readResolve() {
|
private Object readResolve() {
|
||||||
return (this.type == null ? NONE : this);
|
return (this.type == EmptyType.INSTANCE ? NONE : this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1567,7 +1568,6 @@ public class ResolvableType implements Serializable {
|
||||||
resolveToWildcard = resolveToWildcard.resolveType();
|
resolveToWildcard = resolveToWildcard.resolveType();
|
||||||
}
|
}
|
||||||
WildcardType wildcardType = (WildcardType) resolveToWildcard.type;
|
WildcardType wildcardType = (WildcardType) resolveToWildcard.type;
|
||||||
Assert.state(wildcardType != null, "Wildcard type not resolved");
|
|
||||||
Kind boundsType = (wildcardType.getLowerBounds().length > 0 ? Kind.LOWER : Kind.UPPER);
|
Kind boundsType = (wildcardType.getLowerBounds().length > 0 ? Kind.LOWER : Kind.UPPER);
|
||||||
Type[] bounds = boundsType == Kind.UPPER ? wildcardType.getUpperBounds() : wildcardType.getLowerBounds();
|
Type[] bounds = boundsType == Kind.UPPER ? wildcardType.getUpperBounds() : wildcardType.getLowerBounds();
|
||||||
ResolvableType[] resolvableBounds = new ResolvableType[bounds.length];
|
ResolvableType[] resolvableBounds = new ResolvableType[bounds.length];
|
||||||
|
@ -1583,4 +1583,15 @@ public class ResolvableType implements Serializable {
|
||||||
enum Kind {UPPER, LOWER}
|
enum Kind {UPPER, LOWER}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
static class EmptyType implements Type, Serializable {
|
||||||
|
|
||||||
|
static final Type INSTANCE = new EmptyType();
|
||||||
|
|
||||||
|
Object readResolve() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,19 +37,19 @@ import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal utility class that can be used to obtain wrapped {@link Serializable} variants
|
* Internal utility class that can be used to obtain wrapped {@link Serializable}
|
||||||
* of {@link java.lang.reflect.Type}s.
|
* variants of {@link java.lang.reflect.Type}s.
|
||||||
*
|
*
|
||||||
* <p>{@link #forField(Field) Fields} or {@link #forMethodParameter(MethodParameter)
|
* <p>{@link #forField(Field) Fields} or {@link #forMethodParameter(MethodParameter)
|
||||||
* MethodParameters} can be used as the root source for a serializable type. Alternatively
|
* MethodParameters} can be used as the root source for a serializable type.
|
||||||
* the {@link #forGenericSuperclass(Class) superclass},
|
* Alternatively the {@link #forGenericSuperclass(Class) superclass},
|
||||||
* {@link #forGenericInterfaces(Class) interfaces} or {@link #forTypeParameters(Class)
|
* {@link #forGenericInterfaces(Class) interfaces} or {@link #forTypeParameters(Class)
|
||||||
* type parameters} or a regular {@link Class} can also be used as source.
|
* type parameters} or a regular {@link Class} can also be used as source.
|
||||||
*
|
*
|
||||||
* <p>The returned type will either be a {@link Class} or a serializable proxy of
|
* <p>The returned type will either be a {@link Class} or a serializable proxy of
|
||||||
* {@link GenericArrayType}, {@link ParameterizedType}, {@link TypeVariable} or
|
* {@link GenericArrayType}, {@link ParameterizedType}, {@link TypeVariable} or
|
||||||
* {@link WildcardType}. With the exception of {@link Class} (which is final) calls to
|
* {@link WildcardType}. With the exception of {@link Class} (which is final) calls
|
||||||
* methods that return further {@link Type}s (for example
|
* to methods that return further {@link Type}s (for example
|
||||||
* {@link GenericArrayType#getGenericComponentType()}) will be automatically wrapped.
|
* {@link GenericArrayType#getGenericComponentType()}) will be automatically wrapped.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
@ -123,13 +123,12 @@ abstract class SerializableTypeWrapper {
|
||||||
* @return the original non-serializable type
|
* @return the original non-serializable type
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
|
||||||
public static <T extends Type> T unwrap(T type) {
|
public static <T extends Type> T unwrap(T type) {
|
||||||
Type unwrapped = type;
|
Type unwrapped = type;
|
||||||
while (unwrapped instanceof SerializableTypeProxy) {
|
while (unwrapped instanceof SerializableTypeProxy) {
|
||||||
unwrapped = ((SerializableTypeProxy) type).getTypeProvider().getType();
|
unwrapped = ((SerializableTypeProxy) type).getTypeProvider().getType();
|
||||||
}
|
}
|
||||||
return (T) unwrapped;
|
return (unwrapped != null ? (T) unwrapped : type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -423,7 +423,7 @@ public class AnnotatedElementUtils {
|
||||||
|
|
||||||
// Exhaustive retrieval of merged annotation attributes...
|
// Exhaustive retrieval of merged annotation attributes...
|
||||||
AnnotationAttributes attributes = getMergedAnnotationAttributes(element, annotationType);
|
AnnotationAttributes attributes = getMergedAnnotationAttributes(element, annotationType);
|
||||||
return AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element);
|
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -726,7 +726,7 @@ public class AnnotatedElementUtils {
|
||||||
|
|
||||||
// Exhaustive retrieval of merged annotation attributes...
|
// Exhaustive retrieval of merged annotation attributes...
|
||||||
AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationType, false, false);
|
AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationType, false, false);
|
||||||
return AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element);
|
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1482,8 +1482,7 @@ public abstract class AnnotationUtils {
|
||||||
* @param annotationType the type of annotation to synthesize
|
* @param annotationType the type of annotation to synthesize
|
||||||
* @param annotatedElement the element that is annotated with the annotation
|
* @param annotatedElement the element that is annotated with the annotation
|
||||||
* corresponding to the supplied attributes; may be {@code null} if unknown
|
* corresponding to the supplied attributes; may be {@code null} if unknown
|
||||||
* @return the synthesized annotation, or {@code null} if the supplied attributes
|
* @return the synthesized annotation
|
||||||
* map is {@code null}
|
|
||||||
* @throws IllegalArgumentException if a required attribute is missing or if an
|
* @throws IllegalArgumentException if a required attribute is missing or if an
|
||||||
* attribute is not of the correct type
|
* attribute is not of the correct type
|
||||||
* @throws AnnotationConfigurationException if invalid configuration of
|
* @throws AnnotationConfigurationException if invalid configuration of
|
||||||
|
@ -1495,14 +1494,11 @@ public abstract class AnnotationUtils {
|
||||||
* @see #getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
|
* @see #getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
public static <A extends Annotation> A synthesizeAnnotation(Map<String, Object> attributes,
|
||||||
public static <A extends Annotation> A synthesizeAnnotation(@Nullable Map<String, Object> attributes,
|
|
||||||
Class<A> annotationType, @Nullable AnnotatedElement annotatedElement) {
|
Class<A> annotationType, @Nullable AnnotatedElement annotatedElement) {
|
||||||
|
|
||||||
|
Assert.notNull(attributes, "'attributes' must not be null");
|
||||||
Assert.notNull(annotationType, "'annotationType' must not be null");
|
Assert.notNull(annotationType, "'annotationType' must not be null");
|
||||||
if (attributes == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
MapAnnotationAttributeExtractor attributeExtractor =
|
MapAnnotationAttributeExtractor attributeExtractor =
|
||||||
new MapAnnotationAttributeExtractor(attributes, annotationType, annotatedElement);
|
new MapAnnotationAttributeExtractor(attributes, annotationType, annotatedElement);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.core.style;
|
package org.springframework.core.style;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
@ -77,7 +78,7 @@ public class DefaultToStringStyler implements ToStringStyler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void styleField(StringBuilder buffer, String fieldName, Object value) {
|
public void styleField(StringBuilder buffer, String fieldName, @Nullable Object value) {
|
||||||
styleFieldStart(buffer, fieldName);
|
styleFieldStart(buffer, fieldName);
|
||||||
styleValue(buffer, value);
|
styleValue(buffer, value);
|
||||||
styleFieldEnd(buffer, fieldName);
|
styleFieldEnd(buffer, fieldName);
|
||||||
|
@ -91,7 +92,7 @@ public class DefaultToStringStyler implements ToStringStyler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void styleValue(StringBuilder buffer, Object value) {
|
public void styleValue(StringBuilder buffer, @Nullable Object value) {
|
||||||
buffer.append(this.valueStyler.style(value));
|
buffer.append(this.valueStyler.style(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class ToStringCreator {
|
||||||
* @param value the field value
|
* @param value the field value
|
||||||
* @return this, to support call-chaining
|
* @return this, to support call-chaining
|
||||||
*/
|
*/
|
||||||
public ToStringCreator append(String fieldName, Object value) {
|
public ToStringCreator append(String fieldName, @Nullable Object value) {
|
||||||
printFieldSeparatorIfNecessary();
|
printFieldSeparatorIfNecessary();
|
||||||
this.styler.styleField(this.buffer, fieldName, value);
|
this.styler.styleField(this.buffer, fieldName, value);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.core.style;
|
package org.springframework.core.style;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A strategy interface for pretty-printing {@code toString()} methods.
|
* A strategy interface for pretty-printing {@code toString()} methods.
|
||||||
* Encapsulates the print algorithms; some other object such as a builder
|
* Encapsulates the print algorithms; some other object such as a builder
|
||||||
|
@ -46,7 +48,7 @@ public interface ToStringStyler {
|
||||||
* @param fieldName the he name of the field
|
* @param fieldName the he name of the field
|
||||||
* @param value the field value
|
* @param value the field value
|
||||||
*/
|
*/
|
||||||
void styleField(StringBuilder buffer, String fieldName, Object value);
|
void styleField(StringBuilder buffer, String fieldName, @Nullable Object value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style the given value.
|
* Style the given value.
|
||||||
|
|
|
@ -404,6 +404,12 @@ public abstract class CollectionUtils {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V getFirst(K key) {
|
||||||
|
List<V> values = this.map.get(key);
|
||||||
|
return (values != null ? values.get(0) : null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(K key, @Nullable V value) {
|
public void add(K key, @Nullable V value) {
|
||||||
List<V> values = this.map.computeIfAbsent(key, k -> new LinkedList<>());
|
List<V> values = this.map.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
|
@ -411,17 +417,11 @@ public abstract class CollectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAll(K key, List<V> values) {
|
public void addAll(K key, List<? extends V> values) {
|
||||||
List<V> currentValues = this.map.computeIfAbsent(key, k -> new LinkedList<>());
|
List<V> currentValues = this.map.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
currentValues.addAll(values);
|
currentValues.addAll(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public V getFirst(K key) {
|
|
||||||
List<V> values = this.map.get(key);
|
|
||||||
return (values != null ? values.get(0) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(K key, V value) {
|
public void set(K key, V value) {
|
||||||
List<V> values = new LinkedList<>();
|
List<V> values = new LinkedList<>();
|
||||||
|
|
|
@ -75,6 +75,12 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
|
||||||
|
|
||||||
// MultiValueMap implementation
|
// MultiValueMap implementation
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V getFirst(K key) {
|
||||||
|
List<V> values = this.targetMap.get(key);
|
||||||
|
return (values != null ? values.get(0) : null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(K key, @Nullable V value) {
|
public void add(K key, @Nullable V value) {
|
||||||
List<V> values = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
List<V> values = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
|
@ -82,17 +88,11 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAll(K key, List<V> values) {
|
public void addAll(K key, List<? extends V> values) {
|
||||||
List<V> currentValues = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
List<V> currentValues = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
currentValues.addAll(values);
|
currentValues.addAll(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public V getFirst(K key) {
|
|
||||||
List<V> values = this.targetMap.get(key);
|
|
||||||
return (values != null ? values.get(0) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(K key, V value) {
|
public void set(K key, V value) {
|
||||||
List<V> values = new LinkedList<>();
|
List<V> values = new LinkedList<>();
|
||||||
|
|
|
@ -32,7 +32,7 @@ public interface MultiValueMap<K, V> extends Map<K, List<V>> {
|
||||||
/**
|
/**
|
||||||
* Return the first value for the given key.
|
* Return the first value for the given key.
|
||||||
* @param key the key
|
* @param key the key
|
||||||
* @return the first value for the specified key, or {@code null}
|
* @return the first value for the specified key, or {@code null} if none
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
V getFirst(K key);
|
V getFirst(K key);
|
||||||
|
@ -50,7 +50,7 @@ public interface MultiValueMap<K, V> extends Map<K, List<V>> {
|
||||||
* @param values the values to be added
|
* @param values the values to be added
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
void addAll(K key, List<V> values);
|
void addAll(K key, List<? extends V> values);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the given single value under the given key.
|
* Set the given single value under the given key.
|
||||||
|
|
|
@ -119,7 +119,7 @@ public abstract class ReflectionUtils {
|
||||||
* @param target the target object on which to set the field
|
* @param target the target object on which to set the field
|
||||||
* @param value the value to set (may be {@code null})
|
* @param value the value to set (may be {@code null})
|
||||||
*/
|
*/
|
||||||
public static void setField(Field field, Object target, @Nullable Object value) {
|
public static void setField(Field field, @Nullable Object target, @Nullable Object value) {
|
||||||
try {
|
try {
|
||||||
field.set(target, value);
|
field.set(target, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.BDDMockito.any;
|
||||||
import static org.mockito.BDDMockito.*;
|
import static org.mockito.BDDMockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +87,7 @@ public class ResolvableTypeTests {
|
||||||
assertThat(none.getGenerics().length, equalTo(0));
|
assertThat(none.getGenerics().length, equalTo(0));
|
||||||
assertThat(none.getInterfaces().length, equalTo(0));
|
assertThat(none.getInterfaces().length, equalTo(0));
|
||||||
assertThat(none.getSuperType(), equalTo(ResolvableType.NONE));
|
assertThat(none.getSuperType(), equalTo(ResolvableType.NONE));
|
||||||
assertThat(none.getType(), nullValue());
|
assertThat(none.getType(), equalTo(ResolvableType.EmptyType.INSTANCE));
|
||||||
assertThat(none.hasGenerics(), equalTo(false));
|
assertThat(none.hasGenerics(), equalTo(false));
|
||||||
assertThat(none.isArray(), equalTo(false));
|
assertThat(none.isArray(), equalTo(false));
|
||||||
assertThat(none.resolve(), nullValue());
|
assertThat(none.resolve(), nullValue());
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.messaging.Message;
|
import org.springframework.messaging.Message;
|
||||||
import org.springframework.messaging.handler.HandlerMethod;
|
import org.springframework.messaging.handler.HandlerMethod;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
@ -289,9 +288,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getGenericParameterType() {
|
public Type getGenericParameterType() {
|
||||||
Type returnType = this.returnType.getType();
|
return this.returnType.getType();
|
||||||
Assert.state(returnType != null, "No return type");
|
|
||||||
return returnType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -417,7 +417,7 @@ public class StompHeaders implements MultiValueMap<String, String>, Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAll(String headerName, List<String> headerValues) {
|
public void addAll(String headerName, List<? extends String> headerValues) {
|
||||||
List<String> currentValues = headers.computeIfAbsent(headerName, k -> new LinkedList<>());
|
List<String> currentValues = headers.computeIfAbsent(headerName, k -> new LinkedList<>());
|
||||||
currentValues.addAll(headerValues);
|
currentValues.addAll(headerValues);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -72,10 +72,7 @@ public class MockClientHttpResponse extends MockHttpInputMessage implements Clie
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
InputStream body = getBody();
|
getBody().close();
|
||||||
if (body != null) {
|
|
||||||
body.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
// ignore
|
// ignore
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
|
||||||
|
|
||||||
super(uri, headers);
|
super(uri, headers);
|
||||||
this.httpMethod = httpMethod;
|
this.httpMethod = httpMethod;
|
||||||
this.contextPath = (contextPath != null ? contextPath : "");
|
this.contextPath = contextPath;
|
||||||
this.cookies = cookies;
|
this.cookies = cookies;
|
||||||
this.remoteAddress = remoteAddress;
|
this.remoteAddress = remoteAddress;
|
||||||
this.body = Flux.from(body);
|
this.body = Flux.from(body);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +81,9 @@ public class SimpleNamingContext implements Context {
|
||||||
* Create a new naming context with the given naming root,
|
* Create a new naming context with the given naming root,
|
||||||
* the given name/object map, and the JNDI environment entries.
|
* 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.root = root;
|
||||||
this.boundObjects = boundObjects;
|
this.boundObjects = boundObjects;
|
||||||
if (env != null) {
|
if (env != null) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.mock.jndi;
|
package org.springframework.mock.jndi;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import javax.naming.Context;
|
import javax.naming.Context;
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
import javax.naming.spi.InitialContextFactory;
|
import javax.naming.spi.InitialContextFactory;
|
||||||
|
@ -195,7 +194,7 @@ public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder
|
||||||
* @see SimpleNamingContext
|
* @see SimpleNamingContext
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InitialContextFactory createInitialContextFactory(Hashtable<?,?> environment) {
|
public InitialContextFactory createInitialContextFactory(@Nullable Hashtable<?,?> environment) {
|
||||||
if (activated == null && environment != null) {
|
if (activated == null && environment != null) {
|
||||||
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
|
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
|
||||||
if (icf != null) {
|
if (icf != null) {
|
||||||
|
|
|
@ -68,10 +68,12 @@ class HeaderValueHolder {
|
||||||
return Collections.unmodifiableList(stringList);
|
return Collections.unmodifiableList(stringList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
return (!this.values.isEmpty() ? this.values.get(0) : null);
|
return (!this.values.isEmpty() ? this.values.get(0) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getStringValue() {
|
public String getStringValue() {
|
||||||
return (!this.values.isEmpty() ? String.valueOf(this.values.get(0)) : null);
|
return (!this.values.isEmpty() ? String.valueOf(this.values.get(0)) : null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class MockAsyncContext implements AsyncContext {
|
||||||
private final List<Runnable> dispatchHandlers = new ArrayList<>();
|
private final List<Runnable> dispatchHandlers = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
public MockAsyncContext(ServletRequest request, ServletResponse response) {
|
public MockAsyncContext(ServletRequest request, @Nullable ServletResponse response) {
|
||||||
this.request = (HttpServletRequest) request;
|
this.request = (HttpServletRequest) request;
|
||||||
this.response = (HttpServletResponse) response;
|
this.response = (HttpServletResponse) response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.jsp.JspWriter;
|
import javax.servlet.jsp.JspWriter;
|
||||||
import javax.servlet.jsp.tagext.BodyContent;
|
import javax.servlet.jsp.tagext.BodyContent;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class.
|
* Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class.
|
||||||
* Only necessary for testing applications when testing custom JSP tags.
|
* Only necessary for testing applications when testing custom JSP tags.
|
||||||
|
@ -60,12 +62,12 @@ public class MockBodyContent extends BodyContent {
|
||||||
* @param response the servlet response to wrap
|
* @param response the servlet response to wrap
|
||||||
* @param targetWriter the target Writer to wrap
|
* @param targetWriter the target Writer to wrap
|
||||||
*/
|
*/
|
||||||
public MockBodyContent(String content, HttpServletResponse response, Writer targetWriter) {
|
public MockBodyContent(String content, @Nullable HttpServletResponse response, @Nullable Writer targetWriter) {
|
||||||
super(adaptJspWriter(targetWriter, response));
|
super(adaptJspWriter(targetWriter, response));
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JspWriter adaptJspWriter(Writer targetWriter, HttpServletResponse response) {
|
private static JspWriter adaptJspWriter(@Nullable Writer targetWriter, @Nullable HttpServletResponse response) {
|
||||||
if (targetWriter instanceof JspWriter) {
|
if (targetWriter instanceof JspWriter) {
|
||||||
return (JspWriter) targetWriter;
|
return (JspWriter) targetWriter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||||
import javax.servlet.FilterConfig;
|
import javax.servlet.FilterConfig;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +65,7 @@ public class MockFilterConfig implements FilterConfig {
|
||||||
* Create a new MockFilterConfig.
|
* Create a new MockFilterConfig.
|
||||||
* @param servletContext the ServletContext that the servlet runs in
|
* @param servletContext the ServletContext that the servlet runs in
|
||||||
*/
|
*/
|
||||||
public MockFilterConfig(ServletContext servletContext) {
|
public MockFilterConfig(@Nullable ServletContext servletContext) {
|
||||||
this(servletContext, "");
|
this(servletContext, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ public class MockFilterConfig implements FilterConfig {
|
||||||
* @param servletContext the ServletContext that the servlet runs in
|
* @param servletContext the ServletContext that the servlet runs in
|
||||||
* @param filterName the name of the filter
|
* @param filterName the name of the filter
|
||||||
*/
|
*/
|
||||||
public MockFilterConfig(ServletContext servletContext, String filterName) {
|
public MockFilterConfig(@Nullable ServletContext servletContext, String filterName) {
|
||||||
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
this.filterName = filterName;
|
this.filterName = filterName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
|
@ -64,6 +63,7 @@ import org.springframework.util.Assert;
|
||||||
import org.springframework.util.LinkedCaseInsensitiveMap;
|
import org.springframework.util.LinkedCaseInsensitiveMap;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.StreamUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
@ -370,6 +370,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getCharacterEncoding() {
|
public String getCharacterEncoding() {
|
||||||
return this.characterEncoding;
|
return this.characterEncoding;
|
||||||
}
|
}
|
||||||
|
@ -449,7 +450,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
return getContentLength();
|
return getContentLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentType(String contentType) {
|
public void setContentType(@Nullable String contentType) {
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -470,6 +471,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
return this.contentType;
|
return this.contentType;
|
||||||
}
|
}
|
||||||
|
@ -530,7 +532,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
* <p>If there are already one or more values registered for the given
|
* <p>If there are already one or more values registered for the given
|
||||||
* parameter name, the given value will be added to the end of the list.
|
* parameter name, the given value will be added to the end of the list.
|
||||||
*/
|
*/
|
||||||
public void addParameter(String name, String value) {
|
public void addParameter(String name, @Nullable String value) {
|
||||||
addParameter(name, new String[] {value});
|
addParameter(name, new String[] {value});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,8 +593,10 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getParameter(String name) {
|
public String getParameter(String name) {
|
||||||
String[] arr = (name != null ? this.parameters.get(name) : null);
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
String[] arr = this.parameters.get(name);
|
||||||
return (arr != null && arr.length > 0 ? arr[0] : null);
|
return (arr != null && arr.length > 0 ? arr[0] : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +607,8 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getParameterValues(String name) {
|
public String[] getParameterValues(String name) {
|
||||||
return (name != null ? this.parameters.get(name) : null);
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
return this.parameters.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -709,7 +714,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, Object value) {
|
public void setAttribute(String name, @Nullable Object value) {
|
||||||
checkActive();
|
checkActive();
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
@ -903,6 +908,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public AsyncContext getAsyncContext() {
|
public AsyncContext getAsyncContext() {
|
||||||
return this.asyncContext;
|
return this.asyncContext;
|
||||||
}
|
}
|
||||||
|
@ -930,17 +936,18 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
return this.authType;
|
return this.authType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCookies(Cookie... cookies) {
|
public void setCookies(@Nullable Cookie... cookies) {
|
||||||
this.cookies = cookies;
|
this.cookies = (ObjectUtils.isEmpty(cookies) ? null : cookies);
|
||||||
this.headers.remove(HttpHeaders.COOKIE);
|
this.headers.remove(HttpHeaders.COOKIE);
|
||||||
if (cookies != null) {
|
if (this.cookies != null) {
|
||||||
Arrays.stream(cookies)
|
Arrays.stream(this.cookies)
|
||||||
.map(c -> c.getName() + '=' + (c.getValue() == null ? "" : c.getValue()))
|
.map(c -> c.getName() + '=' + (c.getValue() == null ? "" : c.getValue()))
|
||||||
.forEach(value -> doAddHeaderValue(HttpHeaders.COOKIE, value, false));
|
.forEach(value -> doAddHeaderValue(HttpHeaders.COOKIE, value, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Cookie[] getCookies() {
|
public Cookie[] getCookies() {
|
||||||
return this.cookies;
|
return this.cookies;
|
||||||
}
|
}
|
||||||
|
@ -978,7 +985,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doAddHeaderValue(String name, Object value, boolean replace) {
|
private void doAddHeaderValue(String name, @Nullable Object value, boolean replace) {
|
||||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
Assert.notNull(value, "Header value must not be null");
|
Assert.notNull(value, "Header value must not be null");
|
||||||
if (header == null || replace) {
|
if (header == null || replace) {
|
||||||
|
@ -1045,6 +1052,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getHeader(String name) {
|
public String getHeader(String name) {
|
||||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
return (header != null ? header.getStringValue() : null);
|
return (header != null ? header.getStringValue() : null);
|
||||||
|
@ -1098,6 +1106,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getPathTranslated() {
|
public String getPathTranslated() {
|
||||||
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
|
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
|
||||||
}
|
}
|
||||||
|
@ -1111,7 +1120,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
return this.contextPath;
|
return this.contextPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQueryString(String queryString) {
|
public void setQueryString(@Nullable String queryString) {
|
||||||
this.queryString = queryString;
|
this.queryString = queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1129,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
return this.queryString;
|
return this.queryString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRemoteUser(String remoteUser) {
|
public void setRemoteUser(@Nullable String remoteUser) {
|
||||||
this.remoteUser = remoteUser;
|
this.remoteUser = remoteUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,6 +1206,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public HttpSession getSession(boolean create) {
|
public HttpSession getSession(boolean create) {
|
||||||
checkActive();
|
checkActive();
|
||||||
// Reset session if invalidated.
|
// Reset session if invalidated.
|
||||||
|
@ -1211,6 +1221,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public HttpSession getSession() {
|
public HttpSession getSession() {
|
||||||
return getSession(true);
|
return getSession(true);
|
||||||
}
|
}
|
||||||
|
@ -1284,6 +1295,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
|
public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
|
||||||
return this.parts.getFirst(name);
|
return this.parts.getFirst(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -171,6 +170,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getCharacterEncoding() {
|
public String getCharacterEncoding() {
|
||||||
return this.characterEncoding;
|
return this.characterEncoding;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setContentType(String contentType) {
|
public void setContentType(@Nullable String contentType) {
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -247,6 +247,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
return this.contentType;
|
return this.contentType;
|
||||||
}
|
}
|
||||||
|
@ -302,7 +303,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLocale(Locale locale) {
|
public void setLocale(@Nullable Locale locale) {
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
if (locale != null) {
|
if (locale != null) {
|
||||||
doAddHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, locale.toLanguageTag(), true);
|
doAddHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, locale.toLanguageTag(), true);
|
||||||
|
@ -357,6 +358,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
return this.cookies.toArray(new Cookie[this.cookies.size()]);
|
return this.cookies.toArray(new Cookie[this.cookies.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Cookie getCookie(String name) {
|
public Cookie getCookie(String name) {
|
||||||
Assert.notNull(name, "Cookie name must not be null");
|
Assert.notNull(name, "Cookie name must not be null");
|
||||||
for (Cookie cookie : this.cookies) {
|
for (Cookie cookie : this.cookies) {
|
||||||
|
@ -502,6 +504,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
setCommitted(true);
|
setCommitted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getRedirectedUrl() {
|
public String getRedirectedUrl() {
|
||||||
return getHeader(HttpHeaders.LOCATION);
|
return getHeader(HttpHeaders.LOCATION);
|
||||||
}
|
}
|
||||||
|
@ -639,17 +642,19 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
this.forwardedUrl = forwardedUrl;
|
this.forwardedUrl = forwardedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getForwardedUrl() {
|
public String getForwardedUrl() {
|
||||||
return this.forwardedUrl;
|
return this.forwardedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIncludedUrl(String includedUrl) {
|
public void setIncludedUrl(@Nullable String includedUrl) {
|
||||||
this.includedUrls.clear();
|
this.includedUrls.clear();
|
||||||
if (includedUrl != null) {
|
if (includedUrl != null) {
|
||||||
this.includedUrls.add(includedUrl);
|
this.includedUrls.add(includedUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getIncludedUrl() {
|
public String getIncludedUrl() {
|
||||||
int count = this.includedUrls.size();
|
int count = this.includedUrls.size();
|
||||||
Assert.state(count <= 1,
|
Assert.state(count <= 1,
|
||||||
|
|
|
@ -29,6 +29,7 @@ import javax.servlet.http.HttpSession;
|
||||||
import javax.servlet.http.HttpSessionBindingEvent;
|
import javax.servlet.http.HttpSessionBindingEvent;
|
||||||
import javax.servlet.http.HttpSessionBindingListener;
|
import javax.servlet.http.HttpSessionBindingListener;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +80,7 @@ public class MockHttpSession implements HttpSession {
|
||||||
* Create a new MockHttpSession.
|
* Create a new MockHttpSession.
|
||||||
* @param servletContext the ServletContext that the session runs in
|
* @param servletContext the ServletContext that the session runs in
|
||||||
*/
|
*/
|
||||||
public MockHttpSession(ServletContext servletContext) {
|
public MockHttpSession(@Nullable ServletContext servletContext) {
|
||||||
this(servletContext, null);
|
this(servletContext, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ public class MockHttpSession implements HttpSession {
|
||||||
* @param servletContext the ServletContext that the session runs in
|
* @param servletContext the ServletContext that the session runs in
|
||||||
* @param id a unique identifier for this session
|
* @param id a unique identifier for this session
|
||||||
*/
|
*/
|
||||||
public MockHttpSession(ServletContext servletContext, String id) {
|
public MockHttpSession(@Nullable ServletContext servletContext, @Nullable String id) {
|
||||||
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
this.id = (id != null ? id : Integer.toString(nextId++));
|
this.id = (id != null ? id : Integer.toString(nextId++));
|
||||||
}
|
}
|
||||||
|
@ -171,7 +172,7 @@ public class MockHttpSession implements HttpSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, Object value) {
|
public void setAttribute(String name, @Nullable Object value) {
|
||||||
assertIsValid();
|
assertIsValid();
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.io.Writer;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.jsp.JspWriter;
|
import javax.servlet.jsp.JspWriter;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock implementation of the {@link javax.servlet.jsp.JspWriter} class.
|
* Mock implementation of the {@link javax.servlet.jsp.JspWriter} class.
|
||||||
* Only necessary for testing applications when testing custom JSP tags.
|
* Only necessary for testing applications when testing custom JSP tags.
|
||||||
|
@ -58,7 +60,7 @@ public class MockJspWriter extends JspWriter {
|
||||||
* @param response the servlet response to wrap
|
* @param response the servlet response to wrap
|
||||||
* @param targetWriter the target Writer to wrap
|
* @param targetWriter the target Writer to wrap
|
||||||
*/
|
*/
|
||||||
public MockJspWriter(HttpServletResponse response, Writer targetWriter) {
|
public MockJspWriter(@Nullable HttpServletResponse response, @Nullable Writer targetWriter) {
|
||||||
super(DEFAULT_BUFFER, true);
|
super(DEFAULT_BUFFER, true);
|
||||||
this.response = (response != null ? response : new MockHttpServletResponse());
|
this.response = (response != null ? response : new MockHttpServletResponse());
|
||||||
if (targetWriter instanceof PrintWriter) {
|
if (targetWriter instanceof PrintWriter) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -21,6 +21,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
@ -53,7 +54,7 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
* @param name the name of the file
|
* @param name the name of the file
|
||||||
* @param content the content of the file
|
* @param content the content of the file
|
||||||
*/
|
*/
|
||||||
public MockMultipartFile(String name, byte[] content) {
|
public MockMultipartFile(String name, @Nullable byte[] content) {
|
||||||
this(name, "", null, content);
|
this(name, "", null, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +75,9 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
* @param contentType the content type (if known)
|
* @param contentType the content type (if known)
|
||||||
* @param content the content of the file
|
* @param content the content of the file
|
||||||
*/
|
*/
|
||||||
public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
|
public MockMultipartFile(
|
||||||
|
String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
|
||||||
|
|
||||||
Assert.hasLength(name, "Name must not be null");
|
Assert.hasLength(name, "Name must not be null");
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.originalFilename = (originalFilename != null ? originalFilename : "");
|
this.originalFilename = (originalFilename != null ? originalFilename : "");
|
||||||
|
@ -90,7 +93,8 @@ public class MockMultipartFile implements MultipartFile {
|
||||||
* @param contentStream the content of the file as stream
|
* @param contentStream the content of the file as stream
|
||||||
* @throws IOException if reading from the stream failed
|
* @throws IOException if reading from the stream failed
|
||||||
*/
|
*/
|
||||||
public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream)
|
public MockMultipartFile(
|
||||||
|
String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
|
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
|
||||||
|
|
|
@ -36,6 +36,7 @@ import javax.servlet.http.HttpSession;
|
||||||
import javax.servlet.jsp.JspWriter;
|
import javax.servlet.jsp.JspWriter;
|
||||||
import javax.servlet.jsp.PageContext;
|
import javax.servlet.jsp.PageContext;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +80,7 @@ public class MockPageContext extends PageContext {
|
||||||
* @param servletContext the ServletContext that the JSP page runs in
|
* @param servletContext the ServletContext that the JSP page runs in
|
||||||
* (only necessary when actually accessing the ServletContext)
|
* (only necessary when actually accessing the ServletContext)
|
||||||
*/
|
*/
|
||||||
public MockPageContext(ServletContext servletContext) {
|
public MockPageContext(@Nullable ServletContext servletContext) {
|
||||||
this(servletContext, null, null, null);
|
this(servletContext, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ public class MockPageContext extends PageContext {
|
||||||
* @param request the current HttpServletRequest
|
* @param request the current HttpServletRequest
|
||||||
* (only necessary when actually accessing the request)
|
* (only necessary when actually accessing the request)
|
||||||
*/
|
*/
|
||||||
public MockPageContext(ServletContext servletContext, HttpServletRequest request) {
|
public MockPageContext(@Nullable ServletContext servletContext, @Nullable HttpServletRequest request) {
|
||||||
this(servletContext, request, null, null);
|
this(servletContext, request, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,9 @@ public class MockPageContext extends PageContext {
|
||||||
* @param response the current HttpServletResponse
|
* @param response the current HttpServletResponse
|
||||||
* (only necessary when actually writing to the response)
|
* (only necessary when actually writing to the response)
|
||||||
*/
|
*/
|
||||||
public MockPageContext(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) {
|
public MockPageContext(@Nullable ServletContext servletContext, @Nullable HttpServletRequest request,
|
||||||
|
@Nullable HttpServletResponse response) {
|
||||||
|
|
||||||
this(servletContext, request, response, null);
|
this(servletContext, request, response, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +115,8 @@ public class MockPageContext extends PageContext {
|
||||||
* @param response the current HttpServletResponse
|
* @param response the current HttpServletResponse
|
||||||
* @param servletConfig the ServletConfig (hardly ever accessed from within a tag)
|
* @param servletConfig the ServletConfig (hardly ever accessed from within a tag)
|
||||||
*/
|
*/
|
||||||
public MockPageContext(ServletContext servletContext, HttpServletRequest request,
|
public MockPageContext(@Nullable ServletContext servletContext, @Nullable HttpServletRequest request,
|
||||||
HttpServletResponse response, ServletConfig servletConfig) {
|
@Nullable HttpServletResponse response, @Nullable ServletConfig servletConfig) {
|
||||||
|
|
||||||
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
this.request = (request != null ? request : new MockHttpServletRequest(servletContext));
|
this.request = (request != null ? request : new MockHttpServletRequest(servletContext));
|
||||||
|
@ -135,7 +138,7 @@ public class MockPageContext extends PageContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, Object value) {
|
public void setAttribute(String name, @Nullable Object value) {
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
this.attributes.put(name, value);
|
this.attributes.put(name, value);
|
||||||
|
@ -146,7 +149,7 @@ public class MockPageContext extends PageContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, Object value, int scope) {
|
public void setAttribute(String name, @Nullable Object value, int scope) {
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
case PAGE_SCOPE:
|
case PAGE_SCOPE:
|
||||||
|
@ -167,12 +170,14 @@ public class MockPageContext extends PageContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object getAttribute(String name) {
|
public Object getAttribute(String name) {
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
return this.attributes.get(name);
|
return this.attributes.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object getAttribute(String name, int scope) {
|
public Object getAttribute(String name, int scope) {
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
|
@ -191,6 +196,7 @@ public class MockPageContext extends PageContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object findAttribute(String name) {
|
public Object findAttribute(String name) {
|
||||||
Object value = getAttribute(name);
|
Object value = getAttribute(name);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
@ -267,7 +273,7 @@ public class MockPageContext extends PageContext {
|
||||||
return this.request.getAttributeNames();
|
return this.request.getAttributeNames();
|
||||||
case SESSION_SCOPE:
|
case SESSION_SCOPE:
|
||||||
HttpSession session = this.request.getSession(false);
|
HttpSession session = this.request.getSession(false);
|
||||||
return (session != null ? session.getAttributeNames() : null);
|
return (session != null ? session.getAttributeNames() : Collections.emptyEnumeration());
|
||||||
case APPLICATION_SCOPE:
|
case APPLICATION_SCOPE:
|
||||||
return this.servletContext.getAttributeNames();
|
return this.servletContext.getAttributeNames();
|
||||||
default:
|
default:
|
||||||
|
@ -290,12 +296,14 @@ public class MockPageContext extends PageContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public ELContext getELContext() {
|
public ELContext getELContext() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@Nullable
|
||||||
public javax.servlet.jsp.el.VariableResolver getVariableResolver() {
|
public javax.servlet.jsp.el.VariableResolver getVariableResolver() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -321,6 +329,7 @@ public class MockPageContext extends PageContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Exception getException() {
|
public Exception getException() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,15 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import javax.servlet.http.Part;
|
import javax.servlet.http.Part;
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock implementation of {@code javax.servlet.http.Part}.
|
* Mock implementation of {@code javax.servlet.http.Part}.
|
||||||
*
|
*
|
||||||
|
@ -55,7 +56,7 @@ public class MockPart implements Part {
|
||||||
/**
|
/**
|
||||||
* Constructor for a part with a filename.
|
* Constructor for a part with a filename.
|
||||||
*/
|
*/
|
||||||
public MockPart(String name, String filename, InputStream content) throws IOException {
|
public MockPart(String name, @Nullable String filename, InputStream content) throws IOException {
|
||||||
this(name, filename, FileCopyUtils.copyToByteArray(content));
|
this(name, filename, FileCopyUtils.copyToByteArray(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ public class MockPart implements Part {
|
||||||
* Constructor for a part with byte[] content only.
|
* Constructor for a part with byte[] content only.
|
||||||
* @see #getHeaders()
|
* @see #getHeaders()
|
||||||
*/
|
*/
|
||||||
private MockPart(String name, String filename, byte[] content) {
|
private MockPart(String name, @Nullable String filename, @Nullable byte[] content) {
|
||||||
Assert.hasLength(name, "Name must not be null");
|
Assert.hasLength(name, "Name must not be null");
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
|
@ -83,6 +84,7 @@ public class MockPart implements Part {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
MediaType contentType = this.headers.getContentType();
|
MediaType contentType = this.headers.getContentType();
|
||||||
return (contentType != null ? contentType.toString() : null);
|
return (contentType != null ? contentType.toString() : null);
|
||||||
|
@ -99,13 +101,15 @@ public class MockPart implements Part {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getHeader(String name) {
|
public String getHeader(String name) {
|
||||||
return this.headers.getFirst(name);
|
return this.headers.getFirst(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getHeaders(String name) {
|
public Collection<String> getHeaders(String name) {
|
||||||
return this.headers.get(name);
|
Collection<String> headerValues = this.headers.get(name);
|
||||||
|
return (headerValues != null ? headerValues : Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Map;
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +61,7 @@ public class MockServletConfig implements ServletConfig {
|
||||||
* Create a new MockServletConfig.
|
* Create a new MockServletConfig.
|
||||||
* @param servletContext the ServletContext that the servlet runs in
|
* @param servletContext the ServletContext that the servlet runs in
|
||||||
*/
|
*/
|
||||||
public MockServletConfig(ServletContext servletContext) {
|
public MockServletConfig(@Nullable ServletContext servletContext) {
|
||||||
this(servletContext, "");
|
this(servletContext, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public class MockServletConfig implements ServletConfig {
|
||||||
* @param servletContext the ServletContext that the servlet runs in
|
* @param servletContext the ServletContext that the servlet runs in
|
||||||
* @param servletName the name of the servlet
|
* @param servletName the name of the servlet
|
||||||
*/
|
*/
|
||||||
public MockServletConfig(ServletContext servletContext, String servletName) {
|
public MockServletConfig(@Nullable ServletContext servletContext, String servletName) {
|
||||||
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
this.servletName = servletName;
|
this.servletName = servletName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ public class MockServletContext implements ServletContext {
|
||||||
*/
|
*/
|
||||||
public MockServletContext(String resourceBasePath, @Nullable ResourceLoader resourceLoader) {
|
public MockServletContext(String resourceBasePath, @Nullable ResourceLoader resourceLoader) {
|
||||||
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
|
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
|
||||||
this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : "");
|
this.resourceBasePath = resourceBasePath;
|
||||||
|
|
||||||
// Use JVM temp dir as ServletContext temp dir.
|
// Use JVM temp dir as ServletContext temp dir.
|
||||||
String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY);
|
String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY);
|
||||||
|
@ -207,7 +207,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContextPath(String contextPath) {
|
public void setContextPath(String contextPath) {
|
||||||
this.contextPath = (contextPath != null ? contextPath : "");
|
this.contextPath = contextPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -287,6 +287,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Set<String> getResourcePaths(String path) {
|
public Set<String> getResourcePaths(String path) {
|
||||||
String actualPath = (path.endsWith("/") ? path : path + "/");
|
String actualPath = (path.endsWith("/") ? path : path + "/");
|
||||||
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
|
||||||
|
@ -313,6 +314,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public URL getResource(String path) throws MalformedURLException {
|
public URL getResource(String path) throws MalformedURLException {
|
||||||
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
||||||
if (!resource.exists()) {
|
if (!resource.exists()) {
|
||||||
|
@ -331,6 +333,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public InputStream getResourceAsStream(String path) {
|
public InputStream getResourceAsStream(String path) {
|
||||||
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
||||||
if (!resource.exists()) {
|
if (!resource.exists()) {
|
||||||
|
@ -410,6 +413,7 @@ public class MockServletContext implements ServletContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@Nullable
|
||||||
public Servlet getServlet(String name) {
|
public Servlet getServlet(String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -443,6 +447,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public String getRealPath(String path) {
|
public String getRealPath(String path) {
|
||||||
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
||||||
try {
|
try {
|
||||||
|
@ -486,6 +491,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object getAttribute(String name) {
|
public Object getAttribute(String name) {
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
return this.attributes.get(name);
|
return this.attributes.get(name);
|
||||||
|
@ -497,7 +503,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, Object value) {
|
public void setAttribute(String name, @Nullable Object value) {
|
||||||
Assert.notNull(name, "Attribute name must not be null");
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
this.attributes.put(name, value);
|
this.attributes.put(name, value);
|
||||||
|
@ -523,6 +529,7 @@ public class MockServletContext implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return ClassUtils.getDefaultClassLoader();
|
return ClassUtils.getDefaultClassLoader();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.springframework.web.server.WebSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock implementation of {@link ServerRequest}.
|
* Mock implementation of {@link ServerRequest}.
|
||||||
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
|
@ -70,9 +71,9 @@ public class MockServerRequest implements ServerRequest {
|
||||||
|
|
||||||
private Principal principal;
|
private Principal principal;
|
||||||
|
|
||||||
private MockServerRequest(HttpMethod method, URI uri,
|
|
||||||
MockHeaders headers, @Nullable Object body, Map<String, Object> attributes,
|
private MockServerRequest(HttpMethod method, URI uri, MockHeaders headers, @Nullable Object body,
|
||||||
MultiValueMap<String, String> queryParams,
|
Map<String, Object> attributes, MultiValueMap<String, String> queryParams,
|
||||||
Map<String, String> pathVariables, WebSession session, Principal principal) {
|
Map<String, String> pathVariables, WebSession session, Principal principal) {
|
||||||
|
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
@ -104,25 +105,29 @@ public class MockServerRequest implements ServerRequest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <S> S body(BodyExtractor<S, ? super ServerHttpRequest> extractor){
|
public <S> S body(BodyExtractor<S, ? super ServerHttpRequest> extractor) {
|
||||||
|
Assert.state(this.body != null, "No body");
|
||||||
return (S) this.body;
|
return (S) this.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <S> S body(BodyExtractor<S, ? super ServerHttpRequest> extractor, Map<String, Object> hints) {
|
public <S> S body(BodyExtractor<S, ? super ServerHttpRequest> extractor, Map<String, Object> hints) {
|
||||||
|
Assert.state(this.body != null, "No body");
|
||||||
return (S) this.body;
|
return (S) this.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <S> Mono<S> bodyToMono(Class<? extends S> elementClass) {
|
public <S> Mono<S> bodyToMono(Class<? extends S> elementClass) {
|
||||||
|
Assert.state(this.body != null, "No body");
|
||||||
return (Mono<S>) this.body;
|
return (Mono<S>) this.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <S> Flux<S> bodyToFlux(Class<? extends S> elementClass) {
|
public <S> Flux<S> bodyToFlux(Class<? extends S> elementClass) {
|
||||||
|
Assert.state(this.body != null, "No body");
|
||||||
return (Flux<S>) this.body;
|
return (Flux<S>) this.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -77,6 +77,7 @@ public abstract class ProfileValueUtils {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
profileValueSourceType = (Class<? extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType);
|
profileValueSourceType = (Class<? extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType);
|
||||||
|
Assert.state(profileValueSourceType != null, "No default ProfileValueSource class");
|
||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class [" +
|
logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class [" +
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -158,7 +158,7 @@ public @interface ContextConfiguration {
|
||||||
* @see #inheritInitializers
|
* @see #inheritInitializers
|
||||||
* @see #loader
|
* @see #loader
|
||||||
*/
|
*/
|
||||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers() default {};
|
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not {@link #locations resource locations} or <em>annotated
|
* Whether or not {@link #locations resource locations} or <em>annotated
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -58,7 +58,7 @@ public class ContextConfigurationAttributes {
|
||||||
|
|
||||||
private final boolean inheritLocations;
|
private final boolean inheritLocations;
|
||||||
|
|
||||||
private final Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers;
|
private final Class<? extends ApplicationContextInitializer<?>>[] initializers;
|
||||||
|
|
||||||
private final boolean inheritInitializers;
|
private final boolean inheritInitializers;
|
||||||
|
|
||||||
|
@ -101,9 +101,10 @@ public class ContextConfigurationAttributes {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ContextConfigurationAttributes(Class<?> declaringClass, AnnotationAttributes annAttrs) {
|
public ContextConfigurationAttributes(Class<?> declaringClass, AnnotationAttributes annAttrs) {
|
||||||
this(declaringClass, annAttrs.getStringArray("locations"), annAttrs.getClassArray("classes"), annAttrs.getBoolean("inheritLocations"),
|
this(declaringClass, annAttrs.getStringArray("locations"), annAttrs.getClassArray("classes"),
|
||||||
(Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[]) annAttrs.getClassArray("initializers"),
|
annAttrs.getBoolean("inheritLocations"),
|
||||||
annAttrs.getBoolean("inheritInitializers"), annAttrs.getString("name"), (Class<? extends ContextLoader>) annAttrs.getClass("loader"));
|
(Class<? extends ApplicationContextInitializer<?>>[]) annAttrs.getClassArray("initializers"),
|
||||||
|
annAttrs.getBoolean("inheritInitializers"), annAttrs.getString("name"), annAttrs.getClass("loader"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,7 +124,7 @@ public class ContextConfigurationAttributes {
|
||||||
*/
|
*/
|
||||||
public ContextConfigurationAttributes(
|
public ContextConfigurationAttributes(
|
||||||
Class<?> declaringClass, String[] locations, Class<?>[] classes, boolean inheritLocations,
|
Class<?> declaringClass, String[] locations, Class<?>[] classes, boolean inheritLocations,
|
||||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers,
|
Class<? extends ApplicationContextInitializer<?>>[] initializers,
|
||||||
boolean inheritInitializers, Class<? extends ContextLoader> contextLoaderClass) {
|
boolean inheritInitializers, Class<? extends ContextLoader> contextLoaderClass) {
|
||||||
|
|
||||||
this(declaringClass, locations, classes, inheritLocations, initializers, inheritInitializers, null,
|
this(declaringClass, locations, classes, inheritLocations, initializers, inheritInitializers, null,
|
||||||
|
@ -148,11 +149,11 @@ public class ContextConfigurationAttributes {
|
||||||
*/
|
*/
|
||||||
public ContextConfigurationAttributes(
|
public ContextConfigurationAttributes(
|
||||||
Class<?> declaringClass, String[] locations, Class<?>[] classes, boolean inheritLocations,
|
Class<?> declaringClass, String[] locations, Class<?>[] classes, boolean inheritLocations,
|
||||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers,
|
Class<? extends ApplicationContextInitializer<?>>[] initializers,
|
||||||
boolean inheritInitializers, String name, Class<? extends ContextLoader> contextLoaderClass) {
|
boolean inheritInitializers, @Nullable String name, Class<? extends ContextLoader> contextLoaderClass) {
|
||||||
|
|
||||||
Assert.notNull(declaringClass, "declaringClass must not be null");
|
Assert.notNull(declaringClass, "'declaringClass' must not be null");
|
||||||
Assert.notNull(contextLoaderClass, "contextLoaderClass must not be null");
|
Assert.notNull(contextLoaderClass, "'contextLoaderClass' must not be null");
|
||||||
|
|
||||||
if (!ObjectUtils.isEmpty(locations) && !ObjectUtils.isEmpty(classes) && logger.isDebugEnabled()) {
|
if (!ObjectUtils.isEmpty(locations) && !ObjectUtils.isEmpty(classes) && logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format(
|
logger.debug(String.format(
|
||||||
|
@ -199,13 +200,12 @@ public class ContextConfigurationAttributes {
|
||||||
* <p>Note: this is a mutable property. The returned value may therefore
|
* <p>Note: this is a mutable property. The returned value may therefore
|
||||||
* represent a <em>processed</em> value that does not match the original value
|
* represent a <em>processed</em> value that does not match the original value
|
||||||
* declared via {@link ContextConfiguration @ContextConfiguration}.
|
* declared via {@link ContextConfiguration @ContextConfiguration}.
|
||||||
* @return the annotated classes; potentially {@code null} or <em>empty</em>
|
* @return the annotated classes (potentially {<em>empty</em>)
|
||||||
* @see ContextConfiguration#classes
|
* @see ContextConfiguration#classes
|
||||||
* @see #setClasses(Class[])
|
* @see #setClasses(Class[])
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public Class<?>[] getClasses() {
|
public Class<?>[] getClasses() {
|
||||||
return this.classes;
|
return (this.classes != null ? this.classes : new Class<?>[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,14 +234,13 @@ public class ContextConfigurationAttributes {
|
||||||
* <p>Note: this is a mutable property. The returned value may therefore
|
* <p>Note: this is a mutable property. The returned value may therefore
|
||||||
* represent a <em>processed</em> value that does not match the original value
|
* represent a <em>processed</em> value that does not match the original value
|
||||||
* declared via {@link ContextConfiguration @ContextConfiguration}.
|
* declared via {@link ContextConfiguration @ContextConfiguration}.
|
||||||
* @return the resource locations; potentially {@code null} or <em>empty</em>
|
* @return the resource locations (potentially <em>empty</em>)
|
||||||
* @see ContextConfiguration#value
|
* @see ContextConfiguration#value
|
||||||
* @see ContextConfiguration#locations
|
* @see ContextConfiguration#locations
|
||||||
* @see #setLocations(String[])
|
* @see #setLocations
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public String[] getLocations() {
|
public String[] getLocations() {
|
||||||
return this.locations;
|
return (this.locations != null ? this.locations : new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,7 +282,7 @@ public class ContextConfigurationAttributes {
|
||||||
* @return the {@code ApplicationContextInitializer} classes
|
* @return the {@code ApplicationContextInitializer} classes
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] getInitializers() {
|
public Class<? extends ApplicationContextInitializer<?>>[] getInitializers() {
|
||||||
return this.initializers;
|
return this.initializers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -60,7 +60,7 @@ public interface ContextLoader {
|
||||||
* application context (can be {@code null} or empty)
|
* application context (can be {@code null} or empty)
|
||||||
* @return an array of application context resource locations
|
* @return an array of application context resource locations
|
||||||
*/
|
*/
|
||||||
String[] processLocations(Class<?> clazz, @Nullable String... locations);
|
String[] processLocations(Class<?> clazz, String... locations);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a new {@link ApplicationContext context} based on the supplied
|
* Loads a new {@link ApplicationContext context} based on the supplied
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -24,7 +24,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextInitializer;
|
import org.springframework.context.ApplicationContextInitializer;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
import org.springframework.core.style.ToStringCreator;
|
import org.springframework.core.style.ToStringCreator;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -73,8 +72,8 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
|
|
||||||
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
|
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
|
||||||
|
|
||||||
private static final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> EMPTY_INITIALIZER_CLASSES =
|
private static final Set<Class<? extends ApplicationContextInitializer<?>>> EMPTY_INITIALIZER_CLASSES =
|
||||||
Collections.<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> emptySet();
|
Collections.<Class<? extends ApplicationContextInitializer<?>>> emptySet();
|
||||||
|
|
||||||
private static final Set<ContextCustomizer> EMPTY_CONTEXT_CUSTOMIZERS = Collections.<ContextCustomizer> emptySet();
|
private static final Set<ContextCustomizer> EMPTY_CONTEXT_CUSTOMIZERS = Collections.<ContextCustomizer> emptySet();
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
|
|
||||||
private final Class<?>[] classes;
|
private final Class<?>[] classes;
|
||||||
|
|
||||||
private final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses;
|
private final Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses;
|
||||||
|
|
||||||
private final String[] activeProfiles;
|
private final String[] activeProfiles;
|
||||||
|
|
||||||
|
@ -102,52 +101,9 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
private final MergedContextConfiguration parent;
|
private final MergedContextConfiguration parent;
|
||||||
|
|
||||||
|
|
||||||
private static String[] processStrings(String[] array) {
|
|
||||||
return (array != null ? array : EMPTY_STRING_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Class<?>[] processClasses(Class<?>[] classes) {
|
|
||||||
return (classes != null ? classes : EMPTY_CLASS_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> processContextInitializerClasses(
|
|
||||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses) {
|
|
||||||
|
|
||||||
return (contextInitializerClasses != null ?
|
|
||||||
Collections.unmodifiableSet(contextInitializerClasses) : EMPTY_INITIALIZER_CLASSES);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<ContextCustomizer> processContextCustomizers(Set<ContextCustomizer> contextCustomizers) {
|
|
||||||
return (contextCustomizers != null ?
|
|
||||||
Collections.unmodifiableSet(contextCustomizers) : EMPTY_CONTEXT_CUSTOMIZERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] processActiveProfiles(String[] activeProfiles) {
|
|
||||||
if (activeProfiles == null) {
|
|
||||||
return EMPTY_STRING_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active profiles must be unique
|
|
||||||
Set<String> profilesSet = new LinkedHashSet<>(Arrays.asList(activeProfiles));
|
|
||||||
return StringUtils.toStringArray(profilesSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a null-safe {@link String} representation of the supplied
|
|
||||||
* {@link ContextLoader} based solely on the fully qualified name of the
|
|
||||||
* loader or "null" if the supplied loader is {@code null}.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
protected static String nullSafeToString(@Nullable ContextLoader contextLoader) {
|
|
||||||
return (contextLoader != null ? contextLoader.getClass().getName() : "null");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@code MergedContextConfiguration} instance for the
|
* Create a new {@code MergedContextConfiguration} instance for the
|
||||||
* supplied parameters.
|
* supplied parameters.
|
||||||
* <p>Delegates to
|
|
||||||
* {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
|
|
||||||
* @param testClass the test class for which the configuration was merged
|
* @param testClass the test class for which the configuration was merged
|
||||||
* @param locations the merged context resource locations
|
* @param locations the merged context resource locations
|
||||||
* @param classes the merged annotated classes
|
* @param classes the merged annotated classes
|
||||||
|
@ -163,18 +119,15 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Create a new {@code MergedContextConfiguration} instance for the
|
* Create a new {@code MergedContextConfiguration} instance for the
|
||||||
* supplied parameters.
|
* supplied parameters.
|
||||||
* <p>Delegates to
|
|
||||||
* {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
|
|
||||||
* @param testClass the test class for which the configuration was merged
|
* @param testClass the test class for which the configuration was merged
|
||||||
* @param locations the merged context resource locations
|
* @param locations the merged context resource locations
|
||||||
* @param classes the merged annotated classes
|
* @param classes the merged annotated classes
|
||||||
* @param contextInitializerClasses the merged context initializer classes
|
* @param contextInitializerClasses the merged context initializer classes
|
||||||
* @param activeProfiles the merged active bean definition profiles
|
* @param activeProfiles the merged active bean definition profiles
|
||||||
* @param contextLoader the resolved {@code ContextLoader}
|
* @param contextLoader the resolved {@code ContextLoader}
|
||||||
* @see #MergedContextConfiguration(Class, String[], Class[], Set, String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)
|
|
||||||
*/
|
*/
|
||||||
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
|
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
|
||||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses,
|
||||||
String[] activeProfiles, ContextLoader contextLoader) {
|
String[] activeProfiles, ContextLoader contextLoader) {
|
||||||
|
|
||||||
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, contextLoader, null, null);
|
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, contextLoader, null, null);
|
||||||
|
@ -183,8 +136,6 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Create a new {@code MergedContextConfiguration} instance for the
|
* Create a new {@code MergedContextConfiguration} instance for the
|
||||||
* supplied parameters.
|
* supplied parameters.
|
||||||
* <p>Delegates to
|
|
||||||
* {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
|
|
||||||
* @param testClass the test class for which the configuration was merged
|
* @param testClass the test class for which the configuration was merged
|
||||||
* @param locations the merged context resource locations
|
* @param locations the merged context resource locations
|
||||||
* @param classes the merged annotated classes
|
* @param classes the merged annotated classes
|
||||||
|
@ -197,12 +148,13 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
* @since 3.2.2
|
* @since 3.2.2
|
||||||
*/
|
*/
|
||||||
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
|
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
|
||||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses,
|
||||||
String[] activeProfiles, ContextLoader contextLoader,
|
String[] activeProfiles, ContextLoader contextLoader,
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
|
@Nullable CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
|
||||||
|
@Nullable MergedContextConfiguration parent) {
|
||||||
|
|
||||||
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, null, null, contextLoader,
|
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, null, null,
|
||||||
cacheAwareContextLoaderDelegate, parent);
|
contextLoader, cacheAwareContextLoaderDelegate, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,9 +164,9 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
*/
|
*/
|
||||||
public MergedContextConfiguration(MergedContextConfiguration mergedConfig) {
|
public MergedContextConfiguration(MergedContextConfiguration mergedConfig) {
|
||||||
this(mergedConfig.testClass, mergedConfig.locations, mergedConfig.classes,
|
this(mergedConfig.testClass, mergedConfig.locations, mergedConfig.classes,
|
||||||
mergedConfig.contextInitializerClasses, mergedConfig.activeProfiles, mergedConfig.propertySourceLocations,
|
mergedConfig.contextInitializerClasses, mergedConfig.activeProfiles, mergedConfig.propertySourceLocations,
|
||||||
mergedConfig.propertySourceProperties, mergedConfig.contextCustomizers,
|
mergedConfig.propertySourceProperties, mergedConfig.contextCustomizers,
|
||||||
mergedConfig.contextLoader, mergedConfig.cacheAwareContextLoaderDelegate, mergedConfig.parent);
|
mergedConfig.contextLoader, mergedConfig.cacheAwareContextLoaderDelegate, mergedConfig.parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,10 +193,12 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public MergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
public MergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
||||||
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses,
|
||||||
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
|
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations,
|
||||||
ContextLoader contextLoader, CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
|
@Nullable String[] propertySourceProperties, ContextLoader contextLoader,
|
||||||
|
@Nullable CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
|
||||||
@Nullable MergedContextConfiguration parent) {
|
@Nullable MergedContextConfiguration parent) {
|
||||||
|
|
||||||
this(testClass, locations, classes, contextInitializerClasses, activeProfiles,
|
this(testClass, locations, classes, contextInitializerClasses, activeProfiles,
|
||||||
propertySourceLocations, propertySourceProperties,
|
propertySourceLocations, propertySourceProperties,
|
||||||
EMPTY_CONTEXT_CUSTOMIZERS, contextLoader,
|
EMPTY_CONTEXT_CUSTOMIZERS, contextLoader,
|
||||||
|
@ -276,10 +230,11 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
public MergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
public MergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
||||||
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses,
|
||||||
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
|
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations,
|
||||||
@Nullable Set<ContextCustomizer> contextCustomizers, ContextLoader contextLoader,
|
@Nullable String[] propertySourceProperties, @Nullable Set<ContextCustomizer> contextCustomizers,
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
|
ContextLoader contextLoader, @Nullable CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
|
||||||
|
@Nullable MergedContextConfiguration parent) {
|
||||||
|
|
||||||
this.testClass = testClass;
|
this.testClass = testClass;
|
||||||
this.locations = processStrings(locations);
|
this.locations = processStrings(locations);
|
||||||
|
@ -361,7 +316,7 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
* Get the merged {@code ApplicationContextInitializer} classes for the
|
* Get the merged {@code ApplicationContextInitializer} classes for the
|
||||||
* {@linkplain #getTestClass() test class}.
|
* {@linkplain #getTestClass() test class}.
|
||||||
*/
|
*/
|
||||||
public Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> getContextInitializerClasses() {
|
public Set<Class<? extends ApplicationContextInitializer<?>>> getContextInitializerClasses() {
|
||||||
return this.contextInitializerClasses;
|
return this.contextInitializerClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +410,7 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
* {@link #getContextLoader() ContextLoaders}.
|
* {@link #getContextLoader() ContextLoaders}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(@Nullable Object other) {
|
||||||
if (this == other) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -495,7 +450,7 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nullSafeToString(this.contextLoader).equals(nullSafeToString(otherConfig.contextLoader))) {
|
if (!nullSafeClassName(this.contextLoader).equals(nullSafeClassName(otherConfig.contextLoader))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +472,7 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
result = 31 * result + Arrays.hashCode(this.propertySourceProperties);
|
result = 31 * result + Arrays.hashCode(this.propertySourceProperties);
|
||||||
result = 31 * result + this.contextCustomizers.hashCode();
|
result = 31 * result + this.contextCustomizers.hashCode();
|
||||||
result = 31 * result + (this.parent != null ? this.parent.hashCode() : 0);
|
result = 31 * result + (this.parent != null ? this.parent.hashCode() : 0);
|
||||||
result = 31 * result + nullSafeToString(this.contextLoader).hashCode();
|
result = 31 * result + nullSafeClassName(this.contextLoader).hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,9 +498,51 @@ public class MergedContextConfiguration implements Serializable {
|
||||||
.append("propertySourceLocations", ObjectUtils.nullSafeToString(this.propertySourceLocations))
|
.append("propertySourceLocations", ObjectUtils.nullSafeToString(this.propertySourceLocations))
|
||||||
.append("propertySourceProperties", ObjectUtils.nullSafeToString(this.propertySourceProperties))
|
.append("propertySourceProperties", ObjectUtils.nullSafeToString(this.propertySourceProperties))
|
||||||
.append("contextCustomizers", this.contextCustomizers)
|
.append("contextCustomizers", this.contextCustomizers)
|
||||||
.append("contextLoader", nullSafeToString(this.contextLoader))
|
.append("contextLoader", nullSafeClassName(this.contextLoader))
|
||||||
.append("parent", this.parent)
|
.append("parent", this.parent)
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static String[] processStrings(@Nullable String[] array) {
|
||||||
|
return (array != null ? array : EMPTY_STRING_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?>[] processClasses(@Nullable Class<?>[] classes) {
|
||||||
|
return (classes != null ? classes : EMPTY_CLASS_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<Class<? extends ApplicationContextInitializer<?>>> processContextInitializerClasses(
|
||||||
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses) {
|
||||||
|
|
||||||
|
return (contextInitializerClasses != null ?
|
||||||
|
Collections.unmodifiableSet(contextInitializerClasses) : EMPTY_INITIALIZER_CLASSES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<ContextCustomizer> processContextCustomizers(
|
||||||
|
@Nullable Set<ContextCustomizer> contextCustomizers) {
|
||||||
|
|
||||||
|
return (contextCustomizers != null ?
|
||||||
|
Collections.unmodifiableSet(contextCustomizers) : EMPTY_CONTEXT_CUSTOMIZERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] processActiveProfiles(@Nullable String[] activeProfiles) {
|
||||||
|
if (activeProfiles == null) {
|
||||||
|
return EMPTY_STRING_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active profiles must be unique
|
||||||
|
Set<String> profilesSet = new LinkedHashSet<>(Arrays.asList(activeProfiles));
|
||||||
|
return StringUtils.toStringArray(profilesSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a null-safe {@link String} representation of the supplied
|
||||||
|
* {@link ContextLoader} based solely on the fully qualified name of the
|
||||||
|
* loader or "null" if the supplied loader is {@code null}.
|
||||||
|
*/
|
||||||
|
protected static String nullSafeClassName(@Nullable ContextLoader contextLoader) {
|
||||||
|
return (contextLoader != null ? contextLoader.getClass().getName() : "null");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -65,24 +65,21 @@ public interface TestContext extends AttributeAccessor, Serializable {
|
||||||
* @return the current test instance (may be {@code null})
|
* @return the current test instance (may be {@code null})
|
||||||
* @see #updateState(Object, Method, Throwable)
|
* @see #updateState(Object, Method, Throwable)
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
Object getTestInstance();
|
Object getTestInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current {@linkplain Method test method} for this test context.
|
* Get the current {@linkplain Method test method} for this test context.
|
||||||
* <p>Note: this is a mutable property.
|
* <p>Note: this is a mutable property.
|
||||||
* @return the current test method (may be {@code null})
|
* @return the current test method
|
||||||
* @see #updateState(Object, Method, Throwable)
|
* @see #updateState(Object, Method, Throwable)
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
Method getTestMethod();
|
Method getTestMethod();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@linkplain Throwable exception} that was thrown during execution
|
* Get the {@linkplain Throwable exception} that was thrown during execution
|
||||||
* of the {@linkplain #getTestMethod() test method}.
|
* of the {@linkplain #getTestMethod() test method}.
|
||||||
* <p>Note: this is a mutable property.
|
* <p>Note: this is a mutable property.
|
||||||
* @return the exception that was thrown, or {@code null} if no
|
* @return the exception that was thrown, or {@code null} if no exception was thrown
|
||||||
* exception was thrown
|
|
||||||
* @see #updateState(Object, Method, Throwable)
|
* @see #updateState(Object, Method, Throwable)
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -101,14 +98,13 @@ public interface TestContext extends AttributeAccessor, Serializable {
|
||||||
void markApplicationContextDirty(@Nullable HierarchyMode hierarchyMode);
|
void markApplicationContextDirty(@Nullable HierarchyMode hierarchyMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this test context to reflect the state of the currently executing
|
* Update this test context to reflect the state of the currently executing test.
|
||||||
* test.
|
|
||||||
* <p>Caution: concurrent invocations of this method might not be thread-safe,
|
* <p>Caution: concurrent invocations of this method might not be thread-safe,
|
||||||
* depending on the underlying implementation.
|
* depending on the underlying implementation.
|
||||||
* @param testInstance the current test instance (may be {@code null})
|
* @param testInstance the current test instance (may be {@code null})
|
||||||
* @param testMethod the current test method (may be {@code null})
|
* @param testMethod the current test method (may be {@code null})
|
||||||
* @param testException the exception that was thrown in the test method, or
|
* @param testException the exception that was thrown in the test method,
|
||||||
* {@code null} if no exception was thrown
|
* or {@code null} if no exception was thrown
|
||||||
*/
|
*/
|
||||||
void updateState(@Nullable Object testInstance, @Nullable Method testMethod, @Nullable Throwable testException);
|
void updateState(@Nullable Object testInstance, @Nullable Method testMethod, @Nullable Throwable testException);
|
||||||
|
|
||||||
|
|
|
@ -233,7 +233,6 @@ public class TestContextManager {
|
||||||
* @see #getTestExecutionListeners()
|
* @see #getTestExecutionListeners()
|
||||||
*/
|
*/
|
||||||
public void prepareTestInstance(Object testInstance) throws Exception {
|
public void prepareTestInstance(Object testInstance) throws Exception {
|
||||||
Assert.notNull(testInstance, "Test instance must not be null");
|
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("prepareTestInstance(): instance [" + testInstance + "]");
|
logger.trace("prepareTestInstance(): instance [" + testInstance + "]");
|
||||||
}
|
}
|
||||||
|
@ -501,7 +500,6 @@ public class TestContextManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareForBeforeCallback(String callbackName, Object testInstance, Method testMethod) {
|
private void prepareForBeforeCallback(String callbackName, Object testInstance, Method testMethod) {
|
||||||
Assert.notNull(testInstance, "Test instance must not be null");
|
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("%s(): instance [%s], method [%s]", callbackName, testInstance, testMethod));
|
logger.trace(String.format("%s(): instance [%s], method [%s]", callbackName, testInstance, testMethod));
|
||||||
}
|
}
|
||||||
|
@ -509,8 +507,8 @@ public class TestContextManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareForAfterCallback(String callbackName, Object testInstance, Method testMethod,
|
private void prepareForAfterCallback(String callbackName, Object testInstance, Method testMethod,
|
||||||
Throwable exception) {
|
@Nullable Throwable exception) {
|
||||||
Assert.notNull(testInstance, "Test instance must not be null");
|
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("%s(): instance [%s], method [%s], exception [%s]", callbackName, testInstance,
|
logger.trace(String.format("%s(): instance [%s], method [%s], exception [%s]", callbackName, testInstance,
|
||||||
testMethod, exception));
|
testMethod, exception));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -160,12 +160,14 @@ public class DefaultContextCache implements ContextCache {
|
||||||
public void remove(MergedContextConfiguration key, @Nullable HierarchyMode hierarchyMode) {
|
public void remove(MergedContextConfiguration key, @Nullable HierarchyMode hierarchyMode) {
|
||||||
Assert.notNull(key, "Key must not be null");
|
Assert.notNull(key, "Key must not be null");
|
||||||
|
|
||||||
// startKey is the level at which to begin clearing the cache, depending
|
// startKey is the level at which to begin clearing the cache,
|
||||||
// on the configured hierarchy mode.
|
// depending on the configured hierarchy mode.s
|
||||||
MergedContextConfiguration startKey = key;
|
MergedContextConfiguration startKey = key;
|
||||||
if (hierarchyMode == HierarchyMode.EXHAUSTIVE) {
|
if (hierarchyMode == HierarchyMode.EXHAUSTIVE) {
|
||||||
while (startKey.getParent() != null) {
|
MergedContextConfiguration parent = startKey.getParent();
|
||||||
startKey = startKey.getParent();
|
while (parent != null) {
|
||||||
|
startKey = parent;
|
||||||
|
parent = startKey.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -23,7 +23,6 @@ import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
|
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
|
||||||
import org.junit.jupiter.api.extension.ContainerExecutionCondition;
|
import org.junit.jupiter.api.extension.ContainerExecutionCondition;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
@ -142,7 +141,8 @@ abstract class AbstractExpressionEvaluatingCondition implements ContainerExecuti
|
||||||
|
|
||||||
if (loadContext) {
|
if (loadContext) {
|
||||||
applicationContext = SpringExtension.getApplicationContext(extensionContext);
|
applicationContext = SpringExtension.getApplicationContext(extensionContext);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
gac = new GenericApplicationContext();
|
gac = new GenericApplicationContext();
|
||||||
gac.refresh();
|
gac.refresh();
|
||||||
applicationContext = gac;
|
applicationContext = gac;
|
||||||
|
@ -150,7 +150,7 @@ abstract class AbstractExpressionEvaluatingCondition implements ContainerExecuti
|
||||||
|
|
||||||
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
|
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
String contextType = (applicationContext != null ? applicationContext.getClass().getName() : "null");
|
String contextType = applicationContext.getClass().getName();
|
||||||
logger.warn(String.format("@%s(\"%s\") could not be evaluated on [%s] since the test " +
|
logger.warn(String.format("@%s(\"%s\") could not be evaluated on [%s] since the test " +
|
||||||
"ApplicationContext [%s] is not a ConfigurableApplicationContext",
|
"ApplicationContext [%s] is not a ConfigurableApplicationContext",
|
||||||
annotationType.getSimpleName(), expression, element, contextType));
|
annotationType.getSimpleName(), expression, element, contextType));
|
||||||
|
@ -160,17 +160,18 @@ abstract class AbstractExpressionEvaluatingCondition implements ContainerExecuti
|
||||||
|
|
||||||
ConfigurableBeanFactory configurableBeanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
|
ConfigurableBeanFactory configurableBeanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
|
||||||
BeanExpressionResolver expressionResolver = configurableBeanFactory.getBeanExpressionResolver();
|
BeanExpressionResolver expressionResolver = configurableBeanFactory.getBeanExpressionResolver();
|
||||||
|
Assert.state(expressionResolver != null, "No BeanExpressionResolver");
|
||||||
BeanExpressionContext beanExpressionContext = new BeanExpressionContext(configurableBeanFactory, null);
|
BeanExpressionContext beanExpressionContext = new BeanExpressionContext(configurableBeanFactory, null);
|
||||||
|
|
||||||
Object result = expressionResolver.evaluate(configurableBeanFactory.resolveEmbeddedValue(expression),
|
Object result = expressionResolver.evaluate(
|
||||||
beanExpressionContext);
|
configurableBeanFactory.resolveEmbeddedValue(expression), beanExpressionContext);
|
||||||
|
|
||||||
if (gac != null) {
|
if (gac != null) {
|
||||||
gac.close();
|
gac.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result instanceof Boolean) {
|
if (result instanceof Boolean) {
|
||||||
return ((Boolean) result).booleanValue();
|
return (Boolean) result;
|
||||||
}
|
}
|
||||||
else if (result instanceof String) {
|
else if (result instanceof String) {
|
||||||
String str = ((String) result).trim().toLowerCase();
|
String str = ((String) result).trim().toLowerCase();
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.test.context.TestContextManager;
|
import org.springframework.test.context.TestContextManager;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -168,6 +169,7 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
|
||||||
* @see ParameterAutowireUtils#resolveDependency
|
* @see ParameterAutowireUtils#resolveDependency
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) {
|
public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||||
Parameter parameter = parameterContext.getParameter();
|
Parameter parameter = parameterContext.getParameter();
|
||||||
Class<?> testClass = extensionContext.getTestClass().get();
|
Class<?> testClass = extensionContext.getTestClass().get();
|
||||||
|
|
|
@ -73,7 +73,7 @@ public @interface SpringJUnitConfig {
|
||||||
* Alias for {@link ContextConfiguration#initializers}.
|
* Alias for {@link ContextConfiguration#initializers}.
|
||||||
*/
|
*/
|
||||||
@AliasFor(annotation = ContextConfiguration.class)
|
@AliasFor(annotation = ContextConfiguration.class)
|
||||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers() default {};
|
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias for {@link ContextConfiguration#inheritLocations}.
|
* Alias for {@link ContextConfiguration#inheritLocations}.
|
||||||
|
|
|
@ -78,7 +78,7 @@ public @interface SpringJUnitWebConfig {
|
||||||
* Alias for {@link ContextConfiguration#initializers}.
|
* Alias for {@link ContextConfiguration#initializers}.
|
||||||
*/
|
*/
|
||||||
@AliasFor(annotation = ContextConfiguration.class)
|
@AliasFor(annotation = ContextConfiguration.class)
|
||||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers() default {};
|
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias for {@link ContextConfiguration#inheritLocations}.
|
* Alias for {@link ContextConfiguration#inheritLocations}.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -31,6 +31,7 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi
|
||||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract {@linkplain Transactional transactional} extension of
|
* Abstract {@linkplain Transactional transactional} extension of
|
||||||
|
@ -201,8 +202,10 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst
|
||||||
* @see #setSqlScriptEncoding
|
* @see #setSqlScriptEncoding
|
||||||
*/
|
*/
|
||||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||||
|
DataSource ds = this.jdbcTemplate.getDataSource();
|
||||||
|
Assert.state(ds != null, "No DataSource set");
|
||||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||||
new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(jdbcTemplate.getDataSource());
|
new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -22,7 +22,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.internal.runners.model.ReflectiveCallable;
|
import org.junit.internal.runners.model.ReflectiveCallable;
|
||||||
|
@ -107,7 +106,7 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||||
|
|
||||||
withRulesMethod = ReflectionUtils.findMethod(SpringJUnit4ClassRunner.class, "withRules",
|
withRulesMethod = ReflectionUtils.findMethod(SpringJUnit4ClassRunner.class, "withRules",
|
||||||
FrameworkMethod.class, Object.class, Statement.class);
|
FrameworkMethod.class, Object.class, Statement.class);
|
||||||
Assert.state(withRulesMethod != null, "SpringJUnit4ClassRunner requires JUnit 4.12 or higher.");
|
Assert.state(withRulesMethod != null, "SpringJUnit4ClassRunner requires JUnit 4.12 or higher");
|
||||||
ReflectionUtils.makeAccessible(withRulesMethod);
|
ReflectionUtils.makeAccessible(withRulesMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +309,9 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
|
||||||
* Invoke JUnit's private {@code withRules()} method using reflection.
|
* Invoke JUnit's private {@code withRules()} method using reflection.
|
||||||
*/
|
*/
|
||||||
private Statement withRulesReflectively(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
|
private Statement withRulesReflectively(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
|
||||||
return (Statement) ReflectionUtils.invokeMethod(withRulesMethod, this, frameworkMethod, testInstance, statement);
|
Object result = ReflectionUtils.invokeMethod(withRulesMethod, this, frameworkMethod, testInstance, statement);
|
||||||
|
Assert.state(result instanceof Statement, "withRules mismatch");
|
||||||
|
return (Statement) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -23,7 +23,6 @@ import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.rules.MethodRule;
|
import org.junit.rules.MethodRule;
|
||||||
import org.junit.runners.model.FrameworkMethod;
|
import org.junit.runners.model.FrameworkMethod;
|
||||||
|
@ -233,7 +232,9 @@ public class SpringMethodRule implements MethodRule {
|
||||||
"SpringClassRule field [%s] must be annotated with JUnit's @ClassRule annotation. " +
|
"SpringClassRule field [%s] must be annotated with JUnit's @ClassRule annotation. " +
|
||||||
"Consult the javadoc for SpringClassRule for details.", ruleField));
|
"Consult the javadoc for SpringClassRule for details.", ruleField));
|
||||||
|
|
||||||
return (SpringClassRule) ReflectionUtils.getField(ruleField, null);
|
Object result = ReflectionUtils.getField(ruleField, null);
|
||||||
|
Assert.state(result instanceof SpringClassRule, "SpringClassRule field mismatch");
|
||||||
|
return (SpringClassRule) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<Field> findSpringClassRuleField(Class<?> testClass) {
|
private static Optional<Field> findSpringClassRuleField(Class<?> testClass) {
|
||||||
|
|
|
@ -91,7 +91,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
||||||
* @see #processLocations(Class, String...)
|
* @see #processLocations(Class, String...)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void processContextConfiguration(@Nullable ContextConfigurationAttributes configAttributes) {
|
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
|
||||||
String[] processedLocations =
|
String[] processedLocations =
|
||||||
processLocations(configAttributes.getDeclaringClass(), configAttributes.getLocations());
|
processLocations(configAttributes.getDeclaringClass(), configAttributes.getLocations());
|
||||||
configAttributes.setLocations(processedLocations);
|
configAttributes.setLocations(processedLocations);
|
||||||
|
@ -143,7 +143,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
||||||
private void invokeApplicationContextInitializers(ConfigurableApplicationContext context,
|
private void invokeApplicationContextInitializers(ConfigurableApplicationContext context,
|
||||||
MergedContextConfiguration mergedConfig) {
|
MergedContextConfiguration mergedConfig) {
|
||||||
|
|
||||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses =
|
Set<Class<? extends ApplicationContextInitializer<?>>> initializerClasses =
|
||||||
mergedConfig.getContextInitializerClasses();
|
mergedConfig.getContextInitializerClasses();
|
||||||
if (initializerClasses.isEmpty()) {
|
if (initializerClasses.isEmpty()) {
|
||||||
// no ApplicationContextInitializers have been declared -> nothing to do
|
// no ApplicationContextInitializers have been declared -> nothing to do
|
||||||
|
@ -153,7 +153,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
||||||
List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances = new ArrayList<>();
|
List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances = new ArrayList<>();
|
||||||
Class<?> contextClass = context.getClass();
|
Class<?> contextClass = context.getClass();
|
||||||
|
|
||||||
for (Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>> initializerClass : initializerClasses) {
|
for (Class<? extends ApplicationContextInitializer<?>> initializerClass : initializerClasses) {
|
||||||
Class<?> initializerContextClass =
|
Class<?> initializerContextClass =
|
||||||
GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
|
GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
|
||||||
if (initializerContextClass != null && !initializerContextClass.isInstance(context)) {
|
if (initializerContextClass != null && !initializerContextClass.isInstance(context)) {
|
||||||
|
@ -213,7 +213,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
||||||
* @see #processContextConfiguration(ContextConfigurationAttributes)
|
* @see #processContextConfiguration(ContextConfigurationAttributes)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final String[] processLocations(Class<?> clazz, @Nullable String... locations) {
|
public final String[] processLocations(Class<?> clazz, String... locations) {
|
||||||
return (ObjectUtils.isEmpty(locations) && isGenerateDefaultLocations()) ?
|
return (ObjectUtils.isEmpty(locations) && isGenerateDefaultLocations()) ?
|
||||||
generateDefaultLocations(clazz) : modifyLocations(clazz, locations);
|
generateDefaultLocations(clazz) : modifyLocations(clazz, locations);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -300,6 +300,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the last level in the context hierarchy
|
// Return the last level in the context hierarchy
|
||||||
|
Assert.state(mergedConfig != null, "No merged context configuration");
|
||||||
return mergedConfig;
|
return mergedConfig;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -462,7 +463,6 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
||||||
Class<? extends ContextLoader> contextLoaderClass = resolveExplicitContextLoaderClass(configAttributesList);
|
Class<? extends ContextLoader> contextLoaderClass = resolveExplicitContextLoaderClass(configAttributesList);
|
||||||
if (contextLoaderClass == null) {
|
if (contextLoaderClass == null) {
|
||||||
contextLoaderClass = getDefaultContextLoaderClass(testClass);
|
contextLoaderClass = getDefaultContextLoaderClass(testClass);
|
||||||
Assert.state(contextLoaderClass != null, "getDefaultContextLoaderClass() must not return null");
|
|
||||||
}
|
}
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Using ContextLoader class [%s] for test class [%s]",
|
logger.trace(String.format("Using ContextLoader class [%s] for test class [%s]",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -31,6 +31,7 @@ import org.springframework.test.context.ActiveProfilesResolver;
|
||||||
import org.springframework.test.util.MetaAnnotationUtils;
|
import org.springframework.test.util.MetaAnnotationUtils;
|
||||||
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
|
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,16 +108,10 @@ abstract class ActiveProfilesUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] profiles = resolver.resolve(rootDeclaringClass);
|
String[] profiles = resolver.resolve(rootDeclaringClass);
|
||||||
if (profiles == null) {
|
if (!ObjectUtils.isEmpty(profiles)) {
|
||||||
String msg = String.format(
|
profileArrays.add(profiles);
|
||||||
"ActiveProfilesResolver [%s] returned a null array of bean definition profiles",
|
|
||||||
resolverClass.getName());
|
|
||||||
logger.error(msg);
|
|
||||||
throw new IllegalStateException(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
profileArrays.add(profiles);
|
|
||||||
|
|
||||||
descriptor = (annotation.inheritProfiles() ? MetaAnnotationUtils.findAnnotationDescriptor(
|
descriptor = (annotation.inheritProfiles() ? MetaAnnotationUtils.findAnnotationDescriptor(
|
||||||
rootDeclaringClass.getSuperclass(), annotationType) : null);
|
rootDeclaringClass.getSuperclass(), annotationType) : null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -22,7 +22,6 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||||
import org.springframework.context.support.GenericApplicationContext;
|
import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||||
import org.springframework.test.context.MergedContextConfiguration;
|
import org.springframework.test.context.MergedContextConfiguration;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
@ -79,7 +78,7 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader
|
||||||
* @see #detectDefaultConfigurationClasses(Class)
|
* @see #detectDefaultConfigurationClasses(Class)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void processContextConfiguration(@Nullable ContextConfigurationAttributes configAttributes) {
|
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
|
||||||
if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
|
if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
|
||||||
configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
|
configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.test.context.SmartContextLoader;
|
import org.springframework.test.context.SmartContextLoader;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ public abstract class AnnotationConfigContextLoaderUtils {
|
||||||
* @param clazz the class to check
|
* @param clazz the class to check
|
||||||
* @return {@code true} if the supplied class meets the candidate criteria
|
* @return {@code true} if the supplied class meets the candidate criteria
|
||||||
*/
|
*/
|
||||||
private static boolean isDefaultConfigurationClassCandidate(Class<?> clazz) {
|
private static boolean isDefaultConfigurationClassCandidate(@Nullable Class<?> clazz) {
|
||||||
return (clazz != null && isStaticNonPrivateAndNonFinal(clazz) &&
|
return (clazz != null && isStaticNonPrivateAndNonFinal(clazz) &&
|
||||||
AnnotatedElementUtils.hasAnnotation(clazz, Configuration.class));
|
AnnotatedElementUtils.hasAnnotation(clazz, Configuration.class));
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,11 @@ abstract class ApplicationContextInitializerUtils {
|
||||||
* superclasses if appropriate (never {@code null})
|
* superclasses if appropriate (never {@code null})
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
static Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> resolveInitializerClasses(
|
static Set<Class<? extends ApplicationContextInitializer<?>>> resolveInitializerClasses(
|
||||||
List<ContextConfigurationAttributes> configAttributesList) {
|
List<ContextConfigurationAttributes> configAttributesList) {
|
||||||
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
|
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
|
||||||
|
|
||||||
final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses = //
|
final Set<Class<? extends ApplicationContextInitializer<?>>> initializerClasses = //
|
||||||
new HashSet<>();
|
new HashSet<>();
|
||||||
|
|
||||||
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -130,9 +130,11 @@ abstract class ContextLoaderUtils {
|
||||||
}
|
}
|
||||||
else if (contextHierarchyDeclaredLocally) {
|
else if (contextHierarchyDeclaredLocally) {
|
||||||
ContextHierarchy contextHierarchy = getAnnotation(declaringClass, contextHierarchyType);
|
ContextHierarchy contextHierarchy = getAnnotation(declaringClass, contextHierarchyType);
|
||||||
for (ContextConfiguration contextConfiguration : contextHierarchy.value()) {
|
if (contextHierarchy != null) {
|
||||||
convertContextConfigToConfigAttributesAndAddToList(
|
for (ContextConfiguration contextConfiguration : contextHierarchy.value()) {
|
||||||
contextConfiguration, rootDeclaringClass, configAttributesList);
|
convertContextConfigToConfigAttributesAndAddToList(
|
||||||
|
contextConfiguration, rootDeclaringClass, configAttributesList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -74,15 +74,16 @@ public class DefaultTestContext implements TestContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new {@code DefaultTestContext} from the supplied arguments.
|
* Construct a new {@code DefaultTestContext} from the supplied arguments.
|
||||||
* @param testClass the test class for this test context; never {@code null}
|
* @param testClass the test class for this test context
|
||||||
* @param mergedContextConfiguration the merged application context
|
* @param mergedContextConfiguration the merged application context
|
||||||
* configuration for this test context; never {@code null}
|
* configuration for this test context
|
||||||
* @param cacheAwareContextLoaderDelegate the delegate to use for loading
|
* @param cacheAwareContextLoaderDelegate the delegate to use for loading
|
||||||
* and closing the application context for this test context; never {@code null}
|
* and closing the application context for this test context
|
||||||
*/
|
*/
|
||||||
public DefaultTestContext(Class<?> testClass, MergedContextConfiguration mergedContextConfiguration,
|
public DefaultTestContext(Class<?> testClass, MergedContextConfiguration mergedContextConfiguration,
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) {
|
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) {
|
||||||
Assert.notNull(testClass, "testClass must not be null");
|
|
||||||
|
Assert.notNull(testClass, "Test Class must not be null");
|
||||||
Assert.notNull(mergedContextConfiguration, "MergedContextConfiguration must not be null");
|
Assert.notNull(mergedContextConfiguration, "MergedContextConfiguration must not be null");
|
||||||
Assert.notNull(cacheAwareContextLoaderDelegate, "CacheAwareContextLoaderDelegate must not be null");
|
Assert.notNull(cacheAwareContextLoaderDelegate, "CacheAwareContextLoaderDelegate must not be null");
|
||||||
this.testClass = testClass;
|
this.testClass = testClass;
|
||||||
|
@ -132,10 +133,12 @@ public class DefaultTestContext implements TestContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Object getTestInstance() {
|
public final Object getTestInstance() {
|
||||||
|
Assert.state(this.testInstance != null, "No test instance");
|
||||||
return this.testInstance;
|
return this.testInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Method getTestMethod() {
|
public final Method getTestMethod() {
|
||||||
|
Assert.state(this.testMethod != null, "No test method");
|
||||||
return this.testMethod;
|
return this.testMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -73,12 +73,11 @@ class TestPropertySourceAttributes {
|
||||||
|
|
||||||
private TestPropertySourceAttributes(Class<?> declaringClass, String[] locations, boolean inheritLocations,
|
private TestPropertySourceAttributes(Class<?> declaringClass, String[] locations, boolean inheritLocations,
|
||||||
String[] properties, boolean inheritProperties) {
|
String[] properties, boolean inheritProperties) {
|
||||||
Assert.notNull(declaringClass, "declaringClass must not be null");
|
|
||||||
|
|
||||||
|
Assert.notNull(declaringClass, "declaringClass must not be null");
|
||||||
if (ObjectUtils.isEmpty(locations) && ObjectUtils.isEmpty(properties)) {
|
if (ObjectUtils.isEmpty(locations) && ObjectUtils.isEmpty(properties)) {
|
||||||
locations = new String[] { detectDefaultPropertiesFile(declaringClass) };
|
locations = new String[] { detectDefaultPropertiesFile(declaringClass) };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.declaringClass = declaringClass;
|
this.declaringClass = declaringClass;
|
||||||
this.locations = locations;
|
this.locations = locations;
|
||||||
this.inheritLocations = inheritLocations;
|
this.inheritLocations = inheritLocations;
|
||||||
|
@ -86,44 +85,38 @@ class TestPropertySourceAttributes {
|
||||||
this.inheritProperties = inheritProperties;
|
this.inheritProperties = inheritProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@linkplain Class class} that declared {@code @TestPropertySource}.
|
* Get the {@linkplain Class class} that declared {@code @TestPropertySource}.
|
||||||
*
|
|
||||||
* @return the declaring class; never {@code null}
|
* @return the declaring class; never {@code null}
|
||||||
*/
|
*/
|
||||||
Class<?> getDeclaringClass() {
|
Class<?> getDeclaringClass() {
|
||||||
return declaringClass;
|
return this.declaringClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the resource locations that were declared via {@code @TestPropertySource}.
|
* Get the resource locations that were declared via {@code @TestPropertySource}.
|
||||||
*
|
|
||||||
* <p>Note: The returned value may represent a <em>detected default</em>
|
* <p>Note: The returned value may represent a <em>detected default</em>
|
||||||
* that does not match the original value declared via {@code @TestPropertySource}.
|
* that does not match the original value declared via {@code @TestPropertySource}.
|
||||||
*
|
* @return the resource locations; potentially <em>empty</em>
|
||||||
* @return the resource locations; potentially {@code null} or <em>empty</em>
|
|
||||||
* @see TestPropertySource#value
|
* @see TestPropertySource#value
|
||||||
* @see TestPropertySource#locations
|
* @see TestPropertySource#locations
|
||||||
* @see #setLocations(String[])
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
String[] getLocations() {
|
String[] getLocations() {
|
||||||
return locations;
|
return this.locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@code inheritLocations} flag that was declared via {@code @TestPropertySource}.
|
* Get the {@code inheritLocations} flag that was declared via {@code @TestPropertySource}.
|
||||||
*
|
|
||||||
* @return the {@code inheritLocations} flag
|
* @return the {@code inheritLocations} flag
|
||||||
* @see TestPropertySource#inheritLocations
|
* @see TestPropertySource#inheritLocations
|
||||||
*/
|
*/
|
||||||
boolean isInheritLocations() {
|
boolean isInheritLocations() {
|
||||||
return inheritLocations;
|
return this.inheritLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the inlined properties that were declared via {@code @TestPropertySource}.
|
* Get the inlined properties that were declared via {@code @TestPropertySource}.
|
||||||
*
|
|
||||||
* @return the inlined properties; potentially {@code null} or <em>empty</em>
|
* @return the inlined properties; potentially {@code null} or <em>empty</em>
|
||||||
* @see TestPropertySource#properties
|
* @see TestPropertySource#properties
|
||||||
*/
|
*/
|
||||||
|
@ -134,7 +127,6 @@ class TestPropertySourceAttributes {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@code inheritProperties} flag that was declared via {@code @TestPropertySource}.
|
* Get the {@code inheritProperties} flag that was declared via {@code @TestPropertySource}.
|
||||||
*
|
|
||||||
* @return the {@code inheritProperties} flag
|
* @return the {@code inheritProperties} flag
|
||||||
* @see TestPropertySource#inheritProperties
|
* @see TestPropertySource#inheritProperties
|
||||||
*/
|
*/
|
||||||
|
@ -157,6 +149,7 @@ class TestPropertySourceAttributes {
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect a default properties file for the supplied class, as specified
|
* Detect a default properties file for the supplied class, as specified
|
||||||
* in the class-level Javadoc for {@link TestPropertySource}.
|
* in the class-level Javadoc for {@link TestPropertySource}.
|
||||||
|
@ -174,10 +167,10 @@ class TestPropertySourceAttributes {
|
||||||
return prefixedResourcePath;
|
return prefixedResourcePath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String msg = String.format("Could not detect default properties file for test [%s]: "
|
String msg = String.format("Could not detect default properties file for test [%s]: " +
|
||||||
+ "%s does not exist. Either declare the 'locations' or 'properties' attributes "
|
"%s does not exist. Either declare the 'locations' or 'properties' attributes " +
|
||||||
+ "of @TestPropertySource or make the default properties file available.", testClass.getName(),
|
"of @TestPropertySource or make the default properties file available.", testClass.getName(),
|
||||||
classPathResource);
|
classPathResource);
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
throw new IllegalStateException(msg);
|
throw new IllegalStateException(msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -132,7 +132,10 @@ public abstract class TestPropertySourceUtils {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Processing inlined properties for TestPropertySource attributes %s", attrs));
|
logger.trace(String.format("Processing inlined properties for TestPropertySource attributes %s", attrs));
|
||||||
}
|
}
|
||||||
properties.addAll(0, Arrays.asList(attrs.getProperties()));
|
String[] attrProps = attrs.getProperties();
|
||||||
|
if (attrProps != null) {
|
||||||
|
properties.addAll(0, Arrays.asList(attrProps));
|
||||||
|
}
|
||||||
if (!attrs.isInheritProperties()) {
|
if (!attrs.isInheritProperties()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -30,6 +30,7 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi
|
||||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract {@linkplain Transactional transactional} extension of
|
* Abstract {@linkplain Transactional transactional} extension of
|
||||||
|
@ -185,8 +186,10 @@ public abstract class AbstractTransactionalTestNGSpringContextTests extends Abst
|
||||||
* @see #setSqlScriptEncoding
|
* @see #setSqlScriptEncoding
|
||||||
*/
|
*/
|
||||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||||
|
DataSource ds = this.jdbcTemplate.getDataSource();
|
||||||
|
Assert.state(ds != null, "No DataSource set");
|
||||||
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
Resource resource = this.applicationContext.getResource(sqlResourcePath);
|
||||||
new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(jdbcTemplate.getDataSource());
|
new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,6 +19,7 @@ package org.springframework.test.context.transaction;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.test.context.TestContext;
|
import org.springframework.test.context.TestContext;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
|
@ -56,6 +57,7 @@ class TransactionContext {
|
||||||
|
|
||||||
TransactionContext(TestContext testContext, PlatformTransactionManager transactionManager,
|
TransactionContext(TestContext testContext, PlatformTransactionManager transactionManager,
|
||||||
TransactionDefinition transactionDefinition, boolean defaultRollback) {
|
TransactionDefinition transactionDefinition, boolean defaultRollback) {
|
||||||
|
|
||||||
this.testContext = testContext;
|
this.testContext = testContext;
|
||||||
this.transactionManager = transactionManager;
|
this.transactionManager = transactionManager;
|
||||||
this.transactionDefinition = transactionDefinition;
|
this.transactionDefinition = transactionDefinition;
|
||||||
|
@ -63,6 +65,8 @@ class TransactionContext {
|
||||||
this.flaggedForRollback = defaultRollback;
|
this.flaggedForRollback = defaultRollback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
TransactionStatus getTransactionStatus() {
|
TransactionStatus getTransactionStatus() {
|
||||||
return this.transactionStatus;
|
return this.transactionStatus;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +87,7 @@ class TransactionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a new transaction for the configured {@linkplain #getTestContext test context}.
|
* Start a new transaction for the configured test context.
|
||||||
* <p>Only call this method if {@link #endTransaction} has been called or if no
|
* <p>Only call this method if {@link #endTransaction} has been called or if no
|
||||||
* transaction has been previously started.
|
* transaction has been previously started.
|
||||||
* @throws TransactionException if starting the transaction fails
|
* @throws TransactionException if starting the transaction fails
|
||||||
|
@ -102,9 +106,8 @@ class TransactionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immediately force a <em>commit</em> or <em>rollback</em> of the transaction
|
* Immediately force a <em>commit</em> or <em>rollback</em> of the transaction for the
|
||||||
* for the configured {@linkplain #getTestContext test context}, according to
|
* configured test context, according to the {@linkplain #isFlaggedForRollback rollback flag}.
|
||||||
* the {@linkplain #isFlaggedForRollback rollback flag}.
|
|
||||||
*/
|
*/
|
||||||
void endTransaction() {
|
void endTransaction() {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
|
@ -133,4 +136,4 @@ class TransactionContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.test.context.transaction;
|
package org.springframework.test.context.transaction;
|
||||||
|
|
||||||
import org.springframework.core.NamedInheritableThreadLocal;
|
import org.springframework.core.NamedInheritableThreadLocal;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link InheritableThreadLocal}-based holder for the current {@link TransactionContext}.
|
* {@link InheritableThreadLocal}-based holder for the current {@link TransactionContext}.
|
||||||
|
@ -26,18 +27,20 @@ import org.springframework.core.NamedInheritableThreadLocal;
|
||||||
*/
|
*/
|
||||||
class TransactionContextHolder {
|
class TransactionContextHolder {
|
||||||
|
|
||||||
private static final ThreadLocal<TransactionContext> currentTransactionContext = new NamedInheritableThreadLocal<>(
|
private static final ThreadLocal<TransactionContext> currentTransactionContext =
|
||||||
"Test Transaction Context");
|
new NamedInheritableThreadLocal<>("Test Transaction Context");
|
||||||
|
|
||||||
|
|
||||||
|
static void setCurrentTransactionContext(@Nullable TransactionContext transactionContext) {
|
||||||
|
currentTransactionContext.set(transactionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
static TransactionContext getCurrentTransactionContext() {
|
static TransactionContext getCurrentTransactionContext() {
|
||||||
return currentTransactionContext.get();
|
return currentTransactionContext.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCurrentTransactionContext(TransactionContext transactionContext) {
|
@Nullable
|
||||||
currentTransactionContext.set(transactionContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TransactionContext removeCurrentTransactionContext() {
|
static TransactionContext removeCurrentTransactionContext() {
|
||||||
synchronized (currentTransactionContext) {
|
synchronized (currentTransactionContext) {
|
||||||
TransactionContext transactionContext = currentTransactionContext.get();
|
TransactionContext transactionContext = currentTransactionContext.get();
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.test.annotation.Commit;
|
import org.springframework.test.annotation.Commit;
|
||||||
import org.springframework.test.annotation.Rollback;
|
import org.springframework.test.annotation.Rollback;
|
||||||
import org.springframework.test.context.TestContext;
|
import org.springframework.test.context.TestContext;
|
||||||
|
@ -156,8 +157,8 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void beforeTestMethod(final TestContext testContext) throws Exception {
|
public void beforeTestMethod(final TestContext testContext) throws Exception {
|
||||||
final Method testMethod = testContext.getTestMethod();
|
Method testMethod = testContext.getTestMethod();
|
||||||
final Class<?> testClass = testContext.getTestClass();
|
Class<?> testClass = testContext.getTestClass();
|
||||||
Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null");
|
Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null");
|
||||||
|
|
||||||
TransactionContext txContext = TransactionContextHolder.removeCurrentTransactionContext();
|
TransactionContext txContext = TransactionContextHolder.removeCurrentTransactionContext();
|
||||||
|
@ -180,7 +181,6 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
|
||||||
}
|
}
|
||||||
|
|
||||||
tm = getTransactionManager(testContext, transactionAttribute.getQualifier());
|
tm = getTransactionManager(testContext, transactionAttribute.getQualifier());
|
||||||
|
|
||||||
Assert.state(tm != null, () -> String.format(
|
Assert.state(tm != null, () -> String.format(
|
||||||
"Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.",
|
"Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.",
|
||||||
testContext));
|
testContext));
|
||||||
|
@ -212,7 +212,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
|
||||||
TransactionStatus transactionStatus = txContext.getTransactionStatus();
|
TransactionStatus transactionStatus = txContext.getTransactionStatus();
|
||||||
try {
|
try {
|
||||||
// If the transaction is still active...
|
// If the transaction is still active...
|
||||||
if ((transactionStatus != null) && !transactionStatus.isCompleted()) {
|
if (transactionStatus != null && !transactionStatus.isCompleted()) {
|
||||||
txContext.endTransaction();
|
txContext.endTransaction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,6 +306,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
|
||||||
* @throws BeansException if an error occurs while retrieving the transaction manager
|
* @throws BeansException if an error occurs while retrieving the transaction manager
|
||||||
* @see #getTransactionManager(TestContext)
|
* @see #getTransactionManager(TestContext)
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
protected PlatformTransactionManager getTransactionManager(TestContext testContext, String qualifier) {
|
protected PlatformTransactionManager getTransactionManager(TestContext testContext, String qualifier) {
|
||||||
// Look up by type and qualifier from @Transactional
|
// Look up by type and qualifier from @Transactional
|
||||||
if (StringUtils.hasText(qualifier)) {
|
if (StringUtils.hasText(qualifier)) {
|
||||||
|
@ -344,6 +345,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
|
||||||
* exists in the ApplicationContext
|
* exists in the ApplicationContext
|
||||||
* @see #getTransactionManager(TestContext, String)
|
* @see #getTransactionManager(TestContext, String)
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
protected PlatformTransactionManager getTransactionManager(TestContext testContext) {
|
protected PlatformTransactionManager getTransactionManager(TestContext testContext) {
|
||||||
return TestContextTransactionUtils.retrieveTransactionManager(testContext, null);
|
return TestContextTransactionUtils.retrieveTransactionManager(testContext, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -47,10 +47,6 @@ public abstract class TestContextResourceUtils {
|
||||||
private static final String SLASH = "/";
|
private static final String SLASH = "/";
|
||||||
|
|
||||||
|
|
||||||
private TestContextResourceUtils() {
|
|
||||||
/* prevent instantiation */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the supplied paths to classpath resource paths.
|
* Convert the supplied paths to classpath resource paths.
|
||||||
*
|
*
|
||||||
|
@ -65,7 +61,6 @@ public abstract class TestContextResourceUtils {
|
||||||
* {@link ResourceUtils#CLASSPATH_URL_PREFIX classpath:},
|
* {@link ResourceUtils#CLASSPATH_URL_PREFIX classpath:},
|
||||||
* {@link ResourceUtils#FILE_URL_PREFIX file:}, {@code http:}, etc.) will be
|
* {@link ResourceUtils#FILE_URL_PREFIX file:}, {@code http:}, etc.) will be
|
||||||
* {@link StringUtils#cleanPath cleaned} but otherwise unmodified.
|
* {@link StringUtils#cleanPath cleaned} but otherwise unmodified.
|
||||||
*
|
|
||||||
* @param clazz the class with which the paths are associated
|
* @param clazz the class with which the paths are associated
|
||||||
* @param paths the paths to be converted
|
* @param paths the paths to be converted
|
||||||
* @return a new array of converted resource paths
|
* @return a new array of converted resource paths
|
||||||
|
@ -79,8 +74,8 @@ public abstract class TestContextResourceUtils {
|
||||||
convertedPaths[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
|
convertedPaths[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
|
||||||
}
|
}
|
||||||
else if (!ResourcePatternUtils.isUrl(path)) {
|
else if (!ResourcePatternUtils.isUrl(path)) {
|
||||||
convertedPaths[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH
|
convertedPaths[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH +
|
||||||
+ StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + SLASH + path);
|
StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + SLASH + path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
convertedPaths[i] = StringUtils.cleanPath(path);
|
convertedPaths[i] = StringUtils.cleanPath(path);
|
||||||
|
@ -92,7 +87,6 @@ public abstract class TestContextResourceUtils {
|
||||||
/**
|
/**
|
||||||
* Convert the supplied paths to an array of {@link Resource} handles using
|
* Convert the supplied paths to an array of {@link Resource} handles using
|
||||||
* the given {@link ResourceLoader}.
|
* the given {@link ResourceLoader}.
|
||||||
*
|
|
||||||
* @param resourceLoader the {@code ResourceLoader} to use to convert the paths
|
* @param resourceLoader the {@code ResourceLoader} to use to convert the paths
|
||||||
* @param paths the paths to be converted
|
* @param paths the paths to be converted
|
||||||
* @return a new array of resources
|
* @return a new array of resources
|
||||||
|
@ -106,7 +100,6 @@ public abstract class TestContextResourceUtils {
|
||||||
/**
|
/**
|
||||||
* Convert the supplied paths to a list of {@link Resource} handles using
|
* Convert the supplied paths to a list of {@link Resource} handles using
|
||||||
* the given {@link ResourceLoader}.
|
* the given {@link ResourceLoader}.
|
||||||
*
|
|
||||||
* @param resourceLoader the {@code ResourceLoader} to use to convert the paths
|
* @param resourceLoader the {@code ResourceLoader} to use to convert the paths
|
||||||
* @param paths the paths to be converted
|
* @param paths the paths to be converted
|
||||||
* @return a new list of resources
|
* @return a new list of resources
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,7 +20,6 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||||
import org.springframework.test.context.MergedContextConfiguration;
|
import org.springframework.test.context.MergedContextConfiguration;
|
||||||
import org.springframework.test.context.support.AnnotationConfigContextLoaderUtils;
|
import org.springframework.test.context.support.AnnotationConfigContextLoaderUtils;
|
||||||
|
@ -80,7 +79,7 @@ public class AnnotationConfigWebContextLoader extends AbstractGenericWebContextL
|
||||||
* @see #detectDefaultConfigurationClasses(Class)
|
* @see #detectDefaultConfigurationClasses(Class)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void processContextConfiguration(@Nullable ContextConfigurationAttributes configAttributes) {
|
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
|
||||||
if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
|
if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
|
||||||
configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
|
configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration {
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public WebMergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
public WebMergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
||||||
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses,
|
||||||
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
|
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
|
||||||
String resourceBasePath, ContextLoader contextLoader,
|
String resourceBasePath, ContextLoader contextLoader,
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
|
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
|
||||||
|
@ -135,7 +135,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration {
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
public WebMergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
public WebMergedContextConfiguration(Class<?> testClass, @Nullable String[] locations, @Nullable Class<?>[] classes,
|
||||||
@Nullable Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
@Nullable Set<Class<? extends ApplicationContextInitializer<?>>> contextInitializerClasses,
|
||||||
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
|
@Nullable String[] activeProfiles, @Nullable String[] propertySourceLocations, @Nullable String[] propertySourceProperties,
|
||||||
@Nullable Set<ContextCustomizer> contextCustomizers, String resourceBasePath, ContextLoader contextLoader,
|
@Nullable Set<ContextCustomizer> contextCustomizers, String resourceBasePath, ContextLoader contextLoader,
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
|
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, @Nullable MergedContextConfiguration parent) {
|
||||||
|
@ -206,7 +206,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration {
|
||||||
.append("propertySourceProperties", ObjectUtils.nullSafeToString(getPropertySourceProperties()))
|
.append("propertySourceProperties", ObjectUtils.nullSafeToString(getPropertySourceProperties()))
|
||||||
.append("contextCustomizers", getContextCustomizers())
|
.append("contextCustomizers", getContextCustomizers())
|
||||||
.append("resourceBasePath", getResourceBasePath())
|
.append("resourceBasePath", getResourceBasePath())
|
||||||
.append("contextLoader", nullSafeToString(getContextLoader()))
|
.append("contextLoader", nullSafeClassName(getContextLoader()))
|
||||||
.append("parent", getParent())
|
.append("parent", getParent())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.test.context.web.socket;
|
package org.springframework.test.context.web.socket;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.test.context.ContextCustomizer;
|
import org.springframework.test.context.ContextCustomizer;
|
||||||
import org.springframework.test.context.MergedContextConfiguration;
|
import org.springframework.test.context.MergedContextConfiguration;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
@ -35,12 +38,15 @@ class MockServerContainerContextCustomizer implements ContextCustomizer {
|
||||||
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
|
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
|
||||||
if (context instanceof WebApplicationContext) {
|
if (context instanceof WebApplicationContext) {
|
||||||
WebApplicationContext wac = (WebApplicationContext) context;
|
WebApplicationContext wac = (WebApplicationContext) context;
|
||||||
wac.getServletContext().setAttribute("javax.websocket.server.ServerContainer", new MockServerContainer());
|
ServletContext sc = wac.getServletContext();
|
||||||
|
if (sc != null) {
|
||||||
|
sc.setAttribute("javax.websocket.server.ServerContainer", new MockServerContainer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(@Nullable Object other) {
|
||||||
return (this == other || (other != null && getClass() == other.getClass()));
|
return (this == other || (other != null && getClass() == other.getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -50,7 +50,8 @@ public class JdbcTestUtils {
|
||||||
* @return the number of rows in the table
|
* @return the number of rows in the table
|
||||||
*/
|
*/
|
||||||
public static int countRowsInTable(JdbcTemplate jdbcTemplate, String tableName) {
|
public static int countRowsInTable(JdbcTemplate jdbcTemplate, String tableName) {
|
||||||
return jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + tableName, Integer.class);
|
Integer result = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM " + tableName, Integer.class);
|
||||||
|
return (result != null ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +73,8 @@ public class JdbcTestUtils {
|
||||||
if (StringUtils.hasText(whereClause)) {
|
if (StringUtils.hasText(whereClause)) {
|
||||||
sql += " WHERE " + whereClause;
|
sql += " WHERE " + whereClause;
|
||||||
}
|
}
|
||||||
return jdbcTemplate.queryForObject(sql, Integer.class);
|
Integer result = jdbcTemplate.queryForObject(sql, Integer.class);
|
||||||
|
return (result != null ? result : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,14 +114,14 @@ public class JdbcTestUtils {
|
||||||
* optionally the scale.
|
* optionally the scale.
|
||||||
* @return the number of rows deleted from the table
|
* @return the number of rows deleted from the table
|
||||||
*/
|
*/
|
||||||
public static int deleteFromTableWhere(JdbcTemplate jdbcTemplate, String tableName, String whereClause,
|
public static int deleteFromTableWhere(
|
||||||
Object... args) {
|
JdbcTemplate jdbcTemplate, String tableName, String whereClause, Object... args) {
|
||||||
|
|
||||||
String sql = "DELETE FROM " + tableName;
|
String sql = "DELETE FROM " + tableName;
|
||||||
if (StringUtils.hasText(whereClause)) {
|
if (StringUtils.hasText(whereClause)) {
|
||||||
sql += " WHERE " + whereClause;
|
sql += " WHERE " + whereClause;
|
||||||
}
|
}
|
||||||
int rowCount = (args != null && args.length > 0 ? jdbcTemplate.update(sql, args) : jdbcTemplate.update(sql));
|
int rowCount = (args.length > 0 ? jdbcTemplate.update(sql, args) : jdbcTemplate.update(sql));
|
||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info("Deleted " + rowCount + " rows from table " + tableName);
|
logger.info("Deleted " + rowCount + " rows from table " + tableName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.test.util;
|
package org.springframework.test.util;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +51,7 @@ public abstract class AssertionErrors {
|
||||||
* @param expected expected value
|
* @param expected expected value
|
||||||
* @param actual actual value
|
* @param actual actual value
|
||||||
*/
|
*/
|
||||||
public static void fail(String message, Object expected, Object actual) {
|
public static void fail(String message, @Nullable Object expected, @Nullable Object actual) {
|
||||||
throw new AssertionError(message + " expected:<" + expected + "> but was:<" + actual + ">");
|
throw new AssertionError(message + " expected:<" + expected + "> but was:<" + actual + ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ public abstract class AssertionErrors {
|
||||||
* @param expected the expected value
|
* @param expected the expected value
|
||||||
* @param actual the actual value
|
* @param actual the actual value
|
||||||
*/
|
*/
|
||||||
public static void assertEquals(String message, Object expected, Object actual) {
|
public static void assertEquals(String message, @Nullable Object expected, @Nullable Object actual) {
|
||||||
if (!ObjectUtils.nullSafeEquals(expected, actual)) {
|
if (!ObjectUtils.nullSafeEquals(expected, actual)) {
|
||||||
fail(message, ObjectUtils.nullSafeToString(expected), ObjectUtils.nullSafeToString(actual));
|
fail(message, ObjectUtils.nullSafeToString(expected), ObjectUtils.nullSafeToString(actual));
|
||||||
}
|
}
|
||||||
|
@ -92,7 +93,7 @@ public abstract class AssertionErrors {
|
||||||
* @param expected the expected value
|
* @param expected the expected value
|
||||||
* @param actual the actual value
|
* @param actual the actual value
|
||||||
*/
|
*/
|
||||||
public static void assertNotEquals(String message, Object expected, Object actual) {
|
public static void assertNotEquals(String message, @Nullable Object expected, @Nullable Object actual) {
|
||||||
if (ObjectUtils.nullSafeEquals(expected, actual)) {
|
if (ObjectUtils.nullSafeEquals(expected, actual)) {
|
||||||
throw new AssertionError(message + " was not expected to be:" +
|
throw new AssertionError(message + " was not expected to be:" +
|
||||||
"<" + ObjectUtils.nullSafeToString(actual) + ">");
|
"<" + ObjectUtils.nullSafeToString(actual) + ">");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -34,7 +34,6 @@ public class JsonExpectationsHelper {
|
||||||
* are "similar" - i.e. they contain the same attribute-value pairs
|
* are "similar" - i.e. they contain the same attribute-value pairs
|
||||||
* regardless of formatting with a lenient checking (extensible, and non-strict
|
* regardless of formatting with a lenient checking (extensible, and non-strict
|
||||||
* array ordering).
|
* array ordering).
|
||||||
*
|
|
||||||
* @param expected the expected JSON content
|
* @param expected the expected JSON content
|
||||||
* @param actual the actual JSON content
|
* @param actual the actual JSON content
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
|
@ -48,13 +47,11 @@ public class JsonExpectationsHelper {
|
||||||
* Parse the expected and actual strings as JSON and assert the two
|
* Parse the expected and actual strings as JSON and assert the two
|
||||||
* are "similar" - i.e. they contain the same attribute-value pairs
|
* are "similar" - i.e. they contain the same attribute-value pairs
|
||||||
* regardless of formatting.
|
* regardless of formatting.
|
||||||
*
|
|
||||||
* <p>Can compare in two modes, depending on {@code strict} parameter value:
|
* <p>Can compare in two modes, depending on {@code strict} parameter value:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
|
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
|
||||||
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
|
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
|
||||||
* @param expected the expected JSON content
|
* @param expected the expected JSON content
|
||||||
* @param actual the actual JSON content
|
* @param actual the actual JSON content
|
||||||
* @param strict enables strict checking
|
* @param strict enables strict checking
|
||||||
|
@ -69,7 +66,6 @@ public class JsonExpectationsHelper {
|
||||||
* are "not similar" - i.e. they contain different attribute-value pairs
|
* are "not similar" - i.e. they contain different attribute-value pairs
|
||||||
* regardless of formatting with a lenient checking (extensible, and non-strict
|
* regardless of formatting with a lenient checking (extensible, and non-strict
|
||||||
* array ordering).
|
* array ordering).
|
||||||
*
|
|
||||||
* @param expected the expected JSON content
|
* @param expected the expected JSON content
|
||||||
* @param actual the actual JSON content
|
* @param actual the actual JSON content
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
|
@ -83,13 +79,11 @@ public class JsonExpectationsHelper {
|
||||||
* Parse the expected and actual strings as JSON and assert the two
|
* Parse the expected and actual strings as JSON and assert the two
|
||||||
* are "not similar" - i.e. they contain different attribute-value pairs
|
* are "not similar" - i.e. they contain different attribute-value pairs
|
||||||
* regardless of formatting.
|
* regardless of formatting.
|
||||||
*
|
|
||||||
* <p>Can compare in two modes, depending on {@code strict} parameter value:
|
* <p>Can compare in two modes, depending on {@code strict} parameter value:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
|
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
|
||||||
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
|
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
|
||||||
* @param expected the expected JSON content
|
* @param expected the expected JSON content
|
||||||
* @param actual the actual JSON content
|
* @param actual the actual JSON content
|
||||||
* @param strict enables strict checking
|
* @param strict enables strict checking
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -22,6 +22,7 @@ import java.util.Map;
|
||||||
import com.jayway.jsonpath.JsonPath;
|
import com.jayway.jsonpath.JsonPath;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
@ -95,7 +96,7 @@ public class JsonPathExpectationsHelper {
|
||||||
* @param content the JSON content
|
* @param content the JSON content
|
||||||
* @param expectedValue the expected value
|
* @param expectedValue the expected value
|
||||||
*/
|
*/
|
||||||
public void assertValue(String content, Object expectedValue) {
|
public void assertValue(String content, @Nullable Object expectedValue) {
|
||||||
Object actualValue = evaluateJsonPath(content);
|
Object actualValue = evaluateJsonPath(content);
|
||||||
if ((actualValue instanceof List) && !(expectedValue instanceof List)) {
|
if ((actualValue instanceof List) && !(expectedValue instanceof List)) {
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
|
@ -231,11 +232,12 @@ public class JsonPathExpectationsHelper {
|
||||||
assertTrue(failureReason("a non-empty value", value), !ObjectUtils.isEmpty(value));
|
assertTrue(failureReason("a non-empty value", value), !ObjectUtils.isEmpty(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String failureReason(String expectedDescription, Object value) {
|
private String failureReason(String expectedDescription, @Nullable Object value) {
|
||||||
return String.format("Expected %s at JSON path \"%s\" but found: %s", expectedDescription, this.expression,
|
return String.format("Expected %s at JSON path \"%s\" but found: %s", expectedDescription, this.expression,
|
||||||
ObjectUtils.nullSafeToString(StringUtils.quoteIfString(value)));
|
ObjectUtils.nullSafeToString(StringUtils.quoteIfString(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Object evaluateJsonPath(String content) {
|
private Object evaluateJsonPath(String content) {
|
||||||
String message = "No value at JSON path \"" + this.expression + "\"";
|
String message = "No value at JSON path \"" + this.expression + "\"";
|
||||||
try {
|
try {
|
||||||
|
@ -256,6 +258,7 @@ public class JsonPathExpectationsHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Object assertExistsAndReturn(String content) {
|
private Object assertExistsAndReturn(String content) {
|
||||||
Object value = evaluateJsonPath(content);
|
Object value = evaluateJsonPath(content);
|
||||||
String reason = "No value at JSON path \"" + this.expression + "\"";
|
String reason = "No value at JSON path \"" + this.expression + "\"";
|
||||||
|
|
|
@ -100,7 +100,7 @@ public abstract class MetaAnnotationUtils {
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
|
private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
|
||||||
Class<?> clazz, Set<Annotation> visited, Class<T> annotationType) {
|
@Nullable Class<?> clazz, Set<Annotation> visited, Class<T> annotationType) {
|
||||||
|
|
||||||
Assert.notNull(annotationType, "Annotation type must not be null");
|
Assert.notNull(annotationType, "Annotation type must not be null");
|
||||||
if (clazz == null || Object.class == clazz) {
|
if (clazz == null || Object.class == clazz) {
|
||||||
|
@ -187,7 +187,7 @@ public abstract class MetaAnnotationUtils {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
private static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Class<?> clazz,
|
private static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(@Nullable Class<?> clazz,
|
||||||
Set<Annotation> visited, Class<? extends Annotation>... annotationTypes) {
|
Set<Annotation> visited, Class<? extends Annotation>... annotationTypes) {
|
||||||
|
|
||||||
assertNonEmptyAnnotationTypeArray(annotationTypes, "The list of annotation types must not be empty");
|
assertNonEmptyAnnotationTypeArray(annotationTypes, "The list of annotation types must not be empty");
|
||||||
|
@ -298,7 +298,7 @@ public abstract class MetaAnnotationUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||||
Annotation composedAnnotation, T annotation) {
|
@Nullable Annotation composedAnnotation, T annotation) {
|
||||||
|
|
||||||
Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null");
|
Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null");
|
||||||
Assert.notNull(annotation, "Annotation must not be null");
|
Assert.notNull(annotation, "Annotation must not be null");
|
||||||
|
@ -349,6 +349,7 @@ public abstract class MetaAnnotationUtils {
|
||||||
return this.composedAnnotation;
|
return this.composedAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Class<? extends Annotation> getComposedAnnotationType() {
|
public Class<? extends Annotation> getComposedAnnotationType() {
|
||||||
return (this.composedAnnotation != null ? this.composedAnnotation.annotationType() : null);
|
return (this.composedAnnotation != null ? this.composedAnnotation.annotationType() : null);
|
||||||
}
|
}
|
||||||
|
@ -380,7 +381,7 @@ public abstract class MetaAnnotationUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public UntypedAnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
public UntypedAnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||||
Annotation composedAnnotation, Annotation annotation) {
|
@Nullable Annotation composedAnnotation, Annotation annotation) {
|
||||||
|
|
||||||
super(rootDeclaringClass, declaringClass, composedAnnotation, annotation);
|
super(rootDeclaringClass, declaringClass, composedAnnotation, annotation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -81,7 +81,7 @@ public class ReflectionTestUtils {
|
||||||
* @param name the name of the field to set; never {@code null}
|
* @param name the name of the field to set; never {@code null}
|
||||||
* @param value the value to set
|
* @param value the value to set
|
||||||
*/
|
*/
|
||||||
public static void setField(Object targetObject, String name, Object value) {
|
public static void setField(Object targetObject, String name, @Nullable Object value) {
|
||||||
setField(targetObject, name, value, null);
|
setField(targetObject, name, value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public class ReflectionTestUtils {
|
||||||
* @param type the type of the field to set; may be {@code null} if
|
* @param type the type of the field to set; may be {@code null} if
|
||||||
* {@code name} is specified
|
* {@code name} is specified
|
||||||
*/
|
*/
|
||||||
public static void setField(Object targetObject, @Nullable String name, Object value, Class<?> type) {
|
public static void setField(Object targetObject, @Nullable String name, @Nullable Object value, @Nullable Class<?> type) {
|
||||||
setField(targetObject, null, name, value, type);
|
setField(targetObject, null, name, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ public class ReflectionTestUtils {
|
||||||
* @param value the value to set
|
* @param value the value to set
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
public static void setField(Class<?> targetClass, String name, Object value) {
|
public static void setField(Class<?> targetClass, String name, @Nullable Object value) {
|
||||||
setField(null, targetClass, name, value, null);
|
setField(null, targetClass, name, value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,9 @@ public class ReflectionTestUtils {
|
||||||
* {@code name} is specified
|
* {@code name} is specified
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
public static void setField(Class<?> targetClass, @Nullable String name, Object value, @Nullable Class<?> type) {
|
public static void setField(
|
||||||
|
Class<?> targetClass, @Nullable String name, @Nullable Object value, @Nullable Class<?> type) {
|
||||||
|
|
||||||
setField(null, targetClass, name, value, type);
|
setField(null, targetClass, name, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +163,11 @@ public class ReflectionTestUtils {
|
||||||
* @see ReflectionUtils#setField(Field, Object, Object)
|
* @see ReflectionUtils#setField(Field, Object, Object)
|
||||||
* @see AopTestUtils#getUltimateTargetObject(Object)
|
* @see AopTestUtils#getUltimateTargetObject(Object)
|
||||||
*/
|
*/
|
||||||
public static void setField(@Nullable Object targetObject, @Nullable Class<?> targetClass, @Nullable String name, Object value, @Nullable Class<?> type) {
|
public static void setField(@Nullable Object targetObject, @Nullable Class<?> targetClass,
|
||||||
|
@Nullable String name, @Nullable Object value, @Nullable Class<?> type) {
|
||||||
|
|
||||||
Assert.isTrue(targetObject != null || targetClass != null,
|
Assert.isTrue(targetObject != null || targetClass != null,
|
||||||
"Either targetObject or targetClass for the field must be specified");
|
"Either targetObject or targetClass for the field must be specified");
|
||||||
|
|
||||||
Object ultimateTarget = (targetObject != null ? AopTestUtils.getUltimateTargetObject(targetObject) : null);
|
Object ultimateTarget = (targetObject != null ? AopTestUtils.getUltimateTargetObject(targetObject) : null);
|
||||||
|
|
||||||
|
@ -198,6 +202,7 @@ public class ReflectionTestUtils {
|
||||||
* @return the field's current value
|
* @return the field's current value
|
||||||
* @see #getField(Class, String)
|
* @see #getField(Class, String)
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public static Object getField(Object targetObject, String name) {
|
public static Object getField(Object targetObject, String name) {
|
||||||
return getField(targetObject, null, name);
|
return getField(targetObject, null, name);
|
||||||
}
|
}
|
||||||
|
@ -214,6 +219,7 @@ public class ReflectionTestUtils {
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
* @see #getField(Object, String)
|
* @see #getField(Object, String)
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public static Object getField(Class<?> targetClass, String name) {
|
public static Object getField(Class<?> targetClass, String name) {
|
||||||
return getField(null, targetClass, name);
|
return getField(null, targetClass, name);
|
||||||
}
|
}
|
||||||
|
@ -242,6 +248,7 @@ public class ReflectionTestUtils {
|
||||||
* @see ReflectionUtils#getField(Field, Object)
|
* @see ReflectionUtils#getField(Field, Object)
|
||||||
* @see AopTestUtils#getUltimateTargetObject(Object)
|
* @see AopTestUtils#getUltimateTargetObject(Object)
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public static Object getField(@Nullable Object targetObject, @Nullable Class<?> targetClass, String name) {
|
public static Object getField(@Nullable Object targetObject, @Nullable Class<?> targetClass, String name) {
|
||||||
Assert.isTrue(targetObject != null || targetClass != null,
|
Assert.isTrue(targetObject != null || targetClass != null,
|
||||||
"Either targetObject or targetClass for the field must be specified");
|
"Either targetObject or targetClass for the field must be specified");
|
||||||
|
@ -311,7 +318,7 @@ public class ReflectionTestUtils {
|
||||||
* @see ReflectionUtils#makeAccessible(Method)
|
* @see ReflectionUtils#makeAccessible(Method)
|
||||||
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
||||||
*/
|
*/
|
||||||
public static void invokeSetterMethod(Object target, String name, Object value, Class<?> type) {
|
public static void invokeSetterMethod(Object target, String name, @Nullable Object value, @Nullable Class<?> type) {
|
||||||
Assert.notNull(target, "Target object must not be null");
|
Assert.notNull(target, "Target object must not be null");
|
||||||
Assert.hasText(name, "Method name must not be empty");
|
Assert.hasText(name, "Method name must not be empty");
|
||||||
Class<?>[] paramTypes = (type != null ? new Class<?>[] {type} : null);
|
Class<?>[] paramTypes = (type != null ? new Class<?>[] {type} : null);
|
||||||
|
@ -361,6 +368,7 @@ public class ReflectionTestUtils {
|
||||||
* @see ReflectionUtils#makeAccessible(Method)
|
* @see ReflectionUtils#makeAccessible(Method)
|
||||||
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public static Object invokeGetterMethod(Object target, String name) {
|
public static Object invokeGetterMethod(Object target, String name) {
|
||||||
Assert.notNull(target, "Target object must not be null");
|
Assert.notNull(target, "Target object must not be null");
|
||||||
Assert.hasText(name, "Method name must not be empty");
|
Assert.hasText(name, "Method name must not be empty");
|
||||||
|
@ -404,7 +412,7 @@ public class ReflectionTestUtils {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T> T invokeMethod(Object target, String name, @Nullable Object... args) {
|
public static <T> T invokeMethod(Object target, String name, Object... args) {
|
||||||
Assert.notNull(target, "Target object must not be null");
|
Assert.notNull(target, "Target object must not be null");
|
||||||
Assert.hasText(name, "Method name must not be empty");
|
Assert.hasText(name, "Method name must not be empty");
|
||||||
|
|
||||||
|
@ -428,13 +436,13 @@ public class ReflectionTestUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String safeToString(Object target) {
|
private static String safeToString(@Nullable Object target) {
|
||||||
try {
|
try {
|
||||||
return String.format("target object [%s]", target);
|
return String.format("target object [%s]", target);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
return String.format("target of type [%s] whose toString() method threw [%s]",
|
return String.format("target of type [%s] whose toString() method threw [%s]",
|
||||||
(target != null ? target.getClass().getName() : "unknown"), ex);
|
(target != null ? target.getClass().getName() : "unknown"), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,7 +19,6 @@ package org.springframework.test.util;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
@ -75,7 +74,7 @@ public class XpathExpectationsHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private XPathExpression compileXpathExpression(String expression, Map<String, String> namespaces)
|
private XPathExpression compileXpathExpression(String expression, @Nullable Map<String, String> namespaces)
|
||||||
throws XPathExpressionException {
|
throws XPathExpressionException {
|
||||||
|
|
||||||
SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
|
SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
|
||||||
|
@ -96,7 +95,9 @@ public class XpathExpectationsHelper {
|
||||||
* Parse the content, evaluate the XPath expression as a {@link Node},
|
* Parse the content, evaluate the XPath expression as a {@link Node},
|
||||||
* and assert it with the given {@code Matcher<Node>}.
|
* and assert it with the given {@code Matcher<Node>}.
|
||||||
*/
|
*/
|
||||||
public void assertNode(byte[] content, String encoding, final Matcher<? super Node> matcher) throws Exception {
|
public void assertNode(byte[] content, @Nullable String encoding, final Matcher<? super Node> matcher)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
||||||
assertThat("XPath " + this.expression, node, matcher);
|
assertThat("XPath " + this.expression, node, matcher);
|
||||||
|
@ -108,7 +109,7 @@ public class XpathExpectationsHelper {
|
||||||
* @param encoding optional content encoding, if provided as metadata (e.g. in HTTP headers)
|
* @param encoding optional content encoding, if provided as metadata (e.g. in HTTP headers)
|
||||||
* @return the parsed document
|
* @return the parsed document
|
||||||
*/
|
*/
|
||||||
protected Document parseXmlByteArray(byte[] xml, String encoding) throws Exception {
|
protected Document parseXmlByteArray(byte[] xml, @Nullable String encoding) throws Exception {
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
factory.setNamespaceAware(this.hasNamespaces);
|
factory.setNamespaceAware(this.hasNamespaces);
|
||||||
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
|
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
|
||||||
|
@ -124,6 +125,7 @@ public class XpathExpectationsHelper {
|
||||||
* @throws XPathExpressionException
|
* @throws XPathExpressionException
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@Nullable
|
||||||
protected <T> T evaluateXpath(Document document, QName evaluationType, Class<T> expectedClass)
|
protected <T> T evaluateXpath(Document document, QName evaluationType, Class<T> expectedClass)
|
||||||
throws XPathExpressionException {
|
throws XPathExpressionException {
|
||||||
|
|
||||||
|
@ -134,7 +136,7 @@ public class XpathExpectationsHelper {
|
||||||
* Apply the XPath expression and assert the resulting content exists.
|
* Apply the XPath expression and assert the resulting content exists.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void exists(byte[] content, String encoding) throws Exception {
|
public void exists(byte[] content, @Nullable String encoding) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
||||||
assertTrue("XPath " + this.expression + " does not exist", node != null);
|
assertTrue("XPath " + this.expression + " does not exist", node != null);
|
||||||
|
@ -144,7 +146,7 @@ public class XpathExpectationsHelper {
|
||||||
* Apply the XPath expression and assert the resulting content does not exist.
|
* Apply the XPath expression and assert the resulting content does not exist.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void doesNotExist(byte[] content, String encoding) throws Exception {
|
public void doesNotExist(byte[] content, @Nullable String encoding) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
Node node = evaluateXpath(document, XPathConstants.NODE, Node.class);
|
||||||
assertTrue("XPath " + this.expression + " exists", node == null);
|
assertTrue("XPath " + this.expression + " exists", node == null);
|
||||||
|
@ -155,20 +157,22 @@ public class XpathExpectationsHelper {
|
||||||
* given Hamcrest matcher.
|
* given Hamcrest matcher.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertNodeCount(byte[] content, String encoding, Matcher<Integer> matcher) throws Exception {
|
public void assertNodeCount(byte[] content, @Nullable String encoding, Matcher<Integer> matcher) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
NodeList nodeList = evaluateXpath(document, XPathConstants.NODESET, NodeList.class);
|
NodeList nodeList = evaluateXpath(document, XPathConstants.NODESET, NodeList.class);
|
||||||
assertThat("nodeCount for XPath " + this.expression, nodeList.getLength(), matcher);
|
assertThat("nodeCount for XPath " + this.expression,
|
||||||
|
(nodeList != null ? nodeList.getLength() : 0), matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the XPath expression and assert the resulting content as an integer.
|
* Apply the XPath expression and assert the resulting content as an integer.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertNodeCount(byte[] content, String encoding, int expectedCount) throws Exception {
|
public void assertNodeCount(byte[] content, @Nullable String encoding, int expectedCount) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
NodeList nodeList = evaluateXpath(document, XPathConstants.NODESET, NodeList.class);
|
NodeList nodeList = evaluateXpath(document, XPathConstants.NODESET, NodeList.class);
|
||||||
assertEquals("nodeCount for XPath " + this.expression, expectedCount, nodeList.getLength());
|
assertEquals("nodeCount for XPath " + this.expression, expectedCount,
|
||||||
|
(nodeList != null ? nodeList.getLength() : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,7 +180,7 @@ public class XpathExpectationsHelper {
|
||||||
* given Hamcrest matcher.
|
* given Hamcrest matcher.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertString(byte[] content, String encoding, Matcher<? super String> matcher) throws Exception {
|
public void assertString(byte[] content, @Nullable String encoding, Matcher<? super String> matcher) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
String result = evaluateXpath(document, XPathConstants.STRING, String.class);
|
String result = evaluateXpath(document, XPathConstants.STRING, String.class);
|
||||||
assertThat("XPath " + this.expression, result, matcher);
|
assertThat("XPath " + this.expression, result, matcher);
|
||||||
|
@ -186,7 +190,7 @@ public class XpathExpectationsHelper {
|
||||||
* Apply the XPath expression and assert the resulting content as a String.
|
* Apply the XPath expression and assert the resulting content as a String.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertString(byte[] content, String encoding, String expectedValue) throws Exception {
|
public void assertString(byte[] content, @Nullable String encoding, String expectedValue) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
String actual = evaluateXpath(document, XPathConstants.STRING, String.class);
|
String actual = evaluateXpath(document, XPathConstants.STRING, String.class);
|
||||||
assertEquals("XPath " + this.expression, expectedValue, actual);
|
assertEquals("XPath " + this.expression, expectedValue, actual);
|
||||||
|
@ -197,7 +201,7 @@ public class XpathExpectationsHelper {
|
||||||
* given Hamcrest matcher.
|
* given Hamcrest matcher.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertNumber(byte[] content, String encoding, Matcher<? super Double> matcher) throws Exception {
|
public void assertNumber(byte[] content, @Nullable String encoding, Matcher<? super Double> matcher) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
Double result = evaluateXpath(document, XPathConstants.NUMBER, Double.class);
|
Double result = evaluateXpath(document, XPathConstants.NUMBER, Double.class);
|
||||||
assertThat("XPath " + this.expression, result, matcher);
|
assertThat("XPath " + this.expression, result, matcher);
|
||||||
|
@ -207,7 +211,7 @@ public class XpathExpectationsHelper {
|
||||||
* Apply the XPath expression and assert the resulting content as a Double.
|
* Apply the XPath expression and assert the resulting content as a Double.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertNumber(byte[] content, String encoding, Double expectedValue) throws Exception {
|
public void assertNumber(byte[] content, @Nullable String encoding, Double expectedValue) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
Double actual = evaluateXpath(document, XPathConstants.NUMBER, Double.class);
|
Double actual = evaluateXpath(document, XPathConstants.NUMBER, Double.class);
|
||||||
assertEquals("XPath " + this.expression, expectedValue, actual);
|
assertEquals("XPath " + this.expression, expectedValue, actual);
|
||||||
|
@ -217,7 +221,7 @@ public class XpathExpectationsHelper {
|
||||||
* Apply the XPath expression and assert the resulting content as a Boolean.
|
* Apply the XPath expression and assert the resulting content as a Boolean.
|
||||||
* @throws Exception if content parsing or expression evaluation fails
|
* @throws Exception if content parsing or expression evaluation fails
|
||||||
*/
|
*/
|
||||||
public void assertBoolean(byte[] content, String encoding, boolean expectedValue) throws Exception {
|
public void assertBoolean(byte[] content, @Nullable String encoding, boolean expectedValue) throws Exception {
|
||||||
Document document = parseXmlByteArray(content, encoding);
|
Document document = parseXmlByteArray(content, encoding);
|
||||||
String actual = evaluateXpath(document, XPathConstants.STRING, String.class);
|
String actual = evaluateXpath(document, XPathConstants.STRING, String.class);
|
||||||
assertEquals("XPath " + this.expression, expectedValue, Boolean.parseBoolean(actual));
|
assertEquals("XPath " + this.expression, expectedValue, Boolean.parseBoolean(actual));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -48,30 +48,30 @@ public abstract class ModelAndViewAssert {
|
||||||
* Checks whether the model value under the given {@code modelName}
|
* Checks whether the model value under the given {@code modelName}
|
||||||
* exists and checks it type, based on the {@code expectedType}. If the
|
* exists and checks it type, based on the {@code expectedType}. If the
|
||||||
* model entry exists and the type matches, the model value is returned.
|
* model entry exists and the type matches, the model value is returned.
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param modelName name of the object to add to the model (never
|
* @param modelName name of the object to add to the model (never {@code null})
|
||||||
* {@code null})
|
|
||||||
* @param expectedType expected type of the model value
|
* @param expectedType expected type of the model value
|
||||||
* @return the model value
|
* @return the model value
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T assertAndReturnModelAttributeOfType(ModelAndView mav, String modelName, Class<T> expectedType) {
|
public static <T> T assertAndReturnModelAttributeOfType(ModelAndView mav, String modelName, Class<T> expectedType) {
|
||||||
assertTrue("ModelAndView is null", mav != null);
|
if (mav == null) {
|
||||||
assertTrue("Model is null", mav.getModel() != null);
|
fail("ModelAndView is null");
|
||||||
Object obj = mav.getModel().get(modelName);
|
}
|
||||||
assertTrue("Model attribute with name '" + modelName + "' is null", obj != null);
|
Map<String, Object> model = mav.getModel();
|
||||||
assertTrue("Model attribute is not of expected type '" + expectedType.getName() + "' but rather of type '"
|
Object obj = model.get(modelName);
|
||||||
+ obj.getClass().getName() + "'", expectedType.isAssignableFrom(obj.getClass()));
|
if (obj == null) {
|
||||||
|
fail("Model attribute with name '" + modelName + "' is null");
|
||||||
|
}
|
||||||
|
assertTrue("Model attribute is not of expected type '" + expectedType.getName() + "' but rather of type '" +
|
||||||
|
obj.getClass().getName() + "'", expectedType.isAssignableFrom(obj.getClass()));
|
||||||
return (T) obj;
|
return (T) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare each individual entry in a list, without first sorting the lists.
|
* Compare each individual entry in a list, without first sorting the lists.
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param modelName name of the object to add to the model (never
|
* @param modelName name of the object to add to the model (never {@code null})
|
||||||
* {@code null})
|
|
||||||
* @param expectedList the expected list
|
* @param expectedList the expected list
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
|
@ -87,55 +87,53 @@ public abstract class ModelAndViewAssert {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert whether or not a model attribute is available.
|
* Assert whether or not a model attribute is available.
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param modelName name of the object to add to the model (never
|
* @param modelName name of the object to add to the model (never {@code null})
|
||||||
* {@code null})
|
|
||||||
*/
|
*/
|
||||||
public static void assertModelAttributeAvailable(ModelAndView mav, String modelName) {
|
public static void assertModelAttributeAvailable(ModelAndView mav, String modelName) {
|
||||||
assertTrue("ModelAndView is null", mav != null);
|
if (mav == null) {
|
||||||
assertTrue("Model is null", mav.getModel() != null);
|
fail("ModelAndView is null");
|
||||||
assertTrue("Model attribute with name '" + modelName + "' is not available",
|
}
|
||||||
mav.getModel().containsKey(modelName));
|
Map<String, Object> model = mav.getModel();
|
||||||
|
assertTrue("Model attribute with name '" + modelName + "' is not available", model.containsKey(modelName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare a given {@code expectedValue} to the value from the model
|
* Compare a given {@code expectedValue} to the value from the model
|
||||||
* bound under the given {@code modelName}.
|
* bound under the given {@code modelName}.
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param modelName name of the object to add to the model (never
|
* @param modelName name of the object to add to the model (never {@code null})
|
||||||
* {@code null})
|
|
||||||
* @param expectedValue the model value
|
* @param expectedValue the model value
|
||||||
*/
|
*/
|
||||||
public static void assertModelAttributeValue(ModelAndView mav, String modelName, Object expectedValue) {
|
public static void assertModelAttributeValue(ModelAndView mav, String modelName, Object expectedValue) {
|
||||||
assertTrue("ModelAndView is null", mav != null);
|
assertTrue("ModelAndView is null", mav != null);
|
||||||
Object modelValue = assertAndReturnModelAttributeOfType(mav, modelName, Object.class);
|
Object modelValue = assertAndReturnModelAttributeOfType(mav, modelName, Object.class);
|
||||||
assertTrue("Model value with name '" + modelName + "' is not the same as the expected value which was '"
|
assertTrue("Model value with name '" + modelName + "' is not the same as the expected value which was '" +
|
||||||
+ expectedValue + "'", modelValue.equals(expectedValue));
|
expectedValue + "'", modelValue.equals(expectedValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inspect the {@code expectedModel} to see if all elements in the
|
* Inspect the {@code expectedModel} to see if all elements in the
|
||||||
* model appear and are equal.
|
* model appear and are equal.
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param expectedModel the expected model
|
* @param expectedModel the expected model
|
||||||
*/
|
*/
|
||||||
public static void assertModelAttributeValues(ModelAndView mav, Map<String, Object> expectedModel) {
|
public static void assertModelAttributeValues(ModelAndView mav, Map<String, Object> expectedModel) {
|
||||||
assertTrue("ModelAndView is null", mav != null);
|
if (mav == null) {
|
||||||
assertTrue("Model is null", mav.getModel() != null);
|
fail("ModelAndView is null");
|
||||||
|
}
|
||||||
|
Map<String, Object> model = mav.getModel();
|
||||||
|
|
||||||
if (!mav.getModel().keySet().equals(expectedModel.keySet())) {
|
if (!model.keySet().equals(expectedModel.keySet())) {
|
||||||
StringBuilder sb = new StringBuilder("Keyset of expected model does not match.\n");
|
StringBuilder sb = new StringBuilder("Keyset of expected model does not match.\n");
|
||||||
appendNonMatchingSetsErrorMessage(expectedModel.keySet(), mav.getModel().keySet(), sb);
|
appendNonMatchingSetsErrorMessage(expectedModel.keySet(), model.keySet(), sb);
|
||||||
fail(sb.toString());
|
fail(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (String modelName : mav.getModel().keySet()) {
|
for (String modelName : model.keySet()) {
|
||||||
Object assertionValue = expectedModel.get(modelName);
|
Object assertionValue = expectedModel.get(modelName);
|
||||||
Object mavValue = mav.getModel().get(modelName);
|
Object mavValue = model.get(modelName);
|
||||||
if (!assertionValue.equals(mavValue)) {
|
if (!assertionValue.equals(mavValue)) {
|
||||||
sb.append("Value under name '").append(modelName).append("' differs, should have been '").append(
|
sb.append("Value under name '").append(modelName).append("' differs, should have been '").append(
|
||||||
assertionValue).append("' but was '").append(mavValue).append("'\n");
|
assertionValue).append("' but was '").append(mavValue).append("'\n");
|
||||||
|
@ -151,18 +149,15 @@ public abstract class ModelAndViewAssert {
|
||||||
/**
|
/**
|
||||||
* Compare each individual entry in a list after having sorted both lists
|
* Compare each individual entry in a list after having sorted both lists
|
||||||
* (optionally using a comparator).
|
* (optionally using a comparator).
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param modelName name of the object to add to the model (never
|
* @param modelName name of the object to add to the model (never {@code null})
|
||||||
* {@code null})
|
|
||||||
* @param expectedList the expected list
|
* @param expectedList the expected list
|
||||||
* @param comparator the comparator to use (may be {@code null}). If
|
* @param comparator the comparator to use (may be {@code null}). If not
|
||||||
* not specifying the comparator, both lists will be sorted not using any
|
* specifying the comparator, both lists will be sorted not using any comparator.
|
||||||
* comparator.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
public static void assertSortAndCompareListModelAttribute(ModelAndView mav, String modelName, List expectedList,
|
public static void assertSortAndCompareListModelAttribute(
|
||||||
Comparator comparator) {
|
ModelAndView mav, String modelName, List expectedList, Comparator comparator) {
|
||||||
|
|
||||||
assertTrue("ModelAndView is null", mav != null);
|
assertTrue("ModelAndView is null", mav != null);
|
||||||
List modelList = assertAndReturnModelAttributeOfType(mav, modelName, List.class);
|
List modelList = assertAndReturnModelAttributeOfType(mav, modelName, List.class);
|
||||||
|
@ -187,18 +182,20 @@ public abstract class ModelAndViewAssert {
|
||||||
/**
|
/**
|
||||||
* Check to see if the view name in the ModelAndView matches the given
|
* Check to see if the view name in the ModelAndView matches the given
|
||||||
* {@code expectedName}.
|
* {@code expectedName}.
|
||||||
*
|
|
||||||
* @param mav ModelAndView to test against (never {@code null})
|
* @param mav ModelAndView to test against (never {@code null})
|
||||||
* @param expectedName the name of the model value
|
* @param expectedName the name of the model value
|
||||||
*/
|
*/
|
||||||
public static void assertViewName(ModelAndView mav, String expectedName) {
|
public static void assertViewName(ModelAndView mav, String expectedName) {
|
||||||
assertTrue("ModelAndView is null", mav != null);
|
if (mav == null) {
|
||||||
|
fail("ModelAndView is null");
|
||||||
|
}
|
||||||
assertTrue("View name is not equal to '" + expectedName + "' but was '" + mav.getViewName() + "'",
|
assertTrue("View name is not equal to '" + expectedName + "' but was '" + mav.getViewName() + "'",
|
||||||
ObjectUtils.nullSafeEquals(expectedName, mav.getViewName()));
|
ObjectUtils.nullSafeEquals(expectedName, mav.getViewName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendNonMatchingSetsErrorMessage(Set<String> assertionSet, Set<String> incorrectSet,
|
|
||||||
StringBuilder sb) {
|
private static void appendNonMatchingSetsErrorMessage(
|
||||||
|
Set<String> assertionSet, Set<String> incorrectSet, StringBuilder sb) {
|
||||||
|
|
||||||
Set<String> tempSet = new HashSet<>();
|
Set<String> tempSet = new HashSet<>();
|
||||||
tempSet.addAll(incorrectSet);
|
tempSet.addAll(incorrectSet);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -98,8 +98,10 @@ public class ContentRequestMatchers {
|
||||||
public void match(ClientHttpRequest request) throws IOException, AssertionError {
|
public void match(ClientHttpRequest request) throws IOException, AssertionError {
|
||||||
MediaType actualContentType = request.getHeaders().getContentType();
|
MediaType actualContentType = request.getHeaders().getContentType();
|
||||||
assertTrue("Content type not set", actualContentType != null);
|
assertTrue("Content type not set", actualContentType != null);
|
||||||
assertTrue("Content type [" + actualContentType + "] is not compatible with [" + contentType + "]",
|
if (actualContentType != null) {
|
||||||
actualContentType.isCompatibleWith(contentType));
|
assertTrue("Content type [" + actualContentType + "] is not compatible with [" + contentType + "]",
|
||||||
|
actualContentType.isCompatibleWith(contentType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,8 +180,10 @@ public abstract class MockRestRequestMatchers {
|
||||||
@Override
|
@Override
|
||||||
public void match(ClientHttpRequest request) {
|
public void match(ClientHttpRequest request) {
|
||||||
assertValueCount("header", name, request.getHeaders(), matchers.length);
|
assertValueCount("header", name, request.getHeaders(), matchers.length);
|
||||||
for (int i = 0 ; i < matchers.length; i++) {
|
List<String> headerValues = request.getHeaders().get(name);
|
||||||
assertThat("Request header", request.getHeaders().get(name).get(i), matchers[i]);
|
Assert.state(headerValues != null, "No header values");
|
||||||
|
for (int i = 0; i < matchers.length; i++) {
|
||||||
|
assertThat("Request header [" + name + "]", headerValues.get(i), matchers[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -195,9 +197,10 @@ public abstract class MockRestRequestMatchers {
|
||||||
@Override
|
@Override
|
||||||
public void match(ClientHttpRequest request) {
|
public void match(ClientHttpRequest request) {
|
||||||
assertValueCount("header", name, request.getHeaders(), expectedValues.length);
|
assertValueCount("header", name, request.getHeaders(), expectedValues.length);
|
||||||
|
List<String> headerValues = request.getHeaders().get(name);
|
||||||
|
Assert.state(headerValues != null, "No header values");
|
||||||
for (int i = 0 ; i < expectedValues.length; i++) {
|
for (int i = 0 ; i < expectedValues.length; i++) {
|
||||||
assertEquals("Request header + [" + name + "]",
|
assertEquals("Request header [" + name + "]", expectedValues[i], headerValues.get(i));
|
||||||
expectedValues[i], request.getHeaders().get(name).get(i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,9 +43,7 @@ class DefaultRouterFunctionSpec extends AbstractMockServerSpec<WebTestClient.Rou
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WebTestClient.RouterFunctionSpec handlerStrategies(HandlerStrategies handlerStrategies) {
|
public WebTestClient.RouterFunctionSpec handlerStrategies(HandlerStrategies handlerStrategies) {
|
||||||
if (handlerStrategies != null) {
|
this.handlerStrategies = handlerStrategies;
|
||||||
this.handlerStrategies = handlerStrategies;
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,9 @@ import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
import org.springframework.web.util.UriBuilder;
|
import org.springframework.web.util.UriBuilder;
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.*;
|
||||||
import static org.springframework.test.util.AssertionErrors.assertEquals;
|
import static org.springframework.test.util.AssertionErrors.*;
|
||||||
import static org.springframework.test.util.AssertionErrors.assertTrue;
|
import static org.springframework.web.reactive.function.BodyExtractors.*;
|
||||||
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
|
|
||||||
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of {@link WebTestClient}.
|
* Default implementation of {@link WebTestClient}.
|
||||||
|
@ -73,7 +71,7 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
private final AtomicLong requestIndex = new AtomicLong();
|
private final AtomicLong requestIndex = new AtomicLong();
|
||||||
|
|
||||||
|
|
||||||
DefaultWebTestClient(WebClient.Builder clientBuilder, ClientHttpConnector connector, Duration timeout) {
|
DefaultWebTestClient(WebClient.Builder clientBuilder, ClientHttpConnector connector, @Nullable Duration timeout) {
|
||||||
Assert.notNull(clientBuilder, "WebClient.Builder is required");
|
Assert.notNull(clientBuilder, "WebClient.Builder is required");
|
||||||
this.wiretapConnector = new WiretapConnector(connector);
|
this.wiretapConnector = new WiretapConnector(connector);
|
||||||
this.webClient = clientBuilder.clientConnector(this.wiretapConnector).build();
|
this.webClient = clientBuilder.clientConnector(this.wiretapConnector).build();
|
||||||
|
@ -179,15 +177,13 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
|
|
||||||
private final String requestId;
|
private final String requestId;
|
||||||
|
|
||||||
|
DefaultRequestBodySpec(WebClient.RequestBodySpec spec, @Nullable String uriTemplate) {
|
||||||
DefaultRequestBodySpec(WebClient.RequestBodySpec spec, String uriTemplate) {
|
|
||||||
this.bodySpec = spec;
|
this.bodySpec = spec;
|
||||||
this.uriTemplate = uriTemplate;
|
this.uriTemplate = uriTemplate;
|
||||||
this.requestId = String.valueOf(requestIndex.incrementAndGet());
|
this.requestId = String.valueOf(requestIndex.incrementAndGet());
|
||||||
this.bodySpec.header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, this.requestId);
|
this.bodySpec.header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, this.requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RequestBodySpec header(String headerName, String... headerValues) {
|
public RequestBodySpec header(String headerName, String... headerValues) {
|
||||||
this.bodySpec.header(headerName, headerValues);
|
this.bodySpec.header(headerName, headerValues);
|
||||||
|
@ -276,7 +272,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
ExchangeResult exchangeResult = wiretapConnector.claimRequest(this.requestId);
|
ExchangeResult exchangeResult = wiretapConnector.claimRequest(this.requestId);
|
||||||
return new DefaultResponseSpec(exchangeResult, clientResponse, this.uriTemplate, getTimeout());
|
return new DefaultResponseSpec(exchangeResult, clientResponse, this.uriTemplate, getTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,7 +281,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
|
|
||||||
private final Duration timeout;
|
private final Duration timeout;
|
||||||
|
|
||||||
|
|
||||||
UndecodedExchangeResult(ExchangeResult result, ClientResponse response,
|
UndecodedExchangeResult(ExchangeResult result, ClientResponse response,
|
||||||
String uriTemplate, Duration timeout) {
|
String uriTemplate, Duration timeout) {
|
||||||
|
|
||||||
|
@ -295,7 +289,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> EntityExchangeResult<T> decode(ResolvableType bodyType) {
|
public <T> EntityExchangeResult<T> decode(ResolvableType bodyType) {
|
||||||
T body = (T) this.response.body(toMono(bodyType)).block(this.timeout);
|
T body = (T) this.response.body(toMono(bodyType)).block(this.timeout);
|
||||||
|
@ -318,7 +311,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
byte[] body = (resource != null ? resource.getByteArray() : null);
|
byte[] body = (resource != null ? resource.getByteArray() : null);
|
||||||
return new EntityExchangeResult<>(this, body);
|
return new EntityExchangeResult<>(this, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,7 +318,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
|
|
||||||
private final UndecodedExchangeResult result;
|
private final UndecodedExchangeResult result;
|
||||||
|
|
||||||
|
|
||||||
DefaultResponseSpec(ExchangeResult result, ClientResponse response, String uriTemplate, Duration timeout) {
|
DefaultResponseSpec(ExchangeResult result, ClientResponse response, String uriTemplate, Duration timeout) {
|
||||||
this.result = new UndecodedExchangeResult(result, response, uriTemplate, timeout);
|
this.result = new UndecodedExchangeResult(result, response, uriTemplate, timeout);
|
||||||
}
|
}
|
||||||
|
@ -342,13 +333,15 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public <B> BodySpec<B, ?> expectBody(Class<B> bodyType) {
|
public <B> BodySpec<B, ?> expectBody(Class<B> bodyType) {
|
||||||
return expectBody(ResolvableType.forClass(bodyType));
|
return (BodySpec<B, ?>) expectBody(ResolvableType.forClass(bodyType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
public <B> BodySpec<B, ?> expectBody(ResolvableType bodyType) {
|
public <B> BodySpec<B, ?> expectBody(ResolvableType bodyType) {
|
||||||
return new DefaultBodySpec<>(this.result.decode(bodyType));
|
return new DefaultBodySpec(this.result.decode(bodyType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -375,7 +368,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
public <T> FluxExchangeResult<T> returnResult(ResolvableType elementType) {
|
public <T> FluxExchangeResult<T> returnResult(ResolvableType elementType) {
|
||||||
return this.result.decodeToFlux(elementType);
|
return this.result.decodeToFlux(elementType);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -383,26 +375,23 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
|
|
||||||
private final EntityExchangeResult<B> result;
|
private final EntityExchangeResult<B> result;
|
||||||
|
|
||||||
|
|
||||||
DefaultBodySpec(EntityExchangeResult<B> result) {
|
DefaultBodySpec(EntityExchangeResult<B> result) {
|
||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected EntityExchangeResult<B> getResult() {
|
protected EntityExchangeResult<B> getResult() {
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends S> T isEqualTo(B expected) {
|
public <T extends S> T isEqualTo(B expected) {
|
||||||
B actual = this.result.getResponseBody();
|
this.result.assertWithDiagnostics(() ->
|
||||||
this.result.assertWithDiagnostics(() -> assertEquals("Response body", expected, actual));
|
assertEquals("Response body", expected, this.result.getResponseBody()));
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer) {
|
public <T extends S> T consumeWith(Consumer<EntityExchangeResult<B>> consumer) {
|
||||||
B actual = this.result.getResponseBody();
|
|
||||||
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
this.result.assertWithDiagnostics(() -> consumer.accept(this.result));
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
@ -416,24 +405,21 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
public EntityExchangeResult<B> returnResult() {
|
public EntityExchangeResult<B> returnResult() {
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class DefaultListBodySpec<E> extends DefaultBodySpec<List<E>, ListBodySpec<E>>
|
private static class DefaultListBodySpec<E> extends DefaultBodySpec<List<E>, ListBodySpec<E>>
|
||||||
implements ListBodySpec<E> {
|
implements ListBodySpec<E> {
|
||||||
|
|
||||||
|
|
||||||
DefaultListBodySpec(EntityExchangeResult<List<E>> result) {
|
DefaultListBodySpec(EntityExchangeResult<List<E>> result) {
|
||||||
super(result);
|
super(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListBodySpec<E> hasSize(int size) {
|
public ListBodySpec<E> hasSize(int size) {
|
||||||
List<E> actual = getResult().getResponseBody();
|
List<E> actual = getResult().getResponseBody();
|
||||||
String message = "Response body does not contain " + size + " elements";
|
String message = "Response body does not contain " + size + " elements";
|
||||||
getResult().assertWithDiagnostics(() -> assertEquals(message, size, actual.size()));
|
getResult().assertWithDiagnostics(() -> assertEquals(message, size, (actual != null ? actual.size() : 0)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +429,7 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
List<E> expected = Arrays.asList(elements);
|
List<E> expected = Arrays.asList(elements);
|
||||||
List<E> actual = getResult().getResponseBody();
|
List<E> actual = getResult().getResponseBody();
|
||||||
String message = "Response body does not contain " + expected;
|
String message = "Response body does not contain " + expected;
|
||||||
getResult().assertWithDiagnostics(() -> assertTrue(message, actual.containsAll(expected)));
|
getResult().assertWithDiagnostics(() -> assertTrue(message, (actual != null && actual.containsAll(expected))));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,8 +438,8 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
public ListBodySpec<E> doesNotContain(E... elements) {
|
public ListBodySpec<E> doesNotContain(E... elements) {
|
||||||
List<E> expected = Arrays.asList(elements);
|
List<E> expected = Arrays.asList(elements);
|
||||||
List<E> actual = getResult().getResponseBody();
|
List<E> actual = getResult().getResponseBody();
|
||||||
String message = "Response body should have contained " + expected;
|
String message = "Response body should not have contained " + expected;
|
||||||
getResult().assertWithDiagnostics(() -> assertTrue(message, !actual.containsAll(expected)));
|
getResult().assertWithDiagnostics(() -> assertTrue(message, (actual == null || !actual.containsAll(expected))));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +447,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
public EntityExchangeResult<List<E>> returnResult() {
|
public EntityExchangeResult<List<E>> returnResult() {
|
||||||
return getResult();
|
return getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -471,13 +456,11 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
|
|
||||||
private final boolean isEmpty;
|
private final boolean isEmpty;
|
||||||
|
|
||||||
|
|
||||||
DefaultBodyContentSpec(EntityExchangeResult<byte[]> result) {
|
DefaultBodyContentSpec(EntityExchangeResult<byte[]> result) {
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.isEmpty = (result.getResponseBody() == null);
|
this.isEmpty = (result.getResponseBody() == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityExchangeResult<Void> isEmpty() {
|
public EntityExchangeResult<Void> isEmpty() {
|
||||||
this.result.assertWithDiagnostics(() -> assertTrue("Expected empty body", this.isEmpty));
|
this.result.assertWithDiagnostics(() -> assertTrue("Expected empty body", this.isEmpty));
|
||||||
|
@ -502,14 +485,14 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
return new JsonPathAssertions(this, getBodyAsString(), expression, args);
|
return new JsonPathAssertions(this, getBodyAsString(), expression, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String getBodyAsString() {
|
private String getBodyAsString() {
|
||||||
if (this.isEmpty) {
|
byte[] body = this.result.getResponseBody();
|
||||||
return null;
|
if (body == null || body.length == 0) {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
MediaType mediaType = this.result.getResponseHeaders().getContentType();
|
MediaType mediaType = this.result.getResponseHeaders().getContentType();
|
||||||
Charset charset = Optional.ofNullable(mediaType).map(MimeType::getCharset).orElse(UTF_8);
|
Charset charset = Optional.ofNullable(mediaType).map(MimeType::getCharset).orElse(UTF_8);
|
||||||
return new String(this.result.getResponseBody(), charset);
|
return new String(body, charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -522,7 +505,6 @@ class DefaultWebTestClient implements WebTestClient {
|
||||||
public EntityExchangeResult<byte[]> returnResult() {
|
public EntityExchangeResult<byte[]> returnResult() {
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.test.web.reactive.server;
|
package org.springframework.test.web.reactive.server;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code ExchangeResult} sub-class that exposes the response body fully
|
* {@code ExchangeResult} sub-class that exposes the response body fully
|
||||||
* extracted to a representation of type {@code <T>}.
|
* extracted to a representation of type {@code <T>}.
|
||||||
|
@ -30,7 +32,7 @@ public class EntityExchangeResult<T> extends ExchangeResult {
|
||||||
private final T body;
|
private final T body;
|
||||||
|
|
||||||
|
|
||||||
EntityExchangeResult(ExchangeResult result, T body) {
|
EntityExchangeResult(ExchangeResult result, @Nullable T body) {
|
||||||
super(result);
|
super(result);
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +41,7 @@ public class EntityExchangeResult<T> extends ExchangeResult {
|
||||||
/**
|
/**
|
||||||
* Return the entity extracted from the response body.
|
* Return the entity extracted from the response body.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public T getResponseBody() {
|
public T getResponseBody() {
|
||||||
return this.body;
|
return this.body;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseCookie;
|
import org.springframework.http.ResponseCookie;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
|
@ -110,6 +111,7 @@ public class ExchangeResult {
|
||||||
/**
|
/**
|
||||||
* Return the original URI template used to prepare the request, if any.
|
* Return the original URI template used to prepare the request, if any.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public String getUriTemplate() {
|
public String getUriTemplate() {
|
||||||
return this.uriTemplate;
|
return this.uriTemplate;
|
||||||
}
|
}
|
||||||
|
@ -194,11 +196,7 @@ public class ExchangeResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStatusReason() {
|
private String getStatusReason() {
|
||||||
String reason = "";
|
return getStatus().getReasonPhrase();
|
||||||
if (getStatus() != null && getStatus().getReasonPhrase() != null) {
|
|
||||||
reason = getStatus().getReasonPhrase();
|
|
||||||
}
|
|
||||||
return reason;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatHeaders(HttpHeaders headers, String delimiter) {
|
private String formatHeaders(HttpHeaders headers, String delimiter) {
|
||||||
|
@ -207,7 +205,7 @@ public class ExchangeResult {
|
||||||
.collect(Collectors.joining(delimiter));
|
.collect(Collectors.joining(delimiter));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatBody(MediaType contentType, MonoProcessor<byte[]> body) {
|
private String formatBody(@Nullable MediaType contentType, MonoProcessor<byte[]> body) {
|
||||||
if (body.isSuccess()) {
|
if (body.isSuccess()) {
|
||||||
byte[] bytes = body.block(Duration.ZERO);
|
byte[] bytes = body.block(Duration.ZERO);
|
||||||
if (bytes.length == 0) {
|
if (bytes.length == 0) {
|
||||||
|
|
|
@ -23,9 +23,9 @@ import org.springframework.http.CacheControl;
|
||||||
import org.springframework.http.ContentDisposition;
|
import org.springframework.http.ContentDisposition;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
import static org.springframework.test.util.AssertionErrors.assertEquals;
|
import static org.springframework.test.util.AssertionErrors.*;
|
||||||
import static org.springframework.test.util.AssertionErrors.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assertions on headers of the response.
|
* Assertions on headers of the response.
|
||||||
|
@ -62,7 +62,9 @@ public class HeaderAssertions {
|
||||||
*/
|
*/
|
||||||
public WebTestClient.ResponseSpec valueMatches(String name, String pattern) {
|
public WebTestClient.ResponseSpec valueMatches(String name, String pattern) {
|
||||||
String value = getHeaders().getFirst(name);
|
String value = getHeaders().getFirst(name);
|
||||||
assertTrue(getMessage(name) + " not found", value != null);
|
if (value == null) {
|
||||||
|
fail(getMessage(name) + " not found");
|
||||||
|
}
|
||||||
boolean match = Pattern.compile(pattern).matcher(value).matches();
|
boolean match = Pattern.compile(pattern).matcher(value).matches();
|
||||||
String message = getMessage(name) + "=\'" + value + "\' does not match \'" + pattern + "\'";
|
String message = getMessage(name) + "=\'" + value + "\' does not match \'" + pattern + "\'";
|
||||||
this.exchangeResult.assertWithDiagnostics(() -> assertTrue(message, match));
|
this.exchangeResult.assertWithDiagnostics(() -> assertTrue(message, match));
|
||||||
|
@ -122,7 +124,7 @@ public class HeaderAssertions {
|
||||||
return "Response header [" + headerName + "]";
|
return "Response header [" + headerName + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private WebTestClient.ResponseSpec assertHeader(String name, Object expected, Object actual) {
|
private WebTestClient.ResponseSpec assertHeader(String name, @Nullable Object expected, @Nullable Object actual) {
|
||||||
this.exchangeResult.assertWithDiagnostics(() -> assertEquals(getMessage(name), expected, actual));
|
this.exchangeResult.assertWithDiagnostics(() -> assertEquals(getMessage(name), expected, actual));
|
||||||
return this.responseSpec;
|
return this.responseSpec;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.test.web.reactive.server;
|
package org.springframework.test.web.reactive.server;
|
||||||
|
|
||||||
import org.springframework.test.util.JsonPathExpectationsHelper;
|
import org.springframework.test.util.JsonPathExpectationsHelper;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> assertions.
|
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> assertions.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.test.web.servlet;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.web.servlet.FlashMap;
|
import org.springframework.web.servlet.FlashMap;
|
||||||
|
@ -71,7 +72,7 @@ class DefaultMvcResult implements MvcResult {
|
||||||
return this.mockResponse;
|
return this.mockResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHandler(Object handler) {
|
public void setHandler(@Nullable Object handler) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ class DefaultMvcResult implements MvcResult {
|
||||||
return this.handler;
|
return this.handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterceptors(HandlerInterceptor... interceptors) {
|
public void setInterceptors(@Nullable HandlerInterceptor... interceptors) {
|
||||||
this.interceptors = interceptors;
|
this.interceptors = interceptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ class DefaultMvcResult implements MvcResult {
|
||||||
return this.resolvedException;
|
return this.resolvedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModelAndView(ModelAndView mav) {
|
public void setModelAndView(@Nullable ModelAndView mav) {
|
||||||
this.modelAndView = mav;
|
this.modelAndView = mav;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -79,18 +79,16 @@ public final class MockMvc {
|
||||||
* Private constructor, not for direct instantiation.
|
* Private constructor, not for direct instantiation.
|
||||||
* @see org.springframework.test.web.servlet.setup.MockMvcBuilders
|
* @see org.springframework.test.web.servlet.setup.MockMvcBuilders
|
||||||
*/
|
*/
|
||||||
MockMvc(TestDispatcherServlet servlet, Filter[] filters, ServletContext servletContext) {
|
MockMvc(TestDispatcherServlet servlet, Filter... filters) {
|
||||||
|
|
||||||
Assert.notNull(servlet, "DispatcherServlet is required");
|
Assert.notNull(servlet, "DispatcherServlet is required");
|
||||||
Assert.notNull(filters, "filters cannot be null");
|
Assert.notNull(filters, "Filters cannot be null");
|
||||||
Assert.noNullElements(filters, "filters cannot contain null values");
|
Assert.noNullElements(filters, "Filters cannot contain null values");
|
||||||
Assert.notNull(servletContext, "A ServletContext is required");
|
|
||||||
|
|
||||||
this.servlet = servlet;
|
this.servlet = servlet;
|
||||||
this.filters = filters;
|
this.filters = filters;
|
||||||
this.servletContext = servletContext;
|
this.servletContext = servlet.getServletContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default request builder merged into every performed request.
|
* A default request builder merged into every performed request.
|
||||||
* @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#defaultRequest(RequestBuilder)
|
* @see org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder#defaultRequest(RequestBuilder)
|
||||||
|
@ -120,18 +118,14 @@ public final class MockMvc {
|
||||||
/**
|
/**
|
||||||
* Perform a request and return a type that allows chaining further
|
* Perform a request and return a type that allows chaining further
|
||||||
* actions, such as asserting expectations, on the result.
|
* actions, such as asserting expectations, on the result.
|
||||||
*
|
|
||||||
* @param requestBuilder used to prepare the request to execute;
|
* @param requestBuilder used to prepare the request to execute;
|
||||||
* see static factory methods in
|
* see static factory methods in
|
||||||
* {@link org.springframework.test.web.servlet.request.MockMvcRequestBuilders}
|
* {@link org.springframework.test.web.servlet.request.MockMvcRequestBuilders}
|
||||||
*
|
|
||||||
* @return an instance of {@link ResultActions}; never {@code null}
|
* @return an instance of {@link ResultActions}; never {@code null}
|
||||||
*
|
|
||||||
* @see org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
* @see org.springframework.test.web.servlet.request.MockMvcRequestBuilders
|
||||||
* @see org.springframework.test.web.servlet.result.MockMvcResultMatchers
|
* @see org.springframework.test.web.servlet.result.MockMvcResultMatchers
|
||||||
*/
|
*/
|
||||||
public ResultActions perform(RequestBuilder requestBuilder) throws Exception {
|
public ResultActions perform(RequestBuilder requestBuilder) throws Exception {
|
||||||
|
|
||||||
if (this.defaultRequestBuilder != null) {
|
if (this.defaultRequestBuilder != null) {
|
||||||
if (requestBuilder instanceof Mergeable) {
|
if (requestBuilder instanceof Mergeable) {
|
||||||
requestBuilder = (RequestBuilder) ((Mergeable) requestBuilder).merge(this.defaultRequestBuilder);
|
requestBuilder = (RequestBuilder) ((Mergeable) requestBuilder).merge(this.defaultRequestBuilder);
|
||||||
|
@ -156,28 +150,23 @@ public final class MockMvc {
|
||||||
|
|
||||||
if (DispatcherType.ASYNC.equals(request.getDispatcherType()) &&
|
if (DispatcherType.ASYNC.equals(request.getDispatcherType()) &&
|
||||||
request.getAsyncContext() != null & !request.isAsyncStarted()) {
|
request.getAsyncContext() != null & !request.isAsyncStarted()) {
|
||||||
|
|
||||||
request.getAsyncContext().complete();
|
request.getAsyncContext().complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyDefaultResultActions(mvcResult);
|
applyDefaultResultActions(mvcResult);
|
||||||
|
|
||||||
RequestContextHolder.setRequestAttributes(previousAttributes);
|
RequestContextHolder.setRequestAttributes(previousAttributes);
|
||||||
|
|
||||||
return new ResultActions() {
|
return new ResultActions() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultActions andExpect(ResultMatcher matcher) throws Exception {
|
public ResultActions andExpect(ResultMatcher matcher) throws Exception {
|
||||||
matcher.match(mvcResult);
|
matcher.match(mvcResult);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultActions andDo(ResultHandler handler) throws Exception {
|
public ResultActions andDo(ResultHandler handler) throws Exception {
|
||||||
handler.handle(mvcResult);
|
handler.handle(mvcResult);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MvcResult andReturn() {
|
public MvcResult andReturn() {
|
||||||
return mvcResult;
|
return mvcResult;
|
||||||
|
@ -185,6 +174,7 @@ public final class MockMvc {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void applyDefaultResultActions(MvcResult mvcResult) throws Exception {
|
private void applyDefaultResultActions(MvcResult mvcResult) throws Exception {
|
||||||
|
|
||||||
for (ResultMatcher matcher : this.defaultResultMatchers) {
|
for (ResultMatcher matcher : this.defaultResultMatchers) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,10 +18,10 @@ package org.springframework.test.web.servlet;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
import org.springframework.core.NestedRuntimeException;
|
import org.springframework.core.NestedRuntimeException;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.mock.web.MockServletConfig;
|
import org.springframework.mock.web.MockServletConfig;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
@ -43,9 +43,7 @@ public abstract class MockMvcBuilderSupport {
|
||||||
protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
|
protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
|
||||||
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
|
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
|
||||||
List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers,
|
List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers,
|
||||||
List<DispatcherServletCustomizer> dispatcherServletCustomizers) {
|
@Nullable List<DispatcherServletCustomizer> dispatcherServletCustomizers) {
|
||||||
|
|
||||||
ServletContext servletContext = webAppContext.getServletContext();
|
|
||||||
|
|
||||||
TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext);
|
TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext);
|
||||||
if (dispatcherServletCustomizers != null) {
|
if (dispatcherServletCustomizers != null) {
|
||||||
|
@ -61,7 +59,7 @@ public abstract class MockMvcBuilderSupport {
|
||||||
throw new MockMvcBuildException("Failed to initialize TestDispatcherServlet", ex);
|
throw new MockMvcBuildException("Failed to initialize TestDispatcherServlet", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
MockMvc mockMvc = new MockMvc(dispatcherServlet, filters, servletContext);
|
MockMvc mockMvc = new MockMvc(dispatcherServlet, filters);
|
||||||
mockMvc.setDefaultRequest(defaultRequestBuilder);
|
mockMvc.setDefaultRequest(defaultRequestBuilder);
|
||||||
mockMvc.setGlobalResultMatchers(globalResultMatchers);
|
mockMvc.setGlobalResultMatchers(globalResultMatchers);
|
||||||
mockMvc.setGlobalResultHandlers(globalResultHandlers);
|
mockMvc.setGlobalResultHandlers(globalResultHandlers);
|
||||||
|
@ -69,6 +67,7 @@ public abstract class MockMvcBuilderSupport {
|
||||||
return mockMvc;
|
return mockMvc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
private static class MockMvcBuildException extends NestedRuntimeException {
|
private static class MockMvcBuildException extends NestedRuntimeException {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License; Version 2.0 (the "License");
|
* Licensed under the Apache License; Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -60,7 +60,7 @@ public interface MvcResult {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@code ModelAndView} prepared by the handler.
|
* Return the {@code ModelAndView} prepared by the handler.
|
||||||
* @return a {@code ModelAndView}, or {@code null}
|
* @return a {@code ModelAndView}, or {@code null} if none
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
ModelAndView getModelAndView();
|
ModelAndView getModelAndView();
|
||||||
|
@ -68,7 +68,7 @@ public interface MvcResult {
|
||||||
/**
|
/**
|
||||||
* Return any exception raised by a handler and successfully resolved
|
* Return any exception raised by a handler and successfully resolved
|
||||||
* through a {@link HandlerExceptionResolver}.
|
* through a {@link HandlerExceptionResolver}.
|
||||||
* @return an exception, possibly {@code null}
|
* @return an exception, or {@code null} if none
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
Exception getResolvedException();
|
Exception getResolvedException();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -34,7 +34,6 @@ public interface RequestBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the request.
|
* Build the request.
|
||||||
*
|
|
||||||
* @param servletContext the {@link ServletContext} to use to create the request
|
* @param servletContext the {@link ServletContext} to use to create the request
|
||||||
* @return the request
|
* @return the request
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -107,11 +107,13 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
Charset charset = getCharset();
|
Charset charset = getCharset();
|
||||||
String httpMethod = this.webRequest.getHttpMethod().name();
|
String httpMethod = this.webRequest.getHttpMethod().name();
|
||||||
UriComponents uriComponents = uriComponents();
|
UriComponents uriComponents = uriComponents();
|
||||||
|
String path = uriComponents.getPath();
|
||||||
|
|
||||||
MockHttpServletRequest request = new HtmlUnitMockHttpServletRequest(
|
MockHttpServletRequest request = new HtmlUnitMockHttpServletRequest(
|
||||||
servletContext, httpMethod, uriComponents.getPath());
|
servletContext, httpMethod, (path != null ? path : ""));
|
||||||
parent(request, this.parentBuilder);
|
parent(request, this.parentBuilder);
|
||||||
request.setServerName(uriComponents.getHost()); // needs to be first for additional headers
|
String host = uriComponents.getHost();
|
||||||
|
request.setServerName(host != null ? host : ""); // needs to be first for additional headers
|
||||||
authType(request);
|
authType(request);
|
||||||
request.setCharacterEncoding(charset.name());
|
request.setCharacterEncoding(charset.name());
|
||||||
content(request, charset);
|
content(request, charset);
|
||||||
|
@ -125,7 +127,8 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
ports(uriComponents, request);
|
ports(uriComponents, request);
|
||||||
request.setProtocol("HTTP/1.1");
|
request.setProtocol("HTTP/1.1");
|
||||||
request.setQueryString(uriComponents.getQuery());
|
request.setQueryString(uriComponents.getQuery());
|
||||||
request.setScheme(uriComponents.getScheme());
|
String scheme = uriComponents.getScheme();
|
||||||
|
request.setScheme(scheme != null ? scheme : "");
|
||||||
request.setPathInfo(null);
|
request.setPathInfo(null);
|
||||||
|
|
||||||
return postProcess(request);
|
return postProcess(request);
|
||||||
|
@ -146,7 +149,7 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parent(MockHttpServletRequest request, RequestBuilder parent) {
|
private void parent(MockHttpServletRequest request, @Nullable RequestBuilder parent) {
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -156,11 +159,13 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
// session
|
// session
|
||||||
HttpSession parentSession = parentRequest.getSession(false);
|
HttpSession parentSession = parentRequest.getSession(false);
|
||||||
if (parentSession != null) {
|
if (parentSession != null) {
|
||||||
|
HttpSession localSession = request.getSession();
|
||||||
|
Assert.state(localSession != null, "No local HttpSession");
|
||||||
Enumeration<String> attrNames = parentSession.getAttributeNames();
|
Enumeration<String> attrNames = parentSession.getAttributeNames();
|
||||||
while (attrNames.hasMoreElements()) {
|
while (attrNames.hasMoreElements()) {
|
||||||
String attrName = attrNames.nextElement();
|
String attrName = attrNames.nextElement();
|
||||||
Object attrValue = parentSession.getAttribute(attrName);
|
Object attrValue = parentSession.getAttribute(attrName);
|
||||||
request.getSession().setAttribute(attrName, attrValue);
|
localSession.setAttribute(attrName, attrValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +259,8 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Assert.isTrue(uriComponents.getPath().startsWith(this.contextPath),
|
String path = uriComponents.getPath();
|
||||||
|
Assert.isTrue(path != null && path.startsWith(this.contextPath),
|
||||||
() -> "\"" + uriComponents.getPath() +
|
() -> "\"" + uriComponents.getPath() +
|
||||||
"\" should start with context path \"" + this.contextPath + "\"");
|
"\" should start with context path \"" + this.contextPath + "\"");
|
||||||
request.setContextPath(this.contextPath);
|
request.setContextPath(this.contextPath);
|
||||||
|
@ -302,6 +308,7 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private String header(String headerName) {
|
private String header(String headerName) {
|
||||||
return this.webRequest.getAdditionalHeaders().get(headerName);
|
return this.webRequest.getAdditionalHeaders().get(headerName);
|
||||||
}
|
}
|
||||||
|
@ -376,9 +383,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
|
|
||||||
private void servletPath(MockHttpServletRequest request, String requestPath) {
|
private void servletPath(MockHttpServletRequest request, String requestPath) {
|
||||||
String servletPath = requestPath.substring(request.getContextPath().length());
|
String servletPath = requestPath.substring(request.getContextPath().length());
|
||||||
if ("".equals(servletPath)) {
|
|
||||||
servletPath = null;
|
|
||||||
}
|
|
||||||
request.setServletPath(servletPath);
|
request.setServletPath(servletPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +390,8 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
|
||||||
if ("".equals(request.getPathInfo())) {
|
if ("".equals(request.getPathInfo())) {
|
||||||
request.setPathInfo(null);
|
request.setPathInfo(null);
|
||||||
}
|
}
|
||||||
servletPath(request, uriComponents.getPath());
|
String path = uriComponents.getPath();
|
||||||
|
servletPath(request, (path != null ? path : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ports(UriComponents uriComponents, MockHttpServletRequest request) {
|
private void ports(UriComponents uriComponents, MockHttpServletRequest request) {
|
||||||
|
|
|
@ -154,9 +154,6 @@ public final class MockMvcWebConnection implements WebConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeCookies(WebRequest webRequest, javax.servlet.http.Cookie[] cookies) {
|
private void storeCookies(WebRequest webRequest, javax.servlet.http.Cookie[] cookies) {
|
||||||
if (cookies == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
CookieManager cookieManager = this.webClient.getCookieManager();
|
CookieManager cookieManager = this.webClient.getCookieManager();
|
||||||
for (javax.servlet.http.Cookie cookie : cookies) {
|
for (javax.servlet.http.Cookie cookie : cookies) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue