Polishing

This commit is contained in:
Juergen Hoeller 2015-07-21 22:58:34 +02:00
parent 1a636b1023
commit edd6e76b9f
43 changed files with 244 additions and 262 deletions

View File

@ -43,7 +43,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
* meaningful validation. All exposed Commons Pool properties use the
* corresponding Commons Pool defaults.
*
* <p>Compatible with Apache Commons Pool 2.4
* <p>Compatible with Apache Commons Pool 2.4, as of Spring 4.2.
*
* @author Rod Johnson
* @author Rob Harrop
@ -90,6 +90,7 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
setMaxSize(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL);
}
/**
* Set the maximum number of idle objects in the pool.
* Default is 8.
@ -185,9 +186,10 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
* Specify if the call should block when the pool is exhausted.
*/
public boolean isBlockWhenExhausted() {
return blockWhenExhausted;
return this.blockWhenExhausted;
}
/**
* Creates and holds an ObjectPool instance.
* @see #createObjectPool()
@ -220,7 +222,7 @@ public class CommonsPool2TargetSource extends AbstractPoolingTargetSource implem
/**
* Borrow an object from the {@code ObjectPool}.
* Borrows an object from the {@code ObjectPool}.
*/
@Override
public Object getTarget() throws Exception {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 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.
@ -20,7 +20,8 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
import org.springframework.transaction.annotation.Transactional;
/**
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
* Concrete AspectJ transaction aspect using Spring's
* {@link org.springframework.transaction.annotation.Transactional} annotation.
*
* <p>When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
@ -66,8 +67,6 @@ public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
* will have Spring transaction management applied.
*/
protected pointcut transactionalMethodExecution(Object txObject) :
(executionOfAnyPublicMethodInAtTransactionalType()
|| executionOfTransactionalMethod() )
&& this(txObject);
(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 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.
@ -23,7 +23,8 @@ import org.aspectj.lang.annotation.RequiredTypes;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
/**
* Concrete AspectJ transaction aspect using {@code javax.transaction.Transactional} annotation.
* Concrete AspectJ transaction aspect using the JTA 1.2
* {@link javax.transaction.Transactional} annotation.
*
* <p>When using this aspect, you <i>must</i> annotate the implementation class
* (and/or methods within that class), <i>not</i> the interface (if any) that
@ -41,7 +42,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
*
* @author Stephane Nicoll
* @since 4.2
* @see Transactional
* @see javax.transaction.Transactional
* @see AnnotationTransactionAspect
*/
@RequiredTypes({"javax.transaction.Transactional"})
@ -69,8 +70,6 @@ public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
* will have Spring transaction management applied.
*/
protected pointcut transactionalMethodExecution(Object txObject) :
(executionOfAnyPublicMethodInAtTransactionalType()
|| executionOfTransactionalMethod() )
&& this(txObject);
(executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject);
}

View File

@ -101,6 +101,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
*/
private Map<String, AbstractNestablePropertyAccessor> nestedPropertyAccessors;
/**
* Create new empty accessor. Wrapped instance needs to be set afterwards.
* Registers default editors.
@ -168,6 +169,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
setConversionService(parent.getConversionService());
}
/**
* Specify a limit for array and collection auto-growing.
* <p>Default is unlimited on a plain accessor.
@ -758,7 +760,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
for (int i = length; i < Array.getLength(newArray); i++) {
Array.set(newArray, i, newValue(componentType, null, name));
}
// TODO this is not efficient because conversion may create a copy ... set directly because we know it is assignable.
setPropertyValue(name, newArray);
return getPropertyValue(name);
}
@ -802,7 +803,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
* @param propertyPath property property path, which may be nested
* @return a property accessor for the target bean
*/
@SuppressWarnings("unchecked") // avoid nested generic
@SuppressWarnings("unchecked") // avoid nested generic
protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
// Handle nested properties recursively.
@ -1024,9 +1025,9 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
public abstract Object getValue() throws Exception;
public abstract void setValue(Object object, Object value) throws Exception;
}
protected static class PropertyTokenHolder {
public String canonicalName;
@ -1055,4 +1056,5 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
return !((Optional<?>) optionalObject).isPresent();
}
}
}

View File

