KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mr > ra > ResourceAdapterImpl


1 /*
2  * Copyright 2002 by
3  * <a HREF="http://www.coridan.com">Coridan</a>
4  * <a HREF="mailto: support@coridan.com ">support@coridan.com</a>
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is "MantaRay" (TM).
17  *
18  * The Initial Developer of the Original Code is Coridan.
19  * Portions created by the Initial Developer are Copyright (C) 2006
20  * Coridan Inc. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source
23  * code where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LESSER GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above. If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LESSER GENERAL PUBLIC LICENSE.
34  
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Lesser General Public License as published by the Free Software Foundation;
39  * either version 2.1 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
44  * License for more details.
45  */

46
47 package org.mr.ra;
48
49 import java.io.Serializable JavaDoc;
50 import java.util.HashMap JavaDoc;
51
52 import javax.jms.Connection JavaDoc;
53 import javax.jms.JMSException JavaDoc;
54 import javax.jms.XAConnection JavaDoc;
55 import javax.jms.XASession JavaDoc;
56 import javax.resource.NotSupportedException JavaDoc;
57 import javax.resource.ResourceException JavaDoc;
58 import javax.resource.spi.ActivationSpec JavaDoc;
59 import javax.resource.spi.BootstrapContext JavaDoc;
60 import javax.resource.spi.ResourceAdapter JavaDoc;
61 import javax.resource.spi.ResourceAdapterInternalException JavaDoc;
62 import javax.resource.spi.endpoint.MessageEndpointFactory JavaDoc;
63 import javax.transaction.xa.XAResource JavaDoc;
64
65 import org.apache.commons.logging.Log;
66 import org.apache.commons.logging.LogFactory;
67 import org.mr.api.jms.MantaConnection;
68 import org.mr.api.jms.MantaConnectionFactory;
69 import org.mr.api.jms.MantaXAConnection;
70 import org.mr.api.jms.MantaXAConnectionFactory;
71 import org.mr.ra.inbound.ActivationSpecImpl;
72 import org.mr.ra.inbound.EndpointKey;
73 import org.mr.ra.inbound.MantaAsfEndpointWorker;
74 import org.mr.ra.inbound.MantaBaseEndpointWorker;
75 //import org.activemq.XmlConfigHelper;
76
//import org.activemq.util.IdGenerator;
77

78 /**
79  * Knows how to connect to one ActiveMQ server. It can then activate endpoints
80  * and deliver messages to those enpoints using the connection configure in the
81  * resource adapter. <p/>Must override equals and hashCode (JCA spec 16.4)
82  *
83  * @version $Revision: 1.2 $
84  */

85 public class ResourceAdapterImpl
86 implements ResourceAdapter JavaDoc, Serializable JavaDoc
87 {
88     private static final long serialVersionUID = 3257291318350000180L;
89     private static final Log log = LogFactory.getLog(ResourceAdapterImpl.class);
90
91 // private static final String ASF_ENDPOINT_WORKER_TYPE = "asf";
92

93 // private static final String POLLING_ENDPOINT_WORKER_TYPE = "polling";
94

95     private BootstrapContext JavaDoc bootContext = null;
96     private HashMap JavaDoc endpointWorkers = new HashMap JavaDoc();
97     final private ConnectionRequestInfoImpl info;// = new ConnectionRequestInfoImpl();
98

99     // private String endpointWorkerType = ASF_ENDPOINT_WORKER_TYPE;
100
//private MantaConnectionFactory connectionFactory;
101
private HashMap JavaDoc connectionFactoryMap = new HashMap JavaDoc(1);
102     
103     
104     public ResourceAdapterImpl() {
105         info = new ConnectionRequestInfoImpl();
106     }
107     
108     
109     // Implementing ResourceAdapter Interface
110

111     /**
112      * @see javax.resource.spi.ResourceAdapter#start(javax.resource.spi.BootstrapContext)
113      */

114     public void start(BootstrapContext JavaDoc bootstrapContext) throws ResourceAdapterInternalException JavaDoc {
115         this.bootContext = bootstrapContext;
116     }
117     
118     
119     /**
120      * @see javax.resource.spi.ResourceAdapter#stop()
121      */

122     public void stop() {
123         this.bootContext = null;
124     }
125     
126     
127     
128     /**
129      * @see javax.resource.spi.ResourceAdapter#endpointActivation(javax.resource.spi.endpoint.MessageEndpointFactory,
130      * javax.resource.spi.ActivationSpec)
131      */

132     public void endpointActivation(MessageEndpointFactory JavaDoc endpointFactory,
133                                    ActivationSpec JavaDoc activationSpec)
134                                    throws ResourceException JavaDoc {
135         
136         //throw new ResourceException("Endpoint activation not supported yet");
137

138         // spec section 5.3.3
139
if (activationSpec.getResourceAdapter() != this) {
140             throw new ResourceException JavaDoc("Activation spec not initialized with this ResourceAdapter instance");
141         }
142
143         // TODO: why not using instanceof?
144
if (activationSpec.getClass().equals(ActivationSpecImpl.class)) {
145             EndpointKey key = new EndpointKey(endpointFactory, (ActivationSpecImpl) activationSpec);
146
147             // This is weird.. the same endpoint activated twice.. must be a
148
// container error.
149
// Shai: Is it true? When?
150
if (endpointWorkers.containsKey(key)) {
151                 throw new IllegalStateException JavaDoc("Endpoint previously activated");
152             }
153             
154             // Start a workwer for MDB
155
MantaBaseEndpointWorker worker = new MantaAsfEndpointWorker(this, key);
156             endpointWorkers.put(key, worker);
157             worker.start();
158         } else {
159             throw new NotSupportedException JavaDoc("That type of ActicationSpec not supported: " + activationSpec.getClass());
160         }
161     }
162
163     /**
164      * @see javax.resource.spi.ResourceAdapter#endpointDeactivation(javax.resource.spi.endpoint.MessageEndpointFactory,
165      * javax.resource.spi.ActivationSpec)
166      */

167     public void endpointDeactivation(MessageEndpointFactory JavaDoc endpointFactory, ActivationSpec JavaDoc activationSpec) {
168
169         if (activationSpec.getClass().equals(ActivationSpecImpl.class)) {
170             EndpointKey key = new EndpointKey(endpointFactory, (ActivationSpecImpl) activationSpec);
171             MantaBaseEndpointWorker worker = (MantaBaseEndpointWorker) endpointWorkers.remove(key);
172             if (worker == null) {
173                 // This is weird.. that endpoint was not activated.. oh well..
174
// this method
175
// does not throw exceptions so just return.
176
return;
177             }
178             try {
179                 worker.stop();
180             } catch (InterruptedException JavaDoc e) {
181                 // We interrupted.. we won't throw an exception but will stop
182
// waiting for the worker
183
// to stop.. we tried our best. Keep trying to interrupt the
184
// thread.
185
Thread.currentThread().interrupt();
186             }
187         }
188     }
189
190
191     
192     /**
193      * We only connect to one resource manager per ResourceAdapter instance, so
194      * any ActivationSpec will return the same XAResource.
195      *
196      * @see javax.resource.spi.ResourceAdapter#getXAResources(javax.resource.spi.ActivationSpec[])
197      */

198     public XAResource JavaDoc[] getXAResources(ActivationSpec JavaDoc[] activationSpecs) throws ResourceException JavaDoc {
199         Connection JavaDoc connection = null;
200         try {
201             connection = makeConnection();
202             if (connection instanceof XAConnection JavaDoc) {
203                 XASession JavaDoc session = ((XAConnection JavaDoc) connection).createXASession();
204                 XAResource JavaDoc xaResource = session.getXAResource();
205                 return new XAResource JavaDoc[] { xaResource };
206             } else {
207                 return new XAResource JavaDoc[] {};
208             }
209         } catch (JMSException JavaDoc e) {
210             throw new ResourceException JavaDoc(e);
211         } finally {
212             try {
213                 connection.close();
214             } catch (Throwable JavaDoc ignore) {
215             }
216         }
217     }
218     
219     /**
220      * Need to override equals(). See Spec section 5.3.1,
221      * paragraph 4.
222      * In our case there could be only 1 instance of the
223      * resource adapter and that's why we return true.
224      * No other parameters to check.
225      */

226     public boolean equals(Object JavaDoc o) {
227         if (this == o) {
228             return true;
229         }
230         if (!(o instanceof ResourceAdapterImpl)) {
231             return false;
232         }
233         return true;
234     }
235     
236
237     /**
238      * Need to override hashCode() because we override equals().
239      * See Spec section 5.3.1.
240      * In our case there could be only 1 instance of the
241      * resource adapter so we can use anything we want.
242      */

243     public int hashCode() {
244         return 851; // = 23 * 37
245
}
246
247     
248     //////////////////////
249
//
250
// Additional methods
251
//
252
//////////////////////
253

254     /**
255      * Return a connection using the default connection request info from the RAR
256      * deployment.
257      */

258     public MantaConnection makeConnection() throws JMSException JavaDoc {
259         return makeConnection(info);
260     }
261
262     /**
263      * Return a connection using a specific connection request info.
264      */

265     public MantaXAConnection makeConnection(ConnectionRequestInfoImpl crInfo) throws JMSException JavaDoc {
266         MantaXAConnectionFactory connectionFactory = getConnectionFactory(crInfo);
267         String JavaDoc userName = info.getUserName();
268         String JavaDoc password = info.getPassword();
269         MantaXAConnection physicalConnection = (MantaXAConnection) connectionFactory.createXAConnection(userName, password);
270         return physicalConnection;
271     }
272
273     /**
274      * @param activationSpec
275      */

276     public MantaXAConnection makeConnection(ActivationSpecImpl activationSpec) throws JMSException JavaDoc {
277         //use the default RA connection request for info
278
MantaXAConnectionFactory connectionFactory = getConnectionFactory(info);
279         String JavaDoc userName = defaultValue(activationSpec.getUserName(), info.getUserName());
280         String JavaDoc password = defaultValue(activationSpec.getPassword(), info.getPassword());
281         MantaXAConnection physicalConnection = (MantaXAConnection) connectionFactory.createXAConnection(userName, password);
282         if (activationSpec.isDurableSubscription()) {
283             physicalConnection.setClientID(activationSpec.getClientId());
284         }
285         return physicalConnection;
286     }
287
288     /**
289      * Returns a connection factory given a connection configuration.
290      * The implementation of this method treats the factories as singletons
291      * only creating one factory for a given set of configuration data.
292      */

293     private MantaXAConnectionFactory getConnectionFactory(ConnectionRequestInfoImpl crInfo) {
294         //use adapter default if none provided
295
if(crInfo == null) {
296             crInfo = info;
297         }
298
299         synchronized(connectionFactoryMap) {
300             if(!(connectionFactoryMap.containsKey(crInfo))) {
301                 MantaXAConnectionFactory factory = new MantaXAConnectionFactory();
302                 connectionFactoryMap.put(crInfo, factory);
303                 return factory;
304             }
305         }
306         return (MantaXAConnectionFactory)connectionFactoryMap.get(crInfo);
307     }
308
309     
310     /**
311      * @return
312      */

313     public BootstrapContext JavaDoc getBootstrapContext() {
314         return bootContext;
315     }
316     
317     /**
318      * @return Returns the info.
319      */

320     public ConnectionRequestInfoImpl getInfo() {
321         return info;
322     }
323     
324         
325     /////////////////////////////////
326
//
327
// Java Bean getters and setters
328
//
329
/////////////////////////////////
330

331     /**
332      * @return
333      */

334     public String JavaDoc getPassword() {
335         return emptyToNull(info.getPassword());
336     }
337     
338     /**
339      * @param password
340      */

341     public void setPassword(String JavaDoc password) {
342         info.setPassword(password);
343     }
344
345     /**
346      * @return
347      */

348     public String JavaDoc getUserName() {
349         return emptyToNull(info.getUserName());
350     }
351
352     /**
353      * @param userid
354      */

355     public void setUserName(String JavaDoc userid) {
356         info.setUserName(userid);
357     }
358
359
360     ///////////////////
361
//
362
// Utility methods
363
//
364
///////////////////
365

366     // a utility method
367
private boolean notEqual(Object JavaDoc o1, Object JavaDoc o2) {
368         return (o1 == null ^ o2 == null) || (o1 != null && !o1.equals(o2));
369     }
370     
371     // a utility method
372
private String JavaDoc defaultValue(String JavaDoc value, String JavaDoc defaultValue) {
373         if (value != null)
374             return value;
375         return defaultValue;
376     }
377     
378     // a utility method
379
private String JavaDoc emptyToNull(String JavaDoc value) {
380         if (value == null || value.length() == 0) {
381             return null;
382         }
383         return value;
384     }
385 }
386
Popular Tags