1 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 ID_NAME = "idstore"; 33 private static final String DEFAULT_TABLE_NAME = "IDSTORE"; 34 private static final String 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 dataSource; 41 private static String 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 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 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 getNextId(String idName) throws IDException { 78 return getNextId(idName, null); 79 } 80 81 public static synchronized Integer getNextId(String 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 return new Integer (cacheValue.lastId); 94 } 95 96 public static synchronized void initializeCache(Object 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 idName) { 110 if(generator == null) { 111 generator = new IDCache(); 112 } 113 idCache.remove(idName); 114 } 115 116 public static synchronized void deleteCache(String 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 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 idName) throws IDException { 160 getNextIdGroup(idName, null); 161 } 162 163 private static synchronized void getNextIdGroup(String 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 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 idName, Connection conn) throws IDException { 226 Logger.logDebug("IDCache: Creating new id group " + idName); 227 228 try { 229 String 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 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 nameIn, int lastIdIn, int maxIdIn) { 265 name = nameIn; 266 lastId = lastIdIn; 267 maxId = maxIdIn; 268 } 269 } 270 271 272 } 273 274 | Popular Tags |