Merge branch '3.2.x' into master
Conflicts: gradle.properties spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/AbstractLobHandler.java spring-web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java spring-web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -39,11 +40,13 @@ import org.springframework.context.i18n.LocaleContext;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.context.i18n.SimpleLocaleContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.context.ConfigurableWebEnvironment;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
@@ -638,7 +641,10 @@ public abstract class FrameworkServlet extends HttpServletBean {
|
||||
// the context is refreshed; do it eagerly here to ensure servlet property sources
|
||||
// are in place for use in any post-processing or initialization that occurs
|
||||
// below prior to #refresh
|
||||
wac.getEnvironment().initPropertySources(getServletContext(), getServletConfig());
|
||||
ConfigurableEnvironment env = wac.getEnvironment();
|
||||
if (env instanceof ConfigurableWebEnvironment) {
|
||||
((ConfigurableWebEnvironment)env).initPropertySources(getServletContext(), getServletConfig());
|
||||
}
|
||||
|
||||
postProcessWebApplicationContext(wac);
|
||||
|
||||
@@ -861,10 +867,18 @@ public abstract class FrameworkServlet extends HttpServletBean {
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.doOptions(request, response);
|
||||
String allowedMethods = response.getHeader("Allow");
|
||||
allowedMethods += ", " + RequestMethod.PATCH.name();
|
||||
response.setHeader("Allow", allowedMethods);
|
||||
|
||||
// Use response wrapper for Servlet 2.5 compatibility where
|
||||
// the getHeader() method does not exist
|
||||
super.doOptions(request, new HttpServletResponseWrapper(response) {
|
||||
@Override
|
||||
public void setHeader(String name, String value) {
|
||||
if("Allow".equals(name)) {
|
||||
value = (StringUtils.hasLength(value) ? value + ", " : "") + RequestMethod.PATCH.name();
|
||||
}
|
||||
super.setHeader(name, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@ import javax.servlet.http.HttpServlet;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
@@ -35,6 +34,7 @@ import org.springframework.beans.PropertyAccessorFactory;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.EnvironmentCapable;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -42,9 +42,8 @@ import org.springframework.core.io.ResourceEditor;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.ConfigurableWebEnvironment;
|
||||
import org.springframework.web.context.support.StandardServletEnvironment;
|
||||
import org.springframework.web.context.support.ServletContextResourceLoader;
|
||||
import org.springframework.web.context.support.StandardServletEnvironment;
|
||||
|
||||
/**
|
||||
* Simple extension of {@link javax.servlet.http.HttpServlet} which treats
|
||||
@@ -91,7 +90,7 @@ public abstract class HttpServletBean extends HttpServlet
|
||||
*/
|
||||
private final Set<String> requiredProperties = new HashSet<String>();
|
||||
|
||||
private ConfigurableWebEnvironment environment;
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
|
||||
/**
|
||||
@@ -187,11 +186,11 @@ public abstract class HttpServletBean extends HttpServlet
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws IllegalArgumentException if environment is not assignable to
|
||||
* {@code ConfigurableWebEnvironment}.
|
||||
* {@code ConfigurableEnvironment}.
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
Assert.isInstanceOf(ConfigurableWebEnvironment.class, environment);
|
||||
this.environment = (ConfigurableWebEnvironment)environment;
|
||||
Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
|
||||
this.environment = (ConfigurableEnvironment) environment;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,7 +198,7 @@ public abstract class HttpServletBean extends HttpServlet
|
||||
* <p>If {@code null}, a new environment will be initialized via
|
||||
* {@link #createEnvironment()}.
|
||||
*/
|
||||
public ConfigurableWebEnvironment getEnvironment() {
|
||||
public ConfigurableEnvironment getEnvironment() {
|
||||
if (this.environment == null) {
|
||||
this.environment = this.createEnvironment();
|
||||
}
|
||||
@@ -210,7 +209,7 @@ public abstract class HttpServletBean extends HttpServlet
|
||||
* Create and return a new {@link StandardServletEnvironment}. Subclasses may override
|
||||
* in order to configure the environment or specialize the environment type returned.
|
||||
*/
|
||||
protected ConfigurableWebEnvironment createEnvironment() {
|
||||
protected ConfigurableEnvironment createEnvironment() {
|
||||
return new StandardServletEnvironment();
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,6 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
handlerMappingDef.setSource(source);
|
||||
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
handlerMappingDef.getPropertyValues().add("order", 0);
|
||||
handlerMappingDef.getPropertyValues().add("removeSemicolonContent", false);
|
||||
handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
|
||||
String methodMappingName = parserContext.getReaderContext().registerWithGeneratedName(handlerMappingDef);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,7 +29,7 @@ import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
|
||||
|
||||
/**
|
||||
* Helps with configuring a options for asynchronous request processing.
|
||||
* Helps with configuring options for asynchronous request processing.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
@@ -50,9 +50,9 @@ public class AsyncSupportConfigurer {
|
||||
/**
|
||||
* Set the default {@link AsyncTaskExecutor} to use when a controller method
|
||||
* returns a {@link Callable}. Controller methods can override this default on
|
||||
* a per-request basis by returning an {@link WebAsyncTask}.
|
||||
* a per-request basis by returning a {@link WebAsyncTask}.
|
||||
*
|
||||
* <p>By default a {@link SimpleAsyncTaskExecutor} instance is used and it's
|
||||
* <p>By default a {@link SimpleAsyncTaskExecutor} instance is used, and it's
|
||||
* highly recommended to change that default in production since the simple
|
||||
* executor does not re-use threads.
|
||||
*
|
||||
@@ -79,7 +79,7 @@ public class AsyncSupportConfigurer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure lifecycle intercepters with callbacks around concurrent request
|
||||
* Configure lifecycle interceptors with callbacks around concurrent request
|
||||
* execution that starts when a controller returns a
|
||||
* {@link java.util.concurrent.Callable}.
|
||||
*
|
||||
@@ -92,7 +92,7 @@ public class AsyncSupportConfigurer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure lifecycle intercepters with callbacks around concurrent request
|
||||
* Configure lifecycle interceptors with callbacks around concurrent request
|
||||
* execution that starts when a controller returns a {@link DeferredResult}.
|
||||
*
|
||||
* @param interceptors the interceptors to register
|
||||
|
||||
@@ -95,4 +95,4 @@ public class DefaultServletHandlerConfigurer {
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,4 +108,4 @@ public class ResourceHandlerRegistry {
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,4 +74,4 @@ public class ViewControllerRegistry {
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +192,6 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
RequestMappingHandlerMapping handlerMapping = new RequestMappingHandlerMapping();
|
||||
handlerMapping.setOrder(0);
|
||||
handlerMapping.setRemoveSemicolonContent(false);
|
||||
handlerMapping.setInterceptors(getInterceptors());
|
||||
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
|
||||
return handlerMapping;
|
||||
|
||||
@@ -128,4 +128,4 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||
|
||||
/**
|
||||
* Set if ";" (semicolon) content should be stripped from the request URI.
|
||||
* <p>The default value is {@code false}.
|
||||
* @see org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean)
|
||||
*/
|
||||
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.HandlerMethodSelector;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link HandlerMapping} implementations that define a
|
||||
@@ -61,6 +62,12 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||
private final MultiValueMap<String, T> urlMap = new LinkedMultiValueMap<String, T>();
|
||||
|
||||
|
||||
public AbstractHandlerMethodMapping() {
|
||||
UrlPathHelper pathHelper = new UrlPathHelper();
|
||||
pathHelper.setRemoveSemicolonContent(false);
|
||||
setUrlPathHelper(pathHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to detect handler methods in beans in ancestor ApplicationContexts.
|
||||
* <p>Default is "false": Only beans in the current ApplicationContext are
|
||||
@@ -165,25 +172,17 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||
* under the same mapping
|
||||
*/
|
||||
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
|
||||
HandlerMethod handlerMethod;
|
||||
if (handler instanceof String) {
|
||||
String beanName = (String) handler;
|
||||
handlerMethod = new HandlerMethod(beanName, getApplicationContext(), method);
|
||||
}
|
||||
else {
|
||||
handlerMethod = new HandlerMethod(handler, method);
|
||||
}
|
||||
|
||||
HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);
|
||||
HandlerMethod oldHandlerMethod = handlerMethods.get(mapping);
|
||||
if (oldHandlerMethod != null && !oldHandlerMethod.equals(handlerMethod)) {
|
||||
throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + handlerMethod.getBean()
|
||||
+ "' bean method \n" + handlerMethod + "\nto " + mapping + ": There is already '"
|
||||
if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {
|
||||
throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + newHandlerMethod.getBean()
|
||||
+ "' bean method \n" + newHandlerMethod + "\nto " + mapping + ": There is already '"
|
||||
+ oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped.");
|
||||
}
|
||||
|
||||
this.handlerMethods.put(mapping, handlerMethod);
|
||||
this.handlerMethods.put(mapping, newHandlerMethod);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod);
|
||||
logger.info("Mapped \"" + mapping + "\" onto " + newHandlerMethod);
|
||||
}
|
||||
|
||||
Set<String> patterns = getMappingPathPatterns(mapping);
|
||||
@@ -194,6 +193,24 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the HandlerMethod instance.
|
||||
* @param handler either a bean name or an actual handler instance
|
||||
* @param method the target method
|
||||
* @return the created HandlerMethod
|
||||
*/
|
||||
protected HandlerMethod createHandlerMethod(Object handler, Method method) {
|
||||
HandlerMethod handlerMethod;
|
||||
if (handler instanceof String) {
|
||||
String beanName = (String) handler;
|
||||
handlerMethod = new HandlerMethod(beanName, getApplicationContext(), method);
|
||||
}
|
||||
else {
|
||||
handlerMethod = new HandlerMethod(handler, method);
|
||||
}
|
||||
return handlerMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract and return the URL paths contained in a mapping.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,9 @@ package org.springframework.web.servlet.mvc.annotation;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
@@ -32,9 +35,17 @@ import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
|
||||
* <p>This exception resolver is enabled by default in the {@link org.springframework.web.servlet.DispatcherServlet}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||
public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver implements MessageSourceAware {
|
||||
|
||||
private MessageSource messageSource;
|
||||
|
||||
|
||||
public void setMessageSource(MessageSource messageSource) {
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
|
||||
@@ -69,6 +80,9 @@ public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionRes
|
||||
|
||||
int statusCode = responseStatus.value().value();
|
||||
String reason = responseStatus.reason();
|
||||
if (this.messageSource != null) {
|
||||
reason = this.messageSource.getMessage(reason, null, reason, LocaleContextHolder.getLocale());
|
||||
}
|
||||
if (!StringUtils.hasLength(reason)) {
|
||||
response.sendError(statusCode);
|
||||
}
|
||||
|
||||
@@ -107,4 +107,4 @@ abstract class AbstractMediaTypeExpression implements Comparable<AbstractMediaTy
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,4 @@ public interface MediaTypeExpression {
|
||||
|
||||
boolean isNegated();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,4 @@ public interface NameValueExpression<T> {
|
||||
|
||||
boolean isNegated();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,16 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
*/
|
||||
public final class PatternsRequestCondition extends AbstractRequestCondition<PatternsRequestCondition> {
|
||||
|
||||
private static UrlPathHelper pathHelperNoSemicolonContent;
|
||||
|
||||
static {
|
||||
pathHelperNoSemicolonContent = new UrlPathHelper();
|
||||
pathHelperNoSemicolonContent.setRemoveSemicolonContent(true);
|
||||
}
|
||||
|
||||
private final Set<String> patterns;
|
||||
|
||||
private final UrlPathHelper urlPathHelper;
|
||||
private final UrlPathHelper pathHelper;
|
||||
|
||||
private final PathMatcher pathMatcher;
|
||||
|
||||
@@ -105,7 +112,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
List<String> fileExtensions) {
|
||||
|
||||
this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns));
|
||||
this.urlPathHelper = urlPathHelper != null ? urlPathHelper : new UrlPathHelper();
|
||||
this.pathHelper = urlPathHelper != null ? urlPathHelper : new UrlPathHelper();
|
||||
this.pathMatcher = pathMatcher != null ? pathMatcher : new AntPathMatcher();
|
||||
this.useSuffixPatternMatch = useSuffixPatternMatch;
|
||||
this.useTrailingSlashMatch = useTrailingSlashMatch;
|
||||
@@ -179,7 +186,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
else {
|
||||
result.add("");
|
||||
}
|
||||
return new PatternsRequestCondition(result, this.urlPathHelper, this.pathMatcher, this.useSuffixPatternMatch,
|
||||
return new PatternsRequestCondition(result, this.pathHelper, this.pathMatcher, this.useSuffixPatternMatch,
|
||||
this.useTrailingSlashMatch, this.fileExtensions);
|
||||
}
|
||||
|
||||
@@ -206,17 +213,24 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
if (this.patterns.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
|
||||
|
||||
String lookupPath = this.pathHelper.getLookupPathForRequest(request);
|
||||
String lookupPathNoSemicolonContent = (lookupPath.indexOf(';') != -1) ?
|
||||
pathHelperNoSemicolonContent.getLookupPathForRequest(request) : null;
|
||||
|
||||
List<String> matches = new ArrayList<String>();
|
||||
for (String pattern : patterns) {
|
||||
String match = getMatchingPattern(pattern, lookupPath);
|
||||
if (match == null && lookupPathNoSemicolonContent != null) {
|
||||
match = getMatchingPattern(pattern, lookupPathNoSemicolonContent);
|
||||
}
|
||||
if (match != null) {
|
||||
matches.add(match);
|
||||
}
|
||||
}
|
||||
Collections.sort(matches, this.pathMatcher.getPatternComparator(lookupPath));
|
||||
return matches.isEmpty() ? null :
|
||||
new PatternsRequestCondition(matches, this.urlPathHelper, this.pathMatcher, this.useSuffixPatternMatch,
|
||||
new PatternsRequestCondition(matches, this.pathHelper, this.pathMatcher, this.useSuffixPatternMatch,
|
||||
this.useTrailingSlashMatch, this.fileExtensions);
|
||||
}
|
||||
|
||||
@@ -225,7 +239,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
return pattern;
|
||||
}
|
||||
if (this.useSuffixPatternMatch) {
|
||||
if (useSmartSuffixPatternMatch(pattern, lookupPath)) {
|
||||
if (!this.fileExtensions.isEmpty() && lookupPath.indexOf('.') != -1) {
|
||||
for (String extension : this.fileExtensions) {
|
||||
if (this.pathMatcher.match(pattern + extension, lookupPath)) {
|
||||
return pattern + extension;
|
||||
@@ -251,14 +265,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to match by known file extensions. Return "true" if file extensions
|
||||
* are configured, and the lookup path has a suffix.
|
||||
*/
|
||||
private boolean useSmartSuffixPatternMatch(String pattern, String lookupPath) {
|
||||
return (!this.fileExtensions.isEmpty() && lookupPath.indexOf('.') != -1) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the two conditions based on the URL patterns they contain.
|
||||
* Patterns are compared one at a time, from top to bottom via
|
||||
@@ -272,7 +278,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
* the best matches on top.
|
||||
*/
|
||||
public int compareTo(PatternsRequestCondition other, HttpServletRequest request) {
|
||||
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
|
||||
String lookupPath = this.pathHelper.getLookupPathForRequest(request);
|
||||
Comparator<String> patternComparator = this.pathMatcher.getPatternComparator(lookupPath);
|
||||
|
||||
Iterator<String> iterator = patterns.iterator();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,15 +28,19 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
|
||||
import org.springframework.web.servlet.mvc.condition.NameValueExpression;
|
||||
import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
@@ -100,7 +104,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables);
|
||||
|
||||
if (isMatrixVariableContentAvailable()) {
|
||||
request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, extractMatrixVariables(uriVariables));
|
||||
request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, extractMatrixVariables(request, uriVariables));
|
||||
}
|
||||
|
||||
if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) {
|
||||
@@ -113,7 +117,9 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
return !getUrlPathHelper().shouldRemoveSemicolonContent();
|
||||
}
|
||||
|
||||
private Map<String, MultiValueMap<String, String>> extractMatrixVariables(Map<String, String> uriVariables) {
|
||||
private Map<String, MultiValueMap<String, String>> extractMatrixVariables(
|
||||
HttpServletRequest request, Map<String, String> uriVariables) {
|
||||
|
||||
Map<String, MultiValueMap<String, String>> result = new LinkedHashMap<String, MultiValueMap<String, String>>();
|
||||
for (Entry<String, String> uriVar : uriVariables.entrySet()) {
|
||||
String uriVarValue = uriVar.getValue();
|
||||
@@ -134,7 +140,8 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
uriVariables.put(uriVar.getKey(), uriVarValue.substring(0, semicolonIndex));
|
||||
}
|
||||
|
||||
result.put(uriVar.getKey(), WebUtils.parseMatrixVariables(matrixVariables));
|
||||
MultiValueMap<String, String> vars = WebUtils.parseMatrixVariables(matrixVariables);
|
||||
result.put(uriVar.getKey(), getUrlPathHelper().decodeMatrixVariables(request, vars));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -182,26 +189,38 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
|
||||
Set<MediaType> consumableMediaTypes;
|
||||
Set<MediaType> producibleMediaTypes;
|
||||
Set<String> paramConditions;
|
||||
|
||||
if (patternAndMethodMatches.isEmpty()) {
|
||||
consumableMediaTypes = getConsumableMediaTypes(request, patternMatches);
|
||||
producibleMediaTypes = getProdicubleMediaTypes(request, patternMatches);
|
||||
paramConditions = getRequestParams(request, patternMatches);
|
||||
}
|
||||
else {
|
||||
consumableMediaTypes = getConsumableMediaTypes(request, patternAndMethodMatches);
|
||||
producibleMediaTypes = getProdicubleMediaTypes(request, patternAndMethodMatches);
|
||||
paramConditions = getRequestParams(request, patternAndMethodMatches);
|
||||
}
|
||||
|
||||
if (!consumableMediaTypes.isEmpty()) {
|
||||
MediaType contentType = null;
|
||||
if (StringUtils.hasLength(request.getContentType())) {
|
||||
contentType = MediaType.parseMediaType(request.getContentType());
|
||||
try {
|
||||
contentType = MediaType.parseMediaType(request.getContentType());
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new HttpMediaTypeNotSupportedException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList<MediaType>(consumableMediaTypes));
|
||||
}
|
||||
else if (!producibleMediaTypes.isEmpty()) {
|
||||
throw new HttpMediaTypeNotAcceptableException(new ArrayList<MediaType>(producibleMediaTypes));
|
||||
}
|
||||
else if (!CollectionUtils.isEmpty(paramConditions)) {
|
||||
String[] params = paramConditions.toArray(new String[paramConditions.size()]);
|
||||
throw new UnsatisfiedServletRequestParameterException(params, request.getParameterMap());
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
@@ -227,4 +246,18 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<String> getRequestParams(HttpServletRequest request, Set<RequestMappingInfo> partialMatches) {
|
||||
for (RequestMappingInfo partialMatch : partialMatches) {
|
||||
ParamsRequestCondition condition = partialMatch.getParamsCondition();
|
||||
if (!CollectionUtils.isEmpty(condition.getExpressions()) && (condition.getMatchingCondition(request) == null)) {
|
||||
Set<String> expressions = new HashSet<String>();
|
||||
for (NameValueExpression expr : condition.getExpressions()) {
|
||||
expressions.add(expr.toString());
|
||||
}
|
||||
return expressions;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
|
||||
}
|
||||
}
|
||||
if (compatibleMediaTypes.isEmpty()) {
|
||||
throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
|
||||
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
|
||||
}
|
||||
|
||||
List<MediaType> mediaTypes = new ArrayList<MediaType>(compatibleMediaTypes);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -68,7 +68,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
|
||||
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
Class<?> parameterType = returnType.getParameterType();
|
||||
return HttpEntity.class.equals(parameterType) || ResponseEntity.class.equals(parameterType);
|
||||
return HttpEntity.class.isAssignableFrom(parameterType) || ResponseEntity.class.isAssignableFrom(parameterType);
|
||||
}
|
||||
|
||||
public Object resolveArgument(
|
||||
|
||||
@@ -67,4 +67,4 @@ public class PathVariableMapMethodArgumentResolver implements HandlerMethodArgum
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,4 +119,4 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueMethod
|
||||
super(annotation.value(), true, ValueConstants.DEFAULT_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,4 +879,4 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,9 +20,11 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.EmbeddedValueResolverAware;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.mvc.condition.AbstractRequestCondition;
|
||||
@@ -46,7 +48,8 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping {
|
||||
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
|
||||
implements EmbeddedValueResolverAware {
|
||||
|
||||
private boolean useSuffixPatternMatch = true;
|
||||
|
||||
@@ -58,6 +61,8 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
||||
|
||||
private final List<String> fileExtensions = new ArrayList<String>();
|
||||
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to use suffix pattern match (".*") when matching patterns to
|
||||
@@ -101,6 +106,11 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
||||
this.useTrailingSlashMatch = useTrailingSlashMatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||
this.embeddedValueResolver = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link ContentNegotiationManager} to use to determine requested media types.
|
||||
* If not set, the default constructor is used.
|
||||
@@ -142,15 +152,15 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
||||
* Return the file extensions to use for suffix pattern matching.
|
||||
*/
|
||||
public List<String> getFileExtensions() {
|
||||
return fileExtensions;
|
||||
return this.fileExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
if (this.useRegisteredSuffixPatternMatch) {
|
||||
this.fileExtensions.addAll(contentNegotiationManager.getAllFileExtensions());
|
||||
}
|
||||
super.afterPropertiesSet();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,8 +237,9 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
||||
* Created a RequestMappingInfo from a RequestMapping annotation.
|
||||
*/
|
||||
private RequestMappingInfo createRequestMappingInfo(RequestMapping annotation, RequestCondition<?> customCondition) {
|
||||
String[] patterns = resolveEmbeddedValuesInPatterns(annotation.value());
|
||||
return new RequestMappingInfo(
|
||||
new PatternsRequestCondition(annotation.value(), getUrlPathHelper(), getPathMatcher(),
|
||||
new PatternsRequestCondition(patterns, getUrlPathHelper(), getPathMatcher(),
|
||||
this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions),
|
||||
new RequestMethodsRequestCondition(annotation.method()),
|
||||
new ParamsRequestCondition(annotation.params()),
|
||||
@@ -238,4 +249,21 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
|
||||
customCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve placeholder values in the given array of patterns.
|
||||
* @return a new array with updated patterns
|
||||
*/
|
||||
protected String[] resolveEmbeddedValuesInPatterns(String[] patterns) {
|
||||
if (this.embeddedValueResolver == null) {
|
||||
return patterns;
|
||||
}
|
||||
else {
|
||||
String[] resolvedPatterns = new String[patterns.length];
|
||||
for (int i=0; i < patterns.length; i++) {
|
||||
resolvedPatterns[i] = this.embeddedValueResolver.resolveStringValue(patterns[i]);
|
||||
}
|
||||
return resolvedPatterns;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -190,4 +190,4 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,4 +60,4 @@ public class ServletCookieValueMethodArgumentResolver extends AbstractCookieValu
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,4 +153,4 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
|
||||
servletBinder.bind(servletRequest);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,4 +51,4 @@ public class ServletWebArgumentResolverAdapter extends AbstractWebArgumentResolv
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,14 +50,14 @@ import org.springframework.web.util.WebUtils;
|
||||
*
|
||||
* <p>Note that the second strategy also supports the use of submit buttons of
|
||||
* type 'image'. That is, an image submit button named 'reset' will normally be
|
||||
* submitted by the browser as two request paramters called 'reset.x', and
|
||||
* 'reset.y'. When checking for the existence of a paramter from the
|
||||
* submitted by the browser as two request parameters called 'reset.x', and
|
||||
* 'reset.y'. When checking for the existence of a parameter from the
|
||||
* {@code methodParamNames} list, to indicate that a specific method should
|
||||
* be called, the code will look for request parameter in the "reset" form
|
||||
* (exactly as spcified in the list), and in the "reset.x" form ('.x' appended to
|
||||
* the name in the list). In this way it can handle both normal and image submit
|
||||
* buttons. The actual method name resolved if there is a match will always be
|
||||
* the bare form without the ".x".
|
||||
* be called, the code will look for a request parameter in the "reset" form
|
||||
* (exactly as specified in the list), and in the "reset.x" form ('.x' appended
|
||||
* to the name in the list). In this way it can handle both normal and image
|
||||
* submit buttons. The actual method name resolved, if there is a match, will
|
||||
* always be the bare form without the ".x".
|
||||
*
|
||||
* <p><b>Note:</b> If both strategies are configured, i.e. both "paramName"
|
||||
* and "methodParamNames" are specified, then both will be checked for any given
|
||||
@@ -69,7 +69,7 @@ import org.springframework.web.util.WebUtils;
|
||||
*
|
||||
* <p>For both resolution strategies, the method name is of course coming from
|
||||
* some sort of view code, (such as a JSP page). While this may be acceptable,
|
||||
* it is sometimes desireable to treat this only as a 'logical' method name,
|
||||
* it is sometimes desirable to treat this only as a 'logical' method name,
|
||||
* with a further mapping to a 'real' method name. As such, an optional
|
||||
* 'logical' mapping may be specified for this purpose.
|
||||
*
|
||||
|
||||
@@ -94,6 +94,11 @@ public abstract class AbstractDispatcherServletInitializer
|
||||
|
||||
ServletRegistration.Dynamic registration =
|
||||
servletContext.addServlet(servletName, dispatcherServlet);
|
||||
|
||||
Assert.notNull(registration,
|
||||
"Failed to register servlet with name '" + servletName + "'." +
|
||||
"Check if there is another servlet registered under the same name.");
|
||||
|
||||
registration.setLoadOnStartup(1);
|
||||
registration.addMapping(getServletMappings());
|
||||
registration.setAsyncSupported(isAsyncSupported());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.ui.context.ThemeSource;
|
||||
import org.springframework.ui.context.support.ResourceBundleThemeSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
@@ -61,6 +62,7 @@ import org.springframework.web.util.WebUtils;
|
||||
* appropriate fallback for the locale (the HttpServletRequest's primary locale).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 03.03.2003
|
||||
* @see org.springframework.web.servlet.DispatcherServlet
|
||||
* @see org.springframework.web.servlet.view.AbstractView#setRequestContextAttribute
|
||||
@@ -233,8 +235,10 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the fallback locale for this context. <p>The default implementation checks for a JSTL locale attribute
|
||||
* in request, session or application scope; if not found, returns the {@code HttpServletRequest.getLocale()}.
|
||||
* Determine the fallback locale for this context.
|
||||
* <p>The default implementation checks for a JSTL locale attribute in request,
|
||||
* session or application scope; if not found, returns the
|
||||
* {@code HttpServletRequest.getLocale()}.
|
||||
* @return the fallback locale (never {@code null})
|
||||
* @see javax.servlet.http.HttpServletRequest#getLocale()
|
||||
*/
|
||||
@@ -249,8 +253,8 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the fallback theme for this context. <p>The default implementation returns the default theme (with name
|
||||
* "theme").
|
||||
* Determine the fallback theme for this context.
|
||||
* <p>The default implementation returns the default theme (with name "theme").
|
||||
* @return the fallback theme (never {@code null})
|
||||
*/
|
||||
protected Theme getFallbackTheme() {
|
||||
@@ -309,8 +313,8 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current theme (never {@code null}). <p>Resolved lazily for more efficiency when theme support is
|
||||
* not being used.
|
||||
* Return the current theme (never {@code null}).
|
||||
* <p>Resolved lazily for more efficiency when theme support is not being used.
|
||||
*/
|
||||
public final Theme getTheme() {
|
||||
if (this.theme == null) {
|
||||
@@ -350,7 +354,8 @@ public class RequestContext {
|
||||
|
||||
/**
|
||||
* Set the UrlPathHelper to use for context path and request URI decoding. Can be used to pass a shared
|
||||
* UrlPathHelper instance in. <p>A default UrlPathHelper is always available.
|
||||
* UrlPathHelper instance in.
|
||||
* <p>A default UrlPathHelper is always available.
|
||||
*/
|
||||
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
|
||||
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
|
||||
@@ -359,7 +364,8 @@ public class RequestContext {
|
||||
|
||||
/**
|
||||
* Return the UrlPathHelper used for context path and request URI decoding. Can be used to configure the current
|
||||
* UrlPathHelper. <p>A default UrlPathHelper is always available.
|
||||
* UrlPathHelper.
|
||||
* <p>A default UrlPathHelper is always available.
|
||||
*/
|
||||
public UrlPathHelper getUrlPathHelper() {
|
||||
return this.urlPathHelper;
|
||||
@@ -376,8 +382,8 @@ public class RequestContext {
|
||||
|
||||
/**
|
||||
* Return the context path of the original request, that is, the path that indicates the current web application.
|
||||
* This is useful for building links to other resources within the application. <p>Delegates to the UrlPathHelper
|
||||
* for decoding.
|
||||
* This is useful for building links to other resources within the application.
|
||||
* <p>Delegates to the UrlPathHelper for decoding.
|
||||
* @see javax.servlet.http.HttpServletRequest#getContextPath
|
||||
* @see #getUrlPathHelper
|
||||
*/
|
||||
@@ -422,22 +428,22 @@ public class RequestContext {
|
||||
* context path and the servlet path of the original request. This is useful
|
||||
* for building links to other resources within the application where a
|
||||
* servlet mapping of the style {@code "/main/*"} is used.
|
||||
* <p>Delegates to the UrlPathHelper for decoding the context path.
|
||||
* @see javax.servlet.http.HttpServletRequest#getContextPath
|
||||
* @see javax.servlet.http.HttpServletRequest#getServletPath()
|
||||
* @see #getUrlPathHelper
|
||||
* <p>Delegates to the UrlPathHelper to determine the context and servlet path.
|
||||
*/
|
||||
public String getPathToServlet() {
|
||||
return this.urlPathHelper.getOriginatingContextPath(this.request)
|
||||
+ this.urlPathHelper.getOriginatingServletPath(this.request);
|
||||
String path = this.urlPathHelper.getOriginatingContextPath(this.request);
|
||||
if (StringUtils.hasText(this.urlPathHelper.getPathWithinServletMapping(this.request))) {
|
||||
path += this.urlPathHelper.getOriginatingServletPath(this.request);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the request URI of the original request, that is, the invoked URL without parameters. This is particularly
|
||||
* useful as HTML form action target, possibly in combination with the original query string. <p><b>Note this
|
||||
* implementation will correctly resolve to the URI of any originating root request in the presence of a forwarded
|
||||
* request. However, this can only work when the Servlet 2.4 'forward' request attributes are present. <p>Delegates
|
||||
* to the UrlPathHelper for decoding.
|
||||
* request. However, this can only work when the Servlet 2.4 'forward' request attributes are present.
|
||||
* <p>Delegates to the UrlPathHelper for decoding.
|
||||
* @see #getQueryString
|
||||
* @see org.springframework.web.util.UrlPathHelper#getOriginatingRequestUri
|
||||
* @see #getUrlPathHelper
|
||||
@@ -573,8 +579,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the theme message for the given code. <p>Note that theme messages are never HTML-escaped, as they
|
||||
* typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the theme message for the given code.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param code code of the message
|
||||
* @param defaultMessage String to return if the lookup fails
|
||||
* @return the message
|
||||
@@ -584,8 +591,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the theme message for the given code. <p>Note that theme messages are never HTML-escaped, as they
|
||||
* typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the theme message for the given code.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param code code of the message
|
||||
* @param args arguments for the message, or {@code null} if none
|
||||
* @param defaultMessage String to return if the lookup fails
|
||||
@@ -596,8 +604,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the theme message for the given code. <p>Note that theme messages are never HTML-escaped, as they
|
||||
* typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the theme message for the given code.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param code code of the message
|
||||
* @param args arguments for the message as a List, or {@code null} if none
|
||||
* @param defaultMessage String to return if the lookup fails
|
||||
@@ -609,8 +618,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the theme message for the given code. <p>Note that theme messages are never HTML-escaped, as they
|
||||
* typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the theme message for the given code.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param code code of the message
|
||||
* @return the message
|
||||
* @throws org.springframework.context.NoSuchMessageException if not found
|
||||
@@ -620,8 +630,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the theme message for the given code. <p>Note that theme messages are never HTML-escaped, as they
|
||||
* typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the theme message for the given code.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param code code of the message
|
||||
* @param args arguments for the message, or {@code null} if none
|
||||
* @return the message
|
||||
@@ -632,8 +643,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the theme message for the given code. <p>Note that theme messages are never HTML-escaped, as they
|
||||
* typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the theme message for the given code.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param code code of the message
|
||||
* @param args arguments for the message as a List, or {@code null} if none
|
||||
* @return the message
|
||||
@@ -644,8 +656,9 @@ public class RequestContext {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given MessageSourceResolvable in the current theme. <p>Note that theme messages are never
|
||||
* HTML-escaped, as they typically denote theme-specific resource paths and not client-visible messages.
|
||||
* Retrieve the given MessageSourceResolvable in the current theme.
|
||||
* <p>Note that theme messages are never HTML-escaped, as they typically denote
|
||||
* theme-specific resource paths and not client-visible messages.
|
||||
* @param resolvable the MessageSourceResolvable
|
||||
* @return the message
|
||||
* @throws org.springframework.context.NoSuchMessageException if not found
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -95,9 +95,12 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
String scheme = request.getScheme();
|
||||
int port = request.getServerPort();
|
||||
|
||||
String header = request.getHeader("X-Forwarded-Host");
|
||||
String host = StringUtils.hasText(header) ? header: request.getServerName();
|
||||
|
||||
ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder();
|
||||
builder.scheme(scheme);
|
||||
builder.host(request.getServerName());
|
||||
builder.host(host);
|
||||
if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) {
|
||||
builder.port(port);
|
||||
}
|
||||
@@ -138,7 +141,10 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder {
|
||||
return fromRequest(getCurrentRequest());
|
||||
}
|
||||
|
||||
private static HttpServletRequest getCurrentRequest() {
|
||||
/**
|
||||
* Obtain the request through {@link RequestContextHolder}.
|
||||
*/
|
||||
protected static HttpServletRequest getCurrentRequest() {
|
||||
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
Assert.state(requestAttributes != null, "Could not find current request via RequestContextHolder");
|
||||
Assert.isInstanceOf(ServletRequestAttributes.class, requestAttributes);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,9 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.HttpSessionRequiredException;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
||||
import org.springframework.web.servlet.mvc.LastModified;
|
||||
|
||||
/**
|
||||
* Convenient superclass for any kind of web content generator,
|
||||
@@ -79,6 +81,8 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
|
||||
|
||||
private int cacheSeconds = -1;
|
||||
|
||||
private boolean alwaysMustRevalidate = false;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new WebContentGenerator which supports
|
||||
@@ -194,6 +198,25 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
|
||||
return this.useCacheControlNoStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* An option to add 'must-revalidate' to every Cache-Control header. This
|
||||
* may be useful with annotated controller methods, which can
|
||||
* programmatically do a lastModified calculation as described in
|
||||
* {@link WebRequest#checkNotModified(long)}. Default is "false",
|
||||
* effectively relying on whether the handler implements
|
||||
* {@link LastModified} or not.
|
||||
*/
|
||||
public void setAlwaysMustRevalidate(boolean mustRevalidate) {
|
||||
this.alwaysMustRevalidate = mustRevalidate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether 'must-revaliate' is added to every Cache-Control header.
|
||||
*/
|
||||
public boolean isAlwaysMustRevalidate() {
|
||||
return alwaysMustRevalidate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache content for the given number of seconds. Default is -1,
|
||||
* indicating no generation of cache-related headers.
|
||||
@@ -313,7 +336,7 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
|
||||
if (this.useCacheControlHeader) {
|
||||
// HTTP 1.1 header
|
||||
String headerValue = "max-age=" + seconds;
|
||||
if (mustRevalidate) {
|
||||
if (mustRevalidate || this.alwaysMustRevalidate) {
|
||||
headerValue += ", must-revalidate";
|
||||
}
|
||||
response.setHeader(HEADER_CACHE_CONTROL, headerValue);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,6 +50,7 @@ import org.springframework.web.util.HtmlUtils;
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Scott Andrews
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.0
|
||||
* @see org.springframework.web.servlet.mvc.SimpleFormController
|
||||
*/
|
||||
@@ -411,6 +412,10 @@ public class FormTag extends AbstractHtmlElementTag {
|
||||
protected String resolveAction() throws JspException {
|
||||
String action = getAction();
|
||||
if (StringUtils.hasText(action)) {
|
||||
String pathToServlet = getRequestContext().getPathToServlet();
|
||||
if (action.startsWith("/") && !action.startsWith(getRequestContext().getContextPath())) {
|
||||
action = pathToServlet + action;
|
||||
}
|
||||
action = getDisplayString(evaluate(ACTION_ATTRIBUTE, action));
|
||||
return processAction(action);
|
||||
}
|
||||
@@ -469,8 +474,8 @@ public class FormTag extends AbstractHtmlElementTag {
|
||||
if (hiddenFields != null) {
|
||||
for (String name : hiddenFields.keySet()) {
|
||||
this.tagWriter.appendValue("<input type=\"hidden\" ");
|
||||
this.tagWriter.appendValue("name=\"" + name + "\" value=\"" + hiddenFields.get(name) + "\">");
|
||||
this.tagWriter.appendValue("</input>\n");
|
||||
this.tagWriter.appendValue("name=\"" + name + "\" value=\"" + hiddenFields.get(name) + "\" ");
|
||||
this.tagWriter.appendValue("/>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,9 @@ package org.springframework.web.servlet.view;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
||||
import org.springframework.web.servlet.View;
|
||||
@@ -42,19 +45,38 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||
/** Default maximum number of entries for the view cache: 1024 */
|
||||
public static final int DEFAULT_CACHE_LIMIT = 1024;
|
||||
|
||||
/** Dummy marker object for unresolved views in the cache Maps */
|
||||
private static final View UNRESOLVED_VIEW = new View() {
|
||||
public String getContentType() {
|
||||
return null;
|
||||
}
|
||||
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** The maximum number of entries in the cache */
|
||||
private volatile int cacheLimit = DEFAULT_CACHE_LIMIT;
|
||||
|
||||
/** Whether we should refrain from resolving views again if unresolved once */
|
||||
private boolean cacheUnresolved = true;
|
||||
|
||||
/** Map from view key to View instance */
|
||||
/** Fast access cache for Views, returning already cached instances without a global lock */
|
||||
private final Map<Object, View> viewAccessCache = new ConcurrentHashMap<Object, View>(DEFAULT_CACHE_LIMIT);
|
||||
|
||||
/** Map from view key to View instance, synchronized for View creation */
|
||||
@SuppressWarnings("serial")
|
||||
private final Map<Object, View> viewCache =
|
||||
private final Map<Object, View> viewCreationCache =
|
||||
new LinkedHashMap<Object, View>(DEFAULT_CACHE_LIMIT, 0.75f, true) {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Object, View> eldest) {
|
||||
return size() > getCacheLimit();
|
||||
if (size() > getCacheLimit()) {
|
||||
viewAccessCache.remove(eldest.getKey());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,20 +144,27 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||
}
|
||||
else {
|
||||
Object cacheKey = getCacheKey(viewName, locale);
|
||||
synchronized (this.viewCache) {
|
||||
View view = this.viewCache.get(cacheKey);
|
||||
if (view == null && (!this.cacheUnresolved || !this.viewCache.containsKey(cacheKey))) {
|
||||
// Ask the subclass to create the View object.
|
||||
view = createView(viewName, locale);
|
||||
if (view != null || this.cacheUnresolved) {
|
||||
this.viewCache.put(cacheKey, view);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Cached view [" + cacheKey + "]");
|
||||
View view = this.viewAccessCache.get(cacheKey);
|
||||
if (view == null) {
|
||||
synchronized (this.viewCreationCache) {
|
||||
view = this.viewCreationCache.get(cacheKey);
|
||||
if (view == null) {
|
||||
// Ask the subclass to create the View object.
|
||||
view = createView(viewName, locale);
|
||||
if (view == null && this.cacheUnresolved) {
|
||||
view = UNRESOLVED_VIEW;
|
||||
}
|
||||
if (view != null) {
|
||||
this.viewAccessCache.put(cacheKey, view);
|
||||
this.viewCreationCache.put(cacheKey, view);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Cached view [" + cacheKey + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
return (view != UNRESOLVED_VIEW ? view : null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,17 +195,16 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||
else {
|
||||
Object cacheKey = getCacheKey(viewName, locale);
|
||||
Object cachedView;
|
||||
synchronized (this.viewCache) {
|
||||
cachedView = this.viewCache.remove(cacheKey);
|
||||
synchronized (this.viewCreationCache) {
|
||||
this.viewAccessCache.remove(cacheKey);
|
||||
cachedView = this.viewCreationCache.remove(cacheKey);
|
||||
}
|
||||
if (cachedView == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
// Some debug output might be useful...
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (cachedView == null) {
|
||||
logger.debug("No cached instance for view '" + cacheKey + "' was found");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
else {
|
||||
logger.debug("Cache for view " + cacheKey + " has been cleared");
|
||||
}
|
||||
}
|
||||
@@ -189,8 +217,9 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
|
||||
*/
|
||||
public void clearCache() {
|
||||
logger.debug("Clearing entire view cache");
|
||||
synchronized (this.viewCache) {
|
||||
this.viewCache.clear();
|
||||
synchronized (this.viewCreationCache) {
|
||||
this.viewAccessCache.clear();
|
||||
this.viewCreationCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.activation.FileTypeMap;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -33,6 +32,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.OrderComparator;
|
||||
@@ -95,7 +95,7 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
|
||||
private ContentNegotiationManager contentNegotiationManager;
|
||||
|
||||
private ContentNegotiationManagerFactoryBean cnManagerFactoryBean = new ContentNegotiationManagerFactoryBean();
|
||||
private final ContentNegotiationManagerFactoryBean cnManagerFactoryBean = new ContentNegotiationManagerFactoryBean();
|
||||
|
||||
private boolean useNotAcceptableStatusCode = false;
|
||||
|
||||
@@ -104,10 +104,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
private List<ViewResolver> viewResolvers;
|
||||
|
||||
|
||||
public ContentNegotiatingViewResolver() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
@@ -118,7 +114,9 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
|
||||
/**
|
||||
* Set the {@link ContentNegotiationManager} to use to determine requested media types.
|
||||
* If not set, the default constructor is used.
|
||||
* <p>If not set, ContentNegotiationManager's default constructor will be used,
|
||||
* applying a {@link org.springframework.web.accept.HeaderContentNegotiationStrategy}.
|
||||
* @see ContentNegotiationManager#ContentNegotiationManager()
|
||||
*/
|
||||
public void setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager) {
|
||||
this.contentNegotiationManager = contentNegotiationManager;
|
||||
@@ -130,18 +128,16 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
* <p>For instance, when this flag is {@code true} (the default), a request for {@code /hotels.pdf}
|
||||
* will result in an {@code AbstractPdfView} being resolved, while the {@code Accept} header can be the
|
||||
* browser-defined {@code text/html,application/xhtml+xml}.
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setFavorPathExtension(boolean favorPathExtension) {
|
||||
this.cnManagerFactoryBean.setFavorParameter(favorPathExtension);
|
||||
this.cnManagerFactoryBean.setFavorPathExtension(favorPathExtension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether to use the Java Activation Framework to map from file extensions to media types.
|
||||
* <p>Default is {@code true}, i.e. the Java Activation Framework is used (if available).
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -155,7 +151,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
* <p>For instance, when this flag is {@code true}, a request for {@code /hotels?format=pdf} will result
|
||||
* in an {@code AbstractPdfView} being resolved, while the {@code Accept} header can be the browser-defined
|
||||
* {@code text/html,application/xhtml+xml}.
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -166,7 +161,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
/**
|
||||
* Set the parameter name that can be used to determine the requested media type if the {@link
|
||||
* #setFavorParameter} property is {@code true}. The default parameter name is {@code format}.
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -179,7 +173,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
* <p>If set to {@code true}, this view resolver will only refer to the file extension and/or
|
||||
* parameter, as indicated by the {@link #setFavorPathExtension favorPathExtension} and
|
||||
* {@link #setFavorParameter favorParameter} properties.
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -191,7 +184,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
* Set the mapping from file extensions to media types.
|
||||
* <p>When this mapping is not set or when an extension is not present, this view resolver
|
||||
* will fall back to using a {@link FileTypeMap} when the Java Action Framework is available.
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -207,7 +199,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
* Set the default content type.
|
||||
* <p>This content type will be used when file extension, parameter, nor {@code Accept}
|
||||
* header define a content-type, either through being disabled or empty.
|
||||
*
|
||||
* @deprecated use {@link #setContentNegotiationManager(ContentNegotiationManager)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -275,7 +266,7 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
|
||||
this.cnManagerFactoryBean.setServletContext(servletContext);
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
public void afterPropertiesSet() {
|
||||
if (this.contentNegotiationManager == null) {
|
||||
this.cnManagerFactoryBean.afterPropertiesSet();
|
||||
this.contentNegotiationManager = this.cnManagerFactoryBean.getObject();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -160,7 +160,7 @@ public class ResourceBundleViewResolver extends AbstractCachingViewResolver
|
||||
* <p>View definitions that define their own parent or carry their own
|
||||
* class can still override this. Strictly speaking, the rule that a
|
||||
* default parent setting does not apply to a bean definition that
|
||||
* carries a class is there for backwards compatiblity reasons.
|
||||
* carries a class is there for backwards compatibility reasons.
|
||||
* It still matches the typical use case.
|
||||
*/
|
||||
public void setDefaultParentView(String defaultParentView) {
|
||||
|
||||
@@ -309,8 +309,8 @@
|
||||
<@bind path />
|
||||
<#assign id="${status.expression?replace('[','')?replace(']','')}">
|
||||
<#assign isSelected = status.value?? && status.value?string=="true">
|
||||
<input type="hidden" name="_${id}" value="on"/>
|
||||
<input type="checkbox" id="${id}" name="${id}"<#if isSelected> checked="checked"</#if> ${attributes}/>
|
||||
<input type="hidden" name="_${status.expression}" value="on"/>
|
||||
<input type="checkbox" id="${id}" name="${status.expression}"<#if isSelected> checked="checked"</#if> ${attributes}/>
|
||||
</#macro>
|
||||
|
||||
<#--
|
||||
|
||||
@@ -43,4 +43,4 @@ public class JasperReportsCsvView extends AbstractJasperReportsSingleFormatView
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.servlet.view.json;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -27,7 +28,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonEncoding;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
@@ -48,13 +48,15 @@ import org.springframework.web.servlet.view.AbstractView;
|
||||
* @author Jeremy Grelle
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1.2
|
||||
* @see org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
|
||||
*/
|
||||
public class MappingJackson2JsonView extends AbstractView {
|
||||
|
||||
/**
|
||||
* Default content type. Overridable as bean property.
|
||||
* Default content type: "application/json".
|
||||
* Overridable through {@link #setContentType}.
|
||||
*/
|
||||
public static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
|
||||
@@ -75,8 +77,9 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
|
||||
private boolean updateContentLength = false;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code JacksonJsonView}, setting the content type to {@code application/json}.
|
||||
* Construct a new {@code MappingJackson2JsonView}, setting the content type to {@code application/json}.
|
||||
*/
|
||||
public MappingJackson2JsonView() {
|
||||
setContentType(DEFAULT_CONTENT_TYPE);
|
||||
@@ -85,13 +88,11 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the {@code ObjectMapper} for this view.
|
||||
* If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper} is used.
|
||||
* <p>Setting a custom-configured {@code ObjectMapper} is one way to take further control
|
||||
* of the JSON serialization process. For example, an extended {@code SerializerFactory}
|
||||
* can be configured that provides custom serializers for specific types. The other option
|
||||
* for refining the serialization process is to use Jackson's provided annotations on the
|
||||
* types to be serialized, in which case a custom-configured ObjectMapper is unnecessary.
|
||||
* Set the {@code ObjectMapper} for this view.
|
||||
* If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper} will be used.
|
||||
* <p>Setting a custom-configured {@code ObjectMapper} is one way to take further control of
|
||||
* the JSON serialization process. The other option is to use Jackson's provided annotations
|
||||
* on the types to be serialized, in which case a custom-configured ObjectMapper is unnecessary.
|
||||
*/
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "'objectMapper' must not be null");
|
||||
@@ -99,14 +100,15 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
configurePrettyPrint();
|
||||
}
|
||||
|
||||
private void configurePrettyPrint() {
|
||||
if (this.prettyPrint != null) {
|
||||
this.objectMapper.configure(SerializationFeature.INDENT_OUTPUT, this.prettyPrint);
|
||||
}
|
||||
/**
|
||||
* Return the {@code ObjectMapper} for this view.
|
||||
*/
|
||||
public final ObjectMapper getObjectMapper() {
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code JsonEncoding} for this converter.
|
||||
* Set the {@code JsonEncoding} for this view.
|
||||
* By default, {@linkplain JsonEncoding#UTF8 UTF-8} is used.
|
||||
*/
|
||||
public void setEncoding(JsonEncoding encoding) {
|
||||
@@ -114,9 +116,16 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code JsonEncoding} for this view.
|
||||
*/
|
||||
public final JsonEncoding getEncoding() {
|
||||
return this.encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the JSON output by this view should be prefixed with <tt>"{} && "</tt>.
|
||||
* Default is false.
|
||||
* Default is {@code false}.
|
||||
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
|
||||
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
|
||||
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed
|
||||
@@ -127,12 +136,11 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use the {@link DefaultPrettyPrinter} when writing JSON.
|
||||
* Whether to use the default pretty printer when writing JSON.
|
||||
* This is a shortcut for setting up an {@code ObjectMapper} as follows:
|
||||
* <pre>
|
||||
* ObjectMapper mapper = new ObjectMapper();
|
||||
* mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
* converter.setObjectMapper(mapper);
|
||||
* </pre>
|
||||
* <p>The default value is {@code false}.
|
||||
*/
|
||||
@@ -141,6 +149,12 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
configurePrettyPrint();
|
||||
}
|
||||
|
||||
private void configurePrettyPrint() {
|
||||
if (this.prettyPrint != null) {
|
||||
this.objectMapper.configure(SerializationFeature.INDENT_OUTPUT, this.prettyPrint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute in the model that should be rendered by this view.
|
||||
* When set, all other model attributes will be ignored.
|
||||
@@ -160,7 +174,7 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
/**
|
||||
* Return the attributes in the model that should be rendered by this view.
|
||||
*/
|
||||
public Set<String> getModelKeys() {
|
||||
public final Set<String> getModelKeys() {
|
||||
return this.modelKeys;
|
||||
}
|
||||
|
||||
@@ -179,7 +193,7 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
* @deprecated use {@link #getModelKeys()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Set<String> getRenderedAttributes() {
|
||||
public final Set<String> getRenderedAttributes() {
|
||||
return this.modelKeys;
|
||||
}
|
||||
|
||||
@@ -212,6 +226,7 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
this.updateContentLength = updateContentLength;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) {
|
||||
setResponseContentType(request, response);
|
||||
@@ -227,34 +242,21 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
|
||||
OutputStream stream = this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream();
|
||||
|
||||
OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream());
|
||||
Object value = filterModel(model);
|
||||
JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding);
|
||||
|
||||
// A workaround for JsonGenerators not applying serialization features
|
||||
// https://github.com/FasterXML/jackson-databind/issues/12
|
||||
if (this.objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
|
||||
generator.useDefaultPrettyPrinter();
|
||||
}
|
||||
|
||||
if (this.prefixJson) {
|
||||
generator.writeRaw("{} && ");
|
||||
}
|
||||
this.objectMapper.writeValue(generator, value);
|
||||
|
||||
writeContent(stream, value, this.prefixJson);
|
||||
if (this.updateContentLength) {
|
||||
writeToResponse(response, (ByteArrayOutputStream) stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out undesired attributes from the given model.
|
||||
* Filter out undesired attributes from the given model.
|
||||
* The return value can be either another {@link Map} or a single value object.
|
||||
* <p>The default implementation removes {@link BindingResult} instances and entries
|
||||
* not included in the {@link #setRenderedAttributes renderedAttributes} property.
|
||||
* @param model the model, as passed on to {@link #renderMergedOutputModel}
|
||||
* @return the object to be rendered
|
||||
* @return the value to be rendered
|
||||
*/
|
||||
protected Object filterModel(Map<String, Object> model) {
|
||||
Map<String, Object> result = new HashMap<String, Object>(model.size());
|
||||
@@ -267,4 +269,27 @@ public class MappingJackson2JsonView extends AbstractView {
|
||||
return (this.extractValueFromSingleKeyModel && result.size() == 1 ? result.values().iterator().next() : result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the actual JSON content to the stream.
|
||||
* @param stream the output stream to use
|
||||
* @param value the value to be rendered, as returned from {@link #filterModel}
|
||||
* @param prefixJson whether the JSON output by this view should be prefixed
|
||||
* with <tt>"{} && "</tt> (as indicated through {@link #setPrefixJson})
|
||||
* @throws IOException if writing failed
|
||||
*/
|
||||
protected void writeContent(OutputStream stream, Object value, boolean prefixJson) throws IOException {
|
||||
JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding);
|
||||
|
||||
// A workaround for JsonGenerators not applying serialization features
|
||||
// https://github.com/FasterXML/jackson-databind/issues/12
|
||||
if (this.objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
|
||||
generator.useDefaultPrettyPrinter();
|
||||
}
|
||||
|
||||
if (prefixJson) {
|
||||
generator.writeRaw("{} && ");
|
||||
}
|
||||
this.objectMapper.writeValue(generator, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,12 +17,12 @@
|
||||
package org.springframework.web.servlet.view.json;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@@ -30,15 +30,13 @@ import org.codehaus.jackson.JsonEncoding;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.map.SerializationConfig;
|
||||
import org.codehaus.jackson.map.SerializerFactory;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
|
||||
/**
|
||||
* Spring MVC {@link View} that renders JSON content by serializing the model for the current request
|
||||
* using <a href="http://jackson.codehaus.org/">Jackson's</a> {@link ObjectMapper}.
|
||||
@@ -50,13 +48,15 @@ import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
* @author Jeremy Grelle
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
|
||||
*/
|
||||
public class MappingJacksonJsonView extends AbstractView {
|
||||
|
||||
/**
|
||||
* Default content type. Overridable as bean property.
|
||||
* Default content type: "application/json".
|
||||
* Overridable through {@link #setContentType}.
|
||||
*/
|
||||
public static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
|
||||
@@ -77,8 +77,9 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
|
||||
private boolean updateContentLength = false;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code JacksonJsonView}, setting the content type to {@code application/json}.
|
||||
* Construct a new {@code MappingJacksonJsonView}, setting the content type to {@code application/json}.
|
||||
*/
|
||||
public MappingJacksonJsonView() {
|
||||
setContentType(DEFAULT_CONTENT_TYPE);
|
||||
@@ -87,13 +88,11 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the {@code ObjectMapper} for this view.
|
||||
* If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper} is used.
|
||||
* <p>Setting a custom-configured {@code ObjectMapper} is one way to take further control
|
||||
* of the JSON serialization process. For example, an extended {@link SerializerFactory}
|
||||
* can be configured that provides custom serializers for specific types. The other option
|
||||
* for refining the serialization process is to use Jackson's provided annotations on the
|
||||
* types to be serialized, in which case a custom-configured ObjectMapper is unnecessary.
|
||||
* Set the {@code ObjectMapper} for this view.
|
||||
* If not set, a default {@link ObjectMapper#ObjectMapper() ObjectMapper} will be used.
|
||||
* <p>Setting a custom-configured {@code ObjectMapper} is one way to take further control of
|
||||
* the JSON serialization process. The other option is to use Jackson's provided annotations
|
||||
* on the types to be serialized, in which case a custom-configured ObjectMapper is unnecessary.
|
||||
*/
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "'objectMapper' must not be null");
|
||||
@@ -101,14 +100,15 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
configurePrettyPrint();
|
||||
}
|
||||
|
||||
private void configurePrettyPrint() {
|
||||
if (this.prettyPrint != null) {
|
||||
this.objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, this.prettyPrint);
|
||||
}
|
||||
/**
|
||||
* Return the {@code ObjectMapper} for this view.
|
||||
*/
|
||||
public final ObjectMapper getObjectMapper() {
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code JsonEncoding} for this converter.
|
||||
* Set the {@code JsonEncoding} for this view.
|
||||
* By default, {@linkplain JsonEncoding#UTF8 UTF-8} is used.
|
||||
*/
|
||||
public void setEncoding(JsonEncoding encoding) {
|
||||
@@ -116,9 +116,16 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code JsonEncoding} for this view.
|
||||
*/
|
||||
public final JsonEncoding getEncoding() {
|
||||
return this.encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the JSON output by this view should be prefixed with <tt>"{} && "</tt>.
|
||||
* Default is false.
|
||||
* Default is {@code false}.
|
||||
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
|
||||
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
|
||||
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed
|
||||
@@ -129,12 +136,11 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use the {@link DefaultPrettyPrinter} when writing JSON.
|
||||
* Whether to use the default pretty printer when writing JSON.
|
||||
* This is a shortcut for setting up an {@code ObjectMapper} as follows:
|
||||
* <pre>
|
||||
* ObjectMapper mapper = new ObjectMapper();
|
||||
* mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
|
||||
* converter.setObjectMapper(mapper);
|
||||
* </pre>
|
||||
* <p>The default value is {@code false}.
|
||||
*/
|
||||
@@ -143,6 +149,12 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
configurePrettyPrint();
|
||||
}
|
||||
|
||||
private void configurePrettyPrint() {
|
||||
if (this.prettyPrint != null) {
|
||||
this.objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, this.prettyPrint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute in the model that should be rendered by this view.
|
||||
* When set, all other model attributes will be ignored.
|
||||
@@ -162,7 +174,7 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
/**
|
||||
* Return the attributes in the model that should be rendered by this view.
|
||||
*/
|
||||
public Set<String> getModelKeys() {
|
||||
public final Set<String> getModelKeys() {
|
||||
return this.modelKeys;
|
||||
}
|
||||
|
||||
@@ -181,7 +193,7 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
* @deprecated use {@link #getModelKeys()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Set<String> getRenderedAttributes() {
|
||||
public final Set<String> getRenderedAttributes() {
|
||||
return this.modelKeys;
|
||||
}
|
||||
|
||||
@@ -230,34 +242,21 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
|
||||
OutputStream stream = this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream();
|
||||
|
||||
OutputStream stream = (this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream());
|
||||
Object value = filterModel(model);
|
||||
JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding);
|
||||
|
||||
// A workaround for JsonGenerators not applying serialization features
|
||||
// https://github.com/FasterXML/jackson-databind/issues/12
|
||||
if (this.objectMapper.getSerializationConfig().isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {
|
||||
generator.useDefaultPrettyPrinter();
|
||||
}
|
||||
|
||||
if (this.prefixJson) {
|
||||
generator.writeRaw("{} && ");
|
||||
}
|
||||
this.objectMapper.writeValue(generator, value);
|
||||
|
||||
writeContent(stream, value, this.prefixJson);
|
||||
if (this.updateContentLength) {
|
||||
writeToResponse(response, (ByteArrayOutputStream) stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out undesired attributes from the given model.
|
||||
* Filter out undesired attributes from the given model.
|
||||
* The return value can be either another {@link Map} or a single value object.
|
||||
* <p>The default implementation removes {@link BindingResult} instances and entries
|
||||
* not included in the {@link #setRenderedAttributes renderedAttributes} property.
|
||||
* @param model the model, as passed on to {@link #renderMergedOutputModel}
|
||||
* @return the object to be rendered
|
||||
* @return the value to be rendered
|
||||
*/
|
||||
protected Object filterModel(Map<String, Object> model) {
|
||||
Map<String, Object> result = new HashMap<String, Object>(model.size());
|
||||
@@ -270,4 +269,27 @@ public class MappingJacksonJsonView extends AbstractView {
|
||||
return (this.extractValueFromSingleKeyModel && result.size() == 1 ? result.values().iterator().next() : result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the actual JSON content to the stream.
|
||||
* @param stream the output stream to use
|
||||
* @param value the value to be rendered, as returned from {@link #filterModel}
|
||||
* @param prefixJson whether the JSON output by this view should be prefixed
|
||||
* with <tt>"{} && "</tt> (as indicated through {@link #setPrefixJson})
|
||||
* @throws IOException if writing failed
|
||||
*/
|
||||
protected void writeContent(OutputStream stream, Object value, boolean prefixJson) throws IOException {
|
||||
JsonGenerator generator = this.objectMapper.getJsonFactory().createJsonGenerator(stream, this.encoding);
|
||||
|
||||
// A workaround for JsonGenerators not applying serialization features
|
||||
// https://github.com/FasterXML/jackson-databind/issues/12
|
||||
if (this.objectMapper.getSerializationConfig().isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {
|
||||
generator.useDefaultPrettyPrinter();
|
||||
}
|
||||
|
||||
if (prefixJson) {
|
||||
generator.writeRaw("{} && ");
|
||||
}
|
||||
this.objectMapper.writeValue(generator, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 17.08.2004
|
||||
*/
|
||||
public class BeanWithObjectProperty {
|
||||
|
||||
private Object object;
|
||||
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObject(Object object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import org.springframework.core.enums.ShortCodedLabeledEnum;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class Colour extends ShortCodedLabeledEnum {
|
||||
|
||||
public static final Colour RED = new Colour(0, "RED");
|
||||
public static final Colour BLUE = new Colour(1, "BLUE");
|
||||
public static final Colour GREEN = new Colour(2, "GREEN");
|
||||
public static final Colour PURPLE = new Colour(3, "PURPLE");
|
||||
|
||||
private Colour(int code, String label) {
|
||||
super(code, label);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public enum CustomEnum {
|
||||
|
||||
VALUE_1, VALUE_2;
|
||||
|
||||
public String toString() {
|
||||
return "CustomEnum: " + name();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 21.08.2003
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class DerivedTestBean extends TestBean implements Serializable, BeanNameAware, DisposableBean {
|
||||
|
||||
private String beanName;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
|
||||
public DerivedTestBean() {
|
||||
}
|
||||
|
||||
public DerivedTestBean(String[] names) {
|
||||
if (names == null || names.length < 2) {
|
||||
throw new IllegalArgumentException("Invalid names array");
|
||||
}
|
||||
setName(names[0]);
|
||||
setBeanName(names[1]);
|
||||
}
|
||||
|
||||
public static DerivedTestBean create(String[] names) {
|
||||
return new DerivedTestBean(names);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBeanName(String beanName) {
|
||||
if (this.beanName == null || beanName == null) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
public void setSpouseRef(String name) {
|
||||
setSpouse(new TestBean(name));
|
||||
}
|
||||
|
||||
|
||||
public void initialize() {
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
public boolean wasInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 07.03.2006
|
||||
*/
|
||||
public class FieldAccessBean {
|
||||
|
||||
public String name;
|
||||
|
||||
protected int age;
|
||||
|
||||
private TestBean spouse;
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public TestBean getSpouse() {
|
||||
return spouse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class GenericBean<T> {
|
||||
|
||||
private Set<Integer> integerSet;
|
||||
|
||||
private Set<ITestBean> testBeanSet;
|
||||
|
||||
private List<Resource> resourceList;
|
||||
|
||||
private List<List<Integer>> listOfLists;
|
||||
|
||||
private ArrayList<String[]> listOfArrays;
|
||||
|
||||
private List<Map<Integer, Long>> listOfMaps;
|
||||
|
||||
private Map plainMap;
|
||||
|
||||
private Map<Short, Integer> shortMap;
|
||||
|
||||
private HashMap<Long, ?> longMap;
|
||||
|
||||
private Map<Number, Collection<? extends Object>> collectionMap;
|
||||
|
||||
private Map<String, Map<Integer, Long>> mapOfMaps;
|
||||
|
||||
private Map<Integer, List<Integer>> mapOfLists;
|
||||
|
||||
private CustomEnum customEnum;
|
||||
|
||||
private T genericProperty;
|
||||
|
||||
private List<T> genericListProperty;
|
||||
|
||||
|
||||
public GenericBean() {
|
||||
}
|
||||
|
||||
public GenericBean(Set<Integer> integerSet) {
|
||||
this.integerSet = integerSet;
|
||||
}
|
||||
|
||||
public GenericBean(Set<Integer> integerSet, List<Resource> resourceList) {
|
||||
this.integerSet = integerSet;
|
||||
this.resourceList = resourceList;
|
||||
}
|
||||
|
||||
public GenericBean(HashSet<Integer> integerSet, Map<Short, Integer> shortMap) {
|
||||
this.integerSet = integerSet;
|
||||
this.shortMap = shortMap;
|
||||
}
|
||||
|
||||
public GenericBean(Map<Short, Integer> shortMap, Resource resource) {
|
||||
this.shortMap = shortMap;
|
||||
this.resourceList = Collections.singletonList(resource);
|
||||
}
|
||||
|
||||
public GenericBean(Map plainMap, Map<Short, Integer> shortMap) {
|
||||
this.plainMap = plainMap;
|
||||
this.shortMap = shortMap;
|
||||
}
|
||||
|
||||
public GenericBean(HashMap<Long, ?> longMap) {
|
||||
this.longMap = longMap;
|
||||
}
|
||||
|
||||
public GenericBean(boolean someFlag, Map<Number, Collection<? extends Object>> collectionMap) {
|
||||
this.collectionMap = collectionMap;
|
||||
}
|
||||
|
||||
|
||||
public Set<Integer> getIntegerSet() {
|
||||
return integerSet;
|
||||
}
|
||||
|
||||
public void setIntegerSet(Set<Integer> integerSet) {
|
||||
this.integerSet = integerSet;
|
||||
}
|
||||
|
||||
public Set<ITestBean> getTestBeanSet() {
|
||||
return testBeanSet;
|
||||
}
|
||||
|
||||
public void setTestBeanSet(Set<ITestBean> testBeanSet) {
|
||||
this.testBeanSet = testBeanSet;
|
||||
}
|
||||
|
||||
public List<Resource> getResourceList() {
|
||||
return resourceList;
|
||||
}
|
||||
|
||||
public void setResourceList(List<Resource> resourceList) {
|
||||
this.resourceList = resourceList;
|
||||
}
|
||||
|
||||
public List<List<Integer>> getListOfLists() {
|
||||
return listOfLists;
|
||||
}
|
||||
|
||||
public ArrayList<String[]> getListOfArrays() {
|
||||
return listOfArrays;
|
||||
}
|
||||
|
||||
public void setListOfArrays(ArrayList<String[]> listOfArrays) {
|
||||
this.listOfArrays = listOfArrays;
|
||||
}
|
||||
|
||||
public void setListOfLists(List<List<Integer>> listOfLists) {
|
||||
this.listOfLists = listOfLists;
|
||||
}
|
||||
|
||||
public List<Map<Integer, Long>> getListOfMaps() {
|
||||
return listOfMaps;
|
||||
}
|
||||
|
||||
public void setListOfMaps(List<Map<Integer, Long>> listOfMaps) {
|
||||
this.listOfMaps = listOfMaps;
|
||||
}
|
||||
|
||||
public Map getPlainMap() {
|
||||
return plainMap;
|
||||
}
|
||||
|
||||
public Map<Short, Integer> getShortMap() {
|
||||
return shortMap;
|
||||
}
|
||||
|
||||
public void setShortMap(Map<Short, Integer> shortMap) {
|
||||
this.shortMap = shortMap;
|
||||
}
|
||||
|
||||
public HashMap<Long, ?> getLongMap() {
|
||||
return longMap;
|
||||
}
|
||||
|
||||
public void setLongMap(HashMap<Long, ?> longMap) {
|
||||
this.longMap = longMap;
|
||||
}
|
||||
|
||||
public Map<Number, Collection<? extends Object>> getCollectionMap() {
|
||||
return collectionMap;
|
||||
}
|
||||
|
||||
public void setCollectionMap(Map<Number, Collection<? extends Object>> collectionMap) {
|
||||
this.collectionMap = collectionMap;
|
||||
}
|
||||
|
||||
public Map<String, Map<Integer, Long>> getMapOfMaps() {
|
||||
return mapOfMaps;
|
||||
}
|
||||
|
||||
public void setMapOfMaps(Map<String, Map<Integer, Long>> mapOfMaps) {
|
||||
this.mapOfMaps = mapOfMaps;
|
||||
}
|
||||
|
||||
public Map<Integer, List<Integer>> getMapOfLists() {
|
||||
return mapOfLists;
|
||||
}
|
||||
|
||||
public void setMapOfLists(Map<Integer, List<Integer>> mapOfLists) {
|
||||
this.mapOfLists = mapOfLists;
|
||||
}
|
||||
|
||||
public T getGenericProperty() {
|
||||
return genericProperty;
|
||||
}
|
||||
|
||||
public void setGenericProperty(T genericProperty) {
|
||||
this.genericProperty = genericProperty;
|
||||
}
|
||||
|
||||
public List<T> getGenericListProperty() {
|
||||
return genericListProperty;
|
||||
}
|
||||
|
||||
public void setGenericListProperty(List<T> genericListProperty) {
|
||||
this.genericListProperty = genericListProperty;
|
||||
}
|
||||
|
||||
public CustomEnum getCustomEnum() {
|
||||
return customEnum;
|
||||
}
|
||||
|
||||
public void setCustomEnum(CustomEnum customEnum) {
|
||||
this.customEnum = customEnum;
|
||||
}
|
||||
|
||||
|
||||
public static GenericBean createInstance(Set<Integer> integerSet) {
|
||||
return new GenericBean(integerSet);
|
||||
}
|
||||
|
||||
public static GenericBean createInstance(Set<Integer> integerSet, List<Resource> resourceList) {
|
||||
return new GenericBean(integerSet, resourceList);
|
||||
}
|
||||
|
||||
public static GenericBean createInstance(HashSet<Integer> integerSet, Map<Short, Integer> shortMap) {
|
||||
return new GenericBean(integerSet, shortMap);
|
||||
}
|
||||
|
||||
public static GenericBean createInstance(Map<Short, Integer> shortMap, Resource resource) {
|
||||
return new GenericBean(shortMap, resource);
|
||||
}
|
||||
|
||||
public static GenericBean createInstance(Map map, Map<Short, Integer> shortMap) {
|
||||
return new GenericBean(map, shortMap);
|
||||
}
|
||||
|
||||
public static GenericBean createInstance(HashMap<Long, ?> longMap) {
|
||||
return new GenericBean(longMap);
|
||||
}
|
||||
|
||||
public static GenericBean createInstance(boolean someFlag, Map<Number, Collection<? extends Object>> collectionMap) {
|
||||
return new GenericBean(someFlag, collectionMap);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
public interface INestedTestBean {
|
||||
|
||||
public String getCompany();
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
public interface IOther {
|
||||
|
||||
void absquatulate();
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface used for {@link org.springframework.beans.TestBean}.
|
||||
*
|
||||
* <p>Two methods are the same as on Person, but if this
|
||||
* extends person it breaks quite a few tests..
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public interface ITestBean {
|
||||
|
||||
int getAge();
|
||||
|
||||
void setAge(int age);
|
||||
|
||||
String getName();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
ITestBean getSpouse();
|
||||
|
||||
void setSpouse(ITestBean spouse);
|
||||
|
||||
ITestBean[] getSpouses();
|
||||
|
||||
String[] getStringArray();
|
||||
|
||||
void setStringArray(String[] stringArray);
|
||||
|
||||
/**
|
||||
* Throws a given (non-null) exception.
|
||||
*/
|
||||
void exceptional(Throwable t) throws Throwable;
|
||||
|
||||
Object returnsThis();
|
||||
|
||||
INestedTestBean getDoctor();
|
||||
|
||||
INestedTestBean getLawyer();
|
||||
|
||||
IndexedTestBean getNestedIndexedBean();
|
||||
|
||||
/**
|
||||
* Increment the age by one.
|
||||
* @return the previous age
|
||||
*/
|
||||
int haveBirthday();
|
||||
|
||||
void unreliableFileOperation() throws IOException;
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 11.11.2003
|
||||
*/
|
||||
public class IndexedTestBean {
|
||||
|
||||
private TestBean[] array;
|
||||
|
||||
private Collection collection;
|
||||
|
||||
private List list;
|
||||
|
||||
private Set set;
|
||||
|
||||
private SortedSet sortedSet;
|
||||
|
||||
private Map map;
|
||||
|
||||
private SortedMap sortedMap;
|
||||
|
||||
|
||||
public IndexedTestBean() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public IndexedTestBean(boolean populate) {
|
||||
if (populate) {
|
||||
populate();
|
||||
}
|
||||
}
|
||||
|
||||
public void populate() {
|
||||
TestBean tb0 = new TestBean("name0", 0);
|
||||
TestBean tb1 = new TestBean("name1", 0);
|
||||
TestBean tb2 = new TestBean("name2", 0);
|
||||
TestBean tb3 = new TestBean("name3", 0);
|
||||
TestBean tb4 = new TestBean("name4", 0);
|
||||
TestBean tb5 = new TestBean("name5", 0);
|
||||
TestBean tb6 = new TestBean("name6", 0);
|
||||
TestBean tb7 = new TestBean("name7", 0);
|
||||
TestBean tbX = new TestBean("nameX", 0);
|
||||
TestBean tbY = new TestBean("nameY", 0);
|
||||
this.array = new TestBean[] {tb0, tb1};
|
||||
this.list = new ArrayList();
|
||||
this.list.add(tb2);
|
||||
this.list.add(tb3);
|
||||
this.set = new TreeSet();
|
||||
this.set.add(tb6);
|
||||
this.set.add(tb7);
|
||||
this.map = new HashMap();
|
||||
this.map.put("key1", tb4);
|
||||
this.map.put("key2", tb5);
|
||||
this.map.put("key.3", tb5);
|
||||
List list = new ArrayList();
|
||||
list.add(tbX);
|
||||
list.add(tbY);
|
||||
this.map.put("key4", list);
|
||||
}
|
||||
|
||||
|
||||
public TestBean[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public void setArray(TestBean[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public Collection getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void setCollection(Collection collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public List getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public Set getSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public void setSet(Set set) {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public SortedSet getSortedSet() {
|
||||
return sortedSet;
|
||||
}
|
||||
|
||||
public void setSortedSet(SortedSet sortedSet) {
|
||||
this.sortedSet = sortedSet;
|
||||
}
|
||||
|
||||
public Map getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public SortedMap getSortedMap() {
|
||||
return sortedMap;
|
||||
}
|
||||
|
||||
public void setSortedMap(SortedMap sortedMap) {
|
||||
this.sortedMap = sortedMap;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
/**
|
||||
* Simple nested test bean used for testing bean factories, AOP framework etc.
|
||||
*
|
||||
* @author Trevor D. Cook
|
||||
* @since 30.09.2003
|
||||
*/
|
||||
public class NestedTestBean implements INestedTestBean {
|
||||
|
||||
private String company = "";
|
||||
|
||||
public NestedTestBean() {
|
||||
}
|
||||
|
||||
public NestedTestBean(String company) {
|
||||
setCompany(company);
|
||||
}
|
||||
|
||||
public void setCompany(String company) {
|
||||
this.company = (company != null ? company : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NestedTestBean)) {
|
||||
return false;
|
||||
}
|
||||
NestedTestBean ntb = (NestedTestBean) obj;
|
||||
return this.company.equals(ntb.company);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.company.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "NestedTestBean: " + this.company;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public interface Person {
|
||||
|
||||
String getName();
|
||||
void setName(String name);
|
||||
int getAge();
|
||||
void setAge(int i);
|
||||
|
||||
/**
|
||||
* Test for non-property method matching.
|
||||
* If the parameter is a Throwable, it will be thrown rather than
|
||||
* returned.
|
||||
*/
|
||||
Object echo(Object o) throws Throwable;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
*/
|
||||
public class Pet {
|
||||
|
||||
private String name;
|
||||
|
||||
public Pet(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final Pet pet = (Pet) o;
|
||||
|
||||
if (name != null ? !name.equals(pet.name) : pet.name != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (name != null ? name.hashCode() : 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Serializable implementation of the Person interface.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class SerializablePerson implements Person, Serializable {
|
||||
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object echo(Object o) throws Throwable {
|
||||
if (o instanceof Throwable) {
|
||||
throw (Throwable) o;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof SerializablePerson)) {
|
||||
return false;
|
||||
}
|
||||
SerializablePerson p = (SerializablePerson) other;
|
||||
return p.age == age && ObjectUtils.nullSafeEquals(name, p.name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,457 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Simple test bean used for testing bean factories, the AOP framework etc.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @since 15 April 2001
|
||||
*/
|
||||
public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOther, Comparable {
|
||||
|
||||
private String beanName;
|
||||
|
||||
private String country;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private boolean postProcessed;
|
||||
|
||||
private String name;
|
||||
|
||||
private String sex;
|
||||
|
||||
private int age;
|
||||
|
||||
private boolean jedi;
|
||||
|
||||
private ITestBean[] spouses;
|
||||
|
||||
private String touchy;
|
||||
|
||||
private String[] stringArray;
|
||||
|
||||
private Integer[] someIntegerArray;
|
||||
|
||||
private Date date = new Date();
|
||||
|
||||
private Float myFloat = new Float(0.0);
|
||||
|
||||
private Collection friends = new LinkedList();
|
||||
|
||||
private Set someSet = new HashSet();
|
||||
|
||||
private Map someMap = new HashMap();
|
||||
|
||||
private List someList = new ArrayList();
|
||||
|
||||
private Properties someProperties = new Properties();
|
||||
|
||||
private INestedTestBean doctor = new NestedTestBean();
|
||||
|
||||
private INestedTestBean lawyer = new NestedTestBean();
|
||||
|
||||
private IndexedTestBean nestedIndexedBean;
|
||||
|
||||
private boolean destroyed;
|
||||
|
||||
private Number someNumber;
|
||||
|
||||
private Colour favouriteColour;
|
||||
|
||||
private Boolean someBoolean;
|
||||
|
||||
private List otherColours;
|
||||
|
||||
private List pets;
|
||||
|
||||
|
||||
public TestBean() {
|
||||
}
|
||||
|
||||
public TestBean(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TestBean(ITestBean spouse) {
|
||||
this.spouses = new ITestBean[] {spouse};
|
||||
}
|
||||
|
||||
public TestBean(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public TestBean(ITestBean spouse, Properties someProperties) {
|
||||
this.spouses = new ITestBean[] {spouse};
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
public TestBean(List someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
|
||||
public TestBean(Set someSet) {
|
||||
this.someSet = someSet;
|
||||
}
|
||||
|
||||
public TestBean(Map someMap) {
|
||||
this.someMap = someMap;
|
||||
}
|
||||
|
||||
public TestBean(Properties someProperties) {
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public BeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
public void setPostProcessed(boolean postProcessed) {
|
||||
this.postProcessed = postProcessed;
|
||||
}
|
||||
|
||||
public boolean isPostProcessed() {
|
||||
return postProcessed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(String sex) {
|
||||
this.sex = sex;
|
||||
if (this.name == null) {
|
||||
this.name = sex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public boolean isJedi() {
|
||||
return jedi;
|
||||
}
|
||||
|
||||
public void setJedi(boolean jedi) {
|
||||
this.jedi = jedi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITestBean getSpouse() {
|
||||
return (spouses != null ? spouses[0] : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
this.spouses = new ITestBean[] {spouse};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITestBean[] getSpouses() {
|
||||
return spouses;
|
||||
}
|
||||
|
||||
public String getTouchy() {
|
||||
return touchy;
|
||||
}
|
||||
|
||||
public void setTouchy(String touchy) throws Exception {
|
||||
if (touchy.indexOf('.') != -1) {
|
||||
throw new Exception("Can't contain a .");
|
||||
}
|
||||
if (touchy.indexOf(',') != -1) {
|
||||
throw new NumberFormatException("Number format exception: contains a ,");
|
||||
}
|
||||
this.touchy = touchy;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getStringArray() {
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStringArray(String[] stringArray) {
|
||||
this.stringArray = stringArray;
|
||||
}
|
||||
|
||||
public Integer[] getSomeIntegerArray() {
|
||||
return someIntegerArray;
|
||||
}
|
||||
|
||||
public void setSomeIntegerArray(Integer[] someIntegerArray) {
|
||||
this.someIntegerArray = someIntegerArray;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public Float getMyFloat() {
|
||||
return myFloat;
|
||||
}
|
||||
|
||||
public void setMyFloat(Float myFloat) {
|
||||
this.myFloat = myFloat;
|
||||
}
|
||||
|
||||
public Collection getFriends() {
|
||||
return friends;
|
||||
}
|
||||
|
||||
public void setFriends(Collection friends) {
|
||||
this.friends = friends;
|
||||
}
|
||||
|
||||
public Set getSomeSet() {
|
||||
return someSet;
|
||||
}
|
||||
|
||||
public void setSomeSet(Set someSet) {
|
||||
this.someSet = someSet;
|
||||
}
|
||||
|
||||
public Map getSomeMap() {
|
||||
return someMap;
|
||||
}
|
||||
|
||||
public void setSomeMap(Map someMap) {
|
||||
this.someMap = someMap;
|
||||
}
|
||||
|
||||
public List getSomeList() {
|
||||
return someList;
|
||||
}
|
||||
|
||||
public void setSomeList(List someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
|
||||
public Properties getSomeProperties() {
|
||||
return someProperties;
|
||||
}
|
||||
|
||||
public void setSomeProperties(Properties someProperties) {
|
||||
this.someProperties = someProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INestedTestBean getDoctor() {
|
||||
return doctor;
|
||||
}
|
||||
|
||||
public void setDoctor(INestedTestBean doctor) {
|
||||
this.doctor = doctor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public INestedTestBean getLawyer() {
|
||||
return lawyer;
|
||||
}
|
||||
|
||||
public void setLawyer(INestedTestBean lawyer) {
|
||||
this.lawyer = lawyer;
|
||||
}
|
||||
|
||||
public Number getSomeNumber() {
|
||||
return someNumber;
|
||||
}
|
||||
|
||||
public void setSomeNumber(Number someNumber) {
|
||||
this.someNumber = someNumber;
|
||||
}
|
||||
|
||||
public Colour getFavouriteColour() {
|
||||
return favouriteColour;
|
||||
}
|
||||
|
||||
public void setFavouriteColour(Colour favouriteColour) {
|
||||
this.favouriteColour = favouriteColour;
|
||||
}
|
||||
|
||||
public Boolean getSomeBoolean() {
|
||||
return someBoolean;
|
||||
}
|
||||
|
||||
public void setSomeBoolean(Boolean someBoolean) {
|
||||
this.someBoolean = someBoolean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexedTestBean getNestedIndexedBean() {
|
||||
return nestedIndexedBean;
|
||||
}
|
||||
|
||||
public void setNestedIndexedBean(IndexedTestBean nestedIndexedBean) {
|
||||
this.nestedIndexedBean = nestedIndexedBean;
|
||||
}
|
||||
|
||||
public List getOtherColours() {
|
||||
return otherColours;
|
||||
}
|
||||
|
||||
public void setOtherColours(List otherColours) {
|
||||
this.otherColours = otherColours;
|
||||
}
|
||||
|
||||
public List getPets() {
|
||||
return pets;
|
||||
}
|
||||
|
||||
public void setPets(List pets) {
|
||||
this.pets = pets;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.ITestBean#exceptional(Throwable)
|
||||
*/
|
||||
@Override
|
||||
public void exceptional(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unreliableFileOperation() throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
/**
|
||||
* @see org.springframework.beans.ITestBean#returnsThis()
|
||||
*/
|
||||
@Override
|
||||
public Object returnsThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.IOther#absquatulate()
|
||||
*/
|
||||
@Override
|
||||
public void absquatulate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int haveBirthday() {
|
||||
return age++;
|
||||
}
|
||||
|
||||
|
||||
public void destroy() {
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
public boolean wasDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || !(other instanceof TestBean)) {
|
||||
return false;
|
||||
}
|
||||
TestBean tb2 = (TestBean) other;
|
||||
return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && this.age == tb2.age);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object other) {
|
||||
if (this.name != null && other instanceof TestBean) {
|
||||
return this.name.compareTo(((TestBean) other).getName());
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
|
||||
/**
|
||||
* Simple factory to allow testing of FactoryBean support in AbstractBeanFactory.
|
||||
* Depending on whether its singleton property is set, it will return a singleton
|
||||
* or a prototype instance.
|
||||
*
|
||||
* <p>Implements InitializingBean interface, so we can check that
|
||||
* factories get this lifecycle callback if they want.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 10.03.2003
|
||||
*/
|
||||
public class DummyFactory
|
||||
implements FactoryBean, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
|
||||
|
||||
public static final String SINGLETON_NAME = "Factory singleton";
|
||||
|
||||
private static boolean prototypeCreated;
|
||||
|
||||
/**
|
||||
* Clear static state.
|
||||
*/
|
||||
public static void reset() {
|
||||
prototypeCreated = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default is for factories to return a singleton instance.
|
||||
*/
|
||||
private boolean singleton = true;
|
||||
|
||||
private String beanName;
|
||||
|
||||
private AutowireCapableBeanFactory beanFactory;
|
||||
|
||||
private boolean postProcessed;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
private TestBean testBean;
|
||||
|
||||
private TestBean otherTestBean;
|
||||
|
||||
|
||||
public DummyFactory() {
|
||||
this.testBean = new TestBean();
|
||||
this.testBean.setName(SINGLETON_NAME);
|
||||
this.testBean.setAge(25);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the bean managed by this factory is a singleton.
|
||||
* @see FactoryBean#isSingleton()
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return this.singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the bean managed by this factory is a singleton.
|
||||
*/
|
||||
public void setSingleton(boolean singleton) {
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
|
||||
this.beanFactory.applyBeanPostProcessorsBeforeInitialization(this.testBean, this.beanName);
|
||||
}
|
||||
|
||||
public BeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
public void setPostProcessed(boolean postProcessed) {
|
||||
this.postProcessed = postProcessed;
|
||||
}
|
||||
|
||||
public boolean isPostProcessed() {
|
||||
return postProcessed;
|
||||
}
|
||||
|
||||
public void setOtherTestBean(TestBean otherTestBean) {
|
||||
this.otherTestBean = otherTestBean;
|
||||
this.testBean.setSpouse(otherTestBean);
|
||||
}
|
||||
|
||||
public TestBean getOtherTestBean() {
|
||||
return otherTestBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (initialized) {
|
||||
throw new RuntimeException("Cannot call afterPropertiesSet twice on the one bean");
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was this initialized by invocation of the
|
||||
* afterPropertiesSet() method from the InitializingBean interface?
|
||||
*/
|
||||
public boolean wasInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public static boolean wasPrototypeCreated() {
|
||||
return prototypeCreated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the managed object, supporting both singleton
|
||||
* and prototype mode.
|
||||
* @see FactoryBean#getObject()
|
||||
*/
|
||||
@Override
|
||||
public Object getObject() throws BeansException {
|
||||
if (isSingleton()) {
|
||||
return this.testBean;
|
||||
}
|
||||
else {
|
||||
TestBean prototype = new TestBean("prototype created at " + System.currentTimeMillis(), 11);
|
||||
if (this.beanFactory != null) {
|
||||
this.beanFactory.applyBeanPostProcessorsBeforeInitialization(prototype, this.beanName);
|
||||
}
|
||||
prototypeCreated = true;
|
||||
return prototype;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getObjectType() {
|
||||
return TestBean.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (this.testBean != null) {
|
||||
this.testBean.setName(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
||||
/**
|
||||
* Simple test of BeanFactory initialization and lifecycle callbacks.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Colin Sampaleanu
|
||||
* @since 12.03.2003
|
||||
*/
|
||||
public class LifecycleBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
|
||||
|
||||
protected boolean initMethodDeclared = false;
|
||||
|
||||
protected String beanName;
|
||||
|
||||
protected BeanFactory owningFactory;
|
||||
|
||||
protected boolean postProcessedBeforeInit;
|
||||
|
||||
protected boolean inited;
|
||||
|
||||
protected boolean initedViaDeclaredInitMethod;
|
||||
|
||||
protected boolean postProcessedAfterInit;
|
||||
|
||||
protected boolean destroyed;
|
||||
|
||||
|
||||
public void setInitMethodDeclared(boolean initMethodDeclared) {
|
||||
this.initMethodDeclared = initMethodDeclared;
|
||||
}
|
||||
|
||||
public boolean isInitMethodDeclared() {
|
||||
return initMethodDeclared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.owningFactory = beanFactory;
|
||||
}
|
||||
|
||||
public void postProcessBeforeInit() {
|
||||
if (this.inited || this.initedViaDeclaredInitMethod) {
|
||||
throw new RuntimeException("Factory called postProcessBeforeInit after afterPropertiesSet");
|
||||
}
|
||||
if (this.postProcessedBeforeInit) {
|
||||
throw new RuntimeException("Factory called postProcessBeforeInit twice");
|
||||
}
|
||||
this.postProcessedBeforeInit = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (this.owningFactory == null) {
|
||||
throw new RuntimeException("Factory didn't call setBeanFactory before afterPropertiesSet on lifecycle bean");
|
||||
}
|
||||
if (!this.postProcessedBeforeInit) {
|
||||
throw new RuntimeException("Factory didn't call postProcessBeforeInit before afterPropertiesSet on lifecycle bean");
|
||||
}
|
||||
if (this.initedViaDeclaredInitMethod) {
|
||||
throw new RuntimeException("Factory initialized via declared init method before initializing via afterPropertiesSet");
|
||||
}
|
||||
if (this.inited) {
|
||||
throw new RuntimeException("Factory called afterPropertiesSet twice");
|
||||
}
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
public void declaredInitMethod() {
|
||||
if (!this.inited) {
|
||||
throw new RuntimeException("Factory didn't call afterPropertiesSet before declared init method");
|
||||
}
|
||||
|
||||
if (this.initedViaDeclaredInitMethod) {
|
||||
throw new RuntimeException("Factory called declared init method twice");
|
||||
}
|
||||
this.initedViaDeclaredInitMethod = true;
|
||||
}
|
||||
|
||||
public void postProcessAfterInit() {
|
||||
if (!this.inited) {
|
||||
throw new RuntimeException("Factory called postProcessAfterInit before afterPropertiesSet");
|
||||
}
|
||||
if (this.initMethodDeclared && !this.initedViaDeclaredInitMethod) {
|
||||
throw new RuntimeException("Factory called postProcessAfterInit before calling declared init method");
|
||||
}
|
||||
if (this.postProcessedAfterInit) {
|
||||
throw new RuntimeException("Factory called postProcessAfterInit twice");
|
||||
}
|
||||
this.postProcessedAfterInit = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy business method that will fail unless the factory
|
||||
* managed the bean's lifecycle correctly
|
||||
*/
|
||||
public void businessMethod() {
|
||||
if (!this.inited || (this.initMethodDeclared && !this.initedViaDeclaredInitMethod) ||
|
||||
!this.postProcessedAfterInit) {
|
||||
throw new RuntimeException("Factory didn't initialize lifecycle object correctly");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (this.destroyed) {
|
||||
throw new IllegalStateException("Already destroyed");
|
||||
}
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
public boolean isDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
|
||||
public static class PostProcessor implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
|
||||
if (bean instanceof LifecycleBean) {
|
||||
((LifecycleBean) bean).postProcessBeforeInit();
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
|
||||
if (bean instanceof LifecycleBean) {
|
||||
((LifecycleBean) bean).postProcessAfterInit();
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Simple test of BeanFactory initialization
|
||||
* @author Rod Johnson
|
||||
* @since 12.03.2003
|
||||
*/
|
||||
public class MustBeInitialized implements InitializingBean {
|
||||
|
||||
private boolean inited;
|
||||
|
||||
/**
|
||||
* @see InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy business method that will fail unless the factory
|
||||
* managed the bean's lifecycle correctly
|
||||
*/
|
||||
public void businessMethod() {
|
||||
if (!this.inited)
|
||||
throw new RuntimeException("Factory didn't call afterPropertiesSet() on MustBeInitialized object");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.springframework.context;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.LifecycleBean;
|
||||
import org.springframework.tests.sample.beans.LifecycleBean;
|
||||
|
||||
/**
|
||||
* Simple bean to test ApplicationContext lifecycle methods for beans
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.http.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Random;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Utility class that finds free BSD ports for use in testing scenario's.
|
||||
*
|
||||
* @author Ben Hale
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class FreePortScanner {
|
||||
|
||||
private static final int MIN_SAFE_PORT = 1024;
|
||||
|
||||
private static final int MAX_PORT = 65535;
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
/**
|
||||
* Returns the number of a free port in the default range.
|
||||
*/
|
||||
public static int getFreePort() {
|
||||
return getFreePort(MIN_SAFE_PORT, MAX_PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of a free port in the given range.
|
||||
*/
|
||||
public static int getFreePort(int minPort, int maxPort) {
|
||||
Assert.isTrue(minPort > 0, "'minPort' must be larger than 0");
|
||||
Assert.isTrue(maxPort > minPort, "'maxPort' must be larger than minPort");
|
||||
int portRange = maxPort - minPort;
|
||||
int candidatePort;
|
||||
int searchCounter = 0;
|
||||
do {
|
||||
if (++searchCounter > portRange) {
|
||||
throw new IllegalStateException(
|
||||
String.format("There were no ports available in the range %d to %d", minPort, maxPort));
|
||||
}
|
||||
candidatePort = getRandomPort(minPort, portRange);
|
||||
}
|
||||
while (!isPortAvailable(candidatePort));
|
||||
|
||||
return candidatePort;
|
||||
}
|
||||
|
||||
private static int getRandomPort(int minPort, int portRange) {
|
||||
return minPort + random.nextInt(portRange);
|
||||
}
|
||||
|
||||
private static boolean isPortAvailable(int port) {
|
||||
ServerSocket serverSocket;
|
||||
try {
|
||||
serverSocket = new ServerSocket();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Unable to create ServerSocket.", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
InetSocketAddress sa = new InetSocketAddress(port);
|
||||
serverSocket.bind(sa);
|
||||
return true;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
serverSocket.close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ui.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class PersonBean {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String street;
|
||||
|
||||
private String city;
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ui.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class ProductBean {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private float quantity;
|
||||
|
||||
private float price;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public float getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(float quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public float getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(float price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.NotSerializableException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Utilities for testing serializability of objects.
|
||||
* Exposes static methods for use in other test cases.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public class SerializationTestUtils {
|
||||
|
||||
public static void testSerialization(Object o) throws IOException {
|
||||
OutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(o);
|
||||
}
|
||||
|
||||
public static boolean isSerializable(Object o) throws IOException {
|
||||
try {
|
||||
testSerialization(o);
|
||||
return true;
|
||||
}
|
||||
catch (NotSerializableException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(o);
|
||||
oos.flush();
|
||||
baos.flush();
|
||||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(is);
|
||||
Object o2 = ois.readObject();
|
||||
return o2;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.context;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.LifecycleBean;
|
||||
import org.springframework.context.ACATester;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.BeanThatListens;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.context.TestListener;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public abstract class AbstractApplicationContextTests extends AbstractListableBeanFactoryTests {
|
||||
|
||||
/** Must be supplied as XML */
|
||||
public static final String TEST_NAMESPACE = "testNamespace";
|
||||
|
||||
protected ConfigurableApplicationContext applicationContext;
|
||||
|
||||
/** Subclass must register this */
|
||||
protected TestListener listener = new TestListener();
|
||||
|
||||
protected TestListener parentListener = new TestListener();
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
this.applicationContext = createContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeanFactory getBeanFactory() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
protected ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must register a TestListener.
|
||||
* Must register standard beans.
|
||||
* Parent must register rod with name Roderick
|
||||
* and father with name Albert.
|
||||
*/
|
||||
protected abstract ConfigurableApplicationContext createContext() throws Exception;
|
||||
|
||||
public void testContextAwareSingletonWasCalledBack() throws Exception {
|
||||
ACATester aca = (ACATester) applicationContext.getBean("aca");
|
||||
assertTrue("has had context set", aca.getApplicationContext() == applicationContext);
|
||||
Object aca2 = applicationContext.getBean("aca");
|
||||
assertTrue("Same instance", aca == aca2);
|
||||
assertTrue("Says is singleton", applicationContext.isSingleton("aca"));
|
||||
}
|
||||
|
||||
public void testContextAwarePrototypeWasCalledBack() throws Exception {
|
||||
ACATester aca = (ACATester) applicationContext.getBean("aca-prototype");
|
||||
assertTrue("has had context set", aca.getApplicationContext() == applicationContext);
|
||||
Object aca2 = applicationContext.getBean("aca-prototype");
|
||||
assertTrue("NOT Same instance", aca != aca2);
|
||||
assertTrue("Says is prototype", !applicationContext.isSingleton("aca-prototype"));
|
||||
}
|
||||
|
||||
public void testParentNonNull() {
|
||||
assertTrue("parent isn't null", applicationContext.getParent() != null);
|
||||
}
|
||||
|
||||
public void testGrandparentNull() {
|
||||
assertTrue("grandparent is null", applicationContext.getParent().getParent() == null);
|
||||
}
|
||||
|
||||
public void testOverrideWorked() throws Exception {
|
||||
TestBean rod = (TestBean) applicationContext.getParent().getBean("rod");
|
||||
assertTrue("Parent's name differs", rod.getName().equals("Roderick"));
|
||||
}
|
||||
|
||||
public void testGrandparentDefinitionFound() throws Exception {
|
||||
TestBean dad = (TestBean) applicationContext.getBean("father");
|
||||
assertTrue("Dad has correct name", dad.getName().equals("Albert"));
|
||||
}
|
||||
|
||||
public void testGrandparentTypedDefinitionFound() throws Exception {
|
||||
TestBean dad = applicationContext.getBean("father", TestBean.class);
|
||||
assertTrue("Dad has correct name", dad.getName().equals("Albert"));
|
||||
}
|
||||
|
||||
public void testCloseTriggersDestroy() {
|
||||
LifecycleBean lb = (LifecycleBean) applicationContext.getBean("lifecycle");
|
||||
assertTrue("Not destroyed", !lb.isDestroyed());
|
||||
applicationContext.close();
|
||||
if (applicationContext.getParent() != null) {
|
||||
((ConfigurableApplicationContext) applicationContext.getParent()).close();
|
||||
}
|
||||
assertTrue("Destroyed", lb.isDestroyed());
|
||||
applicationContext.close();
|
||||
if (applicationContext.getParent() != null) {
|
||||
((ConfigurableApplicationContext) applicationContext.getParent()).close();
|
||||
}
|
||||
assertTrue("Destroyed", lb.isDestroyed());
|
||||
}
|
||||
|
||||
public void testMessageSource() throws NoSuchMessageException {
|
||||
assertEquals("message1", applicationContext.getMessage("code1", null, Locale.getDefault()));
|
||||
assertEquals("message2", applicationContext.getMessage("code2", null, Locale.getDefault()));
|
||||
|
||||
try {
|
||||
applicationContext.getMessage("code0", null, Locale.getDefault());
|
||||
fail("looking for code0 should throw a NoSuchMessageException");
|
||||
}
|
||||
catch (NoSuchMessageException ex) {
|
||||
// that's how it should be
|
||||
}
|
||||
}
|
||||
|
||||
public void testEvents() throws Exception {
|
||||
listener.zeroCounter();
|
||||
parentListener.zeroCounter();
|
||||
assertTrue("0 events before publication", listener.getEventCount() == 0);
|
||||
assertTrue("0 parent events before publication", parentListener.getEventCount() == 0);
|
||||
this.applicationContext.publishEvent(new MyEvent(this));
|
||||
assertTrue("1 events after publication, not " + listener.getEventCount(), listener.getEventCount() == 1);
|
||||
assertTrue("1 parent events after publication", parentListener.getEventCount() == 1);
|
||||
}
|
||||
|
||||
public void testBeanAutomaticallyHearsEvents() throws Exception {
|
||||
//String[] listenerNames = ((ListableBeanFactory) applicationContext).getBeanDefinitionNames(ApplicationListener.class);
|
||||
//assertTrue("listeners include beanThatListens", Arrays.asList(listenerNames).contains("beanThatListens"));
|
||||
BeanThatListens b = (BeanThatListens) applicationContext.getBean("beanThatListens");
|
||||
b.zero();
|
||||
assertTrue("0 events before publication", b.getEventCount() == 0);
|
||||
this.applicationContext.publishEvent(new MyEvent(this));
|
||||
assertTrue("1 events after publication, not " + b.getEventCount(), b.getEventCount() == 1);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public static class MyEvent extends ApplicationEvent {
|
||||
|
||||
public MyEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.context;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyBatchUpdateException;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanIsNotAFactoryException;
|
||||
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
|
||||
import org.springframework.beans.factory.DummyFactory;
|
||||
import org.springframework.beans.factory.LifecycleBean;
|
||||
import org.springframework.beans.factory.MustBeInitialized;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
|
||||
/**
|
||||
* Subclasses must implement setUp() to initialize bean factory
|
||||
* and any other variables they need.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public abstract class AbstractBeanFactoryTests extends TestCase {
|
||||
|
||||
protected abstract BeanFactory getBeanFactory();
|
||||
|
||||
/**
|
||||
* Roderick beans inherits from rod, overriding name only.
|
||||
*/
|
||||
public void testInheritance() {
|
||||
assertTrue(getBeanFactory().containsBean("rod"));
|
||||
assertTrue(getBeanFactory().containsBean("roderick"));
|
||||
TestBean rod = (TestBean) getBeanFactory().getBean("rod");
|
||||
TestBean roderick = (TestBean) getBeanFactory().getBean("roderick");
|
||||
assertTrue("not == ", rod != roderick);
|
||||
assertTrue("rod.name is Rod", rod.getName().equals("Rod"));
|
||||
assertTrue("rod.age is 31", rod.getAge() == 31);
|
||||
assertTrue("roderick.name is Roderick", roderick.getName().equals("Roderick"));
|
||||
assertTrue("roderick.age was inherited", roderick.getAge() == rod.getAge());
|
||||
}
|
||||
|
||||
public void testGetBeanWithNullArg() {
|
||||
try {
|
||||
getBeanFactory().getBean((String) null);
|
||||
fail("Can't get null bean");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// OK
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that InitializingBean objects receive the afterPropertiesSet() callback
|
||||
*/
|
||||
public void testInitializingBeanCallback() {
|
||||
MustBeInitialized mbi = (MustBeInitialized) getBeanFactory().getBean("mustBeInitialized");
|
||||
// The dummy business method will throw an exception if the
|
||||
// afterPropertiesSet() callback wasn't invoked
|
||||
mbi.businessMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that InitializingBean/BeanFactoryAware/DisposableBean objects receive the
|
||||
* afterPropertiesSet() callback before BeanFactoryAware callbacks
|
||||
*/
|
||||
public void testLifecycleCallbacks() {
|
||||
LifecycleBean lb = (LifecycleBean) getBeanFactory().getBean("lifecycle");
|
||||
assertEquals("lifecycle", lb.getBeanName());
|
||||
// The dummy business method will throw an exception if the
|
||||
// necessary callbacks weren't invoked in the right order.
|
||||
lb.businessMethod();
|
||||
assertTrue("Not destroyed", !lb.isDestroyed());
|
||||
}
|
||||
|
||||
public void testFindsValidInstance() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("rod");
|
||||
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
|
||||
TestBean rod = (TestBean) o;
|
||||
assertTrue("rod.name is Rod", rod.getName().equals("Rod"));
|
||||
assertTrue("rod.age is 31", rod.getAge() == 31);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on getting valid instance");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetInstanceByMatchingClass() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("rod", TestBean.class);
|
||||
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on getting valid instance with matching class");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetInstanceByNonmatchingClass() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("rod", BeanFactory.class);
|
||||
fail("Rod bean is not of type BeanFactory; getBeanInstance(rod, BeanFactory.class) should throw BeanNotOfRequiredTypeException");
|
||||
}
|
||||
catch (BeanNotOfRequiredTypeException ex) {
|
||||
// So far, so good
|
||||
assertTrue("Exception has correct bean name", ex.getBeanName().equals("rod"));
|
||||
assertTrue("Exception requiredType must be BeanFactory.class", ex.getRequiredType().equals(BeanFactory.class));
|
||||
assertTrue("Exception actualType as TestBean.class", TestBean.class.isAssignableFrom(ex.getActualType()));
|
||||
assertTrue("Actual type is correct", ex.getActualType() == getBeanFactory().getBean("rod").getClass());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on getting valid instance");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetSharedInstanceByMatchingClass() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("rod", TestBean.class);
|
||||
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on getting valid instance with matching class");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetSharedInstanceByMatchingClassNoCatch() {
|
||||
Object o = getBeanFactory().getBean("rod", TestBean.class);
|
||||
assertTrue("Rod bean is a TestBean", o instanceof TestBean);
|
||||
}
|
||||
|
||||
public void testGetSharedInstanceByNonmatchingClass() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("rod", BeanFactory.class);
|
||||
fail("Rod bean is not of type BeanFactory; getBeanInstance(rod, BeanFactory.class) should throw BeanNotOfRequiredTypeException");
|
||||
}
|
||||
catch (BeanNotOfRequiredTypeException ex) {
|
||||
// So far, so good
|
||||
assertTrue("Exception has correct bean name", ex.getBeanName().equals("rod"));
|
||||
assertTrue("Exception requiredType must be BeanFactory.class", ex.getRequiredType().equals(BeanFactory.class));
|
||||
assertTrue("Exception actualType as TestBean.class", TestBean.class.isAssignableFrom(ex.getActualType()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on getting valid instance");
|
||||
}
|
||||
}
|
||||
|
||||
public void testSharedInstancesAreEqual() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("rod");
|
||||
assertTrue("Rod bean1 is a TestBean", o instanceof TestBean);
|
||||
Object o1 = getBeanFactory().getBean("rod");
|
||||
assertTrue("Rod bean2 is a TestBean", o1 instanceof TestBean);
|
||||
assertTrue("Object equals applies", o == o1);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on getting valid instance");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPrototypeInstancesAreIndependent() {
|
||||
TestBean tb1 = (TestBean) getBeanFactory().getBean("kathy");
|
||||
TestBean tb2 = (TestBean) getBeanFactory().getBean("kathy");
|
||||
assertTrue("ref equal DOES NOT apply", tb1 != tb2);
|
||||
assertTrue("object equal true", tb1.equals(tb2));
|
||||
tb1.setAge(1);
|
||||
tb2.setAge(2);
|
||||
assertTrue("1 age independent = 1", tb1.getAge() == 1);
|
||||
assertTrue("2 age independent = 2", tb2.getAge() == 2);
|
||||
assertTrue("object equal now false", !tb1.equals(tb2));
|
||||
}
|
||||
|
||||
public void testNotThere() {
|
||||
assertFalse(getBeanFactory().containsBean("Mr Squiggle"));
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("Mr Squiggle");
|
||||
fail("Can't find missing bean");
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
//ex.printStackTrace();
|
||||
//fail("Shouldn't throw exception on getting valid instance");
|
||||
}
|
||||
}
|
||||
|
||||
public void testValidEmpty() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("validEmpty");
|
||||
assertTrue("validEmpty bean is a TestBean", o instanceof TestBean);
|
||||
TestBean ve = (TestBean) o;
|
||||
assertTrue("Valid empty has defaults", ve.getName() == null && ve.getAge() == 0 && ve.getSpouse() == null);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Shouldn't throw exception on valid empty");
|
||||
}
|
||||
}
|
||||
|
||||
public void xtestTypeMismatch() {
|
||||
try {
|
||||
Object o = getBeanFactory().getBean("typeMismatch");
|
||||
fail("Shouldn't succeed with type mismatch");
|
||||
}
|
||||
catch (BeanCreationException wex) {
|
||||
assertEquals("typeMismatch", wex.getBeanName());
|
||||
assertTrue(wex.getCause() instanceof PropertyBatchUpdateException);
|
||||
PropertyBatchUpdateException ex = (PropertyBatchUpdateException) wex.getCause();
|
||||
// Further tests
|
||||
assertTrue("Has one error ", ex.getExceptionCount() == 1);
|
||||
assertTrue("Error is for field age", ex.getPropertyAccessException("age") != null);
|
||||
assertTrue("We have rejected age in exception", ex.getPropertyAccessException("age").getPropertyChangeEvent().getNewValue().equals("34x"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGrandparentDefinitionFoundInBeanFactory() throws Exception {
|
||||
TestBean dad = (TestBean) getBeanFactory().getBean("father");
|
||||
assertTrue("Dad has correct name", dad.getName().equals("Albert"));
|
||||
}
|
||||
|
||||
public void testFactorySingleton() throws Exception {
|
||||
assertTrue(getBeanFactory().isSingleton("&singletonFactory"));
|
||||
assertTrue(getBeanFactory().isSingleton("singletonFactory"));
|
||||
TestBean tb = (TestBean) getBeanFactory().getBean("singletonFactory");
|
||||
assertTrue("Singleton from factory has correct name, not " + tb.getName(), tb.getName().equals(DummyFactory.SINGLETON_NAME));
|
||||
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
|
||||
TestBean tb2 = (TestBean) getBeanFactory().getBean("singletonFactory");
|
||||
assertTrue("Singleton references ==", tb == tb2);
|
||||
assertTrue("FactoryBean is BeanFactoryAware", factory.getBeanFactory() != null);
|
||||
}
|
||||
|
||||
public void testFactoryPrototype() throws Exception {
|
||||
assertTrue(getBeanFactory().isSingleton("&prototypeFactory"));
|
||||
assertFalse(getBeanFactory().isSingleton("prototypeFactory"));
|
||||
TestBean tb = (TestBean) getBeanFactory().getBean("prototypeFactory");
|
||||
assertTrue(!tb.getName().equals(DummyFactory.SINGLETON_NAME));
|
||||
TestBean tb2 = (TestBean) getBeanFactory().getBean("prototypeFactory");
|
||||
assertTrue("Prototype references !=", tb != tb2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that we can get the factory bean itself.
|
||||
* This is only possible if we're dealing with a factory
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testGetFactoryItself() throws Exception {
|
||||
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
|
||||
assertTrue(factory != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that afterPropertiesSet gets called on factory
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testFactoryIsInitialized() throws Exception {
|
||||
TestBean tb = (TestBean) getBeanFactory().getBean("singletonFactory");
|
||||
DummyFactory factory = (DummyFactory) getBeanFactory().getBean("&singletonFactory");
|
||||
assertTrue("Factory was initialized because it implemented InitializingBean", factory.wasInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* It should be illegal to dereference a normal bean
|
||||
* as a factory
|
||||
*/
|
||||
public void testRejectsFactoryGetOnNormalBean() {
|
||||
try {
|
||||
getBeanFactory().getBean("&rod");
|
||||
fail("Shouldn't permit factory get on normal bean");
|
||||
}
|
||||
catch (BeanIsNotAFactoryException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: refactor in AbstractBeanFactory (tests for AbstractBeanFactory)
|
||||
// and rename this class
|
||||
public void testAliasing() {
|
||||
BeanFactory bf = getBeanFactory();
|
||||
if (!(bf instanceof ConfigurableBeanFactory)) {
|
||||
return;
|
||||
}
|
||||
ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) bf;
|
||||
|
||||
String alias = "rods alias";
|
||||
try {
|
||||
cbf.getBean(alias);
|
||||
fail("Shouldn't permit factory get on normal bean");
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// Ok
|
||||
assertTrue(alias.equals(ex.getBeanName()));
|
||||
}
|
||||
|
||||
// Create alias
|
||||
cbf.registerAlias("rod", alias);
|
||||
Object rod = getBeanFactory().getBean("rod");
|
||||
Object aliasRod = getBeanFactory().getBean(alias);
|
||||
assertTrue(rod == aliasRod);
|
||||
}
|
||||
|
||||
|
||||
public static class TestBeanEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) {
|
||||
TestBean tb = new TestBean();
|
||||
StringTokenizer st = new StringTokenizer(text, "_");
|
||||
tb.setName(st.nextToken());
|
||||
tb.setAge(Integer.parseInt(st.nextToken()));
|
||||
setValue(tb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package org.springframework.web.context;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public abstract class AbstractListableBeanFactoryTests extends AbstractBeanFactoryTests {
|
||||
|
||||
/** Subclasses must initialize this */
|
||||
protected ListableBeanFactory getListableBeanFactory() {
|
||||
BeanFactory bf = getBeanFactory();
|
||||
if (!(bf instanceof ListableBeanFactory)) {
|
||||
throw new IllegalStateException("ListableBeanFactory required");
|
||||
}
|
||||
return (ListableBeanFactory) bf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this.
|
||||
*/
|
||||
public void testCount() {
|
||||
assertCount(13);
|
||||
}
|
||||
|
||||
protected final void assertCount(int count) {
|
||||
String[] defnames = getListableBeanFactory().getBeanDefinitionNames();
|
||||
assertTrue("We should have " + count + " beans, not " + defnames.length, defnames.length == count);
|
||||
}
|
||||
|
||||
public void assertTestBeanCount(int count) {
|
||||
String[] defNames = getListableBeanFactory().getBeanNamesForType(TestBean.class, true, false);
|
||||
assertTrue("We should have " + count + " beans for class org.springframework.beans.TestBean, not " +
|
||||
defNames.length, defNames.length == count);
|
||||
|
||||
int countIncludingFactoryBeans = count + 2;
|
||||
String[] names = getListableBeanFactory().getBeanNamesForType(TestBean.class, true, true);
|
||||
assertTrue("We should have " + countIncludingFactoryBeans +
|
||||
" beans for class org.springframework.beans.TestBean, not " + names.length,
|
||||
names.length == countIncludingFactoryBeans);
|
||||
}
|
||||
|
||||
public void testGetDefinitionsForNoSuchClass() {
|
||||
String[] defnames = getListableBeanFactory().getBeanNamesForType(String.class);
|
||||
assertTrue("No string definitions", defnames.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that count refers to factory class, not bean class. (We don't know
|
||||
* what type factories may return, and it may even change over time.)
|
||||
*/
|
||||
public void testGetCountForFactoryClass() {
|
||||
assertTrue("Should have 2 factories, not " +
|
||||
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length,
|
||||
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length == 2);
|
||||
|
||||
assertTrue("Should have 2 factories, not " +
|
||||
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length,
|
||||
getListableBeanFactory().getBeanNamesForType(FactoryBean.class).length == 2);
|
||||
}
|
||||
|
||||
public void testContainsBeanDefinition() {
|
||||
assertTrue(getListableBeanFactory().containsBeanDefinition("rod"));
|
||||
assertTrue(getListableBeanFactory().containsBeanDefinition("roderick"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,10 +36,10 @@ import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.LifecycleBean;
|
||||
import org.springframework.tests.sample.beans.LifecycleBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.context;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.context.support.AbstractMessageSource;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.ui.context.Theme;
|
||||
import org.springframework.ui.context.ThemeSource;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.context.support.XmlWebApplicationContext;
|
||||
import org.springframework.web.servlet.theme.AbstractThemeResolver;
|
||||
|
||||
/**
|
||||
* Creates a WebApplicationContext that points to a "web.xml" file that
|
||||
* contains the entry for what file to use for the applicationContext
|
||||
* (file "org/springframework/web/context/WEB-INF/applicationContext.xml").
|
||||
* That file then has an entry for a bean called "messageSource".
|
||||
* Whatever the basename property is set to for this bean is what the name of
|
||||
* a properties file in the classpath must be (in our case the name is
|
||||
* "messages" - note no package names).
|
||||
* Thus the catalog filename will be in the root of where the classes are compiled
|
||||
* to and will be called "messages_XX_YY.properties" where "XX" and "YY" are the
|
||||
* language and country codes known by the ResourceBundle class.
|
||||
*
|
||||
* <p>NOTE: The main method of this class is the "createWebApplicationContext(...)" method,
|
||||
* and it was copied from org.springframework.web.context.XmlWebApplicationContextTests.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Jean-Pierre Pawlak
|
||||
*/
|
||||
public class ResourceBundleMessageSourceTests extends AbstractApplicationContextTests {
|
||||
|
||||
/**
|
||||
* We use ticket WAR root for file structure.
|
||||
* We don't attempt to read web.xml.
|
||||
*/
|
||||
public static final String WAR_ROOT = "/org/springframework/web/context";
|
||||
|
||||
private ConfigurableWebApplicationContext root;
|
||||
|
||||
private MessageSource themeMsgSource;
|
||||
|
||||
@Override
|
||||
protected ConfigurableApplicationContext createContext() throws Exception {
|
||||
root = new XmlWebApplicationContext();
|
||||
MockServletContext sc = new MockServletContext();
|
||||
root.setServletContext(sc);
|
||||
root.setConfigLocations(new String[] {"/org/springframework/web/context/WEB-INF/applicationContext.xml"});
|
||||
root.refresh();
|
||||
|
||||
ConfigurableWebApplicationContext wac = new XmlWebApplicationContext();
|
||||
wac.setParent(root);
|
||||
wac.setServletContext(sc);
|
||||
wac.setNamespace("test-servlet");
|
||||
wac.setConfigLocations(new String[] {"/org/springframework/web/context/WEB-INF/test-servlet.xml"});
|
||||
wac.refresh();
|
||||
|
||||
Theme theme = ((ThemeSource) wac).getTheme(AbstractThemeResolver.ORIGINAL_DEFAULT_THEME_NAME);
|
||||
assertNotNull(theme);
|
||||
assertTrue("Theme name has to be the default theme name", AbstractThemeResolver.ORIGINAL_DEFAULT_THEME_NAME.equals(theme.getName()));
|
||||
themeMsgSource = theme.getMessageSource();
|
||||
assertNotNull(themeMsgSource);
|
||||
return wac;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testCount() {
|
||||
assertTrue("should have 14 beans, not " +
|
||||
this.applicationContext.getBeanDefinitionCount(),
|
||||
this.applicationContext.getBeanDefinitionCount() == 14);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden as we can't trust superclass method.
|
||||
* @see org.springframework.context.AbstractApplicationContextTests#testEvents()
|
||||
*/
|
||||
@Override
|
||||
public void testEvents() throws Exception {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public void testRootMessageSourceWithUseCodeAsDefaultMessage() throws NoSuchMessageException {
|
||||
AbstractMessageSource messageSource = (AbstractMessageSource) root.getBean("messageSource");
|
||||
messageSource.setUseCodeAsDefaultMessage(true);
|
||||
|
||||
assertEquals("message1", applicationContext.getMessage("code1", null, Locale.getDefault()));
|
||||
assertEquals("message2", applicationContext.getMessage("code2", null, Locale.getDefault()));
|
||||
|
||||
try {
|
||||
applicationContext.getMessage("code0", null, Locale.getDefault());
|
||||
fail("looking for code0 should throw a NoSuchMessageException");
|
||||
}
|
||||
catch (NoSuchMessageException ex) {
|
||||
// that's how it should be
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/messagesXXX.properties" files.
|
||||
*/
|
||||
public void testGetMessageWithDefaultPassedInAndFoundInMsgCatalog() {
|
||||
assertTrue("valid msg from resourcebundle with default msg passed in returned default msg. Expected msg from catalog.",
|
||||
getApplicationContext().getMessage("message.format.example2", null, "This is a default msg if not found in msg.cat.", Locale.US
|
||||
)
|
||||
.equals("This is a test message in the message catalog with no args."));
|
||||
// getApplicationContext().getTheme("theme").getMessageSource().getMessage()
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/messagesXXX.properties" files.
|
||||
*/
|
||||
public void testGetMessageWithDefaultPassedInAndNotFoundInMsgCatalog() {
|
||||
assertTrue("bogus msg from resourcebundle with default msg passed in returned default msg",
|
||||
getApplicationContext().getMessage("bogus.message", null, "This is a default msg if not found in msg.cat.", Locale.UK
|
||||
)
|
||||
.equals("This is a default msg if not found in msg.cat."));
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying implementation uses a hashMap to cache messageFormats
|
||||
* once a message has been asked for. This test is an attempt to
|
||||
* make sure the cache is being used properly.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/messagesXXX.properties" files.
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
*/
|
||||
public void testGetMessageWithMessageAlreadyLookedFor() throws Exception {
|
||||
Object[] arguments = {
|
||||
new Integer(7), new Date(System.currentTimeMillis()),
|
||||
"a disturbance in the Force"
|
||||
};
|
||||
|
||||
// The first time searching, we don't care about for this test
|
||||
getApplicationContext().getMessage("message.format.example1", arguments, Locale.US);
|
||||
|
||||
// Now msg better be as expected
|
||||
assertTrue("2nd search within MsgFormat cache returned expected message for Locale.US",
|
||||
getApplicationContext().getMessage("message.format.example1", arguments, Locale.US
|
||||
)
|
||||
.indexOf("there was \"a disturbance in the Force\" on planet 7.") != -1);
|
||||
|
||||
Object[] newArguments = {
|
||||
new Integer(8), new Date(System.currentTimeMillis()),
|
||||
"a disturbance in the Force"
|
||||
};
|
||||
|
||||
// Now msg better be as expected even with different args
|
||||
assertTrue("2nd search within MsgFormat cache with different args returned expected message for Locale.US",
|
||||
getApplicationContext().getMessage("message.format.example1", newArguments, Locale.US
|
||||
)
|
||||
.indexOf("there was \"a disturbance in the Force\" on planet 8.") != -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/messagesXXX.properties" files.
|
||||
* Example taken from the javadocs for the java.text.MessageFormat class
|
||||
*/
|
||||
public void testGetMessageWithNoDefaultPassedInAndFoundInMsgCatalog() throws Exception {
|
||||
Object[] arguments = {
|
||||
new Integer(7), new Date(System.currentTimeMillis()),
|
||||
"a disturbance in the Force"
|
||||
};
|
||||
|
||||
/*
|
||||
Try with Locale.US
|
||||
Since the msg has a time value in it, we will use String.indexOf(...)
|
||||
to just look for a substring without the time. This is because it is
|
||||
possible that by the time we store a time variable in this method
|
||||
and the time the ResourceBundleMessageSource resolves the msg the
|
||||
minutes of the time might not be the same.
|
||||
*/
|
||||
assertTrue("msg from resourcebundle for Locale.US substituting args for placeholders is as expected",
|
||||
getApplicationContext().getMessage("message.format.example1", arguments, Locale.US
|
||||
)
|
||||
.indexOf("there was \"a disturbance in the Force\" on planet 7.") != -1);
|
||||
|
||||
// Try with Locale.UK
|
||||
assertTrue("msg from resourcebundle for Locale.UK substituting args for placeholders is as expected",
|
||||
getApplicationContext().getMessage("message.format.example1", arguments, Locale.UK
|
||||
)
|
||||
.indexOf("there was \"a disturbance in the Force\" on station number 7.") != -1);
|
||||
|
||||
// Try with Locale.US - different test msg that requires no args
|
||||
assertTrue("msg from resourcebundle that requires no args for Locale.US is as expected",
|
||||
getApplicationContext().getMessage("message.format.example2", null, Locale.US)
|
||||
.equals("This is a test message in the message catalog with no args."));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/messagesXXX.properties" files.
|
||||
*/
|
||||
public void testGetMessageWithNoDefaultPassedInAndNotFoundInMsgCatalog() {
|
||||
// Expecting an exception
|
||||
try {
|
||||
getApplicationContext().getMessage("bogus.message", null, Locale.UK);
|
||||
fail("bogus msg from resourcebundle without default msg should have thrown exception");
|
||||
}
|
||||
catch (NoSuchMessageException tExcept) {
|
||||
assertTrue("bogus msg from resourcebundle without default msg threw expected exception",
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetMultipleBasenamesForMessageSource() throws NoSuchMessageException {
|
||||
assertEquals("message1", getApplicationContext().getMessage("code1", null, Locale.UK));
|
||||
assertEquals("message2", getApplicationContext().getMessage("code2", null, Locale.UK));
|
||||
assertEquals("message3", getApplicationContext().getMessage("code3", null, Locale.UK));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/themeXXX.properties" files.
|
||||
*/
|
||||
public void testGetMessageWithDefaultPassedInAndFoundInThemeCatalog() {
|
||||
// Try with Locale.US
|
||||
String msg = getThemeMessage("theme.example1", null, "This is a default theme msg if not found in theme cat.", Locale.US);
|
||||
assertTrue("valid msg from theme resourcebundle with default msg passed in returned default msg. Expected msg from catalog. Received: " + msg,
|
||||
msg.equals("This is a test message in the theme message catalog."));
|
||||
// Try with Locale.UK
|
||||
msg = getThemeMessage("theme.example1", null, "This is a default theme msg if not found in theme cat.", Locale.UK);
|
||||
assertTrue("valid msg from theme resourcebundle with default msg passed in returned default msg. Expected msg from catalog.",
|
||||
msg.equals("This is a test message in the theme message catalog with no args."));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.context.support.AbstractMessageSource for more details.
|
||||
* NOTE: Messages are contained within the "test/org/springframework/web/context/WEB-INF/themeXXX.properties" files.
|
||||
*/
|
||||
public void testGetMessageWithDefaultPassedInAndNotFoundInThemeCatalog() {
|
||||
assertTrue("bogus msg from theme resourcebundle with default msg passed in returned default msg",
|
||||
getThemeMessage("bogus.message", null, "This is a default msg if not found in theme cat.", Locale.UK
|
||||
)
|
||||
.equals("This is a default msg if not found in theme cat."));
|
||||
}
|
||||
|
||||
public void testThemeSourceNesting() throws NoSuchMessageException {
|
||||
String overriddenMsg = getThemeMessage("theme.example2", null, null, Locale.UK);
|
||||
MessageSource ms = ((ThemeSource) root).getTheme(AbstractThemeResolver.ORIGINAL_DEFAULT_THEME_NAME).getMessageSource();
|
||||
String originalMsg = ms.getMessage("theme.example2", null, Locale.UK);
|
||||
assertTrue("correct overridden msg", "test-message2".equals(overriddenMsg));
|
||||
assertTrue("correct original msg", "message2".equals(originalMsg));
|
||||
}
|
||||
|
||||
public void testThemeSourceNestingWithParentDefault() throws NoSuchMessageException {
|
||||
StaticWebApplicationContext leaf = new StaticWebApplicationContext();
|
||||
leaf.setParent(getApplicationContext());
|
||||
leaf.refresh();
|
||||
assertNotNull("theme still found", leaf.getTheme("theme"));
|
||||
MessageSource ms = leaf.getTheme("theme").getMessageSource();
|
||||
String msg = ms.getMessage("theme.example2", null, null, Locale.UK);
|
||||
assertEquals("correct overridden msg", "test-message2", msg);
|
||||
}
|
||||
|
||||
private String getThemeMessage(String code, Object args[], String defaultMessage, Locale locale) {
|
||||
return themeMsgSource.getMessage(code, args, defaultMessage, locale);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean class="org.springframework.beans.TestBean">
|
||||
<bean class="org.springframework.tests.sample.beans.TestBean">
|
||||
<constructor-arg value="${name}"/>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<import resource="/resources/../resources/themeSource.xml"/>
|
||||
|
||||
<bean id="lifecyclePostProcessor" class="org.springframework.beans.factory.LifecycleBean$PostProcessor"/>
|
||||
<bean id="lifecyclePostProcessor" class="org.springframework.tests.sample.beans.LifecycleBean$PostProcessor"/>
|
||||
|
||||
<!--
|
||||
<bean
|
||||
@@ -32,7 +32,7 @@
|
||||
<!-- Inherited tests -->
|
||||
|
||||
<!-- name and age values will be overridden by myinit.properties" -->
|
||||
<bean id="rod" class="org.springframework.beans.TestBean">
|
||||
<bean id="rod" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name">
|
||||
<value>dummy</value>
|
||||
</property>
|
||||
@@ -45,7 +45,7 @@
|
||||
Tests of lifecycle callbacks
|
||||
-->
|
||||
<bean id="mustBeInitialized"
|
||||
class="org.springframework.beans.factory.MustBeInitialized">
|
||||
class="org.springframework.tests.sample.beans.MustBeInitialized">
|
||||
</bean>
|
||||
|
||||
<bean id="lifecycle"
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
<property name="age"><value>31</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="kathy" class="org.springframework.beans.TestBean" scope="prototype"/>
|
||||
<bean id="kathy" class="org.springframework.tests.sample.beans.TestBean" scope="prototype"/>
|
||||
|
||||
<bean id="kerry" class="org.springframework.beans.TestBean">
|
||||
<bean id="kerry" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>Kerry</value></property>
|
||||
<property name="age"><value>34</value></property>
|
||||
<property name="spouse"><ref bean="rod"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="typeMismatch" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<bean id="typeMismatch" class="org.springframework.tests.sample.beans.TestBean" scope="prototype">
|
||||
<property name="name"><value>typeMismatch</value></property>
|
||||
<property name="age"><value>34x</value></property>
|
||||
<property name="spouse"><ref bean="rod"/></property>
|
||||
@@ -31,20 +31,20 @@
|
||||
<!-- Factory beans are automatically treated
|
||||
differently -->
|
||||
<bean id="singletonFactory"
|
||||
class="org.springframework.beans.factory.DummyFactory">
|
||||
class="org.springframework.tests.sample.beans.factory.DummyFactory">
|
||||
</bean>
|
||||
|
||||
<bean id="prototypeFactory"
|
||||
class="org.springframework.beans.factory.DummyFactory">
|
||||
class="org.springframework.tests.sample.beans.factory.DummyFactory">
|
||||
<property name="singleton"><value>false</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="listenerVeto" class="org.springframework.beans.TestBean">
|
||||
<bean id="listenerVeto" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<!-- <listener property="age" beanRef="agistListener" /> -->
|
||||
<property name="name"><value>listenerVeto</value></property>
|
||||
<property name="age"><value>66</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="validEmpty" class="org.springframework.beans.TestBean"/>
|
||||
<bean id="validEmpty" class="org.springframework.tests.sample.beans.TestBean"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- Include snippet to be loaded via entity reference in applicationContext.xml -->
|
||||
|
||||
<bean id="father" class="org.springframework.beans.TestBean">
|
||||
<bean id="father" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>yetanotherdummy</value></property>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
|
||||
|
||||
<bean id="servletContextAwareBean" class="org.springframework.web.context.ServletContextAwareBean"/>
|
||||
|
||||
<bean id="servletConfigAwareBean" class="org.springframework.web.context.ServletConfigAwareBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="rob" class="org.springframework.beans.TestBean">
|
||||
<property name="name" value="dummy"/>
|
||||
<property name="age" value="-1"/>
|
||||
</bean>
|
||||
|
||||
<bean id="rodProto" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<property name="name" value="dummy"/>
|
||||
<property name="age" value="-1"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<bean id="aca-prototype" class="org.springframework.context.ACATester" scope="prototype"/>
|
||||
|
||||
<bean id="rod" class="org.springframework.beans.TestBean">
|
||||
<bean id="rod" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>Rod</value></property>
|
||||
<property name="age"><value>31</value></property>
|
||||
<property name="spouse"><ref bean="father"/></property>
|
||||
@@ -28,32 +28,32 @@
|
||||
<property name="age"><value>31</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="kathy" class="org.springframework.beans.TestBean" scope="prototype"/>
|
||||
<bean id="kathy" class="org.springframework.tests.sample.beans.TestBean" scope="prototype"/>
|
||||
|
||||
<bean id="kerry" class="org.springframework.beans.TestBean">
|
||||
<bean id="kerry" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>Kerry</value></property>
|
||||
<property name="age"><value>34</value></property>
|
||||
<property name="spouse"><ref local="rod"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="typeMismatch" class="org.springframework.beans.TestBean" scope="prototype">
|
||||
<bean id="typeMismatch" class="org.springframework.tests.sample.beans.TestBean" scope="prototype">
|
||||
<property name="name"><value>typeMismatch</value></property>
|
||||
<property name="age"><value>34x</value></property>
|
||||
<property name="spouse"><ref local="rod"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="singletonFactory" class="org.springframework.beans.factory.DummyFactory">
|
||||
<bean id="singletonFactory" class="org.springframework.tests.sample.beans.factory.DummyFactory">
|
||||
</bean>
|
||||
|
||||
<bean id="prototypeFactory" class="org.springframework.beans.factory.DummyFactory">
|
||||
<bean id="prototypeFactory" class="org.springframework.tests.sample.beans.factory.DummyFactory">
|
||||
<property name="singleton"><value>false</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="listenerVeto" class="org.springframework.beans.TestBean">
|
||||
<bean id="listenerVeto" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>listenerVeto</value></property>
|
||||
<property name="age"><value>66</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="validEmpty" class="org.springframework.beans.TestBean"/>
|
||||
<bean id="validEmpty" class="org.springframework.tests.sample.beans.TestBean"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="rod" class="org.springframework.beans.TestBean">
|
||||
<bean id="rod" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>Rod</value></property>
|
||||
<property name="age"><value>31</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="kerryX" class="org.springframework.beans.TestBean">
|
||||
<bean id="kerryX" class="org.springframework.tests.sample.beans.TestBean">
|
||||
<property name="name"><value>Kerry</value></property>
|
||||
<property name="age"><value>34</value></property>
|
||||
<property name="spouse"><ref local="rod"/></property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,12 +21,13 @@ import java.util.Locale;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.AbstractApplicationContextTests;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.context.TestListener;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,7 @@ import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
@@ -41,7 +41,6 @@ import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.support.ManagedSet;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -131,7 +131,7 @@ public class ComplexWebApplicationContext extends StaticWebApplicationContext {
|
||||
registerSingleton("viewResolver2", InternalResourceViewResolver.class, pvs);
|
||||
|
||||
pvs = new MutablePropertyValues();
|
||||
pvs.add("commandClass", "org.springframework.beans.TestBean");
|
||||
pvs.add("commandClass", "org.springframework.tests.sample.beans.TestBean");
|
||||
pvs.add("formView", "form");
|
||||
registerSingleton("formHandler", SimpleFormController.class, pvs);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,12 +16,6 @@
|
||||
|
||||
package org.springframework.web.servlet;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -36,15 +30,15 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.env.DummyEnvironment;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.test.MockServletConfig;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.web.bind.EscapedErrors;
|
||||
import org.springframework.web.context.ConfigurableWebEnvironment;
|
||||
import org.springframework.web.context.ServletConfigAwareBean;
|
||||
@@ -65,6 +59,11 @@ import org.springframework.web.servlet.theme.AbstractThemeResolver;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
@@ -836,14 +835,14 @@ public class DispatcherServletTests extends TestCase {
|
||||
|
||||
public void testEnvironmentOperations() {
|
||||
DispatcherServlet servlet = new DispatcherServlet();
|
||||
ConfigurableWebEnvironment defaultEnv = servlet.getEnvironment();
|
||||
ConfigurableEnvironment defaultEnv = servlet.getEnvironment();
|
||||
assertThat(defaultEnv, notNullValue());
|
||||
ConfigurableEnvironment env1 = new StandardServletEnvironment();
|
||||
servlet.setEnvironment(env1); // should succeed
|
||||
assertThat(servlet.getEnvironment(), sameInstance(env1));
|
||||
try {
|
||||
servlet.setEnvironment(new StandardEnvironment());
|
||||
fail("expected exception");
|
||||
servlet.setEnvironment(new DummyEnvironment());
|
||||
fail("expected IllegalArgumentException for non-configurable Environment");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
}
|
||||
@@ -860,9 +859,10 @@ public class DispatcherServletTests extends TestCase {
|
||||
|
||||
public void testAllowedOptionsIncludesPatchMethod() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(getServletContext(), "OPTIONS", "/foo");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockHttpServletResponse response = spy(new MockHttpServletResponse());
|
||||
DispatcherServlet servlet = new DispatcherServlet();
|
||||
servlet.service(request, response);
|
||||
verify(response, never()).getHeader(anyString()); // SPR-10341
|
||||
assertThat(response.getHeader("Allow"), equalTo("GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH"));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,7 +50,7 @@ public class SimpleWebApplicationContext extends StaticWebApplicationContext {
|
||||
@Override
|
||||
public void refresh() throws BeansException {
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.add("commandClass", "org.springframework.beans.TestBean");
|
||||
pvs.add("commandClass", "org.springframework.tests.sample.beans.TestBean");
|
||||
pvs.add("formView", "form");
|
||||
registerSingleton("/form.do", SimpleFormController.class, pvs);
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
form.(class)=org.springframework.web.servlet.view.InternalResourceView
|
||||
form.requestContextAttribute=rc
|
||||
form.url=myform.jsp
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.io.FileSystemResourceLoader;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.validation.BindException;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,8 +28,8 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.IndexedTestBean;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.IndexedTestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import javax.servlet.http.HttpSession;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
package org.springframework.web.servlet.mvc.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.context.support.StaticMessageSource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
@@ -46,6 +53,24 @@ public class ResponseStatusExceptionResolverTests {
|
||||
assertEquals("Invalid status reason", "You suck!", response.getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void statusCodeAndReasonMessage() {
|
||||
Locale locale = Locale.CHINESE;
|
||||
LocaleContextHolder.setLocale(locale);
|
||||
try {
|
||||
StaticMessageSource messageSource = new StaticMessageSource();
|
||||
messageSource.addMessage("gone.reason", locale, "Gone reason message");
|
||||
exceptionResolver.setMessageSource(messageSource);
|
||||
|
||||
StatusCodeAndReasonMessageException ex = new StatusCodeAndReasonMessageException();
|
||||
exceptionResolver.resolveException(request, response, null, ex);
|
||||
assertEquals("Invalid status reason", "Gone reason message", response.getErrorMessage());
|
||||
}
|
||||
finally {
|
||||
LocaleContextHolder.resetLocaleContext();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notAnnotated() {
|
||||
Exception ex = new Exception();
|
||||
@@ -65,4 +90,11 @@ public class ResponseStatusExceptionResolverTests {
|
||||
private static class StatusCodeAndReasonException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
@ResponseStatus(value = HttpStatus.GONE, reason = "gone.reason")
|
||||
@SuppressWarnings("serial")
|
||||
private static class StatusCodeAndReasonMessageException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,16 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.annotation;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
@@ -43,6 +53,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
@@ -54,17 +65,12 @@ import javax.validation.constraints.NotNull;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.DerivedTestBean;
|
||||
import org.springframework.beans.GenericBean;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.beans.PropertyEditorRegistrar;
|
||||
import org.springframework.beans.PropertyEditorRegistry;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -96,6 +102,10 @@ import org.springframework.mock.web.test.MockServletConfig;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.tests.sample.beans.DerivedTestBean;
|
||||
import org.springframework.tests.sample.beans.GenericBean;
|
||||
import org.springframework.tests.sample.beans.ITestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
@@ -140,8 +150,6 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.util.NestedServletException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
@@ -329,7 +337,7 @@ public class ServletAnnotationControllerTests {
|
||||
request.addParameter("testBeanSet", new String[] {"1", "2"});
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
servlet.service(request, response);
|
||||
assertEquals("[1, 2]-org.springframework.beans.TestBean", response.getContentAsString());
|
||||
assertEquals("[1, 2]-org.springframework.tests.sample.beans.TestBean", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3291,7 +3299,7 @@ public class ServletAnnotationControllerTests {
|
||||
|
||||
@RequestMapping("/integerSet")
|
||||
public void processCsv(@RequestParam("content") Set<Integer> content, HttpServletResponse response) throws IOException {
|
||||
assertTrue(content.iterator().next() instanceof Integer);
|
||||
assertThat(content.iterator().next(), instanceOf(Integer.class));
|
||||
response.getWriter().write(StringUtils.collectionToDelimitedString(content, "-"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -185,6 +186,16 @@ public class PatternsRequestConditionTests {
|
||||
assertNull(match);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchIgnorePathParams() {
|
||||
UrlPathHelper pathHelper = new UrlPathHelper();
|
||||
pathHelper.setRemoveSemicolonContent(false);
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition(new String[] {"/foo/bar"}, pathHelper, null, true, true);
|
||||
PatternsRequestCondition match = condition.getMatchingCondition(new MockHttpServletRequest("GET", "/foo;q=1/bar;s=1"));
|
||||
|
||||
assertNotNull(match);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareEqualPatterns() {
|
||||
PatternsRequestCondition c1 = new PatternsRequestCondition("/foo*");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,6 +42,7 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@@ -89,7 +90,6 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
|
||||
this.handlerMapping = new TestRequestMappingInfoHandlerMapping();
|
||||
this.handlerMapping.registerHandler(testController);
|
||||
this.handlerMapping.setRemoveSemicolonContent(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -180,6 +180,19 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMediaTypeNotValue() throws Exception {
|
||||
try {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/person/1");
|
||||
request.setContentType("bogus");
|
||||
this.handlerMapping.getHandler(request);
|
||||
fail("HttpMediaTypeNotSupportedException expected");
|
||||
}
|
||||
catch (HttpMediaTypeNotSupportedException ex) {
|
||||
assertEquals("Invalid media type \"bogus\": does not contain '/'", ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mediaTypeNotAccepted() throws Exception {
|
||||
testMediaTypeNotAccepted("/persons");
|
||||
@@ -202,6 +215,19 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsatisfiedServletRequestParameterException() throws Exception {
|
||||
try {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/params");
|
||||
this.handlerMapping.getHandler(request);
|
||||
fail("UnsatisfiedServletRequestParameterException expected");
|
||||
}
|
||||
catch (UnsatisfiedServletRequestParameterException ex) {
|
||||
assertArrayEquals("Invalid request parameter conditions",
|
||||
new String[] { "foo=bar" }, ex.getParamConditions());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriTemplateVariables() {
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition("/{path1}/{path2}");
|
||||
@@ -310,48 +336,63 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
MultiValueMap<String, String> matrixVariables;
|
||||
Map<String, String> uriVariables;
|
||||
|
||||
String lookupPath = "/cars;colors=red,blue,green;year=2012";
|
||||
|
||||
// Pattern "/{cars}" : matrix variables stripped from "cars" variable
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/{cars}", lookupPath);
|
||||
testHandleMatch(request, "/{cars}", "/cars;colors=red,blue,green;year=2012");
|
||||
|
||||
matrixVariables = getMatrixVariables(request, "cars");
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
|
||||
assertNotNull(matrixVariables);
|
||||
assertEquals(Arrays.asList("red", "blue", "green"), matrixVariables.get("colors"));
|
||||
assertEquals("2012", matrixVariables.getFirst("year"));
|
||||
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
assertEquals("cars", uriVariables.get("cars"));
|
||||
|
||||
// Pattern "/{cars:[^;]+}{params}" : "cars" and "params" variables unchanged
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/{cars:[^;]+}{params}", lookupPath);
|
||||
testHandleMatch(request, "/{cars:[^;]+}{params}", "/cars;colors=red,blue,green;year=2012");
|
||||
|
||||
matrixVariables = getMatrixVariables(request, "params");
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
|
||||
assertNotNull(matrixVariables);
|
||||
assertEquals(Arrays.asList("red", "blue", "green"), matrixVariables.get("colors"));
|
||||
assertEquals("2012", matrixVariables.getFirst("year"));
|
||||
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
assertEquals("cars", uriVariables.get("cars"));
|
||||
assertEquals(";colors=red,blue,green;year=2012", uriVariables.get("params"));
|
||||
|
||||
// matrix variables not present : "params" variable is empty
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/{cars:[^;]+}{params}", "/cars");
|
||||
|
||||
matrixVariables = getMatrixVariables(request, "params");
|
||||
assertNull(matrixVariables);
|
||||
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
|
||||
assertNull(matrixVariables);
|
||||
assertEquals("cars", uriVariables.get("cars"));
|
||||
assertEquals("", uriVariables.get("params"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matrixVariablesDecoding() {
|
||||
|
||||
MockHttpServletRequest request;
|
||||
|
||||
UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
urlPathHelper.setUrlDecode(false);
|
||||
urlPathHelper.setRemoveSemicolonContent(false);
|
||||
|
||||
this.handlerMapping.setUrlPathHelper(urlPathHelper );
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/path{filter}", "/path;mvar=a%2fb");
|
||||
|
||||
MultiValueMap<String, String> matrixVariables = getMatrixVariables(request, "filter");
|
||||
Map<String, String> uriVariables = getUriTemplateVariables(request);
|
||||
|
||||
assertNotNull(matrixVariables);
|
||||
assertEquals(Arrays.asList("a/b"), matrixVariables.get("mvar"));
|
||||
assertEquals(";mvar=a/b", uriVariables.get("filter"));
|
||||
}
|
||||
|
||||
|
||||
private void testHandleMatch(MockHttpServletRequest request, String pattern, String lookupPath) {
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition(pattern);
|
||||
RequestMappingInfo info = new RequestMappingInfo(patterns, null, null, null, null, null, null);
|
||||
@@ -399,6 +440,11 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
return "";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/params", params="foo=bar")
|
||||
public String param() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/content", produces="application/xml")
|
||||
public String xmlContent() {
|
||||
return "";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,7 @@ import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.web.bind.ServletRequestDataBinder;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ import javax.validation.Valid;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
import org.springframework.core.MethodParameter;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,19 +15,28 @@
|
||||
*/
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.accept.PathExtensionContentNegotiationStrategy;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
|
||||
/**
|
||||
* Tests for {@link RequestMappingHandlerMapping}.
|
||||
@@ -62,6 +71,35 @@ public class RequestMappingHandlerMappingTests {
|
||||
assertEquals(Arrays.asList("json"), this.handlerMapping.getFileExtensions());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useRegsiteredSuffixPatternMatchInitialization() {
|
||||
|
||||
Map<String, MediaType> fileExtensions = Collections.singletonMap("json", MediaType.APPLICATION_JSON);
|
||||
PathExtensionContentNegotiationStrategy strategy = new PathExtensionContentNegotiationStrategy(fileExtensions);
|
||||
ContentNegotiationManager manager = new ContentNegotiationManager(strategy);
|
||||
|
||||
final Set<String> extensions = new HashSet<String>();
|
||||
|
||||
RequestMappingHandlerMapping hm = new RequestMappingHandlerMapping() {
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
extensions.addAll(getFileExtensions());
|
||||
return super.getMappingForMethod(method, handlerType);
|
||||
}
|
||||
};
|
||||
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.registerSingleton("testController", TestController.class);
|
||||
wac.refresh();
|
||||
|
||||
hm.setContentNegotiationManager(manager);
|
||||
hm.setUseRegisteredSuffixPatternMatch(true);
|
||||
hm.setApplicationContext(wac);
|
||||
hm.afterPropertiesSet();
|
||||
|
||||
assertEquals(Collections.singleton("json"), extensions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useSuffixPatternMatch() {
|
||||
assertTrue(this.handlerMapping.useSuffixPatternMatch());
|
||||
@@ -78,4 +116,27 @@ public class RequestMappingHandlerMappingTests {
|
||||
this.handlerMapping.useSuffixPatternMatch());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveEmbeddedValuesInPatterns() {
|
||||
this.handlerMapping.setEmbeddedValueResolver(new StringValueResolver() {
|
||||
public String resolveStringValue(String value) {
|
||||
return "/${pattern}/bar".equals(value) ? "/foo/bar" : value;
|
||||
}
|
||||
});
|
||||
|
||||
String[] patterns = new String[] { "/foo", "/${pattern}/bar" };
|
||||
String[] result = this.handlerMapping.resolveEmbeddedValuesInPatterns(patterns);
|
||||
|
||||
assertArrayEquals(new String[] { "/foo", "/foo/bar" }, result);
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
static class TestController {
|
||||
|
||||
@RequestMapping
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,13 +36,13 @@ import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.FreePortScanner;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.tests.web.FreePortScanner;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -64,10 +64,10 @@ import org.junit.Test;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.beans.DerivedTestBean;
|
||||
import org.springframework.beans.GenericBean;
|
||||
import org.springframework.beans.ITestBean;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.DerivedTestBean;
|
||||
import org.springframework.tests.sample.beans.GenericBean;
|
||||
import org.springframework.tests.sample.beans.ITestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -283,7 +283,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
|
||||
request.addParameter("testBeanSet", new String[] {"1", "2"});
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
assertEquals("[1, 2]-org.springframework.beans.TestBean", response.getContentAsString());
|
||||
assertEquals("[1, 2]-org.springframework.tests.sample.beans.TestBean", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import javax.servlet.http.HttpSession;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
@@ -453,7 +453,7 @@ public class MultiActionControllerTests extends TestCase {
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/handleIllegalStateException.html");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
ModelAndView mav = mac.handleRequest(request, response);
|
||||
mac.handleRequest(request, response);
|
||||
assertEquals(HttpServletResponse.SC_NOT_FOUND, response.getStatus());
|
||||
}
|
||||
|
||||
@@ -524,7 +524,6 @@ public class MultiActionControllerTests extends TestCase {
|
||||
this.invoked.put("commandNoSession", Boolean.TRUE);
|
||||
|
||||
String pname = request.getParameter("name");
|
||||
String page = request.getParameter("age");
|
||||
// ALLOW FOR NULL
|
||||
if (pname == null) {
|
||||
assertTrue("name null", command.getName() == null);
|
||||
@@ -532,6 +531,8 @@ public class MultiActionControllerTests extends TestCase {
|
||||
else {
|
||||
assertTrue("name param set", pname.equals(command.getName()));
|
||||
}
|
||||
|
||||
//String page = request.getParameter("age");
|
||||
// if (page == null)
|
||||
// assertTrue("age default", command.getAge() == 0);
|
||||
// else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,7 @@ import java.util.Collections;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.ConversionNotSupportedException;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user