Polishing

This commit is contained in:
Juergen Hoeller
2015-08-26 00:44:32 +02:00
parent 75187e3a8e
commit a35f71964a
8 changed files with 161 additions and 154 deletions

View File

@@ -275,7 +275,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
/**
* Return the internal BindingResult held by this DataBinder,
* as AbstractPropertyBindingResult.
* as an AbstractPropertyBindingResult.
*/
protected AbstractPropertyBindingResult getInternalBindingResult() {
if (this.bindingResult == null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2015 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,10 +44,10 @@ public interface AliasRegistry {
/**
* Determine whether this given name is defines as an alias
* (as opposed to the name of an actually registered component).
* @param beanName the bean name to check
* @param name the name to check
* @return whether the given name is an alias
*/
boolean isAlias(String beanName);
boolean isAlias(String name);
/**
* Return the aliases for the given name, if defined.

View File

@@ -144,6 +144,22 @@ public class SimpleAliasRegistry implements AliasRegistry {
}
}
/**
* Check whether the given name points back to the given alias as an alias
* in the other direction already, catching a circular reference upfront
* and throwing a corresponding IllegalStateException.
* @param name the candidate name
* @param alias the candidate alias
* @see #registerAlias
*/
protected void checkForAliasCircle(String name, String alias) {
if (alias.equals(canonicalName(name))) {
throw new IllegalStateException("Cannot register alias '" + alias +
"' for name '" + name + "': Circular reference - '" +
name + "' is a direct or indirect alias for '" + alias + "' already");
}
}
/**
* Determine the raw name, resolving aliases to canonical names.
* @param name the user-specified name
@@ -163,20 +179,4 @@ public class SimpleAliasRegistry implements AliasRegistry {
return canonicalName;
}
/**
* Check whether the given name points back to given alias as an alias
* in the other direction, catching a circular reference upfront and
* throwing a corresponding IllegalStateException.
* @param name the candidate name
* @param alias the candidate alias
* @see #registerAlias
*/
protected void checkForAliasCircle(String name, String alias) {
if (alias.equals(canonicalName(name))) {
throw new IllegalStateException("Cannot register alias '" + alias +
"' for name '" + name + "': Circular reference - '" +
name + "' is a direct or indirect alias for '" + alias + "' already");
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 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,14 +30,17 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
private final WebBindingInitializer initializer;
/**
* Create new instance.
* @param initializer for global data binder intialization, or {@code null}
* Create a new {@code DefaultDataBinderFactory} instance.
* @param initializer for global data binder initialization
* (or {@code null} if none)
*/
public DefaultDataBinderFactory(WebBindingInitializer initializer) {
this.initializer = initializer;
}
/**
* Create a new {@link WebDataBinder} for the given target object and
* initialize it through a {@link WebBindingInitializer}.
@@ -46,6 +49,7 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
@Override
public final WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName)
throws Exception {
WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest);
if (this.initializer != null) {
this.initializer.initBinder(dataBinder, webRequest);
@@ -64,6 +68,7 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
*/
protected WebDataBinder createBinderInstance(Object target, String objectName, NativeWebRequest webRequest)
throws Exception {
return new WebRequestDataBinder(target, objectName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -125,7 +125,11 @@ public abstract class WebApplicationObjectSupport extends ApplicationObjectSuppo
if (this.servletContext != null) {
return this.servletContext;
}
ServletContext servletContext = getWebApplicationContext().getServletContext();
WebApplicationContext wac = getWebApplicationContext();
if (wac == null) {
return null;
}
ServletContext servletContext = wac.getServletContext();
if (servletContext == null && isContextRequired()) {
throw new IllegalStateException("WebApplicationObjectSupport instance [" + this +
"] does not run within a ServletContext. Make sure the object is fully configured!");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.util.xml.DomUtils;
/**
* Parse the <mvc:tiles-configurer> MVC namespace element and register
* TilesConfigurer bean
* a corresponding TilesConfigurer bean.
* @author Rossen Stoyanchev
* @since 4.1
@@ -49,11 +49,6 @@ public class TilesConfigurerBeanDefinitionParser extends AbstractSingleBeanDefin
return BEAN_NAME;
}
@Override
protected boolean shouldGenerateId() {
return super.shouldGenerateId();
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
List<Element> childElements = DomUtils.getChildElementsByTagName(element, "definitions");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -338,7 +338,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement
/**
* Create a RequestContext to expose under the specified attribute name.
* <p>Default implementation creates a standard RequestContext instance for the
* <p>The default implementation creates a standard RequestContext instance for the
* given request and model. Can be overridden in subclasses for custom instances.
* @param request current HTTP request
* @param model combined output Map (never {@code null}),

View File

@@ -90,10 +90,10 @@ public class UndertowXhrTransport extends AbstractXhrTransport implements XhrTra
private static final AttachmentKey<String> RESPONSE_BODY = AttachmentKey.create(String.class);
private final UndertowClient httpClient;
private final OptionMap optionMap;
private final UndertowClient httpClient;
private final XnioWorker worker;
private final Pool<ByteBuffer> bufferPool;
@@ -104,9 +104,9 @@ public class UndertowXhrTransport extends AbstractXhrTransport implements XhrTra
}
public UndertowXhrTransport(OptionMap optionMap) throws IOException {
Assert.notNull(optionMap, "'optionMap' is required");
this.httpClient = UndertowClient.getInstance();
Assert.notNull(optionMap, "OptionMap is required");
this.optionMap = optionMap;
this.httpClient = UndertowClient.getInstance();
this.worker = Xnio.getInstance().createWorker(optionMap);
this.bufferPool = new ByteBufferSlicePool(1048, 1048);
}
@@ -152,107 +152,6 @@ public class UndertowXhrTransport extends AbstractXhrTransport implements XhrTra
}
@Override
protected ResponseEntity<String> executeInfoRequestInternal(URI infoUrl) {
return executeRequest(infoUrl, Methods.GET, getRequestHeaders(), null);
}
@Override
protected ResponseEntity<String> executeSendRequestInternal(URI url, HttpHeaders headers, TextMessage message) {
return executeRequest(url, Methods.POST, headers, message.getPayload());
}
protected ResponseEntity<String> executeRequest(URI url, HttpString method, HttpHeaders headers, String body) {
CountDownLatch latch = new CountDownLatch(1);
List<ClientResponse> responses = new CopyOnWriteArrayList<ClientResponse>();
try {
ClientConnection connection = this.httpClient.connect(
url, this.worker, this.bufferPool, this.optionMap).get();
try {
ClientRequest request = new ClientRequest().setMethod(method).setPath(url.getPath());
request.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.HOST), url.getHost());
if (body != null && !body.isEmpty()) {
request.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.CONTENT_LENGTH), body.length());
}
addHttpHeaders(request, headers);
connection.sendRequest(request, createRequestCallback(body, responses, latch));
latch.await();
ClientResponse response = responses.iterator().next();
HttpStatus status = HttpStatus.valueOf(response.getResponseCode());
HttpHeaders responseHeaders = toHttpHeaders(response.getResponseHeaders());
String responseBody = response.getAttachment(RESPONSE_BODY);
return (responseBody != null ?
new ResponseEntity<String>(responseBody, responseHeaders, status) :
new ResponseEntity<String>(responseHeaders, status));
}
finally {
IoUtils.safeClose(connection);
}
}
catch (IOException ex) {
throw new SockJsTransportFailureException("Failed to execute request to " + url, ex);
}
catch (InterruptedException ex) {
throw new SockJsTransportFailureException("Interrupted while processing request to " + url, ex);
}
}
private ClientCallback<ClientExchange> createRequestCallback(final String body,
final List<ClientResponse> responses, final CountDownLatch latch) {
return new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
result.setResponseListener(new ClientCallback<ClientExchange>() {
@Override
public void completed(final ClientExchange result) {
responses.add(result.getResponse());
new StringReadChannelListener(result.getConnection().getBufferPool()) {
@Override
protected void stringDone(String string) {
result.getResponse().putAttachment(RESPONSE_BODY, string);
latch.countDown();
}
@Override
protected void error(IOException ex) {
onFailure(latch, ex);
}
}.setup(result.getResponseChannel());
}
@Override
public void failed(IOException ex) {
onFailure(latch, ex);
}
});
try {
if (body != null) {
result.getRequestChannel().write(ByteBuffer.wrap(body.getBytes()));
}
result.getRequestChannel().shutdownWrites();
if (!result.getRequestChannel().flush()) {
result.getRequestChannel().getWriteSetter()
.set(ChannelListeners.<StreamSinkChannel>flushingChannelListener(null, null));
result.getRequestChannel().resumeWrites();
}
}
catch (IOException ex) {
onFailure(latch, ex);
}
}
@Override
public void failed(IOException ex) {
onFailure(latch, ex);
}
private void onFailure(CountDownLatch latch, IOException ex) {
latch.countDown();
throw new SockJsTransportFailureException("Failed to execute request", ex);
}
};
}
@Override
protected void connectInternal(TransportRequest request, WebSocketHandler handler, URI receiveUrl,
HttpHeaders handshakeHeaders, XhrClientSockJsSession session,
@@ -265,24 +164,24 @@ public class UndertowXhrTransport extends AbstractXhrTransport implements XhrTra
final SettableListenableFuture<WebSocketSession> connectFuture) {
if (logger.isTraceEnabled()) {
logger.trace("Starting XHR receive request, url=" + url);
logger.trace("Starting XHR receive request for " + url);
}
this.httpClient.connect(
new ClientCallback<ClientConnection>() {
@Override
public void completed(ClientConnection result) {
final ClientRequest httpRequest = new ClientRequest().setMethod(Methods.POST).setPath(url.getPath());
httpRequest.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.HOST), url.getHost());
addHttpHeaders(httpRequest, headers);
result.sendRequest(httpRequest, createConnectCallback(url, getRequestHeaders(), session, connectFuture));
}
@Override
public void failed(IOException ex) {
throw new SockJsTransportFailureException("Failed to execute request to " + url, ex);
}
},
url, this.worker, this.bufferPool, this.optionMap);
new ClientCallback<ClientConnection>() {
@Override
public void completed(ClientConnection result) {
final ClientRequest httpRequest = new ClientRequest().setMethod(Methods.POST).setPath(url.getPath());
httpRequest.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.HOST), url.getHost());
addHttpHeaders(httpRequest, headers);
result.sendRequest(httpRequest, createConnectCallback(url, getRequestHeaders(), session, connectFuture));
}
@Override
public void failed(IOException ex) {
throw new SockJsTransportFailureException("Failed to execute request to " + url, ex);
}
},
url, this.worker, this.bufferPool, this.optionMap);
}
@@ -329,10 +228,12 @@ public class UndertowXhrTransport extends AbstractXhrTransport implements XhrTra
}
});
}
@Override
public void failed(IOException exc) {
onFailure(exc);
}
private void onFailure(Throwable failure) {
if (connectFuture.setException(failure)) {
return;
@@ -348,6 +249,108 @@ public class UndertowXhrTransport extends AbstractXhrTransport implements XhrTra
};
}
@Override
protected ResponseEntity<String> executeInfoRequestInternal(URI infoUrl) {
return executeRequest(infoUrl, Methods.GET, getRequestHeaders(), null);
}
@Override
protected ResponseEntity<String> executeSendRequestInternal(URI url, HttpHeaders headers, TextMessage message) {
return executeRequest(url, Methods.POST, headers, message.getPayload());
}
protected ResponseEntity<String> executeRequest(URI url, HttpString method, HttpHeaders headers, String body) {
CountDownLatch latch = new CountDownLatch(1);
List<ClientResponse> responses = new CopyOnWriteArrayList<ClientResponse>();
try {
ClientConnection connection = this.httpClient.connect(url, this.worker,
this.bufferPool, this.optionMap).get();
try {
ClientRequest request = new ClientRequest().setMethod(method).setPath(url.getPath());
request.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.HOST), url.getHost());
if (body != null && !body.isEmpty()) {
request.getRequestHeaders().add(HttpString.tryFromString(HttpHeaders.CONTENT_LENGTH), body.length());
}
addHttpHeaders(request, headers);
connection.sendRequest(request, createRequestCallback(body, responses, latch));
latch.await();
ClientResponse response = responses.iterator().next();
HttpStatus status = HttpStatus.valueOf(response.getResponseCode());
HttpHeaders responseHeaders = toHttpHeaders(response.getResponseHeaders());
String responseBody = response.getAttachment(RESPONSE_BODY);
return (responseBody != null ?
new ResponseEntity<String>(responseBody, responseHeaders, status) :
new ResponseEntity<String>(responseHeaders, status));
}
finally {
IoUtils.safeClose(connection);
}
}
catch (IOException ex) {
throw new SockJsTransportFailureException("Failed to execute request to " + url, ex);
}
catch (InterruptedException ex) {
throw new SockJsTransportFailureException("Interrupted while processing request to " + url, ex);
}
}
private ClientCallback<ClientExchange> createRequestCallback(final String body,
final List<ClientResponse> responses, final CountDownLatch latch) {
return new ClientCallback<ClientExchange>() {
@Override
public void completed(ClientExchange result) {
result.setResponseListener(new ClientCallback<ClientExchange>() {
@Override
public void completed(final ClientExchange result) {
responses.add(result.getResponse());
new StringReadChannelListener(result.getConnection().getBufferPool()) {
@Override
protected void stringDone(String string) {
result.getResponse().putAttachment(RESPONSE_BODY, string);
latch.countDown();
}
@Override
protected void error(IOException ex) {
onFailure(latch, ex);
}
}.setup(result.getResponseChannel());
}
@Override
public void failed(IOException ex) {
onFailure(latch, ex);
}
});
try {
if (body != null) {
result.getRequestChannel().write(ByteBuffer.wrap(body.getBytes()));
}
result.getRequestChannel().shutdownWrites();
if (!result.getRequestChannel().flush()) {
result.getRequestChannel().getWriteSetter()
.set(ChannelListeners.<StreamSinkChannel>flushingChannelListener(null, null));
result.getRequestChannel().resumeWrites();
}
}
catch (IOException ex) {
onFailure(latch, ex);
}
}
@Override
public void failed(IOException ex) {
onFailure(latch, ex);
}
private void onFailure(CountDownLatch latch, IOException ex) {
latch.countDown();
throw new SockJsTransportFailureException("Failed to execute request", ex);
}
};
}
public class SockJsResponseListener implements ChannelListener<StreamSourceChannel> {