KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > binding > jms > su > JMSServiceUnitListener


1 /**
2  * PETALS - PETALS Services Platform.
3  * Copyright (c) 2005 EBM Websourcing, http://www.ebmwebsourcing.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * -------------------------------------------------------------------------
19  * $Id: JmsConnexion.java 676 2006-06-27 15:44:03Z alouis $
20  * -------------------------------------------------------------------------
21  */

22 package org.objectweb.petals.binding.jms.su;
23
24 import java.net.URI JavaDoc;
25 import java.net.URISyntaxException JavaDoc;
26 import java.net.URLClassLoader JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Properties JavaDoc;
30
31 import javax.naming.Context JavaDoc;
32 import javax.naming.InitialContext JavaDoc;
33 import javax.naming.spi.InitialContextFactory JavaDoc;
34
35 import org.objectweb.petals.binding.jms.JMSConnection;
36 import org.objectweb.petals.component.common.PEtALSComponentSDKException;
37 import org.objectweb.petals.component.common.su.ServiceUnitListener;
38 import org.objectweb.petals.component.common.util.PetalsExtensionsUtil;
39 import org.objectweb.petals.tools.jbicommon.descriptor.Extensions;
40 import org.objectweb.petals.tools.jbicommon.descriptor.JBIDescriptor;
41
42 import static org.objectweb.petals.component.common.util.ClassLoaderUtil.createClassLoader;
43
44 /**
45  * This class is used to store information about an external JMS queue acting as
46  * an external service
47  *
48  * @version $Revision: $ $Date: $
49  * @since Petals 1.0
50  * @author alouis
51  */

52 public class JMSServiceUnitListener implements ServiceUnitListener {
53
54     private static final String JavaDoc CONNECTION_FACTORY = "connection-factory";
55
56     private static final String JavaDoc ADDRESS = "address";
57
58     private static final String JavaDoc INITIAL_CONTEXT_FACTORY = "initial-context-factory";
59
60     private static final String JavaDoc USER = "user";
61
62     private static final String JavaDoc PASSWORD = "password";
63
64     private static final String JavaDoc TRANSACTED = "transacted";
65
66     /**
67      * Contains jmsProducerConnections, stored by 'address' (ie jms url
68      * provider)
69      */

70     private Map JavaDoc<String JavaDoc, JMSConnection> jmsProducerConnections;
71
72     /**
73      * Contains jmsConsumerConnections, stored by 'address' (ie jms url
74      * provider)
75      */

76     private Map JavaDoc<String JavaDoc, JMSConnection> jmsConsumerConnections;
77
78     /**
79      * Contains addresses (ie jms url provider), stored by serviceUnitName
80      */

81     private Map JavaDoc<String JavaDoc, String JavaDoc> addresses;
82
83     /**
84      * Constructor
85      *
86      * @param jmsProducerConnections
87      * jmsConnections map used to store jmsConnections for producers.
88      * Used by the JBI listener
89      * @param jmsConsumerConnections
90      * jmsConnections map used to store jmsConnections for consumers.
91      * Used by the external listeners
92      */

93     public JMSServiceUnitListener(
94             Map JavaDoc<String JavaDoc, JMSConnection> jmsProducerConnections,
95             Map JavaDoc<String JavaDoc, JMSConnection> jmsConsumerConnections) {
96         this.jmsProducerConnections = jmsProducerConnections;
97         this.jmsConsumerConnections = jmsConsumerConnections;
98         addresses = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
99     }
100
101     /**
102      * Prepare JMS connection for a service unit. Set a JMS producer or JMS
103      * consumer depending on JBI 'provides' or JBI 'consumes' descriptor
104      * information. Only one 'consumes' or 'provides' section is allowed
105      */

106     public void onSUDeployed(String JavaDoc serviceUnitName, String JavaDoc suRootPath,
107             JBIDescriptor descriptor) throws PEtALSComponentSDKException {
108
109         int providesCount = descriptor.getServices().getProvides().size();
110         int consumesCount = descriptor.getServices().getConsumes().size();
111
112         if (providesCount + consumesCount != 1) {
113             throw new PEtALSComponentSDKException(
114                     "Only one 'Consumes' or 'Provides' is allowed per JMS-BC ServiceUnit.");
115
116         }
117         JMSConnection.Role role = null;
118         Extensions extensions = null;
119
120         if (providesCount == 1) {
121             role = JMSConnection.Role.JMS_PRODUCER;
122             extensions = descriptor.getServices().getProvides().get(0)
123                     .getExtensions();
124
125         } else {
126             role = JMSConnection.Role.JMS_CONSUMER;
127             extensions = descriptor.getServices().getConsumes().get(0)
128                     .getExtensions();
129         }
130
131         // Create the JNDI context used to retrieve jms connection and
132
// destination
133
Context JavaDoc context = setupContext(suRootPath, extensions);
134
135         // create the jmsConnection object that contains all information
136
JMSConnection connection = setupConnection(context, extensions, role);
137
138         // retrieve the jms 'address' to be used as key
139
String JavaDoc address = PetalsExtensionsUtil
140                 .extractValueFromKeyValueExtension(extensions, ADDRESS);
141
142         // store the jmsconnection
143
addresses.put(serviceUnitName, address);
144         if (role == JMSConnection.Role.JMS_PRODUCER) {
145             jmsProducerConnections.put(address, connection);
146         } else {
147             jmsConsumerConnections.put(address, connection);
148         }
149     }
150
151     /**
152      * Start the jms connection and setup the jms producer/consumer
153      */

154     public void onSUStarted(String JavaDoc serviceUnitName)
155             throws PEtALSComponentSDKException {
156
157         String JavaDoc address = addresses.get(serviceUnitName);
158
159         if (address != null) {
160             JMSConnection jmsConnection = jmsProducerConnections.get(address);
161             if (jmsConnection == null) {
162                 jmsConnection = jmsConsumerConnections.get(address);
163             }
164             jmsConnection.start();
165         }
166     }
167
168     /**
169      * Stop the jms connection
170      */

171     public void onSUStopped(String JavaDoc serviceUnitName)
172             throws PEtALSComponentSDKException {
173
174         String JavaDoc address = addresses.get(serviceUnitName);
175
176         if (address != null) {
177             JMSConnection jmsConnection = jmsProducerConnections.get(address);
178             if (jmsConnection == null) {
179                 jmsConnection = jmsConsumerConnections.get(address);
180             }
181             jmsConnection.stop();
182         }
183     }
184
185     public void onSUUndeployed(String JavaDoc serviceUnitName, String JavaDoc suRootPath,
186             JBIDescriptor descriptor) throws PEtALSComponentSDKException {
187
188         String JavaDoc address = addresses.remove(serviceUnitName);
189
190         if (address != null) {
191             JMSConnection jmsConnection = jmsProducerConnections
192                     .remove(address);
193             if (jmsConnection == null) {
194                 jmsConsumerConnections.remove(address);
195             }
196         }
197     }
198
199     /**
200      * Setup a JNDIContext to access a JMS destination.
201      *
202      * @param suRootPath
203      * path where jndi context factory class can be found
204      * @param extensions
205      * jndi properties
206      * @return a JNDI context initialized with the given jbi.xml properties
207      * @throws PEtALSComponentSDKException
208      */

209     private Context JavaDoc setupContext(String JavaDoc suRootPath, Extensions extensions)
210             throws PEtALSComponentSDKException {
211
212         // Create a class loader that will contains all JAR
213
// It will load the specific JndiFactory class
214
// to access the jndi containing Queue and Topic references
215
URLClassLoader JavaDoc classLoader = createClassLoader(suRootPath, this
216                 .getClass().getClassLoader());
217
218         // Create JNDI properties
219
Properties JavaDoc jndiProperties = createJNDIProperties(extensions);
220
221         // Create the JNDI context
222
return createJNDIContext(classLoader, jndiProperties);
223     }
224
225     /**
226      * extract jndi properties from the jbi.xml extensions
227      *
228      * @param extensions
229      * @return
230      * @throws PEtALSComponentSDKException
231      * provider url or factory name not found
232      */

233     private Properties JavaDoc createJNDIProperties(Extensions extensions)
234             throws PEtALSComponentSDKException {
235         Properties JavaDoc outProperties = new Properties JavaDoc();
236
237         String JavaDoc url = null;
238         try {
239             URI JavaDoc address = new URI JavaDoc(PetalsExtensionsUtil
240                     .extractValueFromKeyValueExtension(extensions, ADDRESS));
241             url = address.getScheme() + ":" + address.getSchemeSpecificPart();
242         } catch (URISyntaxException JavaDoc e) {
243             throw new PEtALSComponentSDKException(
244                     ADDRESS
245                             + " property not found in the Service Unit descriptor file."
246                             + e);
247         }
248         String JavaDoc factory = PetalsExtensionsUtil
249                 .extractValueFromKeyValueExtension(extensions,
250                         INITIAL_CONTEXT_FACTORY);
251
252         outProperties.setProperty(InitialContext.PROVIDER_URL, url);
253         outProperties.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY,
254                 factory);
255         return outProperties;
256     }
257
258     /**
259      * Return a JNDI context loaded from the JAR files contained in the
260      * ServiceUnit and the Properties defined in the JBI.XML file.
261      *
262      * @param classLoader
263      * contains the libraries where the JNDI context factory can be
264      * found
265      * @param properties
266      * contains the factory class name and the url provider
267      * @return a JNDI context
268      * @throws PEtALSComponentSDKException
269      * can not retrieved the factory. properties might not be
270      * correct.
271      */

272     private Context JavaDoc createJNDIContext(ClassLoader JavaDoc classLoader,
273             Properties JavaDoc properties) throws PEtALSComponentSDKException {
274         Context JavaDoc ctx = null;
275         try {
276             InitialContextFactory JavaDoc icf = (InitialContextFactory JavaDoc) classLoader
277                     .loadClass(
278                             properties
279                                     .getProperty(InitialContext.INITIAL_CONTEXT_FACTORY))
280                     .newInstance();
281             ctx = icf.getInitialContext(properties);
282         } catch (Exception JavaDoc e) {
283             throw new PEtALSComponentSDKException(
284                     "JNDI context can not be created." + e);
285         }
286         return ctx;
287     }
288
289     /**
290      * Setup a JMS connection to access a JMS destination.
291      *
292      * @param context
293      * jndi context where the connection factory and the destination
294      * can be found
295      * @param extensions
296      * contains connectionFactory and destination names, user/pwd,
297      * transacted and acknowledge modes.
298      * @param role
299      * jms role : consumer or producer
300      * @return a JMSConnection in a stopped state.
301      * @throws PEtALSComponentSDKException
302      * a mandatory property is not found in the JBI.XML descriptor
303      */

304     private JMSConnection setupConnection(Context JavaDoc context,
305             Extensions extensions, JMSConnection.Role role)
306             throws PEtALSComponentSDKException {
307         String JavaDoc connName = PetalsExtensionsUtil
308                 .extractValueFromKeyValueExtension(extensions,
309                         CONNECTION_FACTORY);
310
311         String JavaDoc destName = null;
312         try {
313             URI JavaDoc address = new URI JavaDoc(PetalsExtensionsUtil
314                     .extractValueFromKeyValueExtension(extensions, ADDRESS));
315             destName = address.getFragment();
316         } catch (URISyntaxException JavaDoc e) {
317             throw new PEtALSComponentSDKException(
318                     ADDRESS
319                             + " property not found in the Service Unit descriptor file."
320                             + e);
321         }
322
323         String JavaDoc user = PetalsExtensionsUtil.extractValueFromKeyValueExtension(
324                 extensions, USER);
325
326         String JavaDoc password = PetalsExtensionsUtil
327                 .extractValueFromKeyValueExtension(extensions, PASSWORD);
328
329         boolean transacted = false;
330         String JavaDoc transac = PetalsExtensionsUtil
331                 .extractValueFromKeyValueExtension(extensions, TRANSACTED);
332         transacted = Boolean.valueOf(transac);
333
334         return new JMSConnection(context, connName, destName, transacted, user,
335                 password, role);
336
337     }
338
339 }
Popular Tags