001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.db.explorer;
043:
044: import java.awt.Component;
045: import java.beans.PropertyChangeSupport;
046: import java.beans.PropertyChangeListener;
047: import java.beans.PropertyVetoException;
048: import java.io.ObjectStreamException;
049: import java.sql.Connection;
050: import java.sql.SQLException;
051: import java.text.MessageFormat;
052: import java.util.Collection;
053: import java.util.Collections;
054: import java.util.HashSet;
055: import java.util.Iterator;
056: import java.util.Properties;
057: import java.util.ResourceBundle;
058: import java.util.Set;
059: import java.util.logging.Level;
060: import java.util.logging.Logger;
061: import org.netbeans.modules.db.explorer.actions.ConnectAction;
062: import org.openide.util.Lookup;
063: import org.openide.util.LookupEvent;
064: import org.openide.util.LookupListener;
065: import org.openide.util.Mutex;
066:
067: import org.openide.util.NbBundle;
068: import org.openide.util.RequestProcessor;
069: import org.openide.util.Task;
070:
071: import org.netbeans.lib.ddl.DBConnection;
072: import org.netbeans.lib.ddl.DDLException;
073: import org.netbeans.api.db.explorer.DatabaseException;
074: import org.netbeans.api.db.explorer.JDBCDriver;
075: import org.netbeans.api.db.explorer.JDBCDriverManager;
076:
077: import org.netbeans.modules.db.ExceptionListener;
078: import org.netbeans.modules.db.explorer.infos.ConnectionNodeInfo;
079: import org.netbeans.modules.db.explorer.infos.DatabaseNodeInfo;
080: import org.netbeans.modules.db.explorer.nodes.DatabaseNode;
081: import org.netbeans.modules.db.explorer.nodes.RootNode;
082:
083: import org.netbeans.modules.db.runtime.DatabaseRuntimeManager;
084: import org.netbeans.spi.db.explorer.DatabaseRuntime;
085: import org.openide.explorer.ExplorerManager;
086: import org.openide.nodes.Node;
087: import org.openide.nodes.NodeNotFoundException;
088: import org.openide.nodes.NodeOp;
089: import org.openide.util.Exceptions;
090: import org.openide.windows.TopComponent;
091:
092: /**
093: * Connection information
094: * This class encapsulates all information needed for connection to database
095: * (database and driver url, login name, password and schema name). It can create JDBC
096: * connection and feels to be a bean (has propertychange support and customizer).
097: * Instances of this class uses explorer option to store information about
098: * open connection.
099: */
100: public class DatabaseConnection implements DBConnection {
101:
102: private static final Logger LOGGER = Logger
103: .getLogger(DatabaseConnection.class.getName());
104: private static final boolean LOG = LOGGER.isLoggable(Level.FINE);
105:
106: static final long serialVersionUID = 4554639187416958735L;
107:
108: private Set exceptionListeners = Collections
109: .synchronizedSet(new HashSet());
110: private Connection con;
111:
112: /** Driver URL and name */
113: private String drv, drvname;
114:
115: /** Database URL */
116: private String db;
117:
118: /** User login name */
119: private String usr;
120:
121: /** Schema name */
122: private String schema;
123:
124: /** User password */
125: private String pwd = ""; //NOI18N
126:
127: /** Remembers password */
128: private Boolean rpwd = Boolean.FALSE;
129:
130: /** The support for firing property changes */
131: private PropertyChangeSupport propertySupport;
132:
133: /** Connection name */
134: private String name;
135:
136: /**
137: * The API DatabaseConnection (delegates to this instance)
138: */
139: private transient org.netbeans.api.db.explorer.DatabaseConnection dbconn;
140:
141: private static final String SUPPORT = "_schema_support"; //NOI18N
142: public static final String PROP_DRIVER = "driver"; //NOI18N
143: public static final String PROP_DATABASE = "database"; //NOI18N
144: public static final String PROP_USER = "user"; //NOI18N
145: public static final String PROP_PASSWORD = "password"; //NOI18N
146: public static final String PROP_REMEMBER_PASSWORD = "rememberpwd";
147: public static final String PROP_SCHEMA = "schema"; //NOI18N
148: public static final String PROP_DRIVERNAME = "drivername"; //NOI18N
149: public static final String PROP_NAME = "name"; //NOI18N
150:
151: private OpenConnectionInterface openConnection = null;
152:
153: static private final Lookup.Result openConnectionLookupResult;
154: static private Collection openConnectionServices = null;
155: static {
156: openConnectionLookupResult = Lookup.getDefault().lookup(
157: new Lookup.Template(OpenConnectionInterface.class));
158: openConnectionLookupResult
159: .addLookupListener(new LookupListener() {
160: public void resultChanged(LookupEvent ev) {
161: synchronized (DatabaseConnection.class) {
162: openConnectionServices = null;
163: }
164: }
165: });
166: }
167:
168: /** Default constructor */
169: public DatabaseConnection() {
170: dbconn = DatabaseConnectionAccessor.DEFAULT
171: .createDatabaseConnection(this );
172: propertySupport = new PropertyChangeSupport(this );
173: }
174:
175: /** Advanced constructor
176: * Allows to specify all needed information.
177: * @param driver Driver URL
178: * @param database Database URL
179: * @param user User login name
180: * @param password User password
181: */
182: public DatabaseConnection(String driver, String database,
183: String user, String password) {
184: this (driver, null, database, null, user, password, false);
185: }
186:
187: public DatabaseConnection(String driver, String driverName,
188: String database, String theschema, String user,
189: String password) {
190: this (driver, driverName, database, theschema, user, password,
191: false);
192: }
193:
194: public DatabaseConnection(String driver, String driverName,
195: String database, String theschema, String user,
196: String password, boolean rememberPassword) {
197: this ();
198: drv = driver;
199: drvname = driverName;
200: db = database;
201: usr = user;
202: schema = theschema;
203: pwd = password;
204: name = getName();
205: rpwd = Boolean.valueOf(rememberPassword);
206: }
207:
208: public JDBCDriver findJDBCDriver() {
209: JDBCDriver[] drvs = JDBCDriverManager.getDefault().getDrivers(
210: drv);
211: if (drvs.length <= 0) {
212: return null;
213: }
214:
215: JDBCDriver useDriver = drvs[0];
216: for (int i = 0; i < drvs.length; i++) {
217: if (drvs[i].getName().equals(getDriverName())) {
218: useDriver = drvs[i];
219: break;
220: }
221: }
222: return useDriver;
223: }
224:
225: private Collection getOpenConnections() {
226: if (openConnectionServices == null) {
227: openConnectionServices = openConnectionLookupResult
228: .allInstances();
229: }
230: return openConnectionServices;
231: }
232:
233: private OpenConnectionInterface getOpenConnection() {
234: if (openConnection != null)
235: return openConnection;
236:
237: openConnection = new OpenConnection();
238: String driver = getDriver();
239: if (driver == null) {
240: return openConnection;
241: }
242:
243: // For Java Studio Enterprise. Create instanceof OpenConnection
244: try {
245: Collection c = getOpenConnections();
246: for (Iterator i = c.iterator(); driver != null
247: && i.hasNext();) {
248: OpenConnectionInterface oci = (OpenConnectionInterface) i
249: .next();
250: if (oci.isFor(driver)) {
251: openConnection = oci;
252: break;
253: }
254: }
255: } catch (Exception ex) {
256: Logger.getLogger("global").log(Level.INFO, null, ex);
257: }
258: return openConnection;
259: }
260:
261: /** Returns driver class */
262: public String getDriver() {
263: return drv;
264: }
265:
266: /** Sets driver class
267: * Fires propertychange event.
268: * @param driver DNew driver URL
269: */
270: public void setDriver(String driver) {
271: if (driver == null || driver.equals(drv))
272: return;
273:
274: String olddrv = drv;
275: drv = driver;
276: propertySupport.firePropertyChange(PROP_DRIVER, olddrv, drv);
277: openConnection = null;
278: }
279:
280: public String getDriverName() {
281: return drvname;
282: }
283:
284: public void setDriverName(String name) {
285: if (name == null || name.equals(drvname))
286: return;
287:
288: String olddrv = drvname;
289: drvname = name;
290: if (propertySupport != null)
291: propertySupport.firePropertyChange(PROP_DRIVERNAME, olddrv,
292: drvname);
293: }
294:
295: /** Returns database URL */
296: public String getDatabase() {
297: if (db == null)
298: db = "";
299:
300: return db;
301: }
302:
303: /** Sets database URL
304: * Fires propertychange event.
305: * @param database New database URL
306: */
307: public void setDatabase(String database) {
308: if (database == null || database.equals(db))
309: return;
310:
311: String olddb = db;
312: db = database;
313: name = null;
314: name = getName();
315: if (propertySupport != null)
316: propertySupport
317: .firePropertyChange(PROP_DATABASE, olddb, db);
318: }
319:
320: /** Returns user login name */
321: public String getUser() {
322: if (usr == null)
323: usr = "";
324:
325: return usr;
326: }
327:
328: /** Sets user login name
329: * Fires propertychange event.
330: * @param user New login name
331: */
332: public void setUser(String user) {
333: if (user == null || user.equals(usr))
334: return;
335:
336: String oldusr = usr;
337: usr = user;
338: name = null;
339: name = getName();
340: if (propertySupport != null)
341: propertySupport.firePropertyChange(PROP_USER, oldusr, usr);
342: }
343:
344: /** Returns name of the connection */
345: public String getName() {
346: ResourceBundle bundle = NbBundle
347: .getBundle("org.netbeans.modules.db.resources.Bundle");
348: if (name == null)
349: if ((getSchema() == null) || (getSchema().length() == 0))
350: name = MessageFormat.format(bundle
351: .getString("ConnectionNodeUniqueName"),
352: new String[] { getDatabase(), getUser(),
353: bundle.getString("SchemaIsNotSet") }); //NOI18N
354: else
355: name = MessageFormat.format(bundle
356: .getString("ConnectionNodeUniqueName"),
357: new String[] { getDatabase(), getUser(),
358: getSchema() }); //NOI18N
359: return name;
360: }
361:
362: /** Sets user name of the connection
363: * Fires propertychange event.
364: * @param value New connection name
365: */
366: public void setName(String value) {
367: if (name == null || name.equals(value))
368: return;
369:
370: String old = name;
371: name = value;
372: if (propertySupport != null)
373: propertySupport.firePropertyChange(PROP_NAME, old, name);
374: }
375:
376: /** Returns user schema name */
377: public String getSchema() {
378: if (schema == null)
379: schema = "";
380:
381: return schema;
382: }
383:
384: /** Sets user schema name
385: * Fires propertychange event.
386: * @param schema_name New login name
387: */
388: public void setSchema(String schema_name) {
389: if (schema_name == null || schema_name.equals(schema))
390: return;
391:
392: String oldschema = schema;
393: schema = schema_name;
394: name = null;
395: name = getName();
396: if (propertySupport != null)
397: propertySupport.firePropertyChange(PROP_SCHEMA, oldschema,
398: schema);
399: }
400:
401: /** Returns if password should be remembered */
402: public boolean rememberPassword() {
403: return rpwd.booleanValue();
404: }
405:
406: /** Sets password should be remembered
407: * @param flag New flag
408: */
409: public void setRememberPassword(boolean flag) {
410: Boolean oldrpwd = rpwd;
411: rpwd = Boolean.valueOf(flag);
412: if (propertySupport != null)
413: propertySupport.firePropertyChange(PROP_REMEMBER_PASSWORD,
414: oldrpwd, rpwd);
415: }
416:
417: /** Returns password */
418: public String getPassword() {
419: return pwd;
420: }
421:
422: /** Sets password
423: * Fires propertychange event.
424: * @param password New password
425: */
426: public void setPassword(String password) {
427: if (password == null || password.equals(pwd))
428: return;
429:
430: String oldpwd = pwd;
431: if (password.length() == 0) {
432: password = null;
433: }
434: pwd = password;
435: if (propertySupport != null)
436: propertySupport.firePropertyChange(PROP_PASSWORD, oldpwd,
437: pwd);
438: }
439:
440: /** Creates JDBC connection
441: * Uses DriverManager to create connection to specified database. Throws
442: * DDLException if none of driver/database/user/password is set or if
443: * driver or database does not exist or is inaccessible.
444: */
445: public Connection createJDBCConnection() throws DDLException {
446: if (LOG) {
447: LOGGER.log(Level.FINE, "createJDBCConnection()");
448: }
449:
450: if (drv == null || db == null || usr == null)
451: throw new DDLException(NbBundle.getBundle(
452: "org.netbeans.modules.db.resources.Bundle")
453: .getString("EXC_InsufficientConnInfo"));
454:
455: Properties dbprops = new Properties();
456: if ((usr != null) && (usr.length() > 0)) {
457: dbprops.put("user", usr); //NOI18N
458: dbprops.put("password", pwd); //NOI18N
459: }
460:
461: try {
462: propertySupport
463: .firePropertyChange("connecting", null, null);
464:
465: // For Java Studio Enterprise.
466: getOpenConnection().enable();
467: startRuntimes();
468:
469: // hack for Derby
470: DerbyConectionEventListener.getDefault()
471: .beforeConnect(this );
472:
473: JDBCDriver useDriver = findJDBCDriver();
474: if (useDriver == null) {
475: // will be loaded through DriverManager, make sure it is loaded
476: Class.forName(drv);
477: }
478:
479: Connection connection = DbDriverManager.getDefault()
480: .getConnection(db, dbprops, useDriver);
481: setConnection(connection);
482:
483: DatabaseUILogger.logConnection(drv);
484:
485: propertySupport.firePropertyChange("connected", null, null);
486:
487: // For Java Studio Enterprise.
488: getOpenConnection().disable();
489:
490: return connection;
491: } catch (SQLException e) {
492: String message = MessageFormat.format(NbBundle.getBundle(
493: "org.netbeans.modules.db.resources.Bundle")
494: .getString("EXC_CannotEstablishConnection"),
495: new String[] { db, drv, e.getMessage() }); // NOI18N
496:
497: //commented out for 3.6 release, need to solve for next Studio release
498: // hack for Pointbase Network Server
499: // if(drv.equals(PointbasePlus.DRIVER))
500: // if(e.getErrorCode()==PointbasePlus.ERR_SERVER_REJECTED)
501: // message = MessageFormat.format(bundle.getString("EXC_PointbaseServerRejected"), new String[] {message, db}); // NOI18N
502:
503: propertySupport.firePropertyChange("failed", null, null);
504:
505: // For Java Studio Enterprise.
506: getOpenConnection().disable();
507:
508: initSQLException(e);
509: DDLException ddle = new DDLException(message);
510: ddle.initCause(e);
511: throw ddle;
512: } catch (Exception exc) {
513: String message = MessageFormat.format(NbBundle.getBundle(
514: "org.netbeans.modules.db.resources.Bundle")
515: .getString("EXC_CannotEstablishConnection"),
516: new String[] { db, drv, exc.getMessage() }); // NOI18N
517:
518: propertySupport.firePropertyChange("failed", null, null);
519:
520: // For Java Studio Enterprise.
521: getOpenConnection().disable();
522:
523: DDLException ddle = new DDLException(message);
524: ddle.initCause(exc);
525: throw ddle;
526: }
527: }
528:
529: public void connect() {
530: if (LOG) {
531: LOGGER.log(Level.FINE, "connect()");
532: }
533:
534: createConnectTask();
535: }
536:
537: public Task createConnectTask() {
538: return RequestProcessor.getDefault().post(new Runnable() {
539: public void run() {
540: if (drv == null || db == null || usr == null)
541: sendException(new DDLException(NbBundle.getBundle(
542: "org.netbeans.modules.db.resources.Bundle")
543: .getString("EXC_InsufficientConnInfo")));
544:
545: Properties dbprops = new Properties();
546: if (usr.length() > 0) {
547: dbprops.put("user", usr); //NOI18N
548: }
549: if ((pwd != null && pwd.length() > 0)) {
550: dbprops.put("password", pwd); //NOI18N
551: }
552:
553: Connection conn = null;
554: try {
555: propertySupport.firePropertyChange("connecting",
556: null, null);
557:
558: // For Java Studio Enterprise.
559: getOpenConnection().enable();
560:
561: // For Java Studio Enterprise.
562: getOpenConnection().enable();
563: startRuntimes();
564:
565: // hack for Derby
566: DerbyConectionEventListener.getDefault()
567: .beforeConnect(DatabaseConnection.this );
568:
569: JDBCDriver useDriver = findJDBCDriver();
570: if (useDriver == null) {
571: // will be loaded through DriverManager, make sure it is loaded
572: Class.forName(drv);
573: }
574:
575: conn = DbDriverManager.getDefault().getConnection(
576: db, dbprops, useDriver);
577: setConnection(conn);
578:
579: DatabaseUILogger.logConnection(drv);
580:
581: propertySupport.firePropertyChange("connected",
582: null, null);
583:
584: // For Java Studio Enterprise.
585: getOpenConnection().disable();
586:
587: } catch (SQLException e) {
588: String message = MessageFormat
589: .format(
590: NbBundle
591: .getBundle(
592: "org.netbeans.modules.db.resources.Bundle")
593: .getString(
594: "EXC_CannotEstablishConnection"),
595: new String[] { db, drv,
596: e.getMessage() }); // NOI18N
597:
598: //commented out for 3.6 release, need to solve for next Studio release
599: // hack for Pointbase Network Server
600: // if (drv.equals(PointbasePlus.DRIVER))
601: // if (e.getErrorCode() == PointbasePlus.ERR_SERVER_REJECTED)
602: // message = MessageFormat.format(bundle.getString("EXC_PointbaseServerRejected"), new String[] {message, db}); // NOI18N
603:
604: propertySupport.firePropertyChange("failed", null,
605: null);
606:
607: // For Java Studio Enterprise.
608: getOpenConnection().disable();
609:
610: initSQLException(e);
611: DDLException ddle = new DDLException(message);
612: ddle.initCause(e);
613: sendException(ddle);
614:
615: if (conn != null) {
616: setConnection(null);
617: try {
618: conn.close();
619: } catch (SQLException sqle) {
620: Logger.getLogger("global").log(
621: Level.WARNING, null, sqle); // NOI18N
622: }
623: }
624: } catch (Exception exc) {
625: propertySupport.firePropertyChange("failed", null,
626: null);
627:
628: // For Java Studio Enterprise.
629: getOpenConnection().disable();
630:
631: sendException(exc);
632:
633: setConnection(null);
634: if (conn != null) {
635: try {
636: conn.close();
637: } catch (SQLException sqle) {
638: Logger.getLogger("global").log(
639: Level.WARNING, null, sqle); // NOI18N
640: }
641: }
642: }
643: }
644: }, 0);
645: }
646:
647: /** Calls the initCause() for SQLException with the value
648: * of getNextException() so this exception's stack trace contains
649: * the complete data.
650: */
651: private void initSQLException(SQLException e) {
652: SQLException next = e.getNextException();
653: while (next != null) {
654: try {
655: e.initCause(next);
656: } catch (IllegalStateException e2) {
657: // do nothing, already initialized
658: }
659: e = next;
660: next = e.getNextException();
661: }
662: }
663:
664: private void startRuntimes() {
665: DatabaseRuntime[] runtimes = DatabaseRuntimeManager
666: .getDefault().getRuntimes(drv);
667:
668: for (int i = 0; i < runtimes.length; i++) {
669: DatabaseRuntime runtime = runtimes[i];
670: if (runtime.isRunning()) {
671: continue;
672: }
673: if (runtime.canStart() && runtime.acceptsDatabaseURL(db)) {
674: runtime.start();
675: }
676: }
677: }
678:
679: public void addExceptionListener(ExceptionListener l) {
680: if (l != null)
681: exceptionListeners.add(l);
682: }
683:
684: public void removeExceptionListener(ExceptionListener l) {
685: exceptionListeners.remove(l);
686: }
687:
688: private void sendException(Exception exc) {
689: synchronized (exceptionListeners) {
690: Iterator it = exceptionListeners.iterator();
691: while (it.hasNext()) {
692: ExceptionListener l = (ExceptionListener) it.next();
693: l.exceptionOccurred(exc);
694: }
695: }
696: }
697:
698: public void setConnection(Connection c) {
699: con = c;
700: }
701:
702: public Connection getConnection() {
703: return con;
704: }
705:
706: /** Add property change listener
707: * Registers a listener for the PropertyChange event. The connection object
708: * should fire a PropertyChange event whenever somebody changes driver, database,
709: * login name or password.
710: */
711: public void addPropertyChangeListener(PropertyChangeListener l) {
712: propertySupport.addPropertyChangeListener(l);
713: }
714:
715: /** Remove property change listener
716: * Remove a listener for the PropertyChange event.
717: */
718: public void removePropertyChangeListener(PropertyChangeListener l) {
719: propertySupport.removePropertyChangeListener(l);
720: }
721:
722: public int hashCode() {
723: return drv.hashCode() + db.hashCode() + usr.hashCode();
724: }
725:
726: /** Compares two connections.
727: * Returns true if driver, database and login name equals.
728: */
729: public boolean equals(Object obj) {
730: if (obj instanceof DBConnection) {
731: DBConnection con = (DBConnection) obj;
732: return toString().equals(con.toString());
733: }
734:
735: return false;
736: }
737:
738: /** Reads object from stream */
739: private void readObject(java.io.ObjectInputStream in)
740: throws java.io.IOException, ClassNotFoundException {
741: drv = (String) in.readObject();
742: db = (String) in.readObject();
743: usr = (String) in.readObject();
744: schema = (String) in.readObject();
745: rpwd = Boolean.FALSE;
746: name = (String) in.readObject();
747:
748: try {
749: drvname = (String) in.readObject();
750: } catch (Exception exc) {
751: //IGNORE - not stored in 3.6 and earlier
752: }
753:
754: // boston setting/pilsen setting?
755: if ((name != null) && (name.equals(DatabaseConnection.SUPPORT))) {
756: // pilsen
757: } else {
758: // boston
759: schema = null;
760: }
761: name = null;
762: name = getName();
763:
764: dbconn = DatabaseConnectionAccessor.DEFAULT
765: .createDatabaseConnection(this );
766: }
767:
768: /** Writes object to stream */
769: private void writeObject(java.io.ObjectOutputStream out)
770: throws java.io.IOException {
771: out.writeObject(drv);
772: out.writeObject(db);
773: out.writeObject(usr);
774: out.writeObject(schema);
775: out.writeObject(DatabaseConnection.SUPPORT);
776: out.writeObject(drvname);
777: }
778:
779: public String toString() {
780: return "Driver:" + getDriver() + "Database:"
781: + getDatabase().toLowerCase() + "User:"
782: + getUser().toLowerCase() + "Schema:"
783: + getSchema().toLowerCase(); // NOI18N
784: }
785:
786: /**
787: * Gets the API DatabaseConnection which corresponds to this connection.
788: */
789: public org.netbeans.api.db.explorer.DatabaseConnection getDatabaseConnection() {
790: return dbconn;
791: }
792:
793: public void selectInExplorer() {
794: String nodeName = null;
795: try {
796: nodeName = findConnectionNodeInfo(getName()).getNode()
797: .getName();
798: } catch (DatabaseException e) {
799: Exceptions.printStackTrace(e);
800: return;
801: }
802:
803: // find the Runtime panel top component
804: // quite hacky, but it will be replaced by the Server Navigator
805:
806: TopComponent runtimePanel = null;
807: ExplorerManager runtimeExplorer = null;
808: Node runtimeNode = null;
809:
810: for (Iterator i = TopComponent.getRegistry().getOpened()
811: .iterator(); i.hasNext();) {
812: TopComponent component = (TopComponent) i.next();
813: Component[] children = component.getComponents();
814: if (children.length > 0) {
815: ExplorerManager explorer = ExplorerManager
816: .find(children[0]);
817: if ("Runtime".equals(explorer.getRootContext()
818: .getName())) { // NOI18N
819: runtimePanel = component;
820: runtimeExplorer = explorer;
821: runtimeNode = explorer.getRootContext();
822: }
823: }
824: }
825:
826: if (runtimePanel == null) {
827: return;
828: }
829:
830: Node node = null;
831: try {
832: node = NodeOp.findPath(runtimeNode, new String[] {
833: "Databases", nodeName }); // NOI18N
834: } catch (NodeNotFoundException e) {
835: Exceptions.printStackTrace(e);
836: return;
837: }
838:
839: try {
840: runtimeExplorer.setSelectedNodes(new Node[] { node });
841: } catch (PropertyVetoException e) {
842: Exceptions.printStackTrace(e);
843: return;
844: }
845:
846: runtimePanel.requestActive();
847: }
848:
849: public void showConnectionDialog() {
850: try {
851: final ConnectionNodeInfo cni = findConnectionNodeInfo(getName());
852: if (cni != null && cni.getConnection() == null) {
853: Mutex.EVENT.readAccess(new Runnable() {
854: public void run() {
855: new ConnectAction.ConnectionDialogDisplayer()
856: .showDialog(cni, false);
857: }
858: });
859: }
860: } catch (DatabaseException e) {
861: Exceptions.printStackTrace(e);
862: }
863: }
864:
865: public Connection getJDBCConnection() {
866: try {
867: ConnectionNodeInfo cni = findConnectionNodeInfo(getName());
868: if (cni != null && cni.getConnection() != null) {
869: return cni.getConnection();
870: }
871: } catch (DatabaseException e) {
872: Exceptions.printStackTrace(e);
873: }
874: return null;
875: }
876:
877: public void disconnect() throws DatabaseException {
878: ConnectionNodeInfo cni = findConnectionNodeInfo(getName());
879: if (cni != null && cni.getConnection() != null) {
880: cni.disconnect();
881: }
882: }
883:
884: private ConnectionNodeInfo findConnectionNodeInfo(String connection)
885: throws DatabaseException {
886: assert connection != null;
887:
888: // Got to retrieve the conn nodes and wait for the "Please wait" node to dissapear.
889: // We can't use the info classes here since surprisingly
890: // the CNIs found in RootNode.getInstance().getInfo are different than
891: // the ones the ConnectionNodes in the Databases tree listen to
892:
893: Node[] nodes;
894: String waitNode = NbBundle.getBundle(
895: "org.netbeans.modules.db.resources.Bundle").getString(
896: "WaitNode"); // NOI18N
897:
898: for (;;) {
899: nodes = RootNode.getInstance().getChildren().getNodes();
900: if (nodes.length == 1
901: && waitNode.equals(nodes[0].getName())) {
902: try {
903: Thread.sleep(60);
904: } catch (InterruptedException e) {
905: // PENDING
906: }
907: } else {
908: break;
909: }
910: }
911:
912: for (int i = 0; i < nodes.length; i++) {
913: // Skip nodes registered by node providers
914: if (!(nodes[i] instanceof DatabaseNode)) {
915: continue;
916: }
917:
918: DatabaseNodeInfo info = (DatabaseNodeInfo) nodes[i]
919: .getCookie(DatabaseNodeInfo.class);
920: if (info == null) {
921: continue;
922: }
923: ConnectionNodeInfo nfo = (ConnectionNodeInfo) info
924: .getParent(DatabaseNode.CONNECTION);
925: if (nfo == null) {
926: continue;
927: }
928: if (connection
929: .equals(nfo.getDatabaseConnection().getName())) {
930: return nfo;
931: }
932: }
933: return null;
934: }
935:
936: private Object readResolve() throws ObjectStreamException {
937: // sometimes deserialized objects have a null propertySuppport, not sure why
938: if (propertySupport == null) {
939: propertySupport = new PropertyChangeSupport(this);
940: }
941: return this;
942: }
943: }
|