View Javadoc

1   /*
2    * Copyright 2007 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.ws.transport.jms;
18  
19  import javax.ejb.EJBException;
20  import javax.ejb.MessageDrivenBean;
21  import javax.jms.Connection;
22  import javax.jms.ConnectionFactory;
23  import javax.jms.JMSException;
24  import javax.jms.Message;
25  import javax.jms.Session;
26  import javax.naming.NamingException;
27  
28  import org.springframework.ejb.support.AbstractJmsMessageDrivenBean;
29  import org.springframework.jms.connection.ConnectionFactoryUtils;
30  import org.springframework.jms.support.JmsUtils;
31  import org.springframework.jndi.JndiLookupFailureException;
32  import org.springframework.ws.WebServiceMessageFactory;
33  import org.springframework.ws.transport.WebServiceMessageReceiver;
34  
35  /**
36   * EJB {@link MessageDrivenBean} that can be used to handleMessage incoming JMS messages.
37   * <p/>
38   * This class needs a JMS {@link ConnectionFactory}, a {@link WebServiceMessageFactory} and {@link
39   * WebServiceMessageReceiver} to operate. By default, these are obtained by doing a bean lookup on the bean factory
40   * provided by {@link #getBeanFactory()} the super class.
41   *
42   * @author Arjen Poutsma
43   * @see #createConnectionFactory()
44   * @see #createMessageFactory()
45   * @see #createMessageReceiver()
46   */
47  public class WebServiceMessageDrivenBean extends AbstractJmsMessageDrivenBean {
48  
49      /** Well-known name for the {@link ConnectionFactory} object in the bean factory for this bean. */
50      public static final String CONNECTION_FACTORY_BEAN_NAME = "connectionFactory";
51  
52      /** Well-known name for the {@link WebServiceMessageFactory} bean in the bean factory for this bean. */
53      public static final String MESSAGE_FACTORY_BEAN_NAME = "messageFactory";
54  
55      /** Well-known name for the {@link WebServiceMessageReceiver} object in the bean factory for this bean. */
56      public static final String MESSAGE_RECEIVER_BEAN_NAME = "messageReceiver";
57  
58      private JmsMessageReceiver delegate;
59  
60      private ConnectionFactory connectionFactory;
61  
62      /** Delegates to {@link JmsMessageReceiver#handleMessage(Message,Session)}. */
63      public void onMessage(Message message) {
64          Connection connection = null;
65          Session session = null;
66          try {
67              connection = createConnection(connectionFactory);
68              session = createSession(connection);
69              delegate.handleMessage(message, session);
70          }
71          catch (JmsTransportException ex) {
72              throw JmsUtils.convertJmsAccessException(ex.getJmsException());
73          }
74          catch (JMSException ex) {
75              throw JmsUtils.convertJmsAccessException(ex);
76          }
77          catch (Exception ex) {
78              throw new EJBException(ex);
79          }
80          finally {
81              JmsUtils.closeSession(session);
82              ConnectionFactoryUtils.releaseConnection(connection, connectionFactory, true);
83          }
84      }
85  
86      /**
87       * Creates a new {@link Connection}, {@link WebServiceMessageFactory}, and {@link WebServiceMessageReceiver}.
88       *
89       * @see #createConnectionFactory()
90       * @see #createMessageFactory()
91       * @see #createMessageReceiver()
92       */
93      protected void onEjbCreate() {
94          try {
95              connectionFactory = createConnectionFactory();
96              delegate = new JmsMessageReceiver();
97              delegate.setMessageFactory(createMessageFactory());
98              delegate.setMessageReceiver(createMessageReceiver());
99          }
100         catch (NamingException ex) {
101             throw new JndiLookupFailureException("Could not create connection", ex);
102         }
103         catch (JMSException ex) {
104             throw JmsUtils.convertJmsAccessException(ex);
105         }
106         catch (Exception ex) {
107             throw new EJBException(ex);
108         }
109     }
110 
111     /** Creates a connection factory. Default implemantion does a bean lookup for {@link #CONNECTION_FACTORY_BEAN_NAME}. */
112     protected ConnectionFactory createConnectionFactory() throws Exception {
113         return (ConnectionFactory) getBeanFactory().getBean(CONNECTION_FACTORY_BEAN_NAME, ConnectionFactory.class);
114     }
115 
116     /** Creates a message factory. Default implemantion does a bean lookup for {@link #MESSAGE_FACTORY_BEAN_NAME}. */
117     protected WebServiceMessageFactory createMessageFactory() {
118         return (WebServiceMessageFactory) getBeanFactory()
119                 .getBean(MESSAGE_FACTORY_BEAN_NAME, WebServiceMessageFactory.class);
120     }
121 
122     /** Creates a connection factory. Default implemantion does a bean lookup for {@link #MESSAGE_RECEIVER_BEAN_NAME}. */
123     protected WebServiceMessageReceiver createMessageReceiver() {
124         return (WebServiceMessageReceiver) getBeanFactory()
125                 .getBean(MESSAGE_RECEIVER_BEAN_NAME, WebServiceMessageReceiver.class);
126     }
127 
128     /**
129      * Create a JMS {@link Connection} using the given {@link ConnectionFactory}.
130      * <p/>
131      * This implementation uses JMS 1.1 API.
132      *
133      * @param connectionFactory the JMS ConnectionFactory to create a Connection with
134      * @return the new JMS Connection
135      * @throws JMSException if thrown by JMS API methods
136      * @see ConnectionFactory#createConnection()
137      */
138     protected Connection createConnection(ConnectionFactory connectionFactory) throws JMSException {
139         return connectionFactory.createConnection();
140     }
141 
142     /**
143      * Creates a JMS {@link Session}. Default implemantion creates a non-transactional, {@link Session#AUTO_ACKNOWLEDGE
144      * auto acknowledged} session.
145      * <p/>
146      * This implementation uses JMS 1.1 API.
147      *
148      * @param connection the JMS Connection to create a Session for
149      * @return the new JMS Session
150      * @throws JMSException if thrown by JMS API methods
151      * @see Connection#createSession(boolean,int)
152      */
153     protected Session createSession(Connection connection) throws JMSException {
154         return connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
155     }
156 
157 }