001: package net.sourceforge.squirrel_sql.client.mainframe.action;
002:
003: /*
004: * Copyright (C) 2001-2004 Colin Bell and Johan Compagner
005: * colbell@users.sourceforge.net
006: * jcompagner@j-com.nl
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: */
022: import java.sql.SQLException;
023:
024: import javax.swing.SwingUtilities;
025:
026: import net.sourceforge.squirrel_sql.client.IApplication;
027: import net.sourceforge.squirrel_sql.client.gui.db.ConnectToAliasCallBack;
028: import net.sourceforge.squirrel_sql.client.gui.db.ConnectionInternalFrame;
029: import net.sourceforge.squirrel_sql.client.gui.db.ICompletionCallback;
030: import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias;
031: import net.sourceforge.squirrel_sql.client.session.ISession;
032: import net.sourceforge.squirrel_sql.client.session.SessionManager;
033: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
034: import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
035: import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
036: import net.sourceforge.squirrel_sql.fw.sql.ISQLDriver;
037: import net.sourceforge.squirrel_sql.fw.sql.SQLConnection;
038: import net.sourceforge.squirrel_sql.fw.sql.SQLDriverPropertyCollection;
039: import net.sourceforge.squirrel_sql.fw.util.ICommand;
040: import net.sourceforge.squirrel_sql.fw.util.StringManager;
041: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
042: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
043: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
044:
045: /**
046: * This <CODE>ICommand</CODE> allows the user to connect to
047: * an <TT>ISQLAlias</TT>.
048: *
049: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
050: */
051: public class ConnectToAliasCommand implements ICommand {
052:
053: /** Internationalized strings for this class. */
054: private static final StringManager s_stringMgr = StringManagerFactory
055: .getStringManager(ConnectToAliasCommand.class);
056:
057: /** Logger for this class. */
058: private static final ILogger s_log = LoggerController
059: .createLogger(ConnectToAliasCommand.class);
060:
061: /** Application API. */
062: private IApplication _app;
063:
064: /** The <TT>ISQLAlias</TT> to connect to. */
065: private SQLAlias _sqlAlias;
066:
067: /** If <TT>true</TT> a session is to be created as well as connecting to database. */
068: private boolean _createSession;
069:
070: /** Callback to notify client on the progress of this command. */
071: private ICompletionCallback _callback;
072:
073: /**
074: * Ctor. This ctor will create a new session as well as opening a connection.
075: *
076: * @param app The <TT>IApplication</TT> that defines app API.
077: * @param alias The <TT>ISQLAlias</TT> to connect to.
078: *
079: * @throws IllegalArgumentException
080: * Thrown if a <TT>null</TT> <TT>IApplication</TT> or
081: * <TT>ISQLAlias</TT> passed.
082: */
083: public ConnectToAliasCommand(IApplication app, SQLAlias sqlAlias) {
084: this (app, sqlAlias, true, null);
085: }
086:
087: /**
088: * Ctor.
089: *
090: * @param app The <TT>IApplication</TT> that defines app API.
091: * @param alias The <TT>ISQLAlias</TT> to connect to.
092: * @param createSession If <TT>true</TT> then create a session as well
093: * as connecting to the database.
094: * @param callback Callback for client code to be informed of the
095: * progress of this command.
096: *
097: * Thrown if a <TT>null</TT> <TT>IApplication</TT> or
098: * <TT>ISQLAlias</TT> passed.
099: */
100: public ConnectToAliasCommand(IApplication app, SQLAlias sqlAlias,
101: boolean createSession, ICompletionCallback callback) {
102: super ();
103: if (app == null) {
104: throw new IllegalArgumentException(
105: "Null IApplication passed");
106: }
107: if (sqlAlias == null) {
108: throw new IllegalArgumentException("Null ISQLAlias passed");
109: }
110: _app = app;
111: _sqlAlias = sqlAlias;
112: _createSession = createSession;
113: _callback = callback != null ? callback
114: : new ConnectToAliasCallBack(app, _sqlAlias);
115: }
116:
117: /**
118: * Display connection internal frame.
119: */
120: public void execute() {
121: try {
122: final SheetHandler hdl = new SheetHandler(_app, _sqlAlias,
123: _createSession, _callback);
124:
125: if (SwingUtilities.isEventDispatchThread()) {
126: createConnectionInternalFrame(hdl);
127: } else {
128: SwingUtilities.invokeLater(new Runnable() {
129: public void run() {
130: createConnectionInternalFrame(hdl);
131: }
132: });
133: }
134: } catch (Exception ex) {
135: _app.showErrorDialog(ex);
136: }
137: }
138:
139: private void createConnectionInternalFrame(SheetHandler hdl) {
140: ConnectionInternalFrame sheet = new ConnectionInternalFrame(
141: _app, _sqlAlias, hdl);
142: _app.getMainFrame().addInternalFrame(sheet, true, null);
143: GUIUtils.centerWithinDesktop(sheet);
144: sheet.moveToFront();
145: sheet.setVisible(true);
146: }
147:
148: /**
149: * Handler used for connection internal frame actions.
150: */
151: private static class SheetHandler implements
152: ConnectionInternalFrame.IHandler, Runnable {
153: /** The connection internal frame. */
154: private ConnectionInternalFrame _connSheet;
155:
156: /** Application API. */
157: private IApplication _app;
158:
159: /** <TT>ISQLAlias</TT> to connect to. */
160: private SQLAlias _alias;
161:
162: /** If <TT>true</TT> a session is to be created as well as connecting to database. */
163: private boolean _createSession;
164:
165: /** User name to use to connect to alias. */
166: private String _user;
167:
168: /** Password to use to connect to alias. */
169: private String _password;
170:
171: /** Connection properties. */
172: private SQLDriverPropertyCollection _props;
173:
174: /** If <TT>true</TT> user has requested cancellation of the connection attempt. */
175: private boolean _stopConnection;
176:
177: /** Callback to notify client on the progress of this command. */
178: private ICompletionCallback _callback;
179:
180: /**
181: * Ctor.
182: *
183: * @param app Application API.
184: * @param alias Database alias to connect to.
185: * @param createSession If <TT>true</TT> a session should be created.
186: * @param cmd Command executing this handler.
187: *
188: * @throws IllegalArgumentException
189: * Thrown if <TT>null</TT>IApplication</TT>, <TT>ISQLAlias</TT>,
190: * or <TT>ICompletionCallback</TT> passed.
191: */
192: private SheetHandler(IApplication app, SQLAlias alias,
193: boolean createSession, ICompletionCallback callback) {
194: super ();
195: if (app == null) {
196: throw new IllegalArgumentException(
197: "IApplication == null");
198: }
199: if (alias == null) {
200: throw new IllegalArgumentException("ISQLAlias == null");
201: }
202: if (alias == null) {
203: throw new IllegalArgumentException(
204: "ICompletionCallback == null");
205: }
206: _app = app;
207: _alias = alias;
208: _createSession = createSession;
209: _callback = callback;
210: }
211:
212: /**
213: * User has clicked the OK button to connect to the alias. Run the connection
214: * attempt in a separate thread.
215: *
216: * @param connSheet Connection internal frame.
217: * @param user The user name entered.
218: * @param password The password entered.
219: * @param props Connection properties.
220: */
221: public void performOK(ConnectionInternalFrame connSheet,
222: String user, String password,
223: SQLDriverPropertyCollection props) {
224: _stopConnection = false;
225: _connSheet = connSheet;
226: _user = user;
227: _password = password;
228: _props = props;
229: _app.getThreadPool().addTask(this );
230: }
231:
232: /**
233: * User has clicked the Cancel button to cancel this connection attempt.
234: *
235: * @param connSheet Connection internal frame.
236: */
237: public void performCancelConnect(
238: ConnectionInternalFrame connSheet) {
239: // if blocked that means that it doesn't help anymore
240: // Or an error dialog is shown or the connection is made
241: // and the SessionFrame is being constructed/shown.
242: synchronized (this ) {
243: _stopConnection = true;
244: }
245: }
246:
247: /**
248: * User has clicked the Close button to close the internal frame.
249: *
250: * @param connSheet Connection internal frame.
251: */
252: public void performClose(ConnectionInternalFrame connSheet) {
253: // Empty.
254: }
255:
256: /**
257: * Execute task. Connect to the alias with the information entered
258: * in the connection internal frame.
259: */
260: public void run() {
261: SQLConnection conn = null;
262: final IIdentifier driverID = _alias.getDriverIdentifier();
263: final ISQLDriver sqlDriver = _app.getDataCache().getDriver(
264: driverID);
265:
266: try {
267: OpenConnectionCommand cmd = new OpenConnectionCommand(
268: _app, _alias, _user, _password, _props);
269: cmd.execute();
270:
271: if (_alias.isAutoLogon()) {
272: // If the user checked Auto Logon but gave wrong username/password
273: // in the Alias definition. He will be asked to enter username/password again in an extra dialog.
274: // Here for convenience we transfer these data back into the Alias.
275: // Note: Don't do this when Auto Logon is false.
276: _alias.setUserName(_user);
277: _alias.setPassword(_password);
278: }
279:
280: conn = cmd.getSQLConnection();
281: synchronized (this ) {
282: if (_stopConnection) {
283: if (conn != null) {
284: closeConnection(conn);
285: conn = null;
286: }
287: } else {
288: // After this it can't be stopped anymore!
289: _callback.connected(conn);
290: if (_createSession) {
291: createSession(sqlDriver, conn);
292: } else {
293: _connSheet.executed(true);
294: }
295: }
296: }
297: } catch (Throwable ex) {
298: _connSheet.executed(false);
299: _callback.errorOccured(ex);
300: }
301: }
302:
303: private void closeConnection(ISQLConnection conn) {
304: if (conn != null) {
305: try {
306: conn.close();
307: } catch (SQLException ex) {
308: // i18n[ConnectToAliasCommand.error.closeconnection=Error occured closing Connection]
309: s_log
310: .error(
311: s_stringMgr
312: .getString("ConnectToAliasCommand.error.closeconnection"),
313: ex);
314: }
315: }
316: }
317:
318: private ISession createSession(ISQLDriver sqlDriver,
319: SQLConnection conn) {
320: SessionManager sm = _app.getSessionManager();
321: final ISession session = sm.createSession(_app, sqlDriver,
322: _alias, conn, _user, _password);
323: _callback.sessionCreated(session);
324: SwingUtilities.invokeLater(new Runner(session, _connSheet));
325: return session;
326: }
327: }
328:
329: private static final class Runner implements Runnable {
330: private final ISession _session;
331: private final ConnectionInternalFrame _connSheet;
332:
333: Runner(ISession session, ConnectionInternalFrame connSheet) {
334: super ();
335: _session = session;
336: _connSheet = connSheet;
337: }
338:
339: public void run() {
340: final IApplication app = _session.getApplication();
341: try {
342: app.getPluginManager().sessionCreated(_session);
343: app.getWindowManager().createInternalFrame(_session);
344: _connSheet.executed(true);
345: } catch (Throwable th) {
346: app
347: .showErrorDialog(
348: s_stringMgr
349: .getString("ConnectToAliasCommand.error.opensession"),
350: th);
351: }
352: }
353: }
354: }
|