1 package org.ozoneDB; 9 10 import java.util.ArrayList ; 11 import java.util.Collection ; 12 import java.util.HashMap ; 13 import java.util.Iterator ; 14 15 46 public abstract class AbstractFactory { 47 48 private static class DatabaseInfo { 49 50 private OzoneInterface database; 51 private boolean autoClose = true; 52 private int useCnt = 0; 53 54 public DatabaseInfo(OzoneInterface database) { 55 this.database = database; 56 } 57 58 public final void pin() { 59 useCnt++; 60 } 61 62 public final void unpin() { 63 useCnt--; 64 try { 65 if ((!isPinned()) && getAutoClose() && ((ExternalDatabase) database).isOpen()) { 67 ((ExternalDatabase) database).close(); 68 } 69 } catch (Exception e) { 70 throw new UnexpectedException("could not close database " + e.getMessage()); 71 } 72 } 73 74 public final boolean isPinned() { 75 return useCnt != 0; 76 } 77 78 public final boolean getAutoClose() { 79 return autoClose; 80 } 81 82 public final void setAutoClose(final boolean autoClose) { 83 if (database instanceof ExternalDatabase) { 84 this.autoClose = autoClose; 85 } else { 86 throw new UnexpectedException("cannot change autoClose on server side database"); 87 } 88 } 89 90 public final OzoneInterface getDatabase() { 91 return database; 92 } 93 } 94 95 99 private static Collection factoryClassInfos = new ArrayList (); 100 101 104 private static HashMap databaseInfoMap = new HashMap (); 105 106 107 private static String defaultDatabaseUrl = null; 108 109 111 static void setDefaultDatabase(Database defaultDb) { 112 synchronized(databaseInfoMap) { 115 DatabaseInfo defaultDatabaseInfo = new DatabaseInfo(defaultDb); 116 databaseInfoMap.put(null, defaultDatabaseInfo); 117 } 118 } 119 120 135 public static void setDefaultDatabaseUrl(String url) { 136 synchronized(databaseInfoMap) { 137 if (getDefaultDatabase() instanceof Database) { 138 throw new UnexpectedException("cannot call setDefaultDatabaseUrl() on server/local side"); 139 } 140 defaultDatabaseUrl = url; 141 for (Iterator i = factoryClassInfos.iterator(); i.hasNext(); ) { 142 FactoryClassInfo info = (FactoryClassInfo) i.next(); 143 info.defaultDatabaseUrlChanged(); 144 } 145 } 146 System.gc(); 147 System.runFinalization(); 148 } 149 150 public static String getDefaultDatabaseUrl() { 151 synchronized(databaseInfoMap) { 152 return defaultDatabaseUrl; 153 } 154 } 155 156 protected static OzoneInterface getDefaultDatabase() { 157 synchronized(databaseInfoMap) { 158 DatabaseInfo databaseInfo = (DatabaseInfo) databaseInfoMap.get(getDefaultDatabaseUrl()); 159 return (databaseInfo == null) ? null : databaseInfo.getDatabase(); 160 } 161 } 162 163 protected static void addFactoryClassInfo(FactoryClassInfo info) { 164 synchronized(databaseInfoMap) { 165 factoryClassInfos.add(info); 166 } 167 } 168 169 private String databaseUrl; 170 171 private DatabaseInfo databaseInfo; 172 173 176 protected AbstractFactory() throws Exception { 177 synchronized(databaseInfoMap) { 178 if ((getDefaultDatabase() == null) && (getDefaultDatabaseUrl() == null)) { 179 throw new OzoneRemoteException("default database url not set"); 180 } 181 init(getDefaultDatabaseUrl()); 182 } 183 } 184 185 196 protected AbstractFactory(String databaseUrl) throws Exception { 197 init(databaseUrl); 198 } 199 200 private void init(String databaseUrl) throws Exception { 201 synchronized (databaseInfoMap) { 202 this.databaseUrl = databaseUrl; 203 databaseInfo = (DatabaseInfo) databaseInfoMap.get(databaseUrl); 204 if (databaseInfo == null) { 205 ExternalDatabase db = ExternalDatabase.openDatabase(databaseUrl); 206 databaseInfo = new DatabaseInfo(db); 207 databaseInfoMap.put(databaseUrl, databaseInfo); 208 } 209 databaseInfo.pin(); 210 } 211 } 212 213 218 protected AbstractFactory(AbstractFactory factory) { 219 synchronized (databaseInfoMap) { 220 databaseInfo = (DatabaseInfo) databaseInfoMap.get(factory.getDatabaseUrl()); 221 databaseInfo.pin(); 222 } 223 } 224 225 protected void finalize() throws Throwable { 226 synchronized (databaseInfoMap) { 227 databaseInfo.unpin(); 228 if (!databaseInfo.isPinned()) { 229 databaseInfoMap.remove(getDatabaseUrl()); 232 } 233 } 234 super.finalize(); 235 } 236 237 245 public final void closeDatabase() throws Exception { 246 synchronized (databaseInfoMap) { 247 OzoneInterface db = getDatabase(); 248 if (db instanceof ExternalDatabase) { 249 ((ExternalDatabase) db).close(); 250 databaseInfoMap.remove(getDatabaseUrl()); 251 } else { 252 throw new UnexpectedException("cannot close database on server side"); 253 } 254 } 255 } 256 257 261 abstract protected void defaultClosed(); 262 263 266 public final OzoneInterface getDatabase() { 267 return databaseInfo.getDatabase(); 268 } 269 270 protected final String getDatabaseUrl() { 271 return databaseUrl; 272 } 273 274 279 public final boolean getAutoClose() { 280 return databaseInfo.getAutoClose(); 281 } 282 283 291 public final void setAutoClose(boolean autoClose) { 292 databaseInfo.setAutoClose(autoClose); 293 } 294 295 } | Popular Tags |