1 16 17 package org.springframework.jms.remoting; 18 19 import javax.jms.JMSException ; 20 import javax.jms.Message ; 21 import javax.jms.MessageFormatException ; 22 import javax.jms.ObjectMessage ; 23 import javax.jms.Queue ; 24 import javax.jms.QueueConnection ; 25 import javax.jms.QueueConnectionFactory ; 26 import javax.jms.QueueRequestor ; 27 import javax.jms.QueueSession ; 28 import javax.jms.Session ; 29 30 import org.aopalliance.intercept.MethodInterceptor; 31 import org.aopalliance.intercept.MethodInvocation; 32 33 import org.springframework.aop.support.AopUtils; 34 import org.springframework.beans.factory.InitializingBean; 35 import org.springframework.jms.connection.ConnectionFactoryUtils; 36 import org.springframework.jms.support.JmsUtils; 37 import org.springframework.jms.support.destination.DestinationResolver; 38 import org.springframework.jms.support.destination.DynamicDestinationResolver; 39 import org.springframework.remoting.RemoteAccessException; 40 import org.springframework.remoting.support.DefaultRemoteInvocationFactory; 41 import org.springframework.remoting.support.RemoteInvocation; 42 import org.springframework.remoting.support.RemoteInvocationFactory; 43 import org.springframework.remoting.support.RemoteInvocationResult; 44 import org.springframework.util.Assert; 45 46 61 public class JmsInvokerClientInterceptor implements MethodInterceptor, InitializingBean { 62 63 private QueueConnectionFactory connectionFactory; 64 65 private Object queue; 66 67 private DestinationResolver destinationResolver = new DynamicDestinationResolver(); 68 69 private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory(); 70 71 72 75 public void setConnectionFactory(QueueConnectionFactory connectionFactory) { 76 this.connectionFactory = connectionFactory; 77 } 78 79 82 protected QueueConnectionFactory getConnectionFactory() { 83 return this.connectionFactory; 84 } 85 86 89 public void setQueue(Object queue) { 90 this.queue = queue; 91 } 92 93 96 public void setQueueName(String queueName) { 97 this.queue = queueName; 98 } 99 100 109 public void setDestinationResolver(DestinationResolver destinationResolver) { 110 Assert.notNull(destinationResolver, "DestinationResolver must not be null"); 111 this.destinationResolver = destinationResolver; 112 } 113 114 120 public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) { 121 this.remoteInvocationFactory = remoteInvocationFactory; 122 } 123 124 125 public void afterPropertiesSet() { 126 if (getConnectionFactory() == null) { 127 throw new IllegalArgumentException ("connectionFactory is required"); 128 } 129 if (this.queue == null) { 130 throw new IllegalArgumentException ("'queue' or 'queueName' is required"); 131 } 132 } 133 134 135 public Object invoke(MethodInvocation methodInvocation) throws Throwable { 136 if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { 137 return "JMS invoker proxy for queue [" + this.queue + "]"; 138 } 139 140 RemoteInvocation invocation = createRemoteInvocation(methodInvocation); 141 RemoteInvocationResult result = null; 142 try { 143 result = executeRequest(invocation); 144 } 145 catch (JMSException ex) { 146 throw new RemoteAccessException("Cannot access JMS invoker queue [" + this.queue + "]", ex); 147 } 148 return recreateRemoteInvocationResult(result); 149 } 150 151 162 protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { 163 return this.remoteInvocationFactory.createRemoteInvocation(methodInvocation); 164 } 165 166 175 protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException { 176 QueueConnection con = getConnectionFactory().createQueueConnection(); 177 QueueSession session = null; 178 QueueRequestor requestor = null; 179 try { 180 session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 181 Queue queueToUse = resolveQueue(session); 182 Message requestMessage = createRequestMessage(session, invocation); 183 requestor = new QueueRequestor (session, queueToUse); 184 con.start(); 185 Message responseMessage = requestor.request(requestMessage); 186 return extractInvocationResult(responseMessage); 187 } 188 finally { 189 JmsUtils.closeQueueRequestor(requestor); 190 JmsUtils.closeSession(session); 191 ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), true); 192 } 193 } 194 195 201 protected Queue resolveQueue(Session session) throws JMSException { 202 if (this.queue instanceof Queue ) { 203 return (Queue ) queue; 204 } 205 else if (this.queue instanceof String ) { 206 return resolveQueueName(session, (String ) this.queue); 207 } 208 else { 209 throw new javax.jms.IllegalStateException ( 210 "Queue object [" + this.queue + "] is neither a [javax.jms.Queue] nor a queue name String"); 211 } 212 } 213 214 223 protected Queue resolveQueueName(Session session, String queueName) throws JMSException { 224 return (Queue ) this.destinationResolver.resolveDestinationName(session, queueName, false); 225 } 226 227 235 protected Message createRequestMessage(Session session, RemoteInvocation invocation) throws JMSException { 236 return session.createObjectMessage(invocation); 237 } 238 239 249 protected RemoteInvocationResult extractInvocationResult(Message responseMessage) throws JMSException { 250 if (responseMessage instanceof ObjectMessage ) { 251 ObjectMessage objectMessage = (ObjectMessage ) responseMessage; 252 Object body = objectMessage.getObject(); 253 if (body instanceof RemoteInvocationResult) { 254 return (RemoteInvocationResult) body; 255 } 256 } 257 return onInvalidResponse(responseMessage); 258 } 259 260 271 protected RemoteInvocationResult onInvalidResponse(Message responseMessage) throws JMSException { 272 throw new MessageFormatException ("Invalid response message: " + responseMessage); 273 } 274 275 285 protected Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws Throwable { 286 return result.recreate(); 287 } 288 289 } 290 | Popular Tags |