KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jaspersoft > jasperserver > api > engine > jasperreports > service > impl > JdbcReportDataSourceServiceFactory


1 /*
2  * Copyright (C) 2006 JasperSoft http://www.jaspersoft.com
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed WITHOUT ANY WARRANTY; and without the
10  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
15  * or write to:
16  *
17  * Free Software Foundation, Inc.,
18  * 59 Temple Place - Suite 330,
19  * Boston, MA USA 02111-1307
20  */

21 package com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl;
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import javax.sql.DataSource JavaDoc;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 import com.jaspersoft.jasperserver.api.JSException;
35 import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.JdbcReportDataSource;
36 import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportDataSource;
37 import com.jaspersoft.jasperserver.api.metadata.jasperreports.service.ReportDataSourceService;
38 import com.jaspersoft.jasperserver.api.metadata.jasperreports.service.ReportDataSourceServiceFactory;
39
40 /**
41  * @author Lucian Chirita (lucianc@users.sourceforge.net)
42  * @version $Id: JdbcReportDataSourceServiceFactory.java 3480 2006-05-28 11:36:00Z swood $
43  */

44 public class JdbcReportDataSourceServiceFactory implements ReportDataSourceServiceFactory {
45
46     private static final Log log = LogFactory.getLog(JdbcReportDataSourceServiceFactory.class);
47
48     protected static class PooledDataSourcesCache {
49         protected static class DataSourceEntry {
50             final Object JavaDoc key;
51             final PooledDataSource ds;
52             DataSourceEntry next, prev;
53             long lastAccess;
54
55             public DataSourceEntry(Object JavaDoc key, PooledDataSource ds) {
56                 this.key = key;
57                 this.ds = ds;
58             }
59
60             public void access(long now) {
61                 lastAccess = now;
62             }
63         }
64         
65         final Map JavaDoc cache;
66         DataSourceEntry first, last;
67
68         public PooledDataSourcesCache() {
69             cache = new HashMap JavaDoc();
70             first = last = null;
71         }
72
73         public PooledDataSource get(Object JavaDoc key, long now) {
74             DataSourceEntry entry = (DataSourceEntry) cache.get(key);
75
76             if (entry == null) {
77                 return null;
78             }
79             
80             moveFirst(entry);
81             entry.access(now);
82             return entry.ds;
83         }
84
85         private void moveFirst(DataSourceEntry entry) {
86             entry.next = first;
87             entry.prev = null;
88             if (first != null) {
89                 first.prev = entry;
90             }
91             first = entry;
92             if (last == null) {
93                 last = entry;
94             }
95         }
96
97         public void put(Object JavaDoc key, PooledDataSource ds, long now) {
98             DataSourceEntry entry = new DataSourceEntry(key, ds);
99             moveFirst(entry);
100             entry.access(now);
101             cache.put(key, entry);
102         }
103         
104         public List JavaDoc removeExpired(long now, int timeout) {
105             List JavaDoc expired = new ArrayList JavaDoc();
106             DataSourceEntry entry = last;
107             long expTime = now - timeout * 1000;
108             while (entry != null && entry.lastAccess < expTime) {
109                 expired.add(entry.ds);
110                 remove(entry);
111                 entry = entry.prev;
112             }
113             return expired;
114         }
115
116         protected void remove(DataSourceEntry entry) {
117             cache.remove(entry.key);
118             if (entry.prev != null) {
119                 entry.prev.next = entry.next;
120             }
121             if (entry.next != null) {
122                 entry.next.prev = entry.prev;
123             }
124             if (first == entry) {
125                 first = entry.next;
126             }
127             if (last == entry) {
128                 last = entry.prev;
129             }
130         }
131     }
132
133     private PooledJdbcDataSourceFactory pooledJdbcDataSourceFactory;
134     private PooledDataSourcesCache poolDataSources;
135     private int poolTimeout;
136     
137     public JdbcReportDataSourceServiceFactory () {
138         poolDataSources = new PooledDataSourcesCache();
139     }
140
141     public ReportDataSourceService createService(ReportDataSource reportDataSource) {
142         if (!(reportDataSource instanceof JdbcReportDataSource)) {
143             throw new JSException("Invalid JDBC data source. Was: " + reportDataSource.getClass());
144         }
145         JdbcReportDataSource jdbcDataSource = (JdbcReportDataSource) reportDataSource;
146     
147         DataSource JavaDoc dataSource = getPoolDataSource(jdbcDataSource.getDriverClass(), jdbcDataSource.getConnectionUrl(), jdbcDataSource.getUsername(), jdbcDataSource.getPassword());
148         return new JdbcDataSourceService(dataSource);
149     }
150
151     protected DataSource JavaDoc getPoolDataSource(String JavaDoc driverClass, String JavaDoc url, String JavaDoc username, String JavaDoc password) {
152         Object JavaDoc poolKey = createJdbcPoolKey(driverClass, url, username, password);
153         PooledDataSource dataSource;
154         List JavaDoc expired = null;
155         long now = System.currentTimeMillis();
156         synchronized (poolDataSources) {
157             dataSource = poolDataSources.get(poolKey, now);
158             if (dataSource == null) {
159                 if (log.isDebugEnabled()) {
160                     log.debug("Creating connection pool for driver=\"" + driverClass + "\", url=\"" +
161                             url + "\", username=\"" + username + "\".");
162                 }
163                 dataSource = pooledJdbcDataSourceFactory.createPooledDataSource(driverClass, url, username, password);
164                 poolDataSources.put(poolKey, dataSource, now);
165             }
166
167             if (getPoolTimeout() > 0) {
168                 expired = poolDataSources.removeExpired(now, getPoolTimeout());
169             }
170         }
171
172         if (expired != null && !expired.isEmpty()) {
173             for (Iterator JavaDoc it = expired.iterator(); it.hasNext();) {
174                 PooledDataSource ds = (PooledDataSource) it.next();
175                 try {
176                     ds.release();
177                 } catch (Exception JavaDoc e) {
178                     log.error("Error while releasing connection pool.", e);
179                     // ignore
180
}
181             }
182         }
183
184         return dataSource.getDataSource();
185     }
186
187     public PooledJdbcDataSourceFactory getPooledJdbcDataSourceFactory() {
188         return pooledJdbcDataSourceFactory;
189     }
190
191     public void setPooledJdbcDataSourceFactory(
192             PooledJdbcDataSourceFactory jdbcDataSourceFactory) {
193         this.pooledJdbcDataSourceFactory = jdbcDataSourceFactory;
194     }
195
196     protected Object JavaDoc createJdbcPoolKey(String JavaDoc driverClass,
197             String JavaDoc url, String JavaDoc username, String JavaDoc password) {
198         return new JdbcPoolKey(driverClass, url, username, password);
199     }
200     
201     protected static class JdbcPoolKey {
202         private final String JavaDoc driverClass;
203         private final String JavaDoc url;
204         private final String JavaDoc username;
205         private final String JavaDoc password;
206         private final int hash;
207
208         public JdbcPoolKey(String JavaDoc driverClass, String JavaDoc url, String JavaDoc username,
209                 String JavaDoc password) {
210             this.driverClass = driverClass;
211             this.url = url;
212             this.username = username;
213             this.password = password;
214
215             int hashCode = 559;
216             if (driverClass != null) {
217                 hashCode += driverClass.hashCode();
218             }
219             hashCode *= 43;
220             if (url != null) {
221                 hashCode += url.hashCode();
222             }
223             hashCode *= 43;
224             if (username != null) {
225                 hashCode += username.hashCode();
226             }
227             hashCode *= 43;
228             if (password != null) {
229                 hashCode += password.hashCode();
230             }
231             
232             hash = hashCode;
233         }
234
235         public boolean equals(Object JavaDoc obj) {
236             if (!(obj instanceof JdbcPoolKey)) {
237                 return false;
238             }
239             if (this == obj) {
240                 return true;
241             }
242             
243             JdbcPoolKey key = (JdbcPoolKey) obj;
244             return
245                 (driverClass == null ? key.driverClass == null : (key.driverClass != null && driverClass.equals(key.driverClass))) &&
246                 (url == null ? key.url == null : (key.url != null && url.equals(key.url))) &&
247                 (username == null ? key.username == null : (key.username != null && username.equals(key.username))) &&
248                 (password == null ? key.password == null : (key.password != null && password.equals(key.password)));
249         }
250
251         public int hashCode() {
252             return hash;
253         }
254
255     }
256
257     public int getPoolTimeout() {
258         return poolTimeout;
259     }
260
261     public void setPoolTimeout(int poolTimeout) {
262         this.poolTimeout = poolTimeout;
263     }
264 }
265
Popular Tags