Source Code Cross Referenced for JmsInvokerClientInterceptor.java in  » J2EE » spring-framework-2.0.6 » org » springframework » jms » remoting » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.jms.remoting 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.jms.remoting;
018:
019:        import javax.jms.JMSException;
020:        import javax.jms.Message;
021:        import javax.jms.MessageFormatException;
022:        import javax.jms.Queue;
023:        import javax.jms.QueueConnection;
024:        import javax.jms.QueueConnectionFactory;
025:        import javax.jms.QueueRequestor;
026:        import javax.jms.QueueSession;
027:        import javax.jms.Session;
028:
029:        import org.aopalliance.intercept.MethodInterceptor;
030:        import org.aopalliance.intercept.MethodInvocation;
031:
032:        import org.springframework.aop.support.AopUtils;
033:        import org.springframework.beans.factory.InitializingBean;
034:        import org.springframework.jms.connection.ConnectionFactoryUtils;
035:        import org.springframework.jms.support.JmsUtils;
036:        import org.springframework.jms.support.converter.MessageConverter;
037:        import org.springframework.jms.support.converter.SimpleMessageConverter;
038:        import org.springframework.jms.support.destination.DestinationResolver;
039:        import org.springframework.jms.support.destination.DynamicDestinationResolver;
040:        import org.springframework.remoting.RemoteAccessException;
041:        import org.springframework.remoting.support.DefaultRemoteInvocationFactory;
042:        import org.springframework.remoting.support.RemoteInvocation;
043:        import org.springframework.remoting.support.RemoteInvocationFactory;
044:        import org.springframework.remoting.support.RemoteInvocationResult;
045:
046:        /**
047:         * Interceptor for accessing a JMS-based remote service.
048:         *
049:         * <p>Serializes remote invocation objects and deserializes remote invocation
050:         * result objects. Uses Java serialization just like RMI, but with the JMS
051:         * provider as communication infrastructure.
052:         *
053:         * <p>To be configured with a {@link javax.jms.QueueConnectionFactory} and a
054:         * target queue (either as {@link javax.jms.Queue} reference or as queue name).
055:         *
056:         * <p>Thanks to James Strachan for the original prototype that this
057:         * JMS invoker mechanism was inspired by!
058:         *
059:         * @author Juergen Hoeller
060:         * @author James Strachan
061:         * @since 2.0
062:         * @see #setConnectionFactory
063:         * @see #setQueue
064:         * @see #setQueueName
065:         * @see org.springframework.jms.remoting.JmsInvokerServiceExporter
066:         * @see org.springframework.jms.remoting.JmsInvokerProxyFactoryBean
067:         */
068:        public class JmsInvokerClientInterceptor implements  MethodInterceptor,
069:                InitializingBean {
070:
071:            private QueueConnectionFactory connectionFactory;
072:
073:            private Object queue;
074:
075:            private DestinationResolver destinationResolver = new DynamicDestinationResolver();
076:
077:            private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory();
078:
079:            private MessageConverter messageConverter = new SimpleMessageConverter();
080:
081:            /**
082:             * Set the QueueConnectionFactory to use for obtaining JMS QueueConnections.
083:             */
084:            public void setConnectionFactory(
085:                    QueueConnectionFactory connectionFactory) {
086:                this .connectionFactory = connectionFactory;
087:            }
088:
089:            /**
090:             * Return the QueueConnectionFactory to use for obtaining JMS QueueConnections.
091:             */
092:            protected QueueConnectionFactory getConnectionFactory() {
093:                return this .connectionFactory;
094:            }
095:
096:            /**
097:             * Set the target Queue to send invoker requests to.
098:             */
099:            public void setQueue(Queue queue) {
100:                this .queue = queue;
101:            }
102:
103:            /**
104:             * Set the name of target queue to send invoker requests to.
105:             * The specified name will be dynamically resolved via the
106:             * {@link #setDestinationResolver DestinationResolver}.
107:             */
108:            public void setQueueName(String queueName) {
109:                this .queue = queueName;
110:            }
111:
112:            /**
113:             * Set the DestinationResolver that is to be used to resolve Queue
114:             * references for this accessor.
115:             * <p>The default resolver is a DynamicDestinationResolver. Specify a
116:             * JndiDestinationResolver for resolving destination names as JNDI locations.
117:             * @see org.springframework.jms.support.destination.DynamicDestinationResolver
118:             * @see org.springframework.jms.support.destination.JndiDestinationResolver
119:             */
120:            public void setDestinationResolver(
121:                    DestinationResolver destinationResolver) {
122:                this .destinationResolver = (destinationResolver != null ? destinationResolver
123:                        : new DynamicDestinationResolver());
124:            }
125:
126:            /**
127:             * Set the RemoteInvocationFactory to use for this accessor.
128:             * Default is a {@link org.springframework.remoting.support.DefaultRemoteInvocationFactory}.
129:             * <p>A custom invocation factory can add further context information
130:             * to the invocation, for example user credentials.
131:             */
132:            public void setRemoteInvocationFactory(
133:                    RemoteInvocationFactory remoteInvocationFactory) {
134:                this .remoteInvocationFactory = (remoteInvocationFactory != null ? remoteInvocationFactory
135:                        : new DefaultRemoteInvocationFactory());
136:            }
137:
138:            /**
139:             * Specify the MessageConverter to use for turning
140:             * {@link org.springframework.remoting.support.RemoteInvocation}
141:             * objects into request messages, as well as response messages into
142:             * {@link org.springframework.remoting.support.RemoteInvocationResult} objects.
143:             * <p>Default is a {@link org.springframework.jms.support.converter.SimpleMessageConverter},
144:             * using a standard JMS {@link javax.jms.ObjectMessage} for each invocation /
145:             * invocation result object.
146:             * <p>Custom implementations may generally adapt Serializables into
147:             * special kinds of messages, or might be specifically tailored for
148:             * translating RemoteInvocation(Result)s into specific kinds of messages.
149:             */
150:            public void setMessageConverter(MessageConverter messageConverter) {
151:                this .messageConverter = (messageConverter != null ? messageConverter
152:                        : new SimpleMessageConverter());
153:            }
154:
155:            public void afterPropertiesSet() {
156:                if (getConnectionFactory() == null) {
157:                    throw new IllegalArgumentException(
158:                            "Property 'connectionFactory' is required");
159:                }
160:                if (this .queue == null) {
161:                    throw new IllegalArgumentException(
162:                            "'queue' or 'queueName' is required");
163:                }
164:            }
165:
166:            public Object invoke(MethodInvocation methodInvocation)
167:                    throws Throwable {
168:                if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
169:                    return "JMS invoker proxy for queue [" + this .queue + "]";
170:                }
171:
172:                RemoteInvocation invocation = createRemoteInvocation(methodInvocation);
173:                RemoteInvocationResult result = null;
174:                try {
175:                    result = executeRequest(invocation);
176:                } catch (JMSException ex) {
177:                    throw new RemoteAccessException(
178:                            "Cannot access JMS invoker queue [" + this .queue
179:                                    + "]", ex);
180:                }
181:                return recreateRemoteInvocationResult(result);
182:            }
183:
184:            /**
185:             * Create a new RemoteInvocation object for the given AOP method invocation.
186:             * The default implementation delegates to the RemoteInvocationFactory.
187:             * <p>Can be overridden in subclasses to provide custom RemoteInvocation
188:             * subclasses, containing additional invocation parameters like user credentials.
189:             * Note that it is preferable to use a custom RemoteInvocationFactory which
190:             * is a reusable strategy.
191:             * @param methodInvocation the current AOP method invocation
192:             * @return the RemoteInvocation object
193:             * @see RemoteInvocationFactory#createRemoteInvocation
194:             */
195:            protected RemoteInvocation createRemoteInvocation(
196:                    MethodInvocation methodInvocation) {
197:                return this .remoteInvocationFactory
198:                        .createRemoteInvocation(methodInvocation);
199:            }
200:
201:            /**
202:             * Execute the given remote invocation, sending an invoker request message
203:             * to this accessor's target queue and waiting for a corresponding response.
204:             * @param invocation the RemoteInvocation to execute
205:             * @return the RemoteInvocationResult object
206:             * @throws JMSException in case of JMS failure
207:             * @see #doExecuteRequest
208:             */
209:            protected RemoteInvocationResult executeRequest(
210:                    RemoteInvocation invocation) throws JMSException {
211:                QueueConnection con = getConnectionFactory()
212:                        .createQueueConnection();
213:                QueueSession session = null;
214:                QueueRequestor requestor = null;
215:                try {
216:                    session = con.createQueueSession(false,
217:                            Session.AUTO_ACKNOWLEDGE);
218:                    Queue queueToUse = resolveQueue(session);
219:                    Message requestMessage = createRequestMessage(session,
220:                            invocation);
221:                    con.start();
222:                    Message responseMessage = doExecuteRequest(session,
223:                            queueToUse, requestMessage);
224:                    return extractInvocationResult(responseMessage);
225:                } finally {
226:                    JmsUtils.closeQueueRequestor(requestor);
227:                    JmsUtils.closeSession(session);
228:                    ConnectionFactoryUtils.releaseConnection(con,
229:                            getConnectionFactory(), true);
230:                }
231:            }
232:
233:            /**
234:             * Resolve this accessor's target queue.
235:             * @param session the current JMS Session
236:             * @return the resolved target Queue
237:             * @throws JMSException if resolution failed
238:             */
239:            protected Queue resolveQueue(Session session) throws JMSException {
240:                if (this .queue instanceof  Queue) {
241:                    return (Queue) this .queue;
242:                } else if (this .queue instanceof  String) {
243:                    return resolveQueueName(session, (String) this .queue);
244:                } else {
245:                    throw new javax.jms.IllegalStateException(
246:                            "Queue object ["
247:                                    + this .queue
248:                                    + "] is neither a [javax.jms.Queue] nor a queue name String");
249:                }
250:            }
251:
252:            /**
253:             * Resolve the given queue name into a JMS {@link javax.jms.Queue},
254:             * via this accessor's {@link DestinationResolver}.
255:             * @param session the current JMS Session
256:             * @param queueName the name of the queue
257:             * @return the located Queue
258:             * @throws JMSException if resolution failed
259:             * @see #setDestinationResolver
260:             */
261:            protected Queue resolveQueueName(Session session, String queueName)
262:                    throws JMSException {
263:                return (Queue) this .destinationResolver.resolveDestinationName(
264:                        session, queueName, false);
265:            }
266:
267:            /**
268:             * Create the invoker request message.
269:             * <p>The default implementation creates a JMS ObjectMessage
270:             * for the given RemoteInvocation object.
271:             * @param session the current JMS Session
272:             * @param invocation the remote invocation to send
273:             * @return the JMS Message to send
274:             * @throws JMSException if the message could not be created
275:             */
276:            protected Message createRequestMessage(Session session,
277:                    RemoteInvocation invocation) throws JMSException {
278:                return this .messageConverter.toMessage(invocation, session);
279:            }
280:
281:            /**
282:             * Actually execute the given request, sending the invoker request message
283:             * to the specified target queue and waiting for a corresponding response.
284:             * <p>The default implementation is based on a standard JMS
285:             * {@link javax.jms.QueueRequestor}, using a freshly obtained JMS Session.
286:             * @param session the JMS Session to use
287:             * @param queue the resolved target Queue to send to
288:             * @param requestMessage the JMS Message to send
289:             * @return the RemoteInvocationResult object
290:             * @throws JMSException in case of JMS failure
291:             */
292:            protected Message doExecuteRequest(QueueSession session,
293:                    Queue queue, Message requestMessage) throws JMSException {
294:
295:                QueueRequestor requestor = new QueueRequestor(session, queue);
296:                return requestor.request(requestMessage);
297:            }
298:
299:            /**
300:             * Extract the invocation result from the response message.
301:             * <p>The default implementation expects a JMS ObjectMessage carrying
302:             * a RemoteInvocationResult object. If an invalid response message is
303:             * encountered, the <code>onInvalidResponse</code> callback gets invoked.
304:             * @param responseMessage the response message
305:             * @return the invocation result
306:             * @throws JMSException is thrown if a JMS exception occurs
307:             * @see #onInvalidResponse
308:             */
309:            protected RemoteInvocationResult extractInvocationResult(
310:                    Message responseMessage) throws JMSException {
311:                Object content = this .messageConverter
312:                        .fromMessage(responseMessage);
313:                if (content instanceof  RemoteInvocationResult) {
314:                    return (RemoteInvocationResult) content;
315:                }
316:                return onInvalidResponse(responseMessage);
317:            }
318:
319:            /**
320:             * Callback that is invoked by <code>extractInvocationResult</code>
321:             * when it encounters an invalid response message.
322:             * <p>The default implementation throws a MessageFormatException.
323:             * @param responseMessage the invalid response message
324:             * @return an alternative invocation result that should be
325:             * returned to the caller (if desired)
326:             * @throws JMSException if the invalid response should lead
327:             * to an infrastructure exception propagated to the caller
328:             * @see #extractInvocationResult
329:             */
330:            protected RemoteInvocationResult onInvalidResponse(
331:                    Message responseMessage) throws JMSException {
332:                throw new MessageFormatException("Invalid response message: "
333:                        + responseMessage);
334:            }
335:
336:            /**
337:             * Recreate the invocation result contained in the given RemoteInvocationResult
338:             * object. The default implementation calls the default recreate method.
339:             * <p>Can be overridden in subclass to provide custom recreation, potentially
340:             * processing the returned result object.
341:             * @param result the RemoteInvocationResult to recreate
342:             * @return a return value if the invocation result is a successful return
343:             * @throws Throwable if the invocation result is an exception
344:             * @see org.springframework.remoting.support.RemoteInvocationResult#recreate()
345:             */
346:            protected Object recreateRemoteInvocationResult(
347:                    RemoteInvocationResult result) throws Throwable {
348:                return result.recreate();
349:            }
350:
351:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.