11/*
2- * Copyright 2002-2015 the original author or authors.
2+ * Copyright 2002-2016 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1616
1717package org .springframework .jms .connection ;
1818
19- import java .lang .reflect .InvocationHandler ;
20- import java .lang .reflect .InvocationTargetException ;
21- import java .lang .reflect .Method ;
22- import java .lang .reflect .Proxy ;
19+ import javax .jms .CompletionListener ;
2320import javax .jms .Destination ;
2421import javax .jms .JMSException ;
2522import javax .jms .Message ;
2926import javax .jms .Topic ;
3027import javax .jms .TopicPublisher ;
3128
32- import org .springframework .util .ClassUtils ;
33- import org .springframework .util .ReflectionUtils ;
34-
3529/**
3630 * JMS MessageProducer decorator that adapts calls to a shared MessageProducer
3731 * instance underneath, managing QoS settings locally within the decorator.
4135 */
4236class CachedMessageProducer implements MessageProducer , QueueSender , TopicPublisher {
4337
44- // Various JMS 2.0 MessageProducer methods, if available
45-
46- private static final Method setDeliveryDelayMethod =
47- ClassUtils .getMethodIfAvailable (MessageProducer .class , "setDeliveryDelay" , long .class );
48-
49- private static final Method getDeliveryDelayMethod =
50- ClassUtils .getMethodIfAvailable (MessageProducer .class , "getDeliveryDelay" );
51-
52- private static Class <?> completionListenerClass ;
53-
54- private static Method sendWithCompletionListenerMethod ;
55-
56- private static Method sendWithDestinationAndCompletionListenerMethod ;
57-
58- static {
59- try {
60- completionListenerClass = ClassUtils .forName (
61- "javax.jms.CompletionListener" , CachedMessageProducer .class .getClassLoader ());
62- sendWithCompletionListenerMethod = MessageProducer .class .getMethod (
63- "send" , Message .class , int .class , int .class , long .class , completionListenerClass );
64- sendWithDestinationAndCompletionListenerMethod = MessageProducer .class .getMethod (
65- "send" , Destination .class , Message .class , int .class , int .class , long .class , completionListenerClass );
66- }
67- catch (Exception ex ) {
68- // No JMS 2.0 API available
69- completionListenerClass = null ;
70- }
71- }
72-
73-
7438 private final MessageProducer target ;
7539
7640 private Boolean originalDisableMessageID ;
@@ -120,15 +84,15 @@ public boolean getDisableMessageTimestamp() throws JMSException {
12084 return this .target .getDisableMessageTimestamp ();
12185 }
12286
123- public void setDeliveryDelay (long deliveryDelay ) {
87+ public void setDeliveryDelay (long deliveryDelay ) throws JMSException {
12488 if (this .originalDeliveryDelay == null ) {
125- this .originalDeliveryDelay = ( Long ) ReflectionUtils . invokeMethod ( getDeliveryDelayMethod , this .target );
89+ this .originalDeliveryDelay = this .target . getDeliveryDelay ( );
12690 }
127- ReflectionUtils . invokeMethod ( setDeliveryDelayMethod , this .target , deliveryDelay );
91+ this .target . setDeliveryDelay ( deliveryDelay );
12892 }
12993
130- public long getDeliveryDelay () {
131- return ( Long ) ReflectionUtils . invokeMethod ( getDeliveryDelayMethod , this .target );
94+ public long getDeliveryDelay () throws JMSException {
95+ return this .target . getDeliveryDelay ( );
13296 }
13397
13498 @ Override
@@ -196,6 +160,31 @@ public void send(Destination destination, Message message, int deliveryMode, int
196160 this .target .send (destination , message , deliveryMode , priority , timeToLive );
197161 }
198162
163+ @ Override
164+ public void send (Message message , CompletionListener completionListener ) throws JMSException {
165+ this .target .send (message , this .deliveryMode , this .priority , this .timeToLive , completionListener );
166+ }
167+
168+ @ Override
169+ public void send (Message message , int deliveryMode , int priority , long timeToLive ,
170+ CompletionListener completionListener ) throws JMSException {
171+
172+ this .target .send (message , deliveryMode , priority , timeToLive , completionListener );
173+ }
174+
175+ @ Override
176+ public void send (Destination destination , Message message , CompletionListener completionListener ) throws JMSException {
177+ this .target .send (destination , message , this .deliveryMode , this .priority , this .timeToLive , completionListener );
178+ }
179+
180+ @ Override
181+ public void send (Destination destination , Message message , int deliveryMode , int priority ,
182+ long timeToLive , CompletionListener completionListener ) throws JMSException {
183+
184+ this .target .send (destination , message , deliveryMode , priority , timeToLive , completionListener );
185+
186+ }
187+
199188 @ Override
200189 public void send (Queue queue , Message message ) throws JMSException {
201190 this .target .send (queue , message , this .deliveryMode , this .priority , this .timeToLive );
@@ -238,7 +227,7 @@ public void close() throws JMSException {
238227 this .originalDisableMessageTimestamp = null ;
239228 }
240229 if (this .originalDeliveryDelay != null ) {
241- ReflectionUtils . invokeMethod ( setDeliveryDelayMethod , this .target , this .originalDeliveryDelay );
230+ this .target . setDeliveryDelay ( this .originalDeliveryDelay );
242231 this .originalDeliveryDelay = null ;
243232 }
244233 }
@@ -248,54 +237,4 @@ public String toString() {
248237 return "Cached JMS MessageProducer: " + this .target ;
249238 }
250239
251-
252- /**
253- * Build a dynamic proxy that reflectively adapts to JMS 2.0 API methods, if necessary.
254- * Otherwise simply return this CachedMessageProducer instance itself.
255- */
256- public MessageProducer getProxyIfNecessary () {
257- if (completionListenerClass != null ) {
258- return (MessageProducer ) Proxy .newProxyInstance (CachedMessageProducer .class .getClassLoader (),
259- new Class <?>[] {MessageProducer .class , QueueSender .class , TopicPublisher .class },
260- new Jms2MessageProducerInvocationHandler ());
261- }
262- else {
263- return this ;
264- }
265- }
266-
267-
268- /**
269- * Reflective InvocationHandler which adapts to JMS 2.0 API methods that we
270- * cannot statically compile against while preserving JMS 1.1 compatibility
271- * (due to the new {@code javax.jms.CompletionListener} type in the signatures).
272- */
273- private class Jms2MessageProducerInvocationHandler implements InvocationHandler {
274-
275- @ Override
276- public Object invoke (Object proxy , Method method , Object [] args ) throws Throwable {
277- try {
278- if (method .getName ().equals ("send" ) && args != null &&
279- completionListenerClass == method .getParameterTypes ()[args .length - 1 ]) {
280- switch (args .length ) {
281- case 2 : // send(message, completionListener)
282- return sendWithCompletionListenerMethod .invoke (
283- target , args [0 ], deliveryMode , priority , timeToLive , args [1 ]);
284- case 3 : // send(destination, message, completionListener)
285- return sendWithDestinationAndCompletionListenerMethod .invoke (
286- target , args [0 ], args [1 ], deliveryMode , priority , timeToLive , args [2 ]);
287- case 5 : // send(message, deliveryMode, priority, timeToLive, completionListener)
288- return sendWithCompletionListenerMethod .invoke (target , args );
289- case 6 : // send(destination, message, deliveryMode, priority, timeToLive, completionListener)
290- return sendWithDestinationAndCompletionListenerMethod .invoke (target , args );
291- }
292- }
293- return method .invoke (CachedMessageProducer .this , args );
294- }
295- catch (InvocationTargetException ex ) {
296- throw ex .getTargetException ();
297- }
298- }
299- }
300-
301240}
0 commit comments