Polishing
This commit is contained in:
parent
9243a14794
commit
f84907a1fc
|
@ -45,6 +45,7 @@ public interface MultiValueMap<K, V> extends Map<K, List<V>> {
|
|||
* Add all the values of the given list to the current list of values for the given key.
|
||||
* @param key they key
|
||||
* @param values the values to be added
|
||||
* @since 5.0
|
||||
*/
|
||||
void addAll(K key, List<V> values);
|
||||
|
||||
|
|
|
@ -23,23 +23,17 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class LinkedMultiValueMapTests {
|
||||
|
||||
private LinkedMultiValueMap<String, String> map;
|
||||
private final LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
map = new LinkedMultiValueMap<>();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void add() {
|
||||
|
|
|
@ -76,7 +76,7 @@ import org.springframework.util.Assert;
|
|||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Hand written SpEL parser. Instances are reusable but are not thread-safe.
|
||||
* Hand-written SpEL parser. Instances are reusable but are not thread-safe.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
|
@ -394,10 +394,9 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
// ;
|
||||
private SpelNodeImpl eatDottedNode() {
|
||||
Token t = nextToken(); // it was a '.' or a '?.'
|
||||
boolean nullSafeNavigation = t.kind == TokenKind.SAFE_NAVI;
|
||||
if (maybeEatMethodOrProperty(nullSafeNavigation) || maybeEatFunctionOrVar()
|
||||
|| maybeEatProjection(nullSafeNavigation)
|
||||
|| maybeEatSelection(nullSafeNavigation)) {
|
||||
boolean nullSafeNavigation = (t.kind == TokenKind.SAFE_NAVI);
|
||||
if (maybeEatMethodOrProperty(nullSafeNavigation) || maybeEatFunctionOrVar() ||
|
||||
maybeEatProjection(nullSafeNavigation) || maybeEatSelection(nullSafeNavigation)) {
|
||||
return pop();
|
||||
}
|
||||
if (peekToken() == null) {
|
||||
|
@ -405,8 +404,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
raiseInternalException(t.startPos, SpelMessage.OOD);
|
||||
}
|
||||
else {
|
||||
raiseInternalException(t.startPos, SpelMessage.UNEXPECTED_DATA_AFTER_DOT,
|
||||
toString(peekToken()));
|
||||
raiseInternalException(t.startPos, SpelMessage.UNEXPECTED_DATA_AFTER_DOT, toString(peekToken()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -425,13 +423,13 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
Token functionOrVariableName = eatToken(TokenKind.IDENTIFIER);
|
||||
SpelNodeImpl[] args = maybeEatMethodArgs();
|
||||
if (args == null) {
|
||||
push(new VariableReference(functionOrVariableName.data, toPos(t.startPos,
|
||||
functionOrVariableName.endPos)));
|
||||
push(new VariableReference(functionOrVariableName.data,
|
||||
toPos(t.startPos, functionOrVariableName.endPos)));
|
||||
return true;
|
||||
}
|
||||
|
||||
push(new FunctionReference(functionOrVariableName.data, toPos(t.startPos,
|
||||
functionOrVariableName.endPos), args));
|
||||
push(new FunctionReference(functionOrVariableName.data,
|
||||
toPos(t.startPos, functionOrVariableName.endPos), args));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -448,7 +446,8 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
|
||||
private void eatConstructorArgs(List<SpelNodeImpl> accumulatedArguments) {
|
||||
if (!peekToken(TokenKind.LPAREN)) {
|
||||
throw new InternalParseException(new SpelParseException(this.expressionString,positionOf(peekToken()),SpelMessage.MISSING_CONSTRUCTOR_ARGS));
|
||||
throw new InternalParseException(new SpelParseException(this.expressionString,
|
||||
positionOf(peekToken()), SpelMessage.MISSING_CONSTRUCTOR_ARGS));
|
||||
}
|
||||
consumeArguments(accumulatedArguments);
|
||||
eatToken(TokenKind.RPAREN);
|
||||
|
@ -461,7 +460,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
int pos = peekToken().startPos;
|
||||
Token next;
|
||||
do {
|
||||
nextToken(); // consume ( (first time through) or comma (subsequent times)
|
||||
nextToken(); // consume (first time through) or comma (subsequent times)
|
||||
Token t = peekToken();
|
||||
if (t == null) {
|
||||
raiseInternalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS);
|
||||
|
@ -544,10 +543,12 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
SpelMessage.INVALID_BEAN_REFERENCE);
|
||||
}
|
||||
|
||||
BeanReference beanReference = null;
|
||||
BeanReference beanReference;
|
||||
if (beanRefToken.getKind() == TokenKind.FACTORY_BEAN_REF) {
|
||||
String beanNameString = new StringBuilder().append(TokenKind.FACTORY_BEAN_REF.tokenChars).append(beanName).toString();
|
||||
beanReference = new BeanReference(toPos(beanRefToken.startPos,beanNameToken.endPos),beanNameString);
|
||||
String beanNameString = new StringBuilder().
|
||||
append(TokenKind.FACTORY_BEAN_REF.tokenChars).append(beanName).toString();
|
||||
beanReference = new BeanReference(
|
||||
toPos(beanRefToken.startPos, beanNameToken.endPos), beanNameString);
|
||||
}
|
||||
else {
|
||||
beanReference = new BeanReference(toPos(beanNameToken), beanName);
|
||||
|
@ -561,7 +562,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
private boolean maybeEatTypeReference() {
|
||||
if (peekToken(TokenKind.IDENTIFIER)) {
|
||||
Token typeName = peekToken();
|
||||
if (!typeName.stringValue().equals("T")) {
|
||||
if (!"T".equals(typeName.stringValue())) {
|
||||
return false;
|
||||
}
|
||||
// It looks like a type reference but is T being used as a map key?
|
||||
|
@ -590,7 +591,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
private boolean maybeEatNullReference() {
|
||||
if (peekToken(TokenKind.IDENTIFIER)) {
|
||||
Token nullToken = peekToken();
|
||||
if (!nullToken.stringValue().equalsIgnoreCase("null")) {
|
||||
if (!"null".equalsIgnoreCase(nullToken.stringValue())) {
|
||||
return false;
|
||||
}
|
||||
nextToken();
|
||||
|
@ -636,14 +637,14 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
// '}' - end of list
|
||||
// ',' - more expressions in this list
|
||||
// ':' - this is a map!
|
||||
|
||||
if (peekToken(TokenKind.RCURLY)) { // list with one item in it
|
||||
List<SpelNodeImpl> listElements = new ArrayList<>();
|
||||
listElements.add(firstExpression);
|
||||
closingCurly = eatToken(TokenKind.RCURLY);
|
||||
expr = new InlineList(toPos(t.startPos,closingCurly.endPos),listElements.toArray(new SpelNodeImpl[listElements.size()]));
|
||||
expr = new InlineList(toPos(t.startPos, closingCurly.endPos),
|
||||
listElements.toArray(new SpelNodeImpl[listElements.size()]));
|
||||
}
|
||||
else if (peekToken(TokenKind.COMMA, true)) { // multi item list
|
||||
else if (peekToken(TokenKind.COMMA, true)) { // multi-item list
|
||||
List<SpelNodeImpl> listElements = new ArrayList<>();
|
||||
listElements.add(firstExpression);
|
||||
do {
|
||||
|
@ -651,7 +652,8 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
}
|
||||
while (peekToken(TokenKind.COMMA, true));
|
||||
closingCurly = eatToken(TokenKind.RCURLY);
|
||||
expr = new InlineList(toPos(t.startPos,closingCurly.endPos),listElements.toArray(new SpelNodeImpl[listElements.size()]));
|
||||
expr = new InlineList(toPos(t.startPos, closingCurly.endPos),
|
||||
listElements.toArray(new SpelNodeImpl[listElements.size()]));
|
||||
|
||||
}
|
||||
else if (peekToken(TokenKind.COLON, true)) { // map!
|
||||
|
@ -664,7 +666,8 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
mapElements.add(eatExpression());
|
||||
}
|
||||
closingCurly = eatToken(TokenKind.RCURLY);
|
||||
expr = new InlineMap(toPos(t.startPos,closingCurly.endPos),mapElements.toArray(new SpelNodeImpl[mapElements.size()]));
|
||||
expr = new InlineMap(toPos(t.startPos, closingCurly.endPos),
|
||||
mapElements.toArray(new SpelNodeImpl[mapElements.size()]));
|
||||
}
|
||||
else {
|
||||
raiseInternalException(t.startPos, SpelMessage.OOD);
|
||||
|
@ -729,8 +732,10 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
raiseInternalException(node.startPos, SpelMessage.NOT_EXPECTED_TOKEN,
|
||||
"qualified ID", node.getKind().toString().toLowerCase());
|
||||
}
|
||||
int pos = toPos(qualifiedIdPieces.getFirst().getStartPosition(), qualifiedIdPieces.getLast().getEndPosition());
|
||||
return new QualifiedIdentifier(pos, qualifiedIdPieces.toArray(new SpelNodeImpl[qualifiedIdPieces.size()]));
|
||||
int pos = toPos(qualifiedIdPieces.getFirst().getStartPosition(),
|
||||
qualifiedIdPieces.getLast().getEndPosition());
|
||||
return new QualifiedIdentifier(pos,
|
||||
qualifiedIdPieces.toArray(new SpelNodeImpl[qualifiedIdPieces.size()]));
|
||||
}
|
||||
|
||||
private boolean isValidQualifiedId(Token node) {
|
||||
|
@ -744,19 +749,22 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
return (StringUtils.hasLength(value) && VALID_QUALIFIED_ID_PATTERN.matcher(value).matches());
|
||||
}
|
||||
|
||||
// This is complicated due to the support for dollars in identifiers. Dollars are normally separate tokens but
|
||||
// there we want to combine a series of identifiers and dollars into a single identifier
|
||||
// This is complicated due to the support for dollars in identifiers.
|
||||
// Dollars are normally separate tokens but there we want to combine
|
||||
// a series of identifiers and dollars into a single identifier.
|
||||
private boolean maybeEatMethodOrProperty(boolean nullSafeNavigation) {
|
||||
if (peekToken(TokenKind.IDENTIFIER)) {
|
||||
Token methodOrPropertyName = nextToken();
|
||||
SpelNodeImpl[] args = maybeEatMethodArgs();
|
||||
if (args == null) {
|
||||
// property
|
||||
push(new PropertyOrFieldReference(nullSafeNavigation, methodOrPropertyName.data,toPos(methodOrPropertyName)));
|
||||
push(new PropertyOrFieldReference(nullSafeNavigation, methodOrPropertyName.data,
|
||||
toPos(methodOrPropertyName)));
|
||||
return true;
|
||||
}
|
||||
// method reference
|
||||
push(new MethodReference(nullSafeNavigation, methodOrPropertyName.data, toPos(methodOrPropertyName), args));
|
||||
push(new MethodReference(nullSafeNavigation, methodOrPropertyName.data,
|
||||
toPos(methodOrPropertyName), args));
|
||||
// TODO what is the end position for a method reference? the name or the last arg?
|
||||
return true;
|
||||
}
|
||||
|
@ -792,7 +800,8 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
if (maybeEatInlineListOrMap()) {
|
||||
nodes.add(pop());
|
||||
}
|
||||
push(new ConstructorReference(toPos(newToken), dimensions.toArray(new SpelNodeImpl[dimensions.size()]),
|
||||
push(new ConstructorReference(toPos(newToken),
|
||||
dimensions.toArray(new SpelNodeImpl[dimensions.size()]),
|
||||
nodes.toArray(new SpelNodeImpl[nodes.size()])));
|
||||
}
|
||||
else {
|
||||
|
@ -931,9 +940,11 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
}
|
||||
|
||||
if (desiredTokenKind == TokenKind.IDENTIFIER) {
|
||||
// might be one of the textual forms of the operators (e.g. NE for != ) - in which case we can treat it as an identifier
|
||||
// The list is represented here: Tokenizer.alternativeOperatorNames and those ones are in order in the TokenKind enum
|
||||
if (t.kind.ordinal() >= TokenKind.DIV.ordinal() && t.kind.ordinal() <= TokenKind.NOT.ordinal() && t.data != null) {
|
||||
// Might be one of the textual forms of the operators (e.g. NE for != ) -
|
||||
// in which case we can treat it as an identifier. The list is represented here:
|
||||
// Tokenizer.alternativeOperatorNames and those ones are in order in the TokenKind enum.
|
||||
if (t.kind.ordinal() >= TokenKind.DIV.ordinal() && t.kind.ordinal() <= TokenKind.NOT.ordinal() &&
|
||||
t.data != null) {
|
||||
// if t.data were null, we'd know it wasn't the textual form, it was the symbol form
|
||||
return true;
|
||||
}
|
||||
|
@ -1019,10 +1030,8 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the start and end of a token into a single int.
|
||||
*/
|
||||
private int toPos(Token t) {
|
||||
// Compress the start and end of a token into a single int
|
||||
return (t.startPos<<16) + t.endPos;
|
||||
}
|
||||
|
||||
|
|
|
@ -1333,8 +1333,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
*/
|
||||
@Override
|
||||
public void add(String headerName, String headerValue) {
|
||||
List<String> headerValues =
|
||||
this.headers.computeIfAbsent(headerName, k -> new LinkedList<>());
|
||||
List<String> headerValues = this.headers.computeIfAbsent(headerName, k -> new LinkedList<>());
|
||||
headerValues.add(headerValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,10 +23,12 @@ import java.util.List;
|
|||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* Wrapper for a {@link ClientHttpRequestFactory} that has support for {@link ClientHttpRequestInterceptor}s.
|
||||
* {@link ClientHttpRequestFactory} wrapper with support for {@link ClientHttpRequestInterceptor}s.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.1
|
||||
* @see ClientHttpRequestFactory
|
||||
* @see ClientHttpRequestInterceptor
|
||||
*/
|
||||
public class InterceptingClientHttpRequestFactory extends AbstractClientHttpRequestFactoryWrapper {
|
||||
|
||||
|
@ -45,6 +47,7 @@ public class InterceptingClientHttpRequestFactory extends AbstractClientHttpRequ
|
|||
this.interceptors = (interceptors != null ? interceptors : Collections.emptyList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod, ClientHttpRequestFactory requestFactory) {
|
||||
return new InterceptingClientHttpRequest(requestFactory, this.interceptors, uri, httpMethod);
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.springframework.core.io.Resource;
|
|||
import org.springframework.core.io.ResourceEditor;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.support.ServletContextResourceLoader;
|
||||
import org.springframework.web.context.support.StandardServletEnvironment;
|
||||
|
@ -78,8 +79,7 @@ import org.springframework.web.context.support.StandardServletEnvironment;
|
|||
* @see #doPost
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class HttpServletBean extends HttpServlet
|
||||
implements EnvironmentCapable, EnvironmentAware {
|
||||
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
@ -128,7 +128,9 @@ public abstract class HttpServletBean extends HttpServlet
|
|||
bw.setPropertyValues(pvs, true);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
|
||||
|
@ -231,12 +233,12 @@ public abstract class HttpServletBean extends HttpServlet
|
|||
public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties)
|
||||
throws ServletException {
|
||||
|
||||
Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty()) ?
|
||||
new HashSet<>(requiredProperties) : null;
|
||||
Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty() ?
|
||||
new HashSet<>(requiredProperties) : null);
|
||||
|
||||
Enumeration<String> en = config.getInitParameterNames();
|
||||
while (en.hasMoreElements()) {
|
||||
String property = en.nextElement();
|
||||
Enumeration<String> paramNames = config.getInitParameterNames();
|
||||
while (paramNames.hasMoreElements()) {
|
||||
String property = paramNames.nextElement();
|
||||
Object value = config.getInitParameter(property);
|
||||
addPropertyValue(new PropertyValue(property, value));
|
||||
if (missingProps != null) {
|
||||
|
@ -245,7 +247,7 @@ public abstract class HttpServletBean extends HttpServlet
|
|||
}
|
||||
|
||||
// Fail if we are still missing properties.
|
||||
if (missingProps != null && missingProps.size() > 0) {
|
||||
if (!CollectionUtils.isEmpty(missingProps)) {
|
||||
throw new ServletException(
|
||||
"Initialization from ServletConfig for servlet '" + config.getServletName() +
|
||||
"' failed; the following required properties were missing: " +
|
||||
|
|
|
@ -63,9 +63,9 @@ public class ResponseBodyEmitterReturnValueHandler implements AsyncHandlerMethod
|
|||
|
||||
|
||||
public ResponseBodyEmitterReturnValueHandler(List<HttpMessageConverter<?>> messageConverters) {
|
||||
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
|
||||
Assert.notEmpty(messageConverters, "HttpMessageConverter List must not be empty");
|
||||
this.messageConverters = messageConverters;
|
||||
this.adapterMap = new HashMap<>(3);
|
||||
this.adapterMap = new HashMap<>(4);
|
||||
this.adapterMap.put(ResponseBodyEmitter.class, new SimpleResponseBodyEmitterAdapter());
|
||||
}
|
||||
|
||||
|
|
|
@ -71,12 +71,12 @@ public abstract class AbstractStandardUpgradeStrategy implements RequestUpgradeS
|
|||
}
|
||||
|
||||
protected final HttpServletRequest getHttpServletRequest(ServerHttpRequest request) {
|
||||
Assert.isTrue(request instanceof ServletServerHttpRequest, "ServletServerHttpRequest required");
|
||||
Assert.isInstanceOf(ServletServerHttpRequest.class, request, "ServletServerHttpRequest required");
|
||||
return ((ServletServerHttpRequest) request).getServletRequest();
|
||||
}
|
||||
|
||||
protected final HttpServletResponse getHttpServletResponse(ServerHttpResponse response) {
|
||||
Assert.isTrue(response instanceof ServletServerHttpResponse, "ServletServerHttpResponse required");
|
||||
Assert.isInstanceOf(ServletServerHttpResponse.class, response, "ServletServerHttpResponse required");
|
||||
return ((ServletServerHttpResponse) response).getServletResponse();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue