All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.squirrel_sql.client.session.SessionManager Maven / Gradle / Ivy

Go to download

This is the jar that contains the main application classes which are very specific to SQuirreLSQL.

There is a newer version: 3.5.0
Show newest version
package net.sourceforge.squirrel_sql.client.session;
/*
 * Copyright (C) 2004 Colin Bell
 * [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.sql.SQLException;
import java.util.*;

import javax.swing.*;
import javax.swing.event.EventListenerList;

import net.sourceforge.squirrel_sql.client.IApplication;
import net.sourceforge.squirrel_sql.client.mainframe.action.CloseAllButCurrentSessionsAction;
import net.sourceforge.squirrel_sql.client.mainframe.action.CloseAllSessionsAction;
import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias;
import net.sourceforge.squirrel_sql.client.gui.db.ISQLAliasExt;
import net.sourceforge.squirrel_sql.client.session.event.ISessionListener;
import net.sourceforge.squirrel_sql.client.session.event.SessionEvent;
import net.sourceforge.squirrel_sql.client.session.action.CloseSessionWindowAction;
import net.sourceforge.squirrel_sql.client.session.action.CloseSessionAction;
import net.sourceforge.squirrel_sql.fw.gui.Dialogs;
import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
import net.sourceforge.squirrel_sql.fw.id.IntegerIdentifierFactory;
import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
import net.sourceforge.squirrel_sql.fw.sql.ISQLDriver;
import net.sourceforge.squirrel_sql.fw.sql.SQLConnection;
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;

/**
 * This class manages sessions.
 *
 * @author Colin Bell
 */
public class SessionManager
{
   /** Logger for this class. */
   private static final ILogger s_log =
      LoggerController.createLogger(SessionManager.class);

   /** Internationalized strings for this class. */
   private static final StringManager s_stringMgr =
      StringManagerFactory.getStringManager(SessionManager.class);

   /** Application API. */
   private final IApplication _app;

   private ISession _activeSession;

   /** Linked list of sessions. */
   private final LinkedList _sessionsList = new LinkedList();

   /** Map of sessions keyed by session ID. */
   private final Map _sessionsById = new HashMap();

   private EventListenerList listenerList = new EventListenerList();

   /** Factory used to generate session IDs. */
   private final IntegerIdentifierFactory _idFactory = new IntegerIdentifierFactory(1);
   private ArrayList _allowedSchemaCheckers = new ArrayList();
   private Hashtable _allowedSchemasBySessionID = new Hashtable();
   private HashSet _inCloseSession = new HashSet();

   /**
    * Ctor.
    *
    * @param	app		Application API.
    *
    * @throws	IllegalArgumentException
    * 			Thrown if null IApplication passed.
    */
   public SessionManager(IApplication app)
   {
      super();
      if (app == null)
      {
         throw new IllegalArgumentException("IApplication == null");
      }

      _app = app;
   }

   /**
    * 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
    *
    * @throws	IllegalArgumentException
    *			Thrown if IApplication, ISQLDriver, ISQLAlias,
    * 			or SQLConnection is passed as null.
    */
   public synchronized ISession createSession(IApplication app,
                                              ISQLDriver driver, SQLAlias alias,
                                              SQLConnection conn, String user,
                                              String password)
   {
      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");
      }

      final Session sess = new Session(app, driver, alias, conn, user,
                              password, _idFactory.createIdentifier());
      _sessionsList.addLast(sess);
      _sessionsById.put(sess.getIdentifier(), sess);

      fireSessionAdded(sess);
      setActiveSession(sess);

