001: /*
002: * SystemUtilities.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.executequery;
023:
024: import java.awt.print.PageFormat;
025: import java.io.File;
026: import java.io.IOException;
027: import java.util.Vector;
028:
029: import org.executequery.databasemediators.ConnectionBuilder;
030: import org.executequery.event.ConnectionEvent;
031: import org.executequery.event.ConnectionListener;
032: import org.executequery.databasemediators.DatabaseConnection;
033: import org.executequery.datasource.ConnectionManager;
034: import org.underworldlabs.jdbc.DataSourceException;
035: import org.executequery.gui.SaveOnExitDialog;
036: import org.executequery.gui.editor.QueryEditorSettings;
037:
038: import org.executequery.print.PrintUtilities;
039: import org.underworldlabs.util.FileUtils;
040: import org.underworldlabs.util.MiscUtils;
041:
042: import org.executequery.gui.SaveFunction;
043: import org.executequery.util.Log;
044: import org.executequery.util.SystemResources;
045: import org.underworldlabs.swing.GUIUtils;
046: import org.underworldlabs.util.SystemProperties;
047:
048: /* ----------------------------------------------------------
049: * CVS NOTE: Changes to the CVS repository prior to the
050: * release of version 3.0.0beta1 has meant a
051: * resetting of CVS revision numbers.
052: * ----------------------------------------------------------
053: */
054:
055: /**
056: *
057: * @author Takis Diakoumis
058: * @version $Revision: 1.12 $
059: * @date $Date: 2006/09/30 03:39:36 $
060: */
061: public class SystemUtilities {
062:
063: /** The user history file - ~/.executequery/sql-command.history */
064: private static String historyFile;
065:
066: /** The user recent files file - ~/.executequery/recent.files */
067: private static String recentFile;
068:
069: /** The user defined properties directory - ~/.executequery/conf */
070: private static String userPropertiesPath;
071:
072: /** The user specific log directory - ~/.executequery/logs */
073: private static String userLogsPath;
074:
075: /** An array of saved connections */
076: private static DatabaseConnection[] connections;
077:
078: /** The printing page format */
079: private static PageFormat pageFormat;
080:
081: /**
082: * Returns the user log directory usually ~/executequery/build_number.
083: */
084: public static String getUserPropertiesPath() {
085: return userPropertiesPath;
086: }
087:
088: /**
089: * Returns the user log directory usually ~/executequery/logs.
090: */
091: public static String getUserLogsPath() {
092: return userLogsPath;
093: }
094:
095: /**
096: * Returns the system log absolute file path.
097: */
098: public static String getSystemLogPath() {
099: return getUserLogsPath()
100: + SystemProperties.getProperty("system",
101: "eq.output.log");
102: }
103:
104: /**
105: * Initializes system logging and config file paths.
106: */
107: public static void startup() {
108: String fileSeparator = System.getProperty("file.separator");
109:
110: StringBuffer sb = new StringBuffer();
111:
112: // build the sql command history file path
113: sb
114: .append(System.getProperty("user.home"))
115: .append(fileSeparator)
116: .append(
117: System
118: .getProperty("executequery.user.home.dir"))
119: .append(fileSeparator).append("sql-command.history");
120: historyFile = sb.toString();
121:
122: sb.setLength(0);
123:
124: // build the recent files history file path
125: sb
126: .append(System.getProperty("user.home"))
127: .append(fileSeparator)
128: .append(
129: System
130: .getProperty("executequery.user.home.dir"))
131: .append(fileSeparator).append("recent.files");
132: recentFile = sb.toString();
133:
134: sb.setLength(0);
135:
136: // build the user properties home path
137: sb
138: .append(System.getProperty("user.home"))
139: .append(fileSeparator)
140: .append(
141: System
142: .getProperty("executequery.user.home.dir"))
143: .append(fileSeparator).append(
144: System.getProperty("executequery.build"))
145: .append(fileSeparator);
146: userPropertiesPath = sb.toString();
147:
148: sb.setLength(0);
149:
150: // build the logs directory path
151: sb
152: .append(System.getProperty("user.home"))
153: .append(fileSeparator)
154: .append(
155: System
156: .getProperty("executequery.user.home.dir"))
157: .append(fileSeparator).append("logs").append(
158: fileSeparator);
159: userLogsPath = sb.toString();
160:
161: boolean dirsCreated = SystemResources
162: .createUserHomeDirSettings();
163:
164: if (!dirsCreated) {
165: System.exit(0);
166: }
167:
168: }
169:
170: /**
171: * Updates/sets the internet proxy settings.
172: */
173: public static void initProxySettings() {
174: if (SystemProperties.getBooleanProperty("user",
175: "internet.proxy.set")) {
176: System.getProperties().put(
177: "http.proxyHost",
178: SystemProperties.getProperty("user",
179: "internet.proxy.host"));
180: System.getProperties().put(
181: "http.proxyPort",
182: SystemProperties.getProperty("user",
183: "internet.proxy.port"));
184: } else {
185: System.getProperties().remove("http.proxyHost");
186: System.getProperties().remove("http.proxyPort");
187: }
188: }
189:
190: /**
191: * Returns the recent open files list as an array of strings.
192: *
193: * @return the recent file paths
194: */
195: public static final String[] getRecentFilesList() {
196: try {
197: String files = FileUtils.loadFile(recentFile);
198:
199: if (MiscUtils.isNull(files)) {
200: return new String[0];
201: } else {
202: return MiscUtils.splitSeparatedValues(files, "\n");
203: }
204:
205: } catch (IOException e) {
206: return new String[0];
207: }
208: }
209:
210: /**
211: * Adds the specified file to the recently opened files list.
212: *
213: * @param file - the file to be added
214: */
215: public static final boolean addRecentOpenFile(String file) {
216: try {
217: String[] files = getRecentFilesList();
218:
219: Vector vFiles = new Vector(files.length);
220: for (int i = 0; i < files.length; i++) {
221: vFiles.add(files[i]);
222: }
223:
224: // if it already exists in the list,
225: // move it to the top of the list
226: if (MiscUtils.containsValue(files, file)) {
227: vFiles.add(0, file);
228: for (int i = 1, k = vFiles.size(); i < k; i++) {
229: String _file = vFiles.elementAt(i).toString();
230: if (_file.equals(file)) {
231: vFiles.remove(i);
232: break;
233: }
234: }
235: } else {
236: int maxFiles = SystemProperties.getIntProperty("user",
237: "recent.files.count");
238: if (files.length >= maxFiles) {
239: vFiles.remove(files.length - 1);
240: }
241: vFiles.add(0, file);
242: }
243:
244: StringBuffer sb = new StringBuffer();
245: for (int i = 0, k = vFiles.size(); i < k; i++) {
246: sb.append(vFiles.elementAt(i));
247: if (i != k - 1) {
248: sb.append(Constants.NEW_LINE_STRING);
249: }
250: }
251: FileUtils.writeFile(recentFile, sb.toString());
252: return true;
253: } catch (IOException ioExc) {
254: GUIUtilities
255: .displayErrorMessage("An IO error occurred writing to the recent open files list:\n"
256: + ioExc.getMessage());
257: return false;
258: }
259: }
260:
261: /**
262: * Returns the SQL command history executed within the
263: * query editor and saved to file.
264: *
265: * @return a Vector containing previously executed queries
266: */
267: public static final Vector getSqlCommandHistory() {
268: Vector history = null;
269: try {
270: File file = new File(historyFile);
271: if (!file.exists()) {
272: history = new Vector();
273: } else {
274: Object object = FileUtils.readObject(historyFile);
275: if (object == null || !(object instanceof Vector)) {
276: history = new Vector();
277: } else {
278: history = (Vector) object;
279: }
280: }
281: } catch (IOException ioExc) {
282: GUIUtilities
283: .displayErrorMessage("An IO error occurred reading previously "
284: + "executed history:\n"
285: + ioExc.getMessage());
286: history = new Vector();
287: }
288: return history;
289: }
290:
291: /**
292: * Clears the SQL command history.
293: */
294: public static final void clearSqlCommandHistory() {
295: try {
296: FileUtils.writeObject(new Vector(), historyFile);
297: } catch (IOException ioExc) {
298: }
299: }
300:
301: /**
302: * Adds the specified query to the SQL command list and
303: * saves this to file.
304: */
305: public static final void addSqlCommand(String query) {
306: final Vector history = getSqlCommandHistory();
307:
308: int size = history.size();
309: if (size == QueryEditorSettings.getHistoryMax()) {
310: history.removeElementAt(size - 1);
311: }
312:
313: history.add(0, query);
314:
315: GUIUtils.startWorker(new Runnable() {
316: public void run() {
317: try {
318: FileUtils.writeObject(history, historyFile);
319: } catch (IOException ioExc) {
320: GUIUtilities
321: .displayErrorMessage("An IO error occurred adding the previously "
322: + "executed query to history:\n"
323: + ioExc.getMessage());
324: }
325: }
326: });
327: }
328:
329: /**
330: * Returns whether database resources are available on
331: * any connection within any pool.
332: *
333: * @return whether a connection to a database exists
334: */
335: public static boolean isConnected() {
336: return ConnectionManager.getActiveConnectionPoolCount() > 0;
337: }
338:
339: /**
340: * Disconnects the specified connection.
341: *
342: * @param dc - the connection to be disconnected
343: */
344: public static final void disconnect(DatabaseConnection dc)
345: throws DataSourceException {
346: ConnectionManager.closeConnection(dc);
347: EventMediator.fireEvent(new ConnectionEvent(dc),
348: ConnectionListener.DISCONNECTED);
349: updateStatusActiveConnections();
350: }
351:
352: /**
353: * Updates the first status bar label with the active connection pool
354: * data source count.
355: */
356: public static void updateStatusActiveConnections() {
357: GUIUtilities.getStatusBar().setFirstLabelText(
358: " Active Data Sources: "
359: + ConnectionManager
360: .getActiveConnectionPoolCount());
361: }
362:
363: /**
364: * Returns the open connection count for the specified connection.
365: *
366: * @param dc - the connection to be polled
367: */
368: public static int getOpenConnectionCount(DatabaseConnection dc) {
369: return ConnectionManager.getOpenConnectionCount(dc);
370: }
371:
372: public static final boolean connect(DatabaseConnection dc)
373: throws DataSourceException {
374:
375: ConnectionBuilder builder = null;
376: try {
377: builder = new ConnectionBuilder();
378: builder.establishConnection(dc);
379:
380: if (builder.isCancelled()) {
381: return false;
382: }
383:
384: boolean connected = builder.isConnected();
385: if (!connected) {
386: DataSourceException e = builder.getException();
387: if (e != null) {
388: throw e;
389: } else {
390: throw new RuntimeException(
391: "Unknown error establishing connection.");
392: }
393: }
394:
395: EventMediator.fireEvent(new ConnectionEvent(dc),
396: ConnectionListener.CONNECTED);
397:
398: GUIUtils.scheduleGC();
399: return true;
400: } finally {
401: if (builder != null) {
402: builder.finished();
403: }
404: updateStatusActiveConnections();
405: }
406:
407: }
408:
409: public static final DatabaseConnection[] getSavedConnections() {
410: if (connections == null) {
411: connections = ConnectionProperties.getConnectionsArray();
412: setSavedConnections(connections);
413: }
414: return connections;
415: }
416:
417: public static void setSavedConnections(
418: DatabaseConnection[] _savedConns) {
419: connections = _savedConns;
420: }
421:
422: /**
423: * Returns the running Java VM version in full format using
424: * <code>System.getProperty("java.version")</code>.
425: *
426: * @return the Java VM version
427: */
428: public static final String getVMVersionFull() {
429: return System.getProperty("java.version");
430: }
431:
432: /**
433: * Returns the running Java VM version in short format (major versio only)
434: * using <code>System.getProperty("java.version")</code>.
435: *
436: * @return the Java VM version
437: */
438: public static final double getVMVersion() {
439: return Double.parseDouble(System.getProperty("java.version")
440: .substring(0, 3));
441: }
442:
443: /**
444: * Returns the user defined setting for prompt to save open
445: * documents/files etc before closing.
446: *
447: * @return true | false
448: */
449: public static boolean isPromptingToSave() {
450: return SystemProperties.getBooleanProperty("user",
451: "general.save.prompt");
452: }
453:
454: /**
455: * Program shutdown method.
456: * Does some logging and closes connections cleanly.
457: */
458: public static void exitProgram() {
459:
460: if (SystemProperties.getBooleanProperty("user",
461: "general.save.prompt")
462: && GUIUtilities.hasValidSaveFunction()) {
463:
464: if (GUIUtilities.getOpenSaveFunctionCount() > 0) {
465: SaveOnExitDialog exitDialog = new SaveOnExitDialog();
466:
467: int result = exitDialog.getResult();
468: if (result != SaveFunction.SAVE_COMPLETE
469: || result != SaveOnExitDialog.DISCARD_OPTION) {
470: exitDialog = null;
471: return;
472: }
473: }
474:
475: }
476:
477: // close open connection pools
478: Log.info("Releasing database resources...");
479: try {
480: ConnectionManager.close();
481: } catch (DataSourceException e) {
482: }
483: Log.info("Connection pools destroyed");
484:
485: GUIUtilities.shuttingDown();
486: GUIUtilities.getParentFrame().dispose();
487: System.exit(0);
488: }
489:
490: /**
491: * Returns the page format for printing.
492: *
493: * @return the page format
494: */
495: public static PageFormat getPageFormat() {
496: if (pageFormat == null) {
497: pageFormat = PrintUtilities.getPageFormat();
498: }
499: return pageFormat;
500: }
501:
502: /**
503: * Sets the page format to that specified.
504: *
505: * @param _pageFormat - the page format
506: */
507: public static void setPageFormat(PageFormat _pageFormat) {
508: pageFormat = _pageFormat;
509: }
510:
511: /**
512: * Returns whether user-defined locale settings have been set.
513: */
514: public static boolean hasLocaleSettings() {
515: String language = SystemProperties.getStringProperty("user",
516: "locale.language");
517: String country = SystemProperties.getStringProperty("user",
518: "locale.country");
519: String timezone = SystemProperties.getStringProperty("user",
520: "locale.timezone");
521:
522: // Log.debug("language: " + language + " country: " + country +
523: // " timezone: " + timezone);
524:
525: return !(MiscUtils.isNull(language))
526: && !(MiscUtils.isNull(country))
527: && !(MiscUtils.isNull(timezone));
528: }
529:
530: }
|