001: /*
002: * Copyright 2000-2005 by Mark A. Kobold
003: *
004: * The contents of this file are subject to the Mozilla Public License Version
005: * 1.1 (the "License"); you may not use this file except in compliance with the
006: * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
010: * the specific language governing rights and limitations under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is Markus A. Kobold.
015: *
016: * Portions created by Mark A. Kobold are Copyright (C)
017: * 2000-2005 Mark A. Kobold. All Rights Reserved.
018: *
019: * Contributor(s):
020: * Mark A. Kobold <mkobold@isqlviewer.com>.
021: *
022: * Contributor(s): all the names of the contributors are added in the source
023: * code where applicable.
024: *
025: * If you didn't download this code from the following link, you should check
026: * if you aren't using an obsolete version: http://isql.sourceforge.net/
027: */
028: package org.isqlviewer.util;
029:
030: import java.io.File;
031: import java.io.FileInputStream;
032: import java.io.FileOutputStream;
033: import java.io.IOException;
034: import java.io.InputStream;
035: import java.io.ObjectInputStream;
036: import java.io.ObjectOutputStream;
037: import java.net.URL;
038: import java.security.Key;
039: import java.security.NoSuchAlgorithmException;
040: import java.text.MessageFormat;
041: import java.util.Properties;
042:
043: import javax.crypto.KeyGenerator;
044:
045: import org.apache.log4j.Logger;
046: import org.isqlviewer.xml.SaxResolver;
047: import org.xml.sax.EntityResolver;
048:
049: /**
050: * Toolkit for providing generally static information regarding the iSQL-Viewer application.
051: * <p>
052: *
053: * @author Mark A. Kobold <mkobold at isqlviewer dot com>
054: * @version 1.0
055: */
056: public final class IsqlToolkit {
057:
058: /**
059: * Major version of the iSQL-Viewer code base.
060: * <p>
061: */
062: public static final int VERSION_MAJOR = 3;
063: /**
064: * Minor version of the iSQL-Viewer code base.
065: * <p>
066: */
067: public static final int VERSION_MINOR = 0;
068: /**
069: * Build number or patch level version of the iSQL-Viewer code base.
070: * <p>
071: */
072: public static final int VERSION_BUILD = 0;
073: /**
074: * System property for determining if the iSQL-Viewer MRJ Adapter is installed.
075: */
076: public static final String PROPERTY_MRJ_ENABLED = "isql.mrj.enabled";
077: /**
078: * System property for the fully qualified path where iSQL-Viewer stores related files.
079: */
080: public static final String PROPERTY_HOME = "isql.home";
081: /**
082: * System property for defining the default location for log files.
083: */
084: public static final String PROPERTY_LOGGING_HOME = "isql.logging.home";
085: /**
086: * System property for the fully qualified path for the looking for plugins.
087: */
088: public static final String PROPERTY_PLUGIN_HOME = "isql.plugin.home";
089: /**
090: * System property for the current version of iSQL-Viewer currently running.
091: */
092: public static final String PROPERTY_VERSION = "isql.version";
093: /**
094: * System property flag to indicate that iSQL-Viewer is running embedded or is controlled by another application.
095: */
096: public static final String PROPERTY_STANDALONE = "isql.stand-alone";
097: /**
098: * System property flag that contains the preferences root, this can be useful when running embedded.
099: */
100: public static final String PROPERTY_DEFAULTS_ROOT = "isql.prefs.root";
101:
102: private static final String BookmarkDtdPublicId = "-//iSQL-Viewer.org.//DTD JDBC Bookmarks 2.1.8//EN";
103: private static final String BookmarkDtdResourcePath = "/org/isqlviewer/resource/xml/bookmarks.dtd";
104:
105: private static final String ServiceDtdPublicId_2 = "-//iSQL-Viewer.org.//DTD JDBC Service Definition 2.1.8//EN";
106: private static final String ServiceDtdResourcePath_2 = "/org/isqlviewer/resource/xml/service_2_x.dtd";
107:
108: private static final String ServiceDtdPublicId_3 = "-//iSQL-Viewer.org.//DTD JDBC Service Definition 3.0.0//EN";
109: private static final String ServiceDtdResourcePath_3 = "/org/isqlviewer/resource/xml/service_3_x.dtd";
110: private static final String ENCRYPTION_ALGORITHIM = "DESede";
111:
112: private static final File baseDirectory;
113: private static final File loggingDirectory;
114: private static final File pluginDirectory;
115:
116: private static final String DRIVER_DEFINITIONS_FILE = "driver.properties";
117: private static final String BOOKMARKS_FILE_NAME = "bookmarks.xml";
118: private static final SaxResolver entityResolver;
119:
120: private static final Key localEncryptionKey;
121:
122: static {
123:
124: Properties systemProperties = System.getProperties();
125: boolean exists = false;
126: File location = null;
127:
128: systemProperties.put(PROPERTY_VERSION, getVersionInfo());
129: exists = systemProperties.containsKey(PROPERTY_HOME);
130: if (!exists) {
131: String defaultValue = new File(System
132: .getProperty("user.home"), ".iSQL-Viewer")
133: .getAbsolutePath();
134: systemProperties.setProperty(PROPERTY_HOME, defaultValue);
135: }
136: location = new File(systemProperties.getProperty(PROPERTY_HOME));
137: location.mkdirs();
138: baseDirectory = location;
139:
140: exists = systemProperties.containsKey(PROPERTY_LOGGING_HOME);
141: if (!exists) {
142: String defaultValue = new File(System
143: .getProperty(PROPERTY_HOME), "logs")
144: .getAbsolutePath();
145: systemProperties.setProperty(PROPERTY_LOGGING_HOME,
146: defaultValue);
147: }
148: location = new File(systemProperties
149: .getProperty(PROPERTY_LOGGING_HOME));
150: location.mkdirs();
151: loggingDirectory = location;
152:
153: exists = systemProperties.containsKey(PROPERTY_PLUGIN_HOME);
154: if (!exists) {
155: String defaultValue = new File(System
156: .getProperty(PROPERTY_HOME), "plugins")
157: .getAbsolutePath();
158: systemProperties.setProperty(PROPERTY_PLUGIN_HOME,
159: defaultValue);
160: }
161: location = new File(systemProperties
162: .getProperty(PROPERTY_PLUGIN_HOME));
163: location.mkdirs();
164: pluginDirectory = location;
165:
166: exists = systemProperties.containsKey(PROPERTY_DEFAULTS_ROOT);
167: if (!exists) {
168: String defaultValue = "/org/isqlviewer/preferences";
169: systemProperties.setProperty(PROPERTY_DEFAULTS_ROOT,
170: defaultValue);
171: }
172:
173: exists = systemProperties.containsKey(PROPERTY_STANDALONE);
174: if (!exists) {
175: String defaultValue = Boolean.FALSE.toString();
176: systemProperties.setProperty(PROPERTY_STANDALONE,
177: defaultValue);
178: }
179:
180: Key existingKey = loadExistingPrivateKey();
181: if (existingKey == null) {
182: try {
183: KeyGenerator generator = KeyGenerator
184: .getInstance(ENCRYPTION_ALGORITHIM);
185: localEncryptionKey = generator.generateKey();
186: saveEncryptionKey();
187: } catch (NoSuchAlgorithmException nsae) {
188: throw new RuntimeException(nsae);
189: }
190: } else {
191: localEncryptionKey = existingKey;
192: }
193:
194: entityResolver = new SaxResolver();
195: entityResolver.register(BookmarkDtdPublicId,
196: BookmarkDtdResourcePath, IsqlToolkit.class);
197: entityResolver.register(ServiceDtdPublicId_2,
198: ServiceDtdResourcePath_2, IsqlToolkit.class);
199: entityResolver.register(ServiceDtdPublicId_3,
200: ServiceDtdResourcePath_3, IsqlToolkit.class);
201: }
202:
203: private IsqlToolkit() {
204:
205: // nothing to do or see here.
206: }
207:
208: /**
209: * Gets the version string for this application instance.
210: * <p>
211: *
212: * @return version string for the current instance of iSQL-Viewer.
213: */
214: public static String getVersionInfo() {
215:
216: return VERSION_MAJOR + "." + VERSION_MINOR + "."
217: + VERSION_BUILD;
218: }
219:
220: /**
221: * Gets the base directory for all iSQL-Viewer system files.
222: * <p>
223: * This value can also be queried by the System property 'isql.home'. Metaphorically speaking this location is where
224: * iSQL-Viewer sets up camp and most files loaded by iSQL-Viewer are loaded relative to this location.
225: *
226: * @return File instance where iSQL-Viewer stores its main configuration files.
227: */
228: public static synchronized File getBaseDirectory() {
229:
230: return baseDirectory;
231: }
232:
233: /**
234: * Gets the default location to look for application plug-ins from.
235: * <p>
236: *
237: * @return file location where plug-in components are loaded from.
238: */
239: public static synchronized File getPluginDirectory() {
240:
241: return pluginDirectory;
242: }
243:
244: /**
245: * Gets the default location to write log files to.
246: * <p>
247: *
248: * @return file location where log files are written to.
249: */
250: public static synchronized File getLoggingDirectory() {
251:
252: return loggingDirectory;
253: }
254:
255: /**
256: * Gets the root node for all application preferences to reside from.
257: * <p>
258: *
259: * @return location where to store all preferences from.
260: * @see java.util.prefs.Preferences
261: */
262: public static String getRootPreferencesNode() {
263:
264: return System.getProperty(PROPERTY_DEFAULTS_ROOT);
265: }
266:
267: /**
268: * Loads the defaults driver class to example URL mappings file.
269: * <p>
270: *
271: * @return properties file that contains class names to JDBC connection strings.
272: */
273: public static Properties getDefaultDriverDefinitions() {
274:
275: Properties props = new Properties();
276: InputStream inputStream = null;
277: try {
278: URL url = IsqlToolkit.class
279: .getResource("/org/isqlviewer/resource/"
280: .concat(DRIVER_DEFINITIONS_FILE));
281: inputStream = url.openStream();
282: props.load(inputStream);
283: } catch (Throwable t) {
284: // TODO log error//
285: } finally {
286: if (inputStream != null) {
287: try {
288: inputStream.close();
289: } catch (Throwable ignored) {
290: }
291: }
292: }
293: return props;
294: }
295:
296: public static Logger getApplicationLogger() {
297:
298: return Logger.getLogger("org.isqlviewer");
299: }
300:
301: /**
302: * Gets an instance of an entity resolver for this runtime.
303: * <p>
304: * This entity resolver is setup to resolve all the iSQL-Viewer specific DTDs.
305: *
306: * @return shared instance of an entity resolver.
307: */
308: public static EntityResolver getSharedEntityResolver() {
309:
310: return entityResolver;
311: }
312:
313: /**
314: * Gets the default file location for the iSQL-Viewer bookmarks XML file.
315: * <p>
316: *
317: * @return file location of the iSQL-Viewer bookmarks file.
318: */
319: public static File getDefaultBookmarksFile() {
320:
321: return new File(IsqlToolkit.getBaseDirectory(),
322: BOOKMARKS_FILE_NAME);
323: }
324:
325: public static Key getEncryptionKey() {
326:
327: return localEncryptionKey;
328: }
329:
330: private static void saveEncryptionKey() {
331:
332: String fileName = MessageFormat.format(".{0}.key",
333: new Object[] { ENCRYPTION_ALGORITHIM });
334: File keyFile = new File(getBaseDirectory(), fileName);
335: FileOutputStream outputStream = null;
336: try {
337: outputStream = new FileOutputStream(keyFile);
338: ObjectOutputStream objectOutput = new ObjectOutputStream(
339: outputStream);
340: objectOutput.writeObject(localEncryptionKey);
341: objectOutput.flush();
342: } catch (IOException ignored) {
343: } finally {
344: if (outputStream != null) {
345: try {
346: outputStream.close();
347: } catch (Exception ignored) {
348: }
349: }
350: }
351: }
352:
353: private static Key loadExistingPrivateKey() {
354:
355: String fileName = MessageFormat.format(".{0}.key",
356: new Object[] { ENCRYPTION_ALGORITHIM });
357: File keyFile = new File(getBaseDirectory(), fileName);
358: FileInputStream inputStream = null;
359: try {
360: inputStream = new FileInputStream(keyFile);
361: ObjectInputStream objectInput = new ObjectInputStream(
362: inputStream);
363: return (Key) objectInput.readObject();
364: } catch (IOException ignored) {
365: } catch (ClassNotFoundException ignored) {
366: } finally {
367: if (inputStream != null) {
368: try {
369: inputStream.close();
370: } catch (Exception ignored) {
371: }
372: }
373: }
374: return null;
375: }
376: }
|