KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > providers > oracle > jms > AbstractOracleJmsConnector


1 /*
2  * $Id: AbstractOracleJmsConnector.java 4219 2006-12-09 10:15:14Z lajos $
3  * --------------------------------------------------------------------------------------
4  * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
5  *
6  * The software in this package is published under the terms of the MuleSource MPL
7  * license, a copy of which has been included with this distribution in the
8  * LICENSE.txt file.
9  */

10
11
12 package org.mule.providers.oracle.jms;
13
14 import oracle.jms.AQjmsSession;
15 import oracle.jms.AdtMessage;
16 import oracle.xdb.XMLType;
17 import org.mule.config.i18n.Message;
18 import org.mule.config.i18n.Messages;
19 import org.mule.providers.ConnectException;
20 import org.mule.providers.jms.JmsConnector;
21 import org.mule.providers.jms.JmsConstants;
22 import org.mule.providers.jms.JmsMessageUtils;
23 import org.mule.transaction.TransactionCoordination;
24 import org.mule.umo.TransactionException;
25 import org.mule.umo.UMOTransaction;
26 import org.mule.umo.lifecycle.InitialisationException;
27
28 import javax.jms.Connection JavaDoc;
29 import javax.jms.ConnectionFactory JavaDoc;
30 import javax.jms.JMSException JavaDoc;
31 import javax.jms.Session JavaDoc;
32 import javax.naming.NamingException JavaDoc;
33 import java.io.Serializable JavaDoc;
34 import java.sql.SQLException JavaDoc;
35
36 public abstract class AbstractOracleJmsConnector extends JmsConnector
37 {
38     /**
39      * If a queue's payload is an ADT (Oracle Advanced Data Type), the appropriate
40      * payload factory must be specified in the endpoint's properties. Note: if
41      * <u>all</u> queues are of the same payload type, this property may be set
42      * globally for the connector instead of for each endpoint.
43      */

44     public static final String JavaDoc PAYLOADFACTORY_PROPERTY = "payloadFactory";
45
46     protected String JavaDoc payloadFactory = null;
47     
48     /**
49      * Some versions of Oracle do not support more than one JMS session per
50      * connection. In this case we need to open a new connection for each session,
51      * otherwise we will get the following error:
52      * {@code JMS-106: Cannot have more than one open Session on a JMSConnection.}
53      */

54     private boolean multipleSessionsPerConnection = false;
55
56     public AbstractOracleJmsConnector()
57     {
58         super();
59         registerSupportedProtocol("jms");
60     }
61
62     /**
63      * The Oracle AQ connector supports both the oaq:// and the jms:// protocols.
64      */

65     public String JavaDoc getProtocol()
66     {
67         return "oaq";
68     }
69
70     /**
71      * The Oracle AQ connector supports both the oaq:// and the jms:// protocols.
72      */

73     public boolean supportsProtocol(String JavaDoc protocol)
74     {
75         // The oaq:// protocol handling breaks the model a bit; you do _not_ need to
76
// qualify the jms protocol with oaq (oaq:jms://) hence we need to override
77
// the
78
// default supportsProtocol() method.
79
return getProtocol().equalsIgnoreCase(protocol) || super.getProtocol().equalsIgnoreCase(protocol);
80     }
81
82     public void doConnect() throws ConnectException
83     {
84         try {
85             // Set these to false so that the jndiContext will not be used by the
86
// JmsSupport classes
87
setJndiDestinations(false);
88             setForceJndiDestinations(false);
89
90             setJmsSupport(new OracleJmsSupport(this, null, false, false));
91         }
92         catch (Exception JavaDoc e) {
93             throw new ConnectException(new Message(Messages.FAILED_TO_CREATE_X, "Oracle Jms Connector"), e,
94                     this);
95         }
96
97         // Note it doesn't make sense to start a connection at this point
98
// (as the standard JMS Provider does) because a connection will be created
99
// for
100
// each session.
101
}
102
103     /**
104      * Some versions of Oracle do not support more than one JMS session per
105      * connection. In this case we need to open a new connection for each session,
106      * otherwise we will get the following error:
107      * {@code JMS-106: Cannot have more than one open Session on a JMSConnection.}
108      *
109      * @see #multipleSessionsPerConnection
110      */

111     public Session getSession(boolean transacted, boolean topic) throws JMSException JavaDoc {
112
113         if (multipleSessionsPerConnection) {
114             return super.getSession(transacted, topic);
115         } else {
116             UMOTransaction tx = TransactionCoordination.getInstance().getTransaction();
117
118             // Check to see if we are already in a session.
119
Session session = getSessionFromTransaction();
120             if (session != null) {
121                 logger.debug("Retrieving jms session from current transaction");
122                 return session;
123             }
124
125             // Create a new database connection before creating a new session.
126
Connection JavaDoc connection;
127             try {
128                 connection = createConnection();
129             }
130             catch (NamingException JavaDoc e) {
131                 throw new JMSException JavaDoc("Unable to open new database connection: " + e.getMessage());
132             }
133             catch (InitialisationException e) {
134                 throw new JMSException JavaDoc("Unable to open new database connection: " + e.getMessage());
135             }
136
137             // Create a new session.
138
logger.debug("Retrieving new jms session from connection");
139             session = getJmsSupport().createSession(connection, topic, transacted || tx != null,
140                     getAcknowledgementMode(), isNoLocal());
141             if (tx != null) {
142                 logger.debug("Binding session to current transaction");
143                 try {
144                     tx.bindResource(connection, session);
145                 }
146                 catch (TransactionException e) {
147                     throw new RuntimeException JavaDoc("Could not bind session to current transaction", e);
148                 }
149             }
150             return session;
151         }
152     }
153
154     /**
155      * Oracle throws a "JMS-102: Feature not supported" error if any of these
156      * "standard" properties are used.
157      */

158     public boolean supportsProperty(String JavaDoc property) {
159         return (!JmsConstants.JMS_REPLY_TO.equalsIgnoreCase(property) && !JmsConstants.JMS_TYPE.equalsIgnoreCase(property));
160     }
161
162     /**
163      * If the incoming message is an XMLType, return it as a standard
164      * {@code javax.jms.TextMessage}. If the incoming message is any other
165      * AdtMessage, return it as a standard {@code javax.jms.ObjectMessage}.
166      */

167     public javax.jms.Message JavaDoc preProcessMessage(javax.jms.Message JavaDoc message, Session session) throws Exception JavaDoc {
168         Object JavaDoc payload;
169         javax.jms.Message JavaDoc newMessage;
170
171         if (message instanceof AdtMessage) {
172             payload = ((AdtMessage) message).getAdtPayload();
173
174             if (payload instanceof XMLType) {
175                 newMessage = session.createTextMessage(((XMLType) payload).getStringVal().trim());
176             } else if (payload instanceof Serializable JavaDoc) {
177                 newMessage = session.createObjectMessage((Serializable JavaDoc) payload);
178             } else {
179                 throw new JMSException JavaDoc("The payload of the incoming AdtMessage must be serializable.");
180             }
181             // TODO Is there a better way to do this?
182
JmsMessageUtils.copyJMSProperties(message, newMessage, this);
183             return newMessage;
184         } else {
185             return message;
186         }
187     }
188
189     /**
190      * Attempts to close the underlying JDBC connection before closing the JMS
191      * session.
192      *
193      * @see org.mule.providers.jms.JmsConnector.close( javax.jms.Session)
194      */

195     public void close(Session session) throws JMSException JavaDoc {
196         if (session != null) {
197             java.sql.Connection JavaDoc conn = ((AQjmsSession) session).getDBConnection();
198             try {
199                 if (conn != null && !conn.isClosed()) {
200                     conn.commit();
201                     conn.close();
202                 }
203             }
204             catch (SQLException JavaDoc e) {
205                 JMSException JavaDoc ex = new JMSException JavaDoc(e.getMessage());
206                 ex.setLinkedException(e);
207                 throw ex;
208             }
209         }
210     }
211
212     public abstract java.sql.Connection JavaDoc getJdbcConnection() throws JMSException JavaDoc;
213
214     public boolean isMultipleSessionsPerConnection() {
215         return multipleSessionsPerConnection;
216     }
217
218     public void setMultipleSessionsPerConnection(boolean multipleSessionsPerConnection) {
219         this.multipleSessionsPerConnection = multipleSessionsPerConnection;
220     }
221
222     /**
223      * Oracle has two different factory classes: {@code AQjmsQueueConnectionFactory}
224      * which implements {@code javax.jms.QueueConnectionFactory} and
225      * {@code AQjmsTopicConnectionFactory} which implements
226      * {@code javax.jms.TopicConnectionFactory} so there is no single class to return
227      * in this method.
228      *
229      * @return null
230      */

231     protected ConnectionFactory JavaDoc createConnectionFactory() throws InitialisationException, NamingException JavaDoc {
232         return null;
233     }
234
235     public String JavaDoc getPayloadFactory()
236     {
237         return payloadFactory;
238     }
239
240     public void setPayloadFactory(String JavaDoc payloadFactory)
241     {
242         this.payloadFactory = payloadFactory;
243     }
244 }
245
Popular Tags