KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jms > remoting > JmsInvokerServiceExporter


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.jms.remoting;
18
19 import javax.jms.JMSException JavaDoc;
20 import javax.jms.Message JavaDoc;
21 import javax.jms.MessageFormatException JavaDoc;
22 import javax.jms.MessageProducer JavaDoc;
23 import javax.jms.ObjectMessage JavaDoc;
24 import javax.jms.Session JavaDoc;
25
26 import org.springframework.beans.factory.InitializingBean;
27 import org.springframework.jms.listener.SessionAwareMessageListener;
28 import org.springframework.jms.support.JmsUtils;
29 import org.springframework.remoting.support.RemoteInvocation;
30 import org.springframework.remoting.support.RemoteInvocationBasedExporter;
31 import org.springframework.remoting.support.RemoteInvocationResult;
32
33 /**
34  * JMS MessageListener that exports the specified service bean as a
35  * JMS service endpoint, accessible via a JMS invoker proxy.
36  *
37  * @author Juergen Hoeller
38  * @author James Strachan
39  * @since 2.0
40  * @see JmsInvokerClientInterceptor
41  * @see JmsInvokerProxyFactoryBean
42  */

43 public class JmsInvokerServiceExporter extends RemoteInvocationBasedExporter
44         implements SessionAwareMessageListener, InitializingBean {
45
46     private boolean ignoreInvalidRequests = true;
47
48     private Object JavaDoc proxy;
49
50
51     /**
52      * Set whether invalidly formatted messages should be discarded.
53      * Default is "true".
54      * <p>Switch this flag to "false" to throw an exception back to the
55      * listener container. This will typically lead to redelivery of
56      * the message, which is usually undesirable - since the message
57      * content will be the same (that is, still invalid).
58      */

59     public void setIgnoreInvalidRequests(boolean ignoreInvalidRequests) {
60         this.ignoreInvalidRequests = ignoreInvalidRequests;
61     }
62
63     public void afterPropertiesSet() {
64         this.proxy = getProxyForService();
65     }
66
67
68     public void onMessage(Message JavaDoc requestMessage, Session JavaDoc session) throws JMSException JavaDoc {
69         RemoteInvocation invocation = readRemoteInvocation(requestMessage);
70         if (invocation != null) {
71             RemoteInvocationResult result = invokeAndCreateResult(invocation, this.proxy);
72             writeRemoteInvocationResult(requestMessage, session, result);
73         }
74     }
75
76     /**
77      * Read a RemoteInvocation from the given JMS message.
78      * @param requestMessage current request message
79      * @return the RemoteInvocation object
80      */

81     protected RemoteInvocation readRemoteInvocation(Message JavaDoc requestMessage) throws JMSException JavaDoc {
82         if (requestMessage instanceof ObjectMessage JavaDoc) {
83             ObjectMessage JavaDoc objectMessage = (ObjectMessage JavaDoc) requestMessage;
84             Object JavaDoc body = objectMessage.getObject();
85             if (body instanceof RemoteInvocation) {
86                 return (RemoteInvocation) body;
87             }
88         }
89         return onInvalidRequest(requestMessage);
90     }
91
92
93     /**
94      * Send the given RemoteInvocationResult as a JMS message to the originator.
95      * @param requestMessage current request message
96      * @param session the JMS Session to use
97      * @param result the RemoteInvocationResult object
98      * @throws javax.jms.JMSException if thrown by trying to send the message
99      */

100     protected void writeRemoteInvocationResult(
101             Message JavaDoc requestMessage, Session JavaDoc session, RemoteInvocationResult result) throws JMSException JavaDoc {
102
103         Message JavaDoc response = createResponseMessage(requestMessage, session, result);
104         MessageProducer JavaDoc producer = session.createProducer(requestMessage.getJMSReplyTo());
105         try {
106             producer.send(response);
107         }
108         finally {
109             JmsUtils.closeMessageProducer(producer);
110         }
111     }
112
113     /**
114      * Create the invocation result response message.
115      * <p>The default implementation creates a JMS ObjectMessage
116      * for the given RemoteInvocationResult object.
117      * @param requestMessage the original request message
118      * @param session the JMS session to use
119      * @param result the invocation result
120      * @return the message response to send
121      * @throws javax.jms.JMSException if creating the messsage failed
122      */

123     protected Message JavaDoc createResponseMessage(Message JavaDoc requestMessage, Session JavaDoc session, RemoteInvocationResult result)
124             throws JMSException JavaDoc {
125
126         // An alternative strategy could be to use XStream and text messages.
127
// Though some JMS providers, like ActiveMQ, might do this kind of thing for us under the covers.
128
ObjectMessage JavaDoc response = session.createObjectMessage(result);
129
130         // Let's preserve the correlation ID.
131
response.setJMSCorrelationID(requestMessage.getJMSCorrelationID());
132
133         return response;
134     }
135
136     /**
137      * Callback that is invoked by <code>readRemoteInvocation</code>
138      * when it encounters an invalid request message.
139      * <p>The default implementation either discards the invalid message or
140      * throws a MessageFormatException - according to the "ignoreInvalidRequests"
141      * flag, which is set to "true" (that is, discard invalid messages) by default.
142      * @param requestMessage the invalid request message
143      * @see #readRemoteInvocation
144      * @see #setIgnoreInvalidRequests
145      */

146     protected RemoteInvocation onInvalidRequest(Message JavaDoc requestMessage) throws JMSException JavaDoc {
147         if (this.ignoreInvalidRequests) {
148             if (logger.isWarnEnabled()) {
149                 logger.warn("Invalid request message will be discarded: " + requestMessage);
150             }
151             return null;
152         }
153         else {
154             throw new MessageFormatException JavaDoc("Invalid request message: " + requestMessage);
155         }
156     }
157
158 }
159
Popular Tags