      return sess;
   }

   public void setActiveSession(ISession session)
   {
      if (session != _activeSession)
      {
         _activeSession = session;
         fireSessionActivated(session);
      }
   }

   /**
    * Retrieve an array of all the sessions currently connected.
    *
    * @return array of all connected sessions.
    */
   public synchronized ISession[] getConnectedSessions()
   {
      return _sessionsList.toArray(new ISession[_sessionsList.size()]);
   }

   /**
    * Retrieve the session that is currently activated within the
    * session manager. Any new sql worksheets etc will be created
    * against this session
    */
   public synchronized ISession getActiveSession()
   {
      return _activeSession;
   }

   /**
    * Get the next session opened after the passed one.
    *
    * @return	The next session or the first one if the passed one is
    * 			the last session.
    */
   public synchronized ISession getNextSession(ISession session)
   {
      final int sessionCount = _sessionsList.size();
      int idx = _sessionsList.indexOf(session);
      if (idx != -1)
      {
         ++idx;
         if (idx >= sessionCount)
         {
            idx = 0;
         }
         return _sessionsList.get(idx);
      }

      s_log.error("SessionManager.getNextSession()-> Session " +
               session.getIdentifier() + " not found in _sessionsList");
      if (sessionCount > 0)
      {
         s_log.error("SessionManager.getNextSession()-> Returning first session");
         return _sessionsList.getFirst();
      }
      s_log.error("SessionManager.getNextSession()-> List empty so returning passed session");
      return session;
   }

   /**
    * Get the next session opened before the passed one.
    *
    * @return	The previous session or the last one if the passed one is
    * 			the first session.
    */
   public synchronized ISession getPreviousSession(ISession session)
   {
      final int sessionCount = _sessionsList.size();
      int idx = _sessionsList.indexOf(session);
      if (idx != -1)
      {
         --idx;
         if (idx < 0)
         {
            idx = sessionCount - 1;
         }
         return _sessionsList.get(idx);
      }

      s_log.error("SessionManager.getPreviousSession()-> Session " +
               session.getIdentifier() + " not found in _sessionsList");
      if (sessionCount > 0)
      {
         s_log.error("SessionManager.getPreviousSession()-> Returning last session");
         return _sessionsList.getLast();
      }
      s_log.error("SessionManager.getPreviousSession()-> List empty so returning passed session");
      return session;
   }

   /**
    * Retrieve the session for the passed identifier.
    *
    * @param	sessionID	ID of session we are trying to retrieve.
    *
    * @throws	IllegalArgumentException
    * 			Thrown if null IIdentifier passed.
    */
   public ISession getSession(IIdentifier sessionID)
   {
      return _sessionsById.get(sessionID);
   }

   /**
    * Close a session.
    *
    * @param	session		Session to close.
    *
    * @return	true if session was closed else false.
    *
    * @throws	IllegalArgumentException
    *			Thrown if nullISession passed.
    */
   public synchronized boolean closeSession(ISession session)
   {
      if (session == null)
      {
         throw new IllegalArgumentException("ISession == null");
      }

      try
      {
         if(_inCloseSession.contains(session.getIdentifier()))
         {
            return false;
         }

         _inCloseSession.add(session.getIdentifier());
         if (confirmClose(session))
         {
            // TODO: Should have session listeners instead of these calls.
            session.getApplication().getPluginManager().sessionEnding(session);

            fireSessionClosing(session);
            try {
            	session.close();
            } catch (SQLException sqle) {
                s_log.error("Error closing Session", sqle);
                session.showErrorMessage(s_stringMgr.getString("SessionManager.ErrorClosingSession", sqle));
            }
            fireSessionClosed(session);

            final IIdentifier sessionId = session.getIdentifier();
            if (!_sessionsList.remove(session))
            {
               s_log.error("SessionManager.closeSession()-> Session " +
                     sessionId +
                     " not found in _sessionsList when trying to remove it.");
            }
            if (_sessionsById.remove(sessionId) == null)
            {
               s_log.error("SessionManager.closeSession()-> Session " +
                     sessionId +
                     " not found in _sessionsById when trying to remove it.");
            }

            if (_sessionsList.isEmpty())
            {
               fireAllSessionsClosed();
            }

            // Activate another session since the current
            // active session has closed.
            if (session == _activeSession)
            {
               if (!_sessionsList.isEmpty())
               {
                  setActiveSession(_sessionsList.getLast());
               }
               else
               {
                  _activeSession = null;
               }
            }

            _allowedSchemasBySessionID.remove(session.getIdentifier());

            return true;
         }
      }
      catch (Throwable ex)
      {
         s_log.error("Error closing Session", ex);
         session.showErrorMessage(s_stringMgr.getString("SessionManager.ErrorClosingSession", ex));
      }
      finally
      {
         _inCloseSession.remove(session.getIdentifier());
      }

      return false;
   }

   /**
    * Closes all currently open sessions.
    *
    * @return	true if all sessions closed else false.
    *
    * @throws	SQLException
    * 			Thrown if an error closing the SQL connection. The session
    * 			will still be closed even though the connection may not have
    *			been.
    */
   synchronized public boolean closeAllSessions()
   {
      // Get an array since we dont want trouble with the sessionsList when
      // we remove the sessions from it.
      final ISession[] sessions = getConnectedSessions();
      for (int i = sessions.length - 1; i >= 0; i--)
      {
         if (!closeSession(sessions[i]))
         {
            return false;
         }
      }
      return true;
   }

   synchronized public boolean closeAllButCurrentSessions()
   {
      ISession activeSession = getActiveSession();

      // Get an array since we dont want trouble with the sessionsList when
      // we remove the sessions from it.
      final ISession[] sessions = getConnectedSessions();
      for (int i = sessions.length - 1; i >= 0; i--)
      {
         if(sessions[i] == activeSession)
         {
            continue; 
         }

         if (!closeSession(sessions[i]))
         {
            return false;
         }
      }
      return true;
   }


   /**
    * Adds a session listener
    *
    * @param	lis		The listener to add.
    */
   public void addSessionListener(ISessionListener lis)
   {
      if (lis != null)
      {
         listenerList.add(ISessionListener.class, lis);
      }
      else
      {
         s_log.error("Attempted to add null listener: SessionManager.addSessionListener");
      }
   }

   /**
    * Removes a session listener
    *
    * @param	lis		The listener to remove.
    */
   public void removeSessionListener(ISessionListener lis)
   {
      if (lis != null)
      {
         listenerList.remove(ISessionListener.class, lis);
      }
      else
      {
         s_log.error("Attempted to remove null listener: SessionManager.addSessionListener");
      }
   }

   /**
    * Fired when a session is connected (added) to the session
    * manager
    */
   protected void fireSessionAdded(ISession session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
               evt = new SessionEvent(session);
            ((ISessionListener)listeners[i + 1]).sessionConnected(evt);
         }
      }
   }

   /**
    * Fired when a session is closed (removed) from the session manager
    */
   protected void fireSessionClosed(ISession session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
               evt = new SessionEvent(session);
            ((ISessionListener)listeners[i + 1]).sessionClosed(evt);
         }
      }
   }

   /**
    * Fired when a session is about to close from the session manager
    */
   protected void fireSessionClosing(ISession session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
            {
               evt = new SessionEvent(session);
            }
            ((ISessionListener)listeners[i + 1]).sessionClosing(evt);
         }
      }
   }

   /**
    * Fired when all the session have been closed (removed) from the
    * session manager
    */
   protected void fireAllSessionsClosed()
   {
      Object[] listeners = listenerList.getListenerList();
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            ((ISessionListener)listeners[i + 1]).allSessionsClosed();
         }
      }
   }

   /**
    * Fired when the active session changed
    */
   protected void fireSessionActivated(ISession session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
               evt = new SessionEvent(session);
            ((ISessionListener)listeners[i + 1]).sessionActivated(evt);
         }
      }
   }

   /**
    * Confirm whether session is to be closed.
    *
    * @param	session		Session being closed.
    *
    * @return	true if confirmed to close session.
    */
   private boolean confirmClose(ISession session)
   {
      if (!_app.getSquirrelPreferences().getConfirmSessionClose())
      {
            return session.confirmClose();
        }

      final String msg = s_stringMgr.getString("SessionManager.confirmClose",
                     session.getTitle());
      if (!Dialogs.showYesNo(_app.getMainFrame(), msg)) {
            return false;
        } else {
            return session.confirmClose();
        }
   }

   protected void fireConnectionClosedForReconnect(Session session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
               evt = new SessionEvent(session);
            ((ISessionListener)listeners[i + 1]).connectionClosedForReconnect(evt);
         }
      }
   }

   protected void fireReconnected(Session session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
               evt = new SessionEvent(session);
            ((ISessionListener)listeners[i + 1]).reconnected(evt);
         }
      }
   }

   protected void fireReconnectFailed(Session session)
   {
      Object[] listeners = listenerList.getListenerList();
      SessionEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i -= 2)
      {
         if (listeners[i] == ISessionListener.class)
         {
            // Lazily create the event:
            if (evt == null)
               evt = new SessionEvent(session);
            ((ISessionListener)listeners[i + 1]).reconnectFailed(evt);
         }
      }
   }


   protected void fireSessionFinalized(final IIdentifier sessionIdentifier)
   {
      // invokeLater to make the call synchronto the event queue
      SwingUtilities.invokeLater(new Runnable()
      {
         public void run()
         {
            Object[] listeners = listenerList.getListenerList();
            for (int i = listeners.length - 2; i >= 0; i -= 2)
            {
               if (listeners[i] == ISessionListener.class)
               {
                  ((ISessionListener)listeners[i + 1]).sessionFinalized(sessionIdentifier);
               }
            }
         }
      });

   }

   public void addAllowedSchemaChecker(IAllowedSchemaChecker allowedSchemaChecker)
   {
      _allowedSchemaCheckers.add(allowedSchemaChecker);
   }


   public boolean areAllSchemasAllowed(ISession session)
   {
      try
      {
         String[] allowedSchemas = getAllowedSchemas(session);
         String[] schemas = session.getSQLConnection().getSQLMetaData().getSchemas();

         return allowedSchemas.length == schemas.length;
      }
      catch (SQLException e)
      {
         s_log.error("Failed to check allowed Schemas", e);
         return true;
      }
   }

   public String[] getAllowedSchemas(ISession session)
   {
      String[] allowedSchemas = _allowedSchemasBySessionID.get(session.getIdentifier());
      if(null == allowedSchemas)
      {
         allowedSchemas = getAllowedSchemas(session.getSQLConnection(), session.getAlias());
         _allowedSchemasBySessionID.put(session.getIdentifier(), allowedSchemas);
      }

      return allowedSchemas;

   }


   /**
    * Note: This Method does not cache allowed Schemas.
    * It is preferable to use getAllowedSchemas(ISession) if a Session is avaialable.
    */
   public String[] getAllowedSchemas(ISQLConnection con, ISQLAliasExt alias)
   {
      try
      {
         // Do not do new HashMap() here.
         HashMap uniqueAllowedSchemas = null;

         for (int i = 0; i < _allowedSchemaCheckers.size(); i++)
         {
            String[] allowedSchemas = null;
            try
            {
               allowedSchemas = (_allowedSchemaCheckers.get(i)).getAllowedSchemas(con, alias);
            }
            catch (Exception e)
            {
               s_log.error("Failed to get allowed Schemas from Plugin", e);
            }

            if(null != allowedSchemas)
            {
               if(null == uniqueAllowedSchemas)
               {
                  uniqueAllowedSchemas = new HashMap();
               }

               for (int j = 0; j < allowedSchemas.length; j++)
               {
                  uniqueAllowedSchemas.put(allowedSchemas[j], null);
               }
            }
         }

         if(null == uniqueAllowedSchemas)
         {
            return con.getSQLMetaData().getSchemas();
         }
         else
         {
            ArrayList list = new ArrayList(uniqueAllowedSchemas.keySet());
            Collections.sort(list);
            return list.toArray(new String[list.size()]);
         }
      }
      catch (Exception e)
      {
         s_log.error("Failed to get allowed Schemas", e);
         return new String[0];
      }
   }

   public void clearAllowedSchemaCache(ISession session)
   {
      _allowedSchemasBySessionID.remove(session.getIdentifier());
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy