KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > resource > adapter > jdbc > local > HALocalManagedConnectionFactory


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.resource.adapter.jdbc.local;
23
24 import org.jboss.resource.JBossResourceException;
25 import org.jboss.util.JBossStringBuilder;
26
27 import javax.resource.spi.ManagedConnection JavaDoc;
28 import javax.resource.spi.ConnectionRequestInfo JavaDoc;
29 import javax.resource.ResourceException JavaDoc;
30 import javax.security.auth.Subject JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Properties JavaDoc;
34 import java.util.Collections JavaDoc;
35 import java.sql.Driver JavaDoc;
36 import java.sql.Connection JavaDoc;
37
38 /**
39  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
40  * @version <tt>$Revision: 43316 $</tt>
41  */

42 public class HALocalManagedConnectionFactory
43    extends LocalManagedConnectionFactory
44 {
45    private static final long serialVersionUID = -6506610639011749394L;
46
47    private URLSelector urlSelector;
48    private String JavaDoc urlDelimeter;
49
50    public String JavaDoc getURLDelimeter()
51    {
52       return urlDelimeter;
53    }
54
55    public void setURLDelimeter(String JavaDoc urlDelimeter)
56    {
57       this.urlDelimeter = urlDelimeter;
58       if(getConnectionURL() != null)
59       {
60          initUrlSelector();
61       }
62    }
63
64    public void setConnectionURL(String JavaDoc connectionURL)
65    {
66       super.setConnectionURL(connectionURL);
67       if(urlDelimeter != null)
68       {
69          initUrlSelector();
70       }
71    }
72
73    public ManagedConnection JavaDoc createManagedConnection(Subject JavaDoc subject, ConnectionRequestInfo JavaDoc cri)
74       throws ResourceException
75    {
76       boolean trace = log.isTraceEnabled();
77       Properties JavaDoc props = getConnectionProperties(subject, cri);
78       // Some friendly drivers (Oracle, you guessed right) modify the props you supply.
79
// Since we use our copy to identify compatibility in matchManagedConnection, we need
80
// a pristine copy for our own use. So give the friendly driver a copy.
81
Properties JavaDoc copy = (Properties JavaDoc)props.clone();
82       if(trace)
83       {
84          // Make yet another copy to mask the password
85
Properties JavaDoc logCopy = copy;
86          if(copy.getProperty("password") != null)
87          {
88             logCopy = (Properties JavaDoc)props.clone();
89             logCopy.setProperty("password", "--hidden--");
90          }
91          log.trace("Using properties: " + logCopy);
92       }
93
94       return doCreateManagedConnection(copy, props);
95    }
96
97    private ManagedConnection JavaDoc doCreateManagedConnection(Properties JavaDoc copy, Properties JavaDoc props)
98       throws JBossResourceException
99    {
100       boolean trace = log.isTraceEnabled();
101       
102       if (urlSelector == null)
103       {
104          JBossStringBuilder buffer = new JBossStringBuilder();
105          buffer.append("Missing configuration for HA local datasource. ");
106          if (getConnectionURL() == null)
107             buffer.append("No connection-url. ");
108          if (urlDelimeter == null)
109             buffer.append("No url-delimiter. ");
110          throw new JBossResourceException(buffer.toString());
111       }
112       
113       // try to get a connection as many times as many urls we have in the list
114
for(int i = 0; i < urlSelector.getUrlList().size(); ++i)
115       {
116          String JavaDoc url = urlSelector.getUrl();
117
118          if(trace)
119          {
120             log.trace("Trying to create a connection to " + url);
121          }
122
123          try
124          {
125             Driver JavaDoc d = getDriver(url);
126             Connection JavaDoc con = d.connect(url, copy);
127             if(con == null)
128             {
129                log.warn("Wrong driver class for this connection URL: " + url);
130                urlSelector.failedUrl(url);
131             }
132             else
133             {
134                return new LocalManagedConnection(this, con, props, transactionIsolation, preparedStatementCacheSize);
135             }
136          }
137          catch(Exception JavaDoc e)
138          {
139             log.warn("Failed to create connection for " + url + ": " + e.getMessage());
140             urlSelector.failedUrl(url);
141          }
142       }
143
144       // we have supposedly tried all the urls
145
throw new JBossResourceException(
146          "Could not create connection using any of the URLs: " + urlSelector.getUrlList()
147       );
148    }
149
150    private void initUrlSelector()
151    {
152       boolean trace = log.isTraceEnabled();
153       
154       List JavaDoc urlsList = new ArrayList JavaDoc();
155       String JavaDoc urlsStr = getConnectionURL();
156       String JavaDoc url;
157       int urlStart = 0;
158       int urlEnd = urlsStr.indexOf(urlDelimeter);
159       while(urlEnd > 0)
160       {
161          url = urlsStr.substring(urlStart, urlEnd);
162          urlsList.add(url);
163          urlStart = ++urlEnd;
164          urlEnd = urlsStr.indexOf(urlDelimeter, urlEnd);
165          if (trace)
166           log.trace("added HA connection url: " + url);
167       }
168
169       if(urlStart != urlsStr.length())
170       {
171          url = urlsStr.substring(urlStart, urlsStr.length());
172          urlsList.add(url);
173          if (trace)
174             log.trace("added HA connection url: " + url);
175       }
176
177       this.urlSelector = new URLSelector(urlsList);
178    }
179
180    // Inner
181

182    public static class URLSelector
183    {
184       private final List JavaDoc urls;
185       private int urlIndex;
186       private String JavaDoc url;
187
188       public URLSelector(List JavaDoc urls)
189       {
190          if(urls == null || urls.size() == 0)
191          {
192             throw new IllegalStateException JavaDoc("Expected non-empty list of connection URLs but got: " + urls);
193          }
194          this.urls = Collections.unmodifiableList(urls);
195       }
196
197       public synchronized String JavaDoc getUrl()
198       {
199          if(url == null)
200          {
201             if(urlIndex == urls.size())
202             {
203                urlIndex = 0;
204             }
205             url = (String JavaDoc)urls.get(urlIndex++);
206          }
207          return url;
208       }
209
210       public synchronized void failedUrl(String JavaDoc url)
211       {
212          if(url.equals(this.url))
213          {
214             this.url = null;
215          }
216       }
217
218       public List JavaDoc getUrlList()
219       {
220          return urls;
221       }
222    }
223 }
224
Popular Tags