@ -46,10 +46,10 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
this.payload = payload;
}
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(getClass(),
ResolvableType.forInstance(getPayload()));
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
}
/**

View File

@ -334,11 +334,26 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
publishEvent(event, null);
}
/**
* Publish the given event to all listeners.
* <p>Note: Listeners get initialized after the MessageSource, to be able
* to access it within listener implementations. Thus, MessageSource
* implementations cannot publish events.
* @param event the event to publish (may be an {@link ApplicationEvent}
* or a payload object to be turned into a {@link PayloadApplicationEvent})
*/
@Override
public void publishEvent(Object event) {
publishEvent(event, null);
}
/**
* Publish the given event to all listeners.
* @param event the event to publish (may be an {@link ApplicationEvent}
* or a payload object to be turned into a {@link PayloadApplicationEvent})
* @param eventType the resolved event type, if known
* @since 4.2
*/
protected void publishEvent(Object event, ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {

View File

@ -41,6 +41,7 @@ public class ScriptStatementFailedException extends ScriptException {
super(buildErrorMessage(stmt, stmtNumber, encodedResource), cause);
}
/**
* Build an error message for an SQL script execution failure,
* based on the supplied arguments.
@ -53,8 +54,7 @@ public class ScriptStatementFailedException extends ScriptException {
* @since 4.2
*/
public static String buildErrorMessage(String stmt, int stmtNumber, EncodedResource encodedResource) {
return String.format("Failed to execute SQL script statement #%s of %s: %s",
stmtNumber, encodedResource, stmt);
return String.format("Failed to execute SQL script statement #%s of %s: %s", stmtNumber, encodedResource, stmt);
}
}

View File

@ -24,12 +24,12 @@ import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.util.Assert;
/**
* Return type of any JMS listener method used to indicate the actual response destination
* alongside the response itself. Typically used when said destination needs to be
* computed at runtime.
* <p>
* The example below sends a response with the content of the {@code result} argument to
* the {@code queueOut Queue}:
* Return type of any JMS listener method used to indicate the actual response
* destination alongside the response itself. Typically used when said destination
* needs to be computed at runtime.
*
* <p>The example below sends a response with the content of the {@code result}
* argument to the {@code queueOut Queue}:
*
* <pre class="code">
* package com.acme.foo;
@ -43,8 +43,8 @@ import org.springframework.util.Assert;
* }</pre>
*
* If the destination does not need to be computed at runtime,
* {@link org.springframework.messaging.handler.annotation.SendTo @SendTo} is the
* recommended declarative approach.
* {@link org.springframework.messaging.handler.annotation.SendTo @SendTo}
* is the recommended declarative approach.
*
* @author Stephane Nicoll
* @since 4.2
@ -58,6 +58,7 @@ public class JmsResponse<T> {
private final Object destination;
/**
* Create a new instance
* @param response the content of the result
@ -69,29 +70,6 @@ public class JmsResponse<T> {
this.destination = destination;
}
/**
* Create a {@link JmsResponse} targeting the queue with the specified name.
*/
public static <T> JmsResponse<T> forQueue(T result, String queueName) {
Assert.notNull(queueName, "Queue name must not be null");
return new JmsResponse<T>(result, new DestinationNameHolder(queueName, false));
}
/**
* Create a {@link JmsResponse} targeting the topic with the specified name.
*/
public static <T> JmsResponse<T> forTopic(T result, String topicName) {
Assert.notNull(topicName, "Topic name must not be null");
return new JmsResponse<T>(result, new DestinationNameHolder(topicName, true));
}
/**
* Create a {@link JmsResponse} targeting the specified {@link Destination}.
*/
public static <T> JmsResponse<T> forDestination(T result, Destination destination) {
Assert.notNull(destination, "Destination must not be null");
return new JmsResponse<T>(result, destination);
}
/**
* Return the content of the response.
@ -124,7 +102,32 @@ public class JmsResponse<T> {
@Override
public String toString() {
return "JmsResponse{" + "response=" + this.response + ", destination=" + this.destination + '}';
return "JmsResponse [" + "response=" + this.response + ", destination=" + this.destination + ']';
}
/**
* Create a {@link JmsResponse} targeting the queue with the specified name.
*/
public static <T> JmsResponse<T> forQueue(T result, String queueName) {
Assert.notNull(queueName, "Queue name must not be null");
return new JmsResponse<T>(result, new DestinationNameHolder(queueName, false));
}
/**
* Create a {@link JmsResponse} targeting the topic with the specified name.
*/
public static <T> JmsResponse<T> forTopic(T result, String topicName) {
Assert.notNull(topicName, "Topic name must not be null");
return new JmsResponse<T>(result, new DestinationNameHolder(topicName, true));
}
/**
* Create a {@link JmsResponse} targeting the specified {@link Destination}.
*/
public static <T> JmsResponse<T> forDestination(T result, Destination destination) {
Assert.notNull(destination, "Destination must not be null");
return new JmsResponse<T>(result, destination);
}
@ -132,7 +135,8 @@ public class JmsResponse<T> {
* Internal class combining a destination name
* and its target destination type (queue or topic).
*/
protected static class DestinationNameHolder {
private static class DestinationNameHolder {
private final String destinationName;
private final boolean pubSubDomain;

View File

@ -18,7 +18,6 @@ package org.springframework.messaging.converter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
@ -32,9 +31,7 @@ import org.springframework.beans.TypeMismatchException;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.UnmarshallingFailureException;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
@ -61,8 +58,7 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
* {@link #setUnmarshaller(Unmarshaller)} to be invoked separately.
*/
public MarshallingMessageConverter() {
this(new MimeType("application", "xml"), new MimeType("text", "xml"),
new MimeType("application", "*+xml"));
this(new MimeType("application", "xml"), new MimeType("text", "xml"), new MimeType("application", "*+xml"));
}
/**
@ -76,10 +72,8 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
/**
* Constructor with {@link Marshaller}. If the given {@link Marshaller} also
* implements {@link Unmarshaller}, it is also used for unmarshalling.
*
* <p>Note that all {@code Marshaller} implementations in Spring also implement
* {@code Unmarshaller} so that you can safely use this constructor.
*
* @param marshaller object used as marshaller and unmarshaller
*/
public MarshallingMessageConverter(Marshaller marshaller) {
@ -144,17 +138,13 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
try {
Source source = getSource(message.getPayload());
Object result = this.unmarshaller.unmarshal(source);
if (!targetClass.isInstance(result)) {
throw new TypeMismatchException(result, targetClass);
}
return result;
}
catch (UnmarshallingFailureException ex) {
throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex);
}
catch (IOException ex) {
catch (Exception ex) {
throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex);
}
}
@ -175,26 +165,20 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
if (byte[].class == getSerializedPayloadClass()) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Result result = new StreamResult(out);
this.marshaller.marshal(payload, result);
payload = out.toByteArray();
}
else {
Writer writer = new StringWriter();
Result result = new StreamResult(writer);
this.marshaller.marshal(payload, result);
payload = writer.toString();
}
}
catch (MarshallingFailureException ex) {
throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex);
}
catch (IOException ex) {
catch (Exception ex) {
throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex);
}
return payload;
}
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.handler;
import org.springframework.core.Ordered;

View File

@ -21,7 +21,7 @@ import org.springframework.messaging.Message;
/**
* Convenient base class for {@link AsyncHandlerMethodReturnValueHandler}
* implementations that support only asynchronous (Future-like) return values a
* implementations that support only asynchronous (Future-like) return values
* and merely serve as adapters of such types to Spring's
* {@link org.springframework.util.concurrent.ListenableFuture ListenableFuture}.
*
@ -38,7 +38,7 @@ public abstract class AbstractAsyncReturnValueHandler implements AsyncHandlerMet
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message) {
// Should never be called since we return "true" from isAsyncReturnValue
throw new IllegalStateException("Unexpected invocation.");
throw new IllegalStateException("Unexpected invocation");
}
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.handler.invocation;
import org.springframework.core.MethodParameter;
@ -38,11 +39,9 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
* with success and error callbacks. If this method returns {@code true},
* then {@link #toListenableFuture} is invoked next. If it returns
* {@code false}, then {@link #handleReturnValue} is called.
*
* <p><strong>Note:</strong> this method will only be invoked after
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
* is called and it returns {@code true}.
*
* @param returnValue the value returned from the handler method
* @param returnType the type of the return value.
* @return true if the return value type represents an async value.
@ -55,11 +54,9 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
* {@link org.springframework.util.concurrent.SettableListenableFuture
* SettableListenableFuture}. Return value handling will then continue when
* the ListenableFuture is completed with either success or error.
*
* <p><strong>Note:</strong> this method will only be invoked after
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
* is called and it returns {@code true}.
*
* @param returnValue the value returned from the handler method
* @param returnType the type of the return value.
* @return the resulting ListenableFuture or {@code null} in which case no
@ -67,4 +64,4 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
*/
ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType);
}
}

View File

@ -43,4 +43,4 @@ public class CompletableFutureReturnValueHandler extends AbstractAsyncReturnValu
return new CompletableToListenableFutureAdapter<Object>((CompletableFuture<Object>) returnValue);
}
}
}

View File

@ -121,7 +121,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
* @since 4.2
*/
public void setTaskScheduler(TaskScheduler taskScheduler) {
Assert.notNull(taskScheduler);
Assert.notNull(taskScheduler, "TaskScheduler must not be null");
this.taskScheduler = taskScheduler;
if (this.heartbeatValue == null) {
this.heartbeatValue = new long[] {10000, 10000};
@ -185,7 +185,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
else {
Assert.isTrue(getHeartbeatValue() == null ||
(getHeartbeatValue()[0] == 0 && getHeartbeatValue()[1] == 0),
"Heartbeat values configured but no TaskScheduler is provided.");
"Heartbeat values configured but no TaskScheduler provided");
}
}
@ -328,7 +328,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
@Override
public String toString() {
return "SimpleBroker[" + this.subscriptionRegistry + "]";
return "SimpleBrokerMessageHandler [" + this.subscriptionRegistry + "]";
}
@ -337,7 +337,6 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
/* STOMP spec: receiver SHOULD take into account an error margin */
private static final long HEARTBEAT_MULTIPLIER = 3;
private final String sessiondId;
private final Principal user;
@ -350,7 +349,6 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
private volatile long lastWriteTime;
public SessionInfo(String sessiondId, Principal user, long[] clientHeartbeat, long[] serverHeartbeat) {
this.sessiondId = sessiondId;
this.user = user;
@ -400,6 +398,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
}
}
private class HeartbeatTask implements Runnable {
@Override
@ -420,4 +419,5 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
}
}
}
}

View File

@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import org.springframework.messaging.tcp.TcpConnectionHandler;
import org.springframework.util.concurrent.ListenableFuture;
/**
* A {@link StompSession} that implements
* {@link org.springframework.messaging.tcp.TcpConnectionHandler

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
package org.springframework.messaging.simp.stomp;
/**
* Raised when the connection for a STOMP session is lost rather than closed.
@ -25,7 +25,6 @@ package org.springframework.messaging.simp.stomp;
@SuppressWarnings("serial")
public class ConnectionLostException extends Exception {
public ConnectionLostException(String message) {
super(message);
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import java.lang.reflect.Type;
@ -47,7 +48,6 @@ import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.util.concurrent.SettableListenableFuture;
/**
* Default implementation of {@link ConnectionHandlingStompSession}.
*
@ -56,7 +56,7 @@ import org.springframework.util.concurrent.SettableListenableFuture;
*/
public class DefaultStompSession implements ConnectionHandlingStompSession {
private static Log logger = LogFactory.getLog(DefaultStompSession.class);
private static final Log logger = LogFactory.getLog(DefaultStompSession.class);
private static final IdGenerator idGenerator = new AlternativeJdkIdGenerator();
@ -88,7 +88,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
private long receiptTimeLimit = 15 * 1000;
private volatile boolean autoReceiptEnabled;
private volatile boolean autoReceiptEnabled;
private volatile TcpConnection<byte[]> connection;
@ -107,7 +107,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
/**
* Create a new session.
*
* @param sessionHandler the application handler for the session
* @param connectHeaders headers for the STOMP CONNECT frame
*/
@ -201,7 +200,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
@Override
public boolean isConnected() {
return this.connection != null;
return (this.connection != null);
}
@Override
@ -331,6 +330,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
}
// TcpConnectionHandler
@Override
@ -475,7 +475,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
private class ReceiptHandler implements Receiptable {
private final String receiptId;
@ -488,7 +487,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
private Boolean result;
public ReceiptHandler(String receiptId) {
this.receiptId = receiptId;
if (this.receiptId != null) {
@ -574,6 +572,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
}
private class DefaultSubscription extends ReceiptHandler implements Subscription {
private final String id;
@ -582,7 +581,6 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
private final StompFrameHandler handler;
public DefaultSubscription(String id, String destination, String receiptId, StompFrameHandler handler) {
super(receiptId);
Assert.notNull(destination, "'destination' is required");
@ -620,6 +618,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
}
private class WriteInactivityTask implements Runnable {
@Override
@ -638,6 +637,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
}
private class ReadInactivityTask implements Runnable {
@Override
@ -652,4 +652,4 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
}
}
}

View File

@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import org.springframework.messaging.Message;
import org.springframework.messaging.tcp.TcpOperations;
import org.springframework.messaging.tcp.reactor.Reactor2TcpClient;
import org.springframework.util.concurrent.ListenableFuture;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import reactor.Environment;
import reactor.core.config.ConfigurationReader;
import reactor.core.config.DispatcherConfiguration;
@ -27,9 +28,10 @@ import reactor.core.config.ReactorConfiguration;
import reactor.io.net.NetStreams;
import reactor.io.net.Spec.TcpClientSpec;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.springframework.messaging.Message;
import org.springframework.messaging.tcp.TcpOperations;
import org.springframework.messaging.tcp.reactor.Reactor2TcpClient;
import org.springframework.util.concurrent.ListenableFuture;
/**
* A STOMP over TCP client that uses
@ -73,8 +75,7 @@ public class Reactor2TcpStompClient extends StompClientSupport {
/**
* Connect and notify the given {@link StompSessionHandler} when connected
* on the STOMP level,
*
* on the STOMP level.
* @param handler the handler for the STOMP session
* @return ListenableFuture for access to the session when ready for use
*/
@ -85,9 +86,8 @@ public class Reactor2TcpStompClient extends StompClientSupport {
/**
* An overloaded version of {@link #connect(StompSessionHandler)} that
* accepts headers to use for the STOMP CONNECT frame.
*
* @param connectHeaders headers to add to the CONNECT frame
* @param handler the handler for the STOMP session
* @param handler the handler for the STOMP session
* @return ListenableFuture for access to the session when ready for use
*/
public ListenableFuture<StompSession> connect(StompHeaders connectHeaders, StompSessionHandler handler) {
@ -119,6 +119,7 @@ public class Reactor2TcpStompClient extends StompClientSupport {
}
}
private static class StompTcpClientSpecFactory
implements NetStreams.TcpClientFactory<Message<byte[]>, Message<byte[]>> {

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import java.util.Arrays;
@ -22,11 +23,10 @@ import org.springframework.messaging.converter.SimpleMessageConverter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.Assert;
/**
* Base class for STOMP client implementations.
*
* <p>Sub-classes can connect over WebSocket or TCP using any library.
* <p>Subclasses can connect over WebSocket or TCP using any library.
* When creating a new connection a sub-class can create an instance of
* {@link DefaultStompSession} which extends
* {@link org.springframework.messaging.tcp.TcpConnectionHandler
@ -71,12 +71,10 @@ public abstract class StompClientSupport {
/**
* Configure a scheduler to use for heartbeats and for receipt tracking.
*
* <p><strong>Note:</strong> some transports have built-in support to work
* with heartbeats and therefore do not require a TaskScheduler.
* Receipts however, if needed, do require a TaskScheduler to be configured.
*
* <p>By default this is not set.
* <p>By default, this is not set.
*/
public void setTaskScheduler(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
@ -99,7 +97,7 @@ public abstract class StompClientSupport {
* TaskScheduler to be configured first.
* @param heartbeat the value for the CONNECT "heart-beat" header
* @see <a href="http://stomp.github.io/stomp-specification-1.2.html#Heart-beating">
* http://stomp.github.io/stomp-specification-1.2.html#Heart-beating</a>
* http://stomp.github.io/stomp-specification-1.2.html#Heart-beating</a>
*/
public void setDefaultHeartbeat(long[] heartbeat) {
Assert.notNull(heartbeat);
@ -136,7 +134,7 @@ public abstract class StompClientSupport {
* Return the configured receipt time limit.
*/
public long getReceiptTimeLimit() {
return receiptTimeLimit;
return this.receiptTimeLimit;
}

View File

@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import java.lang.reflect.Type;
/**
* Contract to handle a STOMP frame.
*
@ -36,7 +36,6 @@ public interface StompFrameHandler {
/**
* Handle a STOMP frame with the payload converted to the target type returned
* from {@link #getPayloadType(StompHeaders)}.
*
* @param headers the headers of the frame
* @param payload the payload or {@code null} if there was no payload
*/

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import java.io.Serializable;
@ -45,7 +46,7 @@ import org.springframework.util.StringUtils;
* @author Rossen Stoyanchev
* @since 4.2
* @see <a href="http://stomp.github.io/stomp-specification-1.2.html#Frames_and_Headers">
* http://stomp.github.io/stomp-specification-1.2.html#Frames_and_Headers</a>
* http://stomp.github.io/stomp-specification-1.2.html#Frames_and_Headers</a>
*/
public class StompHeaders implements MultiValueMap<String, String>, Serializable {

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
package org.springframework.messaging.simp.stomp;
/**
* Represents a STOMP session with operations to send messages, create
@ -41,7 +41,6 @@ public interface StompSession {
* the server to return a RECEIPT. An application can then use the
* {@link StompSession.Receiptable
* Receiptable} returned from the operation to track the receipt.
*
* <p>A receipt header can also be added manually through the overloaded
* methods that accept {@code StompHeaders}.
*/
@ -117,7 +116,6 @@ public interface StompSession {
* @see org.springframework.messaging.simp.stomp.StompClientSupport#setReceiptTimeLimit(long)
*/
void addReceiptLostTask(Runnable runnable);
}
/**
@ -134,7 +132,6 @@ public interface StompSession {
* Remove the subscription by sending an UNSUBSCRIBE frame.
*/
void unsubscribe();
}
}

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
package org.springframework.messaging.simp.stomp;
/**
* A contract for client STOMP session lifecycle events including a callback

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import java.lang.reflect.Type;

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
import java.net.InetAddress;
@ -66,6 +67,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
this.id = generateId();
}
private static String generateId() {
String host;
try {
@ -171,7 +173,6 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
private long expirationTime;
public UserRegistryDto() {
}
@ -233,6 +234,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
}
@SuppressWarnings("unused")
private static class SimpUserDto implements SimpUser {
@ -240,7 +242,6 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
private Set<SimpSessionDto> sessions;
public SimpUserDto() {
this.sessions = new HashSet<SimpSessionDto>(1);
}
@ -254,27 +255,18 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
}
@Override
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean hasSessions() {
return !this.sessions.isEmpty();
public String getName() {
return this.name;
}
@Override
public Set<SimpSession> getSessions() {
return new HashSet<SimpSession>(this.sessions);
}
public void setSessions(Set<SimpSessionDto> sessions) {
this.sessions.addAll(sessions);
public boolean hasSessions() {
return !this.sessions.isEmpty();
}
@Override
@ -287,6 +279,15 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
return null;
}
public void setSessions(Set<SimpSessionDto> sessions) {
this.sessions.addAll(sessions);
}
@Override
public Set<SimpSession> getSessions() {
return new HashSet<SimpSession>(this.sessions);
}
private void restoreParentReferences() {
for (SimpSessionDto session : this.sessions) {
session.setUser(this);
@ -296,13 +297,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || !(other instanceof SimpUser)) {
return false;
}
return this.name.equals(((SimpUser) other).getName());
return (this == other || (other instanceof SimpUser && this.name.equals(((SimpUser) other).getName())));
}
@Override
@ -316,6 +311,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
}
@SuppressWarnings("unused")
private static class SimpSessionDto implements SimpSession {
@ -323,8 +319,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
private SimpUserDto user;
private Set<SimpSubscriptionDto> subscriptions;
private final Set<SimpSubscriptionDto> subscriptions;
public SimpSessionDto() {
this.subscriptions = new HashSet<SimpSubscriptionDto>(4);
@ -339,18 +334,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
}
@Override
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
@Override
public SimpUserDto getUser() {
return this.user;
public String getId() {
return this.id;
}
public void setUser(SimpUserDto user) {
@ -358,14 +348,19 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
@Override
public Set<SimpSubscription> getSubscriptions() {
return new HashSet<SimpSubscription>(this.subscriptions);
public SimpUserDto getUser() {
return this.user;
}
public void setSubscriptions(Set<SimpSubscriptionDto> subscriptions) {
this.subscriptions.addAll(subscriptions);
}
@Override
public Set<SimpSubscription> getSubscriptions() {
return new HashSet<SimpSubscription>(this.subscriptions);
}
private void restoreParentReferences() {
for (SimpSubscriptionDto subscription : this.subscriptions) {
subscription.setSession(this);
@ -373,19 +368,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
@Override
public int hashCode() {
return this.id.hashCode();
public boolean equals(Object other) {
return (this == other || (other instanceof SimpSession && this.id.equals(((SimpSession) other).getId())));
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || !(other instanceof SimpSession)) {
return false;
}
return this.id.equals(((SimpSession) other).getId());
public int hashCode() {
return this.id.hashCode();
}
@Override
@ -394,6 +383,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
}
@SuppressWarnings("unused")
private static class SimpSubscriptionDto implements SimpSubscription {
@ -403,7 +393,6 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
private String destination;
public SimpSubscriptionDto() {
}
@ -412,18 +401,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
this.destination = subscription.getDestination();
}
@Override
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
@Override
public SimpSessionDto getSession() {
return this.session;
public String getId() {
return this.id;
}
public void setSession(SimpSessionDto session) {
@ -431,8 +415,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
@Override
public String getDestination() {
return this.destination;
public SimpSessionDto getSession() {
return this.session;
}
public void setDestination(String destination) {
@ -440,8 +424,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
}
@Override
public int hashCode() {
return 31 * this.id.hashCode() + ObjectUtils.nullSafeHashCode(getSession());
public String getDestination() {
return this.destination;
}
@Override
@ -449,7 +433,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
if (this == other) {
return true;
}
if (other == null || !(other instanceof SimpSubscription)) {
if (!(other instanceof SimpSubscription)) {
return false;
}
SimpSubscription otherSubscription = (SimpSubscription) other;
@ -457,12 +441,18 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
this.id.equals(otherSubscription.getId()));
}
@Override
public int hashCode() {
return this.id.hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession());
}
@Override
public String toString() {
return "destination=" + this.destination;
}
}
private static class NoOpSmartApplicationListener implements SmartApplicationListener {
@Override

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
import java.util.Set;

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
/**

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
/**
@ -26,7 +27,7 @@ public interface SimpSubscriptionMatcher {
/**
* Match the given subscription.
* @param subscription the subscription to match
* @return {@code true} in case of match, {@code false} otherwise.
* @return {@code true} in case of a match, {@code false} otherwise
*/
boolean match(SimpSubscription subscription);

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
import java.util.Set;

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
import java.util.Set;

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
import java.util.concurrent.ScheduledFuture;
@ -64,7 +65,6 @@ public class UserRegistryMessageHandler implements MessageHandler, ApplicationLi
Assert.hasText(broadcastDestination, "'broadcastDestination' is required");
Assert.notNull(scheduler, "'scheduler' is required");
this.userRegistry = (MultiServerUserRegistry) userRegistry;
this.brokerTemplate = brokerTemplate;
this.broadcastDestination = broadcastDestination;

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.user;
import java.util.Collections;
@ -48,12 +49,12 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
@Override
public Set<SimpUser> getUsers() {
throw new UnsupportedOperationException("UserSessionRegistry does not expose a listing of users.");
throw new UnsupportedOperationException("UserSessionRegistry does not expose a listing of users");
}
@Override
public Set<SimpSubscription> findSubscriptions(SimpSubscriptionMatcher matcher) {
throw new UnsupportedOperationException("UserSessionRegistry does not support operations across users.");
throw new UnsupportedOperationException("UserSessionRegistry does not support operations across users");
}
@ -63,7 +64,6 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
private final Map<String, SimpSession> sessions;
public SimpleSimpUser(String name, Set<String> sessionIds) {
this.name = name;
this.sessions = new HashMap<String, SimpSession>(sessionIds.size());
@ -93,11 +93,11 @@ public class UserSessionRegistryAdapter implements SimpUserRegistry {
}
}
private static class SimpleSimpSession implements SimpSession {
private final String id;
public SimpleSimpSession(String id) {
this.id = id;
}

View File

@ -59,11 +59,10 @@ import org.springframework.messaging.tcp.TcpOperations;
import org.springframework.util.Assert;
import org.springframework.util.concurrent.ListenableFuture;
/**
* An implementation of {@link org.springframework.messaging.tcp.TcpOperations}
* based on the TCP client support of the Reactor project.
* <p>
*
* <p>This implementation wraps N (Reactor) clients for N {@link #connect} calls,
* i.e. a separate (Reactor) client instance for each connection.
*
@ -76,13 +75,14 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
@SuppressWarnings("rawtypes")
public static final Class<NettyTcpClient> REACTOR_TCP_CLIENT_TYPE = NettyTcpClient.class;
private final NioEventLoopGroup eventLoopGroup;
private final TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory;
private final List<TcpClient<Message<P>, Message<P>>> tcpClients =
new ArrayList<TcpClient<Message<P>, Message<P>>>();
private final NioEventLoopGroup eventLoopGroup;
private boolean stopping;
@ -94,17 +94,14 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
* threads will be shared amongst the active clients.
* <p>Also see the constructor accepting a ready Reactor
* {@link TcpClientSpec} {@link Function} factory.
*
* @param host the host to connect to
* @param port the port to connect to
* @param host the host to connect to
* @param port the port to connect to
* @param codec the codec to use for encoding and decoding the TCP stream
*/
public Reactor2TcpClient(final String host, final int port, final Codec<Buffer, Message<P>, Message<P>> codec) {
this.eventLoopGroup = initEventLoopGroup();
this.tcpClientSpecFactory = new TcpClientFactory<Message<P>, Message<P>>() {
@Override
public TcpClientSpec<Message<P>, Message<P>> apply(TcpClientSpec<Message<P>, Message<P>> spec) {
return spec
@ -116,12 +113,28 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
};
}
/**
* A constructor with a pre-configured {@link TcpClientSpec} {@link Function}
* factory. This might be used to add SSL or specific network parameters to
* the generated client configuration.
* <p><strong>NOTE:</strong> if the client is configured with a thread-creating
* dispatcher, you are responsible for cleaning them, e.g. using
* {@link reactor.core.Dispatcher#shutdown}.
* @param tcpClientSpecFactory the TcpClientSpec {@link Function} to use for each client creation
*/
public Reactor2TcpClient(TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory) {
Assert.notNull(tcpClientSpecFactory, "'tcpClientClientFactory' must not be null");
this.tcpClientSpecFactory = tcpClientSpecFactory;
this.eventLoopGroup = null;
}
private static NioEventLoopGroup initEventLoopGroup() {
int ioThreadCount;
try {
ioThreadCount = Integer.parseInt(System.getProperty("reactor.tcp.ioThreadCount"));
}
catch (Exception i) {
catch (Exception ex) {
ioThreadCount = -1;
}
if (ioThreadCount <= 0l) {
@ -132,26 +145,10 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
new NamedDaemonThreadFactory("reactor-tcp-io"));
}
/**
* A constructor with a pre-configured {@link TcpClientSpec} {@link Function}
* factory. This might be used to add SSL or specific network parameters to
* the generated client configuration.
* <p><strong>NOTE:</strong> if the client is configured with a thread-creating
* dispatcher, you are responsible for cleaning them, e.g. using
* {@link reactor.core.Dispatcher#shutdown}.
*
* @param tcpClientSpecFactory the TcpClientSpec {@link Function} to use for each client creation.
*/
public Reactor2TcpClient(TcpClientFactory<Message<P>, Message<P>> tcpClientSpecFactory) {
Assert.notNull(tcpClientSpecFactory, "'tcpClientClientFactory' must not be null");
this.tcpClientSpecFactory = tcpClientSpecFactory;
this.eventLoopGroup = null;
}
@Override
public ListenableFuture<Void> connect(final TcpConnectionHandler<P> connectionHandler) {
Assert.notNull(connectionHandler, "'connectionHandler' must not be null");
Assert.notNull(connectionHandler, "TcpConnectionHandler must not be null");
TcpClient<Message<P>, Message<P>> tcpClient;
synchronized (this.tcpClients) {
@ -178,8 +175,8 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
@Override
public ListenableFuture<Void> connect(TcpConnectionHandler<P> connectionHandler, ReconnectStrategy strategy) {
Assert.notNull(connectionHandler, "'connectionHandler' must not be null");
Assert.notNull(strategy, "'reconnectStrategy' must not be null");
Assert.notNull(connectionHandler, "TcpConnectionHandler must not be null");
Assert.notNull(strategy, "ReconnectStrategy must not be null");
TcpClient<Message<P>, Message<P>> tcpClient;
synchronized (this.tcpClients) {
@ -204,6 +201,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
synchronized (this.tcpClients) {
this.stopping = true;
}
Promise<Void> promise = Streams.from(this.tcpClients)
.flatMap(new Function<TcpClient<Message<P>, Message<P>>, Promise<Void>>() {
@Override
@ -217,6 +215,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
}
})
.next();
if (this.eventLoopGroup != null) {
final Promise<Void> eventLoopPromise = Promises.prepare();
promise.onComplete(new Consumer<Promise<Void>>() {
@ -249,6 +248,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
}
}
private static class MessageChannelStreamHandler<P>
implements ReactorChannelHandler<Message<P>, Message<P>, ChannelStream<Message<P>, Message<P>>> {
@ -260,14 +260,10 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
@Override
public Publisher<Void> apply(ChannelStream<Message<P>, Message<P>> channelStream) {
Promise<Void> closePromise = Promises.prepare();
this.connectionHandler.afterConnected(new Reactor2TcpConnection<P>(channelStream, closePromise));
channelStream
.finallyDo(new Consumer<Signal<Message<P>>>() {
@Override
public void accept(Signal<Message<P>> signal) {
if (signal.isOnError()) {
@ -279,7 +275,6 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
}
})
.consume(new Consumer<Message<P>>() {
@Override
public void accept(Message<P> message) {
connectionHandler.handleMessage(message);
@ -290,6 +285,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
}
}
private static class ReactorReconnectAdapter implements Reconnect {
private final ReconnectStrategy strategy;
@ -300,7 +296,7 @@ public class Reactor2TcpClient<P> implements TcpOperations<P> {
@Override
public Tuple2<InetSocketAddress, Long> reconnect(InetSocketAddress address, int attempt) {
return Tuple.of(address, strategy.getTimeToNextAttempt(attempt));
return Tuple.of(address, this.strategy.getTimeToNextAttempt(attempt));
}
}

View File

@ -51,19 +51,21 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
private final TransactionalEventListener annotation;
public ApplicationListenerMethodTransactionalAdapter(String beanName, Class<?> targetClass, Method method) {
super(beanName, targetClass, method);
this.annotation = findAnnotation(method);
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronization transactionSynchronization = createTransactionSynchronization(event);
TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
}
else if (annotation.fallbackExecution()) {
if (annotation.phase() == TransactionPhase.AFTER_ROLLBACK) {
else if (this.annotation.fallbackExecution()) {
if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK) {
logger.warn("Processing '" + event + "' as a fallback execution on AFTER_ROLLBACK phase.");
}
processEvent(event);
@ -80,8 +82,8 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
}
static TransactionalEventListener findAnnotation(Method method) {
TransactionalEventListener annotation = AnnotatedElementUtils
.findMergedAnnotation(method, TransactionalEventListener.class);
TransactionalEventListener annotation =
AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
if (annotation == null) {
throw new IllegalStateException("No TransactionalEventListener annotation found on '" + method + "'");
}
@ -97,7 +99,7 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
private final TransactionPhase phase;
protected TransactionSynchronizationEventAdapter(ApplicationListenerMethodAdapter listener,
public TransactionSynchronizationEventAdapter(ApplicationListenerMethodAdapter listener,
ApplicationEvent event, TransactionPhase phase) {
this.listener = listener;
@ -107,20 +109,20 @@ class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerM
@Override
public void beforeCommit(boolean readOnly) {
if (phase == TransactionPhase.BEFORE_COMMIT) {
if (this.phase == TransactionPhase.BEFORE_COMMIT) {
processEvent();
}
}
@Override
public void afterCompletion(int status) {
if (phase == TransactionPhase.AFTER_COMPLETION) {
if (this.phase == TransactionPhase.AFTER_COMPLETION) {
processEvent();
}
else if (phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
else if (this.phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
processEvent();
}
else if (phase == TransactionPhase.AFTER_ROLLBACK && status == STATUS_ROLLED_BACK) {
else if (this.phase == TransactionPhase.AFTER_ROLLBACK && status == STATUS_ROLLED_BACK) {
processEvent();
}
}

View File

@ -34,18 +34,20 @@ public class TransactionalEventListenerFactory implements EventListenerFactory,
private int order = 50;
@Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return order;
}
@Override
public boolean supportsMethod(Method method) {
return AnnotationUtils.findAnnotation(method, TransactionalEventListener.class) != null;
return (AnnotationUtils.findAnnotation(method, TransactionalEventListener.class) != null);
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 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.
@ -158,7 +158,6 @@ public class FacesWebRequest extends FacesRequestAttributes implements NativeWeb
/**
* Last-modified handling not supported for portlet requests:
* As a consequence, this method always returns {@code false}.
*
* @since 4.2
*/
@Override

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.
@ -165,7 +165,6 @@ public class PortletWebRequest extends PortletRequestAttributes implements Nativ
/**
* Last-modified handling not supported for portlet requests:
* As a consequence, this method always returns {@code false}.
*
* @since 4.2
*/
@Override

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.socket.messaging;
import org.springframework.messaging.Message;
@ -35,7 +36,6 @@ public class StompSubProtocolErrorHandler implements SubProtocolErrorHandler<byt
@Override
public Message<byte[]> handleClientMessageProcessingError(Message<byte[]> clientMessage, Throwable ex) {
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.ERROR);
accessor.setMessage(ex.getMessage());
accessor.setLeaveMutable(true);
@ -54,14 +54,11 @@ public class StompSubProtocolErrorHandler implements SubProtocolErrorHandler<byt
@Override
public Message<byte[]> handleErrorMessageToClient(Message<byte[]> errorMessage) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(errorMessage, StompHeaderAccessor.class);
Assert.notNull(accessor, "Expected STOMP headers.");
Assert.notNull(accessor, "Expected STOMP headers");
if (!accessor.isMutable()) {
accessor = StompHeaderAccessor.wrap(errorMessage);
}
return handleInternal(accessor, errorMessage.getPayload(), null, null);
}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.socket.messaging;
import org.springframework.messaging.Message;
@ -28,12 +29,10 @@ public interface SubProtocolErrorHandler<P> {
/**
* Handle errors thrown while processing client messages providing an
* opportunity to prepare the error message or to prevent one from being sent.
*
* <p>Note that the STOMP protocol requires a server to close the connection
* after sending an ERROR frame. To prevent an ERROR frame from being sent,
* a handler could return {@code null} and send a notification message
* through the broker instead, e.g. via a user destination.
*
* @param clientMessage the client message related to the error, possibly
* {@code null} if error occurred while parsing a WebSocket message
* @param ex the cause for the error, never {@code null}

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.socket.messaging;
import java.io.IOException;
@ -87,7 +88,6 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
* Class constructor. Sets {@link #setDefaultHeartbeat} to "0,0" but will
* reset it back to the preferred "10000,10000" when a
* {@link #setTaskScheduler} is configured.
*
* @param webSocketClient the WebSocket client to connect with
*/
public WebSocketStompClient(WebSocketClient webSocketClient) {
@ -302,13 +302,11 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
private final List<ScheduledFuture<?>> inactivityTasks = new ArrayList<ScheduledFuture<?>>(2);
public WebSocketTcpConnectionHandlerAdapter(TcpConnectionHandler<byte[]> connectionHandler) {
Assert.notNull(connectionHandler);
this.connectionHandler = connectionHandler;
}
// ListenableFutureCallback implementation: handshake outcome
@Override
@ -320,7 +318,6 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
this.connectionHandler.afterConnectFailure(ex);
}
// WebSocketHandler implementation
@Override
@ -375,7 +372,6 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
return false;
}
// TcpConnection implementation
@Override
@ -466,12 +462,10 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif
private final BufferingStompDecoder bufferingDecoder;
public StompWebSocketMessageCodec(int messageSizeLimit) {
this.bufferingDecoder = new BufferingStompDecoder(DECODER, messageSizeLimit);
}
public List<Message<byte[]>> decode(WebSocketMessage<?> webSocketMessage) {
List<Message<byte[]>> result = Collections.<Message<byte[]>>emptyList();
ByteBuffer byteBuffer;

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.socket.server.support;
import javax.servlet.ServletContext;

View File

@ -172,7 +172,7 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession {
}
/**
* @deprecated as of 4.2 this method is no longer used.
* @deprecated as of 4.2, since this method is no longer used.
*/
@Deprecated
protected abstract boolean isStreaming();

View File

@ -47,7 +47,7 @@ public abstract class StreamingSockJsSession extends AbstractHttpSockJsSession {
/**
* @deprecated as of 4.2 this method is no longer used.
* @deprecated as of 4.2, since this method is no longer used.
*/
@Override
@Deprecated
@ -61,6 +61,7 @@ public abstract class StreamingSockJsSession extends AbstractHttpSockJsSession {
*/
protected abstract byte[] getPrelude(ServerHttpRequest request);
@Override
protected void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response,
boolean initialRequest) throws IOException {
@ -84,15 +85,13 @@ public abstract class StreamingSockJsSession extends AbstractHttpSockJsSession {
SockJsFrame frame = SockJsFrame.messageFrame(messageCodec, message);
writeFrame(frame);
this.byteCount += frame.getContentBytes().length + 1;
this.byteCount += (frame.getContentBytes().length + 1);
if (logger.isTraceEnabled()) {
logger.trace(this.byteCount + " bytes written so far, "
+ getMessageCache().size() + " more messages not flushed");
logger.trace(this.byteCount + " bytes written so far, " +
getMessageCache().size() + " more messages not flushed");
}
if (this.byteCount >= getSockJsServiceConfig().getStreamBytesLimit()) {
if (logger.isTraceEnabled()) {
logger.trace("Streamed bytes limit reached. Recycling current request");
}
logger.trace("Streamed bytes limit reached, recycling current request");
resetRequest();
this.byteCount = 0;
break;