summaryrefslogtreecommitdiff
path: root/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java
diff options
context:
space:
mode:
Diffstat (limited to 'spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java')
-rw-r--r--spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java106
1 files changed, 94 insertions, 12 deletions
diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java
index 10ae1cf8..2f53f57e 100644
--- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java
+++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,8 +36,10 @@ import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessagingMessageConverter;
import org.springframework.jms.support.converter.SimpleMessageConverter;
+import org.springframework.jms.support.converter.SmartMessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.jms.support.destination.DynamicDestinationResolver;
+import org.springframework.messaging.MessageHeaders;
import org.springframework.util.Assert;
/**
@@ -269,14 +271,17 @@ public abstract class AbstractAdaptableMessageListener
* @see #setMessageConverter
*/
protected Message buildMessage(Session session, Object result) throws JMSException {
- Object content = (result instanceof JmsResponse ? ((JmsResponse<?>) result).getResponse() : result);
- if (content instanceof org.springframework.messaging.Message) {
- return this.messagingMessageConverter.toMessage(content, session);
- }
+ Object content = preProcessResponse(result instanceof JmsResponse
+ ? ((JmsResponse<?>) result).getResponse() : result);
MessageConverter converter = getMessageConverter();
if (converter != null) {
- return converter.toMessage(content, session);
+ if (content instanceof org.springframework.messaging.Message) {
+ return this.messagingMessageConverter.toMessage(content, session);
+ }
+ else {
+ return converter.toMessage(content, session);
+ }
}
if (!(content instanceof Message)) {
@@ -287,6 +292,17 @@ public abstract class AbstractAdaptableMessageListener
}
/**
+ * Pre-process the given result before it is converted to a {@link Message}.
+ * @param result the result of the invocation
+ * @return the payload response to handle, either the {@code result} argument
+ * or any other object (for instance wrapping the result).
+ * @since 4.3
+ */
+ protected Object preProcessResponse(Object result) {
+ return result;
+ }
+
+ /**
* Post-process the given response message before it will be sent.
* <p>The default implementation sets the response's correlation id
* to the request message's correlation id, if any; otherwise to the
@@ -402,11 +418,21 @@ public abstract class AbstractAdaptableMessageListener
/**
- * Delegates payload extraction to {@link #extractMessage(javax.jms.Message)} to
- * enforce backward compatibility.
+ * A {@link MessagingMessageConverter} that lazily invoke payload extraction and
+ * delegate it to {@link #extractMessage(javax.jms.Message)} in order to enforce
+ * backward compatibility.
*/
private class MessagingMessageConverterAdapter extends MessagingMessageConverter {
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException {
+ if (message == null) {
+ return null;
+ }
+ return new LazyResolutionMessage(message);
+ }
+
@Override
protected Object extractPayload(Message message) throws JMSException {
Object payload = extractMessage(message);
@@ -425,13 +451,69 @@ public abstract class AbstractAdaptableMessageListener
}
@Override
- protected Message createMessageForPayload(Object payload, Session session) throws JMSException {
+ protected Message createMessageForPayload(Object payload, Session session, Object conversionHint)
+ throws JMSException {
MessageConverter converter = getMessageConverter();
- if (converter != null) {
- return converter.toMessage(payload, session);
+ if (converter == null) {
+ throw new IllegalStateException("No message converter, cannot handle '" + payload + "'");
}
- throw new IllegalStateException("No message converter - cannot handle [" + payload + "]");
+ if (converter instanceof SmartMessageConverter) {
+ return ((SmartMessageConverter) converter).toMessage(payload, session, conversionHint);
+
+ }
+ return converter.toMessage(payload, session);
}
+
+ protected class LazyResolutionMessage implements org.springframework.messaging.Message<Object> {
+
+ private final javax.jms.Message message;
+
+ private Object payload;
+
+ private MessageHeaders headers;
+
+ public LazyResolutionMessage(javax.jms.Message message) {
+ this.message = message;
+ }
+
+ @Override
+ public Object getPayload() {
+ if (this.payload == null) {
+ try {
+ this.payload = unwrapPayload();
+ }
+ catch (JMSException ex) {
+ throw new MessageConversionException(
+ "Failed to extract payload from [" + this.message + "]", ex);
+ }
+ }
+ //
+ return this.payload;
+ }
+
+ /**
+ * Extract the payload of the current message. Since we deferred the resolution
+ * of the payload, a custom converter may still return a full message for it. In
+ * this case, its payload is returned.
+ * @return the payload of the message
+ */
+ private Object unwrapPayload() throws JMSException {
+ Object payload = extractPayload(this.message);
+ if (payload instanceof org.springframework.messaging.Message) {
+ return ((org.springframework.messaging.Message) payload).getPayload();
+ }
+ return payload;
+ }
+
+ @Override
+ public MessageHeaders getHeaders() {
+ if (this.headers == null) {
+ this.headers = extractHeaders(this.message);
+ }
+ return this.headers;
+ }
+ }
+
}