001: package net.sourceforge.squirrel_sql.client.session.schemainfo;
002:
003: import java.io.File;
004: import java.io.FileInputStream;
005: import java.io.FileOutputStream;
006: import java.io.IOException;
007: import java.io.ObjectInputStream;
008: import java.io.ObjectOutputStream;
009: import java.io.ObjectStreamClass;
010: import java.util.Hashtable;
011:
012: import net.sourceforge.squirrel_sql.client.gui.db.ISQLAliasExt;
013: import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias;
014: import net.sourceforge.squirrel_sql.client.session.ISession;
015: import net.sourceforge.squirrel_sql.client.util.ApplicationFiles;
016: import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
017: import net.sourceforge.squirrel_sql.fw.util.IMessageHandler;
018: import net.sourceforge.squirrel_sql.fw.util.StringManager;
019: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
020: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
021: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
022:
023: public class SchemaInfoCacheSerializer {
024: private static final StringManager s_stringMgr = StringManagerFactory
025: .getStringManager(SchemaInfoCacheSerializer.class);
026:
027: private static final ILogger s_log = LoggerController
028: .createLogger(SchemaInfoCacheSerializer.class);
029: private static Hashtable<IIdentifier, IIdentifier> _storingSessionIDs = new Hashtable<IIdentifier, IIdentifier>();
030:
031: public static SchemaInfoCache load(ISession session) {
032: SchemaInfoCache ret = privateLoad(session);
033: ret.setSession(session);
034:
035: return ret;
036: }
037:
038: private static SchemaInfoCache privateLoad(ISession session) {
039: File schemaCacheFile = getSchemaCacheFile(session.getAlias());
040:
041: if (false == session.getAlias().getSchemaProperties()
042: .getExpectsSomeCachedData()) {
043: // Current Alias Schema properties dont want cache.
044: // so we don't cache.
045:
046: try {
047: if (schemaCacheFile.exists()
048: && false == schemaCacheFile.delete()) {
049: s_log.error("Failed to delete Schema cache file "
050: + schemaCacheFile.getPath());
051: }
052: } catch (Exception e) {
053: s_log.error("Could not delete Schema cache file "
054: + schemaCacheFile.getPath(), e);
055: }
056:
057: return new SchemaInfoCache();
058: }
059:
060: if (false == schemaCacheFile.exists()) {
061: return new SchemaInfoCache();
062: }
063:
064: try {
065: FileInputStream fis = new FileInputStream(schemaCacheFile);
066: ObjectInputStream ois = new ObjectInputStream(fis) {
067: protected Class<?> resolveClass(ObjectStreamClass desc)
068: throws IOException, ClassNotFoundException {
069: ClassLoader loader = SchemaInfoCache.class
070: .getClassLoader();
071: return Class.forName(desc.getName(), false, loader);
072: }
073: };
074: SchemaInfoCache ret = (SchemaInfoCache) ois.readObject();
075: ois.close();
076: fis.close();
077:
078: return ret;
079: } catch (Exception e) {
080: s_log
081: .error(
082: "Failed to load Schema cache. Note: this can happen when the SQuirreL version changed",
083: e);
084: return new SchemaInfoCache();
085: }
086: }
087:
088: public static void store(final ISession session,
089: final SchemaInfoCache schemaInfoCache) {
090:
091: _storingSessionIDs.put(session.getIdentifier(), session
092: .getIdentifier());
093: session.getApplication().getThreadPool().addTask(
094: new Runnable() {
095: public void run() {
096: privateStore(schemaInfoCache, session);
097: }
098: });
099:
100: }
101:
102: private static void privateStore(SchemaInfoCache schemaInfoCache,
103: ISession session) {
104: try {
105: if (false == session.getAlias().getSchemaProperties()
106: .getExpectsSomeCachedData()) {
107: return;
108: }
109:
110: IMessageHandler msgHandler = session.getApplication()
111: .getMessageHandler();
112: File schemaCacheFile = getSchemaCacheFile(session
113: .getAlias());
114:
115: String params[] = { session.getAlias().getName(),
116: schemaCacheFile.getPath() };
117: // i18n[SchemaInfoCacheSerializer.beginStore=Starting to write schema cache for Alias {0}. file: {1}]
118: msgHandler.showMessage(s_stringMgr.getString(
119: "SchemaInfoCacheSerializer.beginStore", params));
120:
121: schemaInfoCache.prepareSerialization();
122:
123: FileOutputStream fos = new FileOutputStream(schemaCacheFile);
124: ObjectOutputStream oOut = new ObjectOutputStream(fos);
125: oOut.writeObject(schemaInfoCache);
126: oOut.close();
127: fos.close();
128:
129: // i18n[SchemaInfoCacheSerializer.endStore=Finished writing schema cache for Alias{0}. file: {1}]
130: msgHandler.showMessage(s_stringMgr.getString(
131: "SchemaInfoCacheSerializer.endStore", params));
132:
133: } catch (Exception e) {
134: s_log.error("Failed to write Schema cache file ", e);
135: } finally {
136: synchronized (SchemaInfoCacheSerializer.class) {
137: _storingSessionIDs.remove(session.getIdentifier());
138: if (0 == _storingSessionIDs.size()) {
139: SchemaInfoCacheSerializer.class.notifyAll();
140: }
141: }
142:
143: }
144: }
145:
146: public static void waitTillStoringIsDone() {
147: try {
148: synchronized (SchemaInfoCacheSerializer.class) {
149: if (0 < _storingSessionIDs.size()) {
150: SchemaInfoCacheSerializer.class.wait(30000);
151: }
152: }
153: } catch (InterruptedException e) {
154: s_log
155: .error(
156: "Error waiting for SchemaInfoCacheSerializer to finish storing",
157: e);
158: }
159: }
160:
161: public static File getSchemaCacheFile(ISQLAliasExt alias) {
162: String uniquePrefix = alias.getIdentifier().toString();
163:
164: uniquePrefix = uniquePrefix.replace(':', '_').replace(
165: File.separatorChar, '-');
166:
167: String path = new ApplicationFiles().getUserSettingsDirectory()
168: .getPath()
169: + File.separator
170: + "schemacaches"
171: + File.separator
172: + uniquePrefix + "_schemacache.ser";
173:
174: File ret = new File(path);
175: ret.getParentFile().mkdirs();
176:
177: return ret;
178:
179: }
180:
181: public static void aliasRemoved(SQLAlias alias) {
182: File schemaCacheFile = getSchemaCacheFile(alias);
183: if (schemaCacheFile.exists()) {
184: schemaCacheFile.delete();
185: }
186: }
187: }
|