
net.sourceforge.squirrel_sql.client.session.Session Maven / Gradle / Ivy
Show all versions of squirrel-sql Show documentation
package net.sourceforge.squirrel_sql.client.session;
/*
* Copyright (C) 2001-2004 Colin Bell
* [email protected]
*
* Modifications copyright (C) 2001-2004 Johan Compagner
* [email protected]
*
* Modifications Copyright (C) 2003-2004 Jason Height
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import net.sourceforge.squirrel_sql.client.IApplication;
import net.sourceforge.squirrel_sql.client.gui.db.ISQLAliasExt;
import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias;
import net.sourceforge.squirrel_sql.client.gui.db.SQLAliasConnectionProperties;
import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.ISessionWidget;
import net.sourceforge.squirrel_sql.client.gui.session.ObjectTreeInternalFrame;
import net.sourceforge.squirrel_sql.client.gui.session.SQLInternalFrame;
import net.sourceforge.squirrel_sql.client.gui.session.SessionInternalFrame;
import net.sourceforge.squirrel_sql.client.gui.session.SessionPanel;
import net.sourceforge.squirrel_sql.client.mainframe.action.OpenConnectionCommand;
import net.sourceforge.squirrel_sql.client.plugin.IPlugin;
import net.sourceforge.squirrel_sql.client.session.mainpanel.IMainPanelTab;
import net.sourceforge.squirrel_sql.client.session.parser.IParserEventsProcessor;
import net.sourceforge.squirrel_sql.client.session.parser.ParserEventsProcessor;
import net.sourceforge.squirrel_sql.client.session.parser.ParserEventsProcessorDummy;
import net.sourceforge.squirrel_sql.client.session.properties.SessionProperties;
import net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo;
import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
import net.sourceforge.squirrel_sql.fw.persist.ValidationException;
import net.sourceforge.squirrel_sql.fw.sql.IQueryTokenizer;
import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
import net.sourceforge.squirrel_sql.fw.sql.ISQLDriver;
import net.sourceforge.squirrel_sql.fw.sql.QueryTokenizer;
import net.sourceforge.squirrel_sql.fw.sql.SQLConnection;
import net.sourceforge.squirrel_sql.fw.sql.SQLConnectionState;
import net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData;
import net.sourceforge.squirrel_sql.fw.sql.TokenizerSessPropsInteractions;
import net.sourceforge.squirrel_sql.fw.util.DefaultExceptionFormatter;
import net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter;
import net.sourceforge.squirrel_sql.fw.util.IMessageHandler;
import net.sourceforge.squirrel_sql.fw.util.NullMessageHandler;
import net.sourceforge.squirrel_sql.fw.util.StringManager;
import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
/**
* Think of a session as being the users view of the database. IE it includes
* the database connection and the UI.
*
* @author Colin Bell
*/
class Session implements ISession
{
/** Logger for this class. */
private static final ILogger s_log =
LoggerController.createLogger(Session.class);
/** Internationalized strings for this class. */
private static final StringManager s_stringMgr =
StringManagerFactory.getStringManager(Session.class);
/** Factory used to generate unique IDs for sessions.
/** Descriptive title for session. */
private String _title = "";
private SessionPanel _sessionSheet;
/** The IIdentifier that uniquely identifies this object. */
private final IIdentifier _id;
/** Application API. */
private IApplication _app;
/** Connection to database. */
private SQLConnection _conn;
/** Driver used to connect to database. */
private ISQLDriver _driver;
/** Alias describing how to connect to database. */
private SQLAlias _alias;
private final String _user;
private final String _password;
/** Properties for this session. */
private SessionProperties _props;
/**
* Objects stored in session. Each entry is a Map
* keyed by IPlugin.getInternalName(). Each Map
* contains the objects saved for the plugin.
*/
private final Map> _pluginObjects =
new HashMap>();
private IMessageHandler _msgHandler = NullMessageHandler.getInstance();
/** Xref info about the current connection. */
private final net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo _schemaInfo;
/** Set to true once session closed. */
private boolean _closed;
private List _statusBarToBeAdded =
new ArrayList();
private SQLConnectionListener _connLis = null;
private ISessionWidget _activeActiveSessionWindow;
private SessionInternalFrame _sessionInternalFrame;
private Hashtable _parserEventsProcessorsByEntryPanelIdentifier = new Hashtable();
/** flag to track whether or not the table data has been loaded in the object tree */
private boolean _finishedLoading = false;
/** flag to track whether or not the plugins have finished loading for this new session */
private boolean _pluginsFinishedLoading = false;
/** This is set to true when a plugin sets a custom IQueryTokenizer */
private boolean customTokenizerInstalled = false;
private IQueryTokenizer tokenizer = null;
/** The default exception formatter */
private DefaultExceptionFormatter formatter = new DefaultExceptionFormatter();
private SessionConnectionKeepAlive _sessionConnectionKeepAlive = null;
/**
* Create a new session.
*
* @param app Application API.
* @param driver JDBC driver for session.
* @param alias Defines URL to database.
* @param conn Connection to database.
* @param user User name connected with.
* @param password Password for user
* @param sessionId ID that uniquely identifies this session.
*
* @throws IllegalArgumentException if any parameter is null.
*/
public Session(IApplication app, ISQLDriver driver, SQLAlias alias,
SQLConnection conn, String user, String password,
IIdentifier sessionId)
{
super();
_schemaInfo = new SchemaInfo(app);
if (app == null)
{
throw new IllegalArgumentException("null IApplication passed");
}
if (driver == null)
{
throw new IllegalArgumentException("null ISQLDriver passed");
}
if (alias == null)
{
throw new IllegalArgumentException("null ISQLAlias passed");
}
if (conn == null)
{
throw new IllegalArgumentException("null SQLConnection passed");
}
if (sessionId == null)
{
throw new IllegalArgumentException("sessionId == null");
}
_app = app;
_driver = driver;
_alias = new SQLAlias();
try
{
_alias.assignFrom(alias, true);
}
catch (ValidationException e)
{
throw new RuntimeException(e);
}
_conn = conn;
_user = user;
_password = password;
_id = sessionId;
setupTitle();
_props = (SessionProperties)_app.getSquirrelPreferences().getSessionProperties().clone();
_connLis = new SQLConnectionListener();
_conn.addPropertyChangeListener(_connLis);
checkDriverVersion();
// Start loading table/column info about the current database.
_app.getThreadPool().addTask(new Runnable()
{
public void run()
{
_schemaInfo.initialLoad(Session.this);
_finishedLoading = true;
}
});
startKeepAliveTaskIfNecessary();
}
private void startKeepAliveTaskIfNecessary() {
SQLAliasConnectionProperties connProps = _alias.getConnectionProperties();
if (connProps.isEnableConnectionKeepAlive()) {
String keepAliveSql = connProps.getKeepAliveSqlStatement();
long sleepMillis = connProps.getKeepAliveSleepTimeSeconds() * 1000;
_sessionConnectionKeepAlive = new SessionConnectionKeepAlive(_conn, sleepMillis, keepAliveSql,
_alias.getName());
_app.getThreadPool().addTask(_sessionConnectionKeepAlive,
"Session Connection Keep-Alive (" + _alias.getName() + ")");
}
}
private void stopKeepAliveTaskIfNecessary() {
if (_sessionConnectionKeepAlive != null) {
_sessionConnectionKeepAlive.setStopped(true);
}
}
/**
* Close this session.
*
* @throws SQLException
* Thrown if an error closing the SQL connection. The session
* will still be closed even though the connection may not have
* been.
*/
public void close() throws SQLException
{
if (!_closed)
{
if (s_log.isDebugEnabled()) {
s_log.debug("Closing session: " + _id);
}
stopKeepAliveTaskIfNecessary();
_conn.removePropertyChangeListener(_connLis);
_connLis = null;
IParserEventsProcessor[] procs =
_parserEventsProcessorsByEntryPanelIdentifier.values().toArray(new IParserEventsProcessor[0]);
for (int i = 0; i < procs.length; i++)
{
try
{
if(procs[i] instanceof ParserEventsProcessor)
{
((ParserEventsProcessor)procs[i]).endProcessing();
}
}
catch(Exception e)
{
if (s_log.isInfoEnabled()) {
s_log.info("Error stopping parser event processor", e);
}
}
}
_schemaInfo.dispose();
try
{
closeSQLConnection();
}
finally
{
// This is set here as SessionPanel.dispose() will attempt
// to close the session.
_closed = true;
if (_sessionSheet != null)
{
_sessionSheet.sessionHasClosed();
_sessionSheet = null;
}
}
if (s_log.isDebugEnabled()) {
s_log.debug("Successfully closed session: " + _id);
}
}
}
/**
* Commit the current SQL transaction.
*/
public synchronized void commit()
{
try
{
getSQLConnection().commit();
final String msg = s_stringMgr.getString("Session.commit");
_msgHandler.showMessage(msg);
}
catch (Throwable ex)
{
_msgHandler.showErrorMessage(ex, formatter);
}
}
/**
* Rollback the current SQL transaction.
*/
public synchronized void rollback()
{
try
{
getSQLConnection().rollback();
final String msg = s_stringMgr.getString("Session.rollback");
_msgHandler.showMessage(msg);
}
catch (Exception ex)
{
_msgHandler.showErrorMessage(ex, formatter);
}
}
/**
* Return the unique identifier for this session.
*
* @return the unique identifier for this session.
*/
public IIdentifier getIdentifier()
{
return _id;
}
/**
* Retrieve whether this session has been closed.
*
* @return true if session closed else false.
*/
public boolean isClosed()
{
return _closed;
}
/**
* Return the Application API object.
*
* @return the Application API object.
*/
public IApplication getApplication()
{
return _app;
}
/**
* @return SQLConnection for this session.
*/
public ISQLConnection getSQLConnection()
{
checkThread();
return _conn;
}
/**
* @return ISQLDriver for this session.
*/
public ISQLDriver getDriver()
{
return _driver;
}
/**
* @return ISQLAlias for this session.
*/
public ISQLAliasExt getAlias()
{
return _alias;
}
public SessionProperties getProperties()
{
return _props;
}
/**
* Retrieve the schema information object for this session.
*/
public SchemaInfo getSchemaInfo()
{
return _schemaInfo;
}
public synchronized Object getPluginObject(IPlugin plugin, String key)
{
if (plugin == null)
{
throw new IllegalArgumentException("Null IPlugin passed");
}
if (key == null)
{
throw new IllegalArgumentException("Null key passed");
}
Map map = _pluginObjects.get(plugin.getInternalName());
if (map == null)
{
map = new HashMap();
_pluginObjects.put(plugin.getInternalName(), map);
}
return map.get(key);
}
/**
* Add the passed action to the session toolbar.
*
* @param action Action to be added.
*/
public void addToToolbar(Action action)
{
_sessionSheet.addToToolbar(action);
}
public void addSeparatorToToolbar()
{
_sessionSheet.addSeparatorToToolbar();
}
public synchronized Object putPluginObject(IPlugin plugin, String key,
Object value)
{
if (plugin == null)
{
throw new IllegalArgumentException("Null IPlugin passed");
}
if (key == null)
{
throw new IllegalArgumentException("Null key passed");
}
Map map = _pluginObjects.get(plugin.getInternalName());
if (map == null)
{
map = new HashMap();
_pluginObjects.put(plugin.getInternalName(), map);
}
return map.put(key, value);
}
public synchronized void removePluginObject(IPlugin plugin, String key)
{
if (plugin == null)
{
throw new IllegalArgumentException("Null IPlugin passed");
}
if (key == null)
{
throw new IllegalArgumentException("Null key passed");
}
Map map = _pluginObjects.get(plugin.getInternalName());
if (map != null)
{
map.remove(key);
}
}
public synchronized void closeSQLConnection() throws SQLException
{
if (_conn != null)
{
stopKeepAliveTaskIfNecessary();
try
{
_conn.close();
}
finally
{
_conn = null;
}
}
}
/**
* Reconnect to the database.
*/
public void reconnect()
{
SQLConnectionState connState = new SQLConnectionState();
if (_conn != null)
{
try
{
connState.saveState(_conn, getProperties(), _msgHandler);
}
catch (SQLException ex)
{
s_log.error("Unexpected SQLException", ex);
}
}
OpenConnectionCommand cmd = new OpenConnectionCommand(_app, _alias,
_user, _password, connState.getConnectionProperties());
try
{
closeSQLConnection();
_app.getSessionManager().fireConnectionClosedForReconnect(this);
}
catch (SQLException ex)
{
final String msg = s_stringMgr.getString("Session.error.connclose");
s_log.error(msg, ex);
_msgHandler.showErrorMessage(msg);
_msgHandler.showErrorMessage(ex, this.getExceptionFormatter());
}
try
{
cmd.execute();
_conn = cmd.getSQLConnection();
if (connState != null)
{
connState.restoreState(_conn, _msgHandler);
getProperties().setAutoCommit(connState.getAutoCommit());
}
final String msg = s_stringMgr.getString("Session.reconn", _alias.getName());
_msgHandler.showMessage(msg);
_app.getSessionManager().fireReconnected(this);
startKeepAliveTaskIfNecessary();
}
catch (Throwable t)
{
final String msg = s_stringMgr.getString("Session.reconnError", _alias.getName());
_msgHandler.showErrorMessage(msg +"\n" + t.toString());
s_log.error(msg, t);
_app.getSessionManager().fireReconnectFailed(this);
}
}
public void setMessageHandler(IMessageHandler handler)
{
_msgHandler = handler != null ? handler : NullMessageHandler.getInstance();
}
public synchronized void setSessionSheet(SessionPanel child)
{
_sessionSheet = child;
if (_sessionSheet != null)
{
final ListIterator it = _statusBarToBeAdded.listIterator();
while (it.hasNext())
{
addToStatusBar(it.next());
it.remove();
}
}
}
public synchronized void setSessionInternalFrame(SessionInternalFrame sif)
{
_sessionInternalFrame = sif;
// This is a reasonable default and makes initialization code run well
_activeActiveSessionWindow = sif;
_sessionSheet = sif.getSessionPanel();
final ListIterator it = _statusBarToBeAdded.listIterator();
while (it.hasNext())
{
addToStatusBar(it.next());
it.remove();
}
}
public synchronized SessionInternalFrame getSessionInternalFrame()
{
return _sessionInternalFrame;
}
public synchronized SessionPanel getSessionSheet()
{
return _sessionSheet;
}
/**
* Select a tab in the main tabbed pane.
*
* @param tabIndex The tab to select. @see ISession.IMainTabIndexes
*
* @throws IllegalArgumentException
* Thrown if an invalid tabId passed.
*/
public void selectMainTab(int tabIndex)
{
_sessionSheet.selectMainTab(tabIndex);
}
public int getSelectedMainTabIndex()
{
return _sessionSheet.getSelectedMainTabIndex();
}
/**
* Add a tab to the main tabbed panel.
*
* @param tab The tab to be added.
*
* @return the index of the new tab that was added.
*
* @throws IllegalArgumentException
* Thrown if a null IMainPanelTab passed.
*/
public int addMainTab(IMainPanelTab tab)
{
return _sessionSheet.addMainTab(tab);
}
/**
* Add component to the session sheets status bar.
*
* @param comp Component to add.
*/
public synchronized void addToStatusBar(JComponent comp)
{
if (_sessionSheet != null)
{
_sessionSheet.addToStatusBar(comp);
}
else
{
_statusBarToBeAdded.add(comp);
}
}
/**
* Remove component from the session sheets status bar.
*
* @param comp Component to remove.
*/
public synchronized void removeFromStatusBar(JComponent comp)
{
if (_sessionSheet != null)
{
_sessionSheet.removeFromStatusBar(comp);
}
else
{
_statusBarToBeAdded.remove(comp);
}
}
// public SQLFilterClauses getSQLFilterClauses()
// {
// return _sqlFilterClauses;
// }
/**
* Retrieve the descriptive title of this session.
*
* @return The descriptive title of this session.
*/
public String getTitle()
{
return _title;
}
public String toString()
{
return getTitle();
}
private void setupTitle()
{
String catalog = null;
try
{
catalog = getSQLConnection().getCatalog();
}
catch (SQLException ex)
{
s_log.error("Error occured retrieving current catalog from Connection", ex);
}
if (catalog == null)
{
catalog = "";
}
else
{
catalog = "(" + catalog + ")";
}
String title = null;
String user = _user != null ? _user : "";
if (user.length() > 0)
{
String[] args = new String[3];
args[0] = getAlias().getName();
args[1] = catalog;
args[2] = user;
title = s_stringMgr.getString("Session.title1", args);
}
else
{
String[] args = new String[2];
args[0] = getAlias().getName();
args[1] = catalog;
title = s_stringMgr.getString("Session.title0", args);
}
_title = _id + " - " + title;
}
/**
* The code in any SQLEditor is parsed in the background. You may attach a listener to the ParserEventsProcessor
* to get to know about the results of parsing. The events are passed synchron with the event queue
* (via SwingUtils.invokeLater()). At the moment events are produced for errors in the SQLScript
* which are highlighted in the syntax plugin and for aliases of table names which are used in the
* code completion plugin.
*
* If you want the ParserEventsProcessor to produce further events feel free to contact [email protected].
*/
public IParserEventsProcessor getParserEventsProcessor(IIdentifier entryPanelIdentifier)
{
IParserEventsProcessor pep = _parserEventsProcessorsByEntryPanelIdentifier.get(entryPanelIdentifier);
if(null == pep)
{
ISQLPanelAPI panelAPI = getSqlPanelApi(entryPanelIdentifier);
if(null != panelAPI)
{
pep = new ParserEventsProcessor(panelAPI, this);
}
else
{
// If there is no sqlPanelAPI (e.g. the Object tree find editor) we assume no parser is necessary and thus provide a dummy impl.
pep = new ParserEventsProcessorDummy();
}
_parserEventsProcessorsByEntryPanelIdentifier.put(entryPanelIdentifier, pep);
}
return pep;
}
private ISQLPanelAPI getSqlPanelApi(IIdentifier entryPanelIdentifier)
{
ISessionWidget[] frames = getApplication().getWindowManager().getAllFramesOfSession(getIdentifier());
for (int i = 0; i < frames.length; i++)
{
if(frames[i] instanceof SQLInternalFrame)
{
ISQLPanelAPI sqlPanelAPI = ((SQLInternalFrame)frames[i]).getSQLPanelAPI();
IIdentifier id = sqlPanelAPI.getSQLEntryPanel().getIdentifier();
if(id.equals(entryPanelIdentifier))
{
return sqlPanelAPI;
}
}
if(frames[i] instanceof SessionInternalFrame)
{
ISQLPanelAPI sqlPanelAPI = ((SessionInternalFrame)frames[i]).getSQLPanelAPI();
IIdentifier sqlEditorID = sqlPanelAPI.getSQLEntryPanel().getIdentifier();
if(sqlEditorID.equals(entryPanelIdentifier))
{
return sqlPanelAPI;
}
IObjectTreeAPI objectTreeApi = ((SessionInternalFrame)frames[i]).getObjectTreeAPI();
IIdentifier findEditorID = objectTreeApi.getFindController().getFindEntryPanel().getIdentifier();
if(findEditorID.equals(entryPanelIdentifier))
{
return null;
}
}
if(frames[i] instanceof ObjectTreeInternalFrame)
{
IObjectTreeAPI objectTreeApi = ((ObjectTreeInternalFrame)frames[i]).getObjectTreeAPI();
IIdentifier findEditorID = objectTreeApi.getFindController().getFindEntryPanel().getIdentifier();
if(findEditorID.equals(entryPanelIdentifier))
{
return null;
}
}
}
throw new IllegalStateException("Session has no entry panel for ID=" + entryPanelIdentifier);
}
public void setActiveSessionWindow(ISessionWidget activeActiveSessionWindow)
{
_activeActiveSessionWindow = activeActiveSessionWindow;
}
public ISessionWidget getActiveSessionWindow()
{
return _activeActiveSessionWindow;
}
/**
*
* @throws IllegalStateException if ActiveSessionWindow doesn't provide an SQLPanelAPI
* for example if it is an ObjectTreeInternalFrame
*/
public ISQLPanelAPI getSQLPanelAPIOfActiveSessionWindow()
{
ISQLPanelAPI sqlPanelAPI;
if(_activeActiveSessionWindow instanceof SessionInternalFrame)
{
sqlPanelAPI = ((SessionInternalFrame)_activeActiveSessionWindow).getSQLPanelAPI();
}
else if(_activeActiveSessionWindow instanceof SQLInternalFrame)
{
sqlPanelAPI = ((SQLInternalFrame)_activeActiveSessionWindow).getSQLPanelAPI();
}
else
{
throw new IllegalStateException("SQLPanelApi can only be provided for SessionInternalFrame or SQLInternalFrame");
}
return sqlPanelAPI;
}
/**
*
* @throws IllegalStateException if ActiveSessionWindow doesn't provide an IObjectTreeAPI
* for example if it is an SQLInternalFrame
*/
public IObjectTreeAPI getObjectTreeAPIOfActiveSessionWindow()
{
IObjectTreeAPI objectTreeAPI;
if(_activeActiveSessionWindow instanceof SessionInternalFrame)
{
objectTreeAPI = ((SessionInternalFrame)_activeActiveSessionWindow).getObjectTreeAPI();
}
else if(_activeActiveSessionWindow instanceof ObjectTreeInternalFrame)
{
objectTreeAPI = ((ObjectTreeInternalFrame)_activeActiveSessionWindow).getObjectTreeAPI();
}
else
{
throw new IllegalStateException("ObjectTreeApi can only be provided for SessionInternalFrame or ObjectTreeInternalFrame");
}
return objectTreeAPI;
}
/**
* The point of this method is to try to determine if the driver being used
* for this session supports the API methods we are likely to use with this
* version of the Java runtime environment. It's not a showstopper to use
* an older driver, but we noticed that in some cases, older versions of
* drivers connecting to newer databases causes various unpredictable error
* conditions that are hard to troubleshoot, given that we don't have the
* source to the driver. Be that as it may, the user will inevitably claim
* that their xyz java app works fine with their antiquated driver,
* whereas SQuirreL does not - therefore it's a SQuirreL bug. So this will
* warn the user when this condition exists and hopefully persuade them to
* correct the problem.
*/
private void checkDriverVersion() {
if (!_app.getSquirrelPreferences().getWarnJreJdbcMismatch()) {
return;
}
String javaVersion = System.getProperty("java.vm.version");
boolean javaVersionIsAtLeast14 = true;
if (javaVersion != null) {
if (javaVersion.startsWith("1.1")
|| javaVersion.startsWith("1.2")
|| javaVersion.startsWith("1.3"))
{
javaVersionIsAtLeast14 = false;
}
}
if (!javaVersionIsAtLeast14) {
return;
}
// At this point we know that we have a 1.4 or higher java runtime
boolean driverIs21Compliant = true;
// Since 1.4 implements interfaces that became available in JDBC 3.0,
// let's warn the user if the driver doesn't support DatabaseMetaData
// methods that were added in JDBC 2.1 and JDBC 3.0 specifications.
SQLDatabaseMetaData md = _conn.getSQLMetaData();
try {
md.supportsResultSetType(ResultSet.TYPE_FORWARD_ONLY);
} catch (Throwable e) {
driverIs21Compliant = false;
}
if (!driverIs21Compliant) {
// i18n[Session.driverCompliance=The driver being used for alias ''{0}'' is not JDBC 2.1 compliant.\nYou should consider getting a more recent version of this driver]
String msg =
s_stringMgr.getString("Session.driverCompliance", _alias.getName());
// i18n[Session.driverComplianceTitle=JRE/JDBC Version Mismatch]
String title =
s_stringMgr.getString("Session.driverComplianceTitle");
showMessageDialog(msg, title, JOptionPane.WARNING_MESSAGE);
s_log.info(msg);
return;
}
boolean driverIs30Compliant = true;
try {
md.supportsSavepoints();
} catch (Throwable e) {
if (s_log.isDebugEnabled()) {
s_log.debug(e);
}
driverIs30Compliant = false;
}
if (!driverIs30Compliant) {
// i18n[Session.driverCompliance3.0=The driver being used for alias ''{0}'' is not JDBC 3.0 compliant.\nYou should consider getting a more recent version of this driver]
String msg =
s_stringMgr.getString("Session.driverCompliance3.0", _alias.getName());
// i18n[Session.driverComplianceTitle=JRE/JDBC Version Mismatch]
String title =
s_stringMgr.getString("Session.driverComplianceTitle");
showMessageDialog(msg, title, JOptionPane.WARNING_MESSAGE);
if (s_log.isInfoEnabled()) {
s_log.info(msg);
}
}
}
private void showMessageDialog(final String message,
final String title,
final int messageType)
{
final JFrame f = _app.getMainFrame();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(f,
message,
title,
messageType);
}
});
}
/**
* Check the thread of the caller to see if it is the event dispatch thread
* and if we are debugging print a debug log message with the call trace.
*/
private void checkThread() {
/* This is extremely useful when trying to track down Swing UI freezing.
* However, it currently fills the log which obscures other debug
* messages even though UI performance is acceptable, so it is commented
* out until it is needed later.
if (s_log.isDebugEnabled() && SwingUtilities.isEventDispatchThread()) {
try {
throw new Exception("GUI Thread is doing database work");
} catch (Exception e) {
s_log.debug(e.getMessage(), e);
}
}
*/
}
private class SQLConnectionListener implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent evt)
{
final String propName = evt.getPropertyName();
if (propName == null || propName == ISQLConnection.IPropertyNames.CATALOG)
{
setupTitle();
}
}
}
protected void finalize() throws Throwable
{
// System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
// System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
// System.out.println("+ Finalize " + getClass() + ". Hash code:" + hashCode());
// System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
// System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
_app.getSessionManager().fireSessionFinalized(_id);
}
/**
* @param _finishedLoading The _finishedLoading to set.
*/
public void setPluginsfinishedLoading(boolean pluginsFinishedLoading) {
this._pluginsFinishedLoading = pluginsFinishedLoading;
}
/**
* @return Returns the _finishedLoading.
*/
public boolean isfinishedLoading() {
return _finishedLoading && _pluginsFinishedLoading;
}
/* (non-Javadoc)
* @see net.sourceforge.squirrel_sql.client.session.ISession#confirmCloseWithUnsavedEdits()
*/
public boolean confirmClose()
{
if(getActiveSessionWindow() instanceof SQLInternalFrame || getActiveSessionWindow() instanceof SessionInternalFrame)
{
if (getSQLPanelAPIOfActiveSessionWindow().confirmClose())
{
return true;
}
else
{
return false;
}
}
return true;
}
/**
* Returns the IQueryTokenizer implementation to use for tokenizing scripts
* statements that should be sent to the server. If the tokenizer hasn't
* been initialized yet, then a default one will be created. If a cutom
* tokenizer has been installed, this will just return that one, in lieu of
* the default one.
*
* @return an implementation of IQueryTokenizer
*/
public IQueryTokenizer getQueryTokenizer() {
if (tokenizer == null || !customTokenizerInstalled) {
// No tokenizer has been set by any installed plugin. Go ahead and
// give the default tokenizer. It is important to not cache this
// object so that session property changes to the current session
// are reflected in this default tokenizer.
tokenizer = new QueryTokenizer(_props.getSQLStatementSeparator(),
_props.getStartOfLineComment(),
_props.getRemoveMultiLineComment());
}
return tokenizer;
}
/**
* Sets the IQueryTokenizer implementation to use for this session.
*
* @param tokenizer
*
* @throws IllegalArgumentException for null argument
* @throws IllegalStateException if a custom tokenizer is already installed.
*/
public void setQueryTokenizer(IQueryTokenizer aTokenizer) {
if (aTokenizer == null) {
throw new IllegalArgumentException("aTokenizer arg cannot be null");
}
if (customTokenizerInstalled) {
String currentTokenizer = tokenizer.getClass().getName();
String newTokenizer = tokenizer.getClass().getName();
throw new IllegalStateException(
"Only one custom query tokenizer can be installed. " +
"Current tokenizer is "+currentTokenizer+". New tokenizer is "+
newTokenizer);
}
customTokenizerInstalled = true;
tokenizer = aTokenizer;
TokenizerSessPropsInteractions tep = tokenizer.getTokenizerSessPropsInteractions();
if(tep.isTokenizerDefinesStatementSeparator())
{
_props.setSQLStatementSeparator(aTokenizer.getSQLStatementSeparator());
}
if(tep.isTokenizerDefinesStatementSeparator())
{
_props.setStartOfLineComment(aTokenizer.getLineCommentBegin());
}
if(tep.isTokenizerDefinesStatementSeparator())
{
_props.setRemoveMultiLineComment(aTokenizer.isRemoveMultiLineComment());
}
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#getMetaData()
*/
public ISQLDatabaseMetaData getMetaData() {
if (_conn != null) {
return _conn.getSQLMetaData();
} else {
return null;
}
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#setExceptionFormatter(net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter)
*/
public void setExceptionFormatter(ExceptionFormatter formatter) {
this.formatter.setCustomExceptionFormatter(formatter);
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#getExceptionFormatter()
*/
public ExceptionFormatter getExceptionFormatter() {
return this.formatter;
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#formatException(java.lang.Throwable)
*/
public String formatException(Throwable th) {
return this.formatter.format(th);
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#showErrorMessage(java.lang.String)
*/
public void showErrorMessage(String msg) {
_msgHandler.showErrorMessage(msg);
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#showErrorMessage(java.lang.Throwable, net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter)
*/
public void showErrorMessage(Throwable th) {
_msgHandler.showErrorMessage(th, formatter);
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#showMessage(java.lang.String)
*/
public void showMessage(String msg) {
_msgHandler.showMessage(msg);
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#showMessage(java.lang.Throwable, net.sourceforge.squirrel_sql.fw.util.ExceptionFormatter)
*/
public void showMessage(Throwable th) {
_msgHandler.showMessage(th, formatter);
}
/**
* @see net.sourceforge.squirrel_sql.client.session.ISession#showWarningMessage(java.lang.String)
*/
public void showWarningMessage(String msg) {
_msgHandler.showWarningMessage(msg);
}
}