KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > cowsultants > itracker > ejb > util > IDCache


1 /*
2  * This software was designed and created by Jason Carroll.
3  * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4  * The author can be reached at jcarroll@cowsultants.com
5  * ITracker website: http://www.cowsultants.com
6  * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it only under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  */

18
19 package cowsultants.itracker.ejb.util;
20
21 import java.sql.*;
22 import java.rmi.*;
23 import java.util.*;
24 import javax.sql.*;
25 import javax.rmi.*;
26 import javax.naming.*;
27
28 import cowsultants.itracker.ejb.client.interfaces.*;
29 import cowsultants.itracker.ejb.client.util.*;
30
31 public class IDCache {
32     private static final String JavaDoc ID_NAME = "idstore";
33     private static final String JavaDoc DEFAULT_TABLE_NAME = "IDSTORE";
34     private static final String JavaDoc DEFAULT_DATASOURCE = "DefaultDS";
35     private static final int DEFAULT_FIRST_ID = 0;
36     private static final int DEFAULT_GROUP_SIZE = 100;
37     private static IDCache generator = null;
38     private static HashMap idCache = new HashMap();
39
40     private static String JavaDoc dataSource;
41     private static String JavaDoc tableName;
42     private static int firstId;
43     private static int groupSize;
44
45     private IDCache() {
46         dataSource = DEFAULT_DATASOURCE;
47         tableName = DEFAULT_TABLE_NAME;
48         firstId = DEFAULT_FIRST_ID;
49         groupSize = DEFAULT_GROUP_SIZE;
50     }
51
52     private IDCache(Object JavaDoc scRef) {
53         try {
54             SystemConfigurationHome scHome = (SystemConfigurationHome) PortableRemoteObject.narrow(scRef, SystemConfigurationHome.class);
55             SystemConfiguration sc = scHome.create();
56
57             dataSource = sc.getProperty("default_ds", DEFAULT_DATASOURCE);
58             tableName = sc.getProperty("idcache_tablename", DEFAULT_TABLE_NAME);
59             firstId = sc.getIntegerProperty("idcache_firstid", DEFAULT_FIRST_ID);
60             groupSize = sc.getIntegerProperty("idcache_groupsize", DEFAULT_GROUP_SIZE);
61         } catch(Exception JavaDoc e) {
62             Logger.logError("ID Cache Initalization Error: " + e.getMessage());
63             dataSource = DEFAULT_DATASOURCE;
64             tableName = DEFAULT_TABLE_NAME;
65             firstId = DEFAULT_FIRST_ID;
66             groupSize = DEFAULT_GROUP_SIZE;
67         }
68
69         if(Logger.isLoggingDebug()) {
70             Logger.logDebug("IDCache Initialized: DataSource = '" + dataSource + "'");
71             Logger.logDebug("IDCache Initialized: TableName = '" + tableName + "'");
72             Logger.logDebug("IDCache Initialized: FirstID = '" + firstId + "'");
73             Logger.logDebug("IDCache Initialized: GroupSize = '" + groupSize + "'");
74         }
75     }
76
77     public static synchronized Integer JavaDoc getNextId(String JavaDoc idName) throws IDException {
78         return getNextId(idName, null);
79     }
80
81     public static synchronized Integer JavaDoc getNextId(String JavaDoc idName, Connection conn) throws IDException {
82         if(generator == null) {
83             generator = new IDCache();
84         }
85         IDCache.CacheValue cacheValue = (IDCache.CacheValue) idCache.get(idName);
86         if(cacheValue == null || cacheValue.maxId == cacheValue.lastId) {
87               getNextIdGroup(idName, conn);
88               cacheValue = (IDCache.CacheValue) idCache.get(idName);
89         }
90         cacheValue.lastId++;
91         idCache.put(idName, cacheValue);
92         //Logger.logDebug("Returning new primary key of " + cacheValue.lastId + " for " + idName);
93
return new Integer JavaDoc(cacheValue.lastId);
94     }
95
96     public static synchronized void initializeCache(Object JavaDoc scRef) {
97         if(generator == null) {
98             generator = new IDCache(scRef);
99         }
100     }
101
102     public static synchronized void resetCache() {
103         if(generator == null) {
104             generator = new IDCache();
105         }
106         idCache.clear();
107     }
108
109     public static synchronized void resetCache(String JavaDoc idName) {
110         if(generator == null) {
111             generator = new IDCache();
112         }
113         idCache.remove(idName);
114     }
115
116     public static synchronized void deleteCache(String JavaDoc idName) throws IDException {
117         if(generator == null) {
118             generator = new IDCache();
119         }
120
121         Connection conn = null;
122
123         try {
124             InitialContext ic = new InitialContext();
125             DataSource ds = (DataSource) ic.lookup(dataSource);
126             conn = ds.getConnection();
127
128             PreparedStatement pstmt = conn.prepareStatement("delete from " + getTableName() + " where name = ?");
129             pstmt.setString(1, idName.toLowerCase());
130             pstmt.executeUpdate();
131             pstmt.close();
132         } catch(NamingException ne) {
133             throw new IDException("Cannot locate Connection Pool: " + ne.getMessage());
134         } catch(SQLException sqle) {
135             throw new IDException("Database Error while deleting cache value: " + sqle.getMessage());
136         } finally {
137             try {
138                 if(conn != null && ! conn.isClosed()) {
139                     conn.close();
140                 }
141             } catch(SQLException sqle) {
142                 throw new IDException("Database Error while deleting cache value: " + sqle.getMessage());
143             }
144         }
145     }
146
147     public static String JavaDoc getTableName() {
148         return tableName;
149     }
150
151     public static int getFirstId() {
152         return firstId;
153     }
154
155     public static int getGroupSize() {
156         return groupSize;
157     }
158
159     private static synchronized void getNextIdGroup(String JavaDoc idName) throws IDException {
160         getNextIdGroup(idName, null);
161     }
162
163     private static synchronized void getNextIdGroup(String JavaDoc idName, Connection conn) throws IDException {
164         boolean closeConnection = false;
165         int lastId;
166         int nextId;
167
168         try {
169             if(conn == null) {
170                 InitialContext ic = new InitialContext();
171                 DataSource ds = (DataSource) ic.lookup(dataSource);
172                 conn = ds.getConnection();
173                 closeConnection = true;
174             }
175
176             Logger.logDebug("IDCache: Getting next id block from database.");
177
178             PreparedStatement pstmt = conn.prepareStatement("select last_id from " + getTableName() + " where name = ?");
179             pstmt.setString(1, idName.toLowerCase());
180             ResultSet rs = pstmt.executeQuery();
181             if(! rs.next()) {
182                 pstmt.close();
183                 createNewID(idName, conn);
184             } else {
185                 try {
186                     lastId = Integer.parseInt(rs.getString(1));
187                     nextId = lastId + getGroupSize();
188                 } catch(NumberFormatException JavaDoc nfe) {
189                     throw new IDException("Invalid id in current table: " + rs.getString(1));
190                 }
191                 rs.close();
192                 pstmt.close();
193
194                 Logger.logDebug("IDCache: Next id block is from " + (lastId + 1) + " to " + nextId);
195
196                 pstmt = conn.prepareStatement("update " + getTableName() + " set last_id = ? where name = ?");
197                 pstmt.setString(1, Integer.toString(nextId));
198                 pstmt.setString(2, idName);
199                 int affectedRows = pstmt.executeUpdate();
200                 pstmt.close();
201                 if(affectedRows != 1) {
202                     throw new IDException("Error incrementing id for " + idName);
203                 }
204                 IDCache.CacheValue cacheValue = generator.new CacheValue();
205                 cacheValue.setValues(idName, lastId, nextId);
206                 idCache.put(idName, cacheValue);
207             }
208         } catch(NamingException ne) {
209             throw new IDException("Cannot locate Connection Pool: " + ne.getMessage());
210         } catch(SQLException sqle) {
211             throw new IDException("Database Error while getting next id: " + sqle.getMessage());
212         } finally {
213             if(closeConnection) {
214                 try {
215                     if(conn != null && ! conn.isClosed()) {
216                         conn.close();
217                     }
218                 } catch(SQLException sqle) {
219                     throw new IDException("Database Error while getting next id: " + sqle.getMessage());
220                 }
221             }
222         }
223     }
224
225     private static synchronized void createNewID(String JavaDoc idName, Connection conn) throws IDException {
226         Logger.logDebug("IDCache: Creating new id group " + idName);
227
228         try {
229             String JavaDoc nextId;
230             if(ID_NAME.equals(idName)) {
231                 Logger.logWarn("Could not find " + ID_NAME + " entry in the " + getTableName() + " table. " +
232                                "Creating new entry with value of 1.");
233                 nextId = "1";
234             } else {
235                 nextId = getNextId(ID_NAME, conn).toString();
236             }
237
238             PreparedStatement pstmt = conn.prepareStatement("insert into " + getTableName() + " (id, name, last_id) values (?, ?, ?)");
239             pstmt.setString(1, nextId);
240             pstmt.setString(2, idName.toLowerCase());
241             pstmt.setString(3, Integer.toString(getFirstId() + getGroupSize()));
242
243             pstmt.executeUpdate();
244             pstmt.close();
245
246             IDCache.CacheValue cacheValue = generator.new CacheValue();
247             cacheValue.setValues(idName, getFirstId(), getFirstId() + getGroupSize());
248             idCache.put(idName, cacheValue);
249         } catch(SQLException sqle) {
250             throw new IDException("Database Error while creating new id: " + sqle.getMessage());
251         }
252     }
253
254     private class CacheValue {
255         private IDCache container;
256         public String JavaDoc name;
257         public int lastId;
258         public int maxId;
259
260         public void CacheValue(IDCache generator) {
261             container = generator;
262         }
263
264         public void setValues(String JavaDoc nameIn, int lastIdIn, int maxIdIn) {
265             name = nameIn;
266             lastId = lastIdIn;
267             maxId = maxIdIn;
268         }
269     }
270
271
272 }
273
274
Popular Tags