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.actions;
043:
044: import java.awt.event.ActionEvent;
045: import java.awt.event.ActionListener;
046: import java.beans.PropertyChangeEvent;
047: import java.beans.PropertyChangeListener;
048: import java.sql.Connection;
049: import java.sql.ResultSet;
050: import java.sql.SQLException;
051: import java.text.MessageFormat;
052: import java.util.Vector;
053: import java.util.logging.Level;
054: import java.util.logging.Logger;
055:
056: import javax.swing.JTabbedPane;
057: import javax.swing.event.ChangeEvent;
058: import javax.swing.event.ChangeListener;
059: import org.netbeans.modules.db.explorer.ConnectionList;
060: import org.netbeans.modules.db.explorer.DbUtilities;
061: import org.netbeans.modules.db.explorer.dlg.ConnectionDialogMediator;
062:
063: import org.openide.DialogDescriptor;
064: import org.openide.DialogDisplayer;
065: import org.openide.NotifyDescriptor;
066: import org.openide.nodes.Node;
067:
068: import org.netbeans.api.db.explorer.DatabaseException;
069: import org.netbeans.modules.db.ExceptionListener;
070: import org.netbeans.modules.db.explorer.DatabaseConnection;
071:
072: //commented out for 3.6 release, need to solve for next Studio release
073: //import org.netbeans.modules.db.explorer.PointbasePlus;
074:
075: import org.netbeans.modules.db.explorer.dlg.ConnectionDialog;
076: import org.netbeans.modules.db.explorer.dlg.NewConnectionPanel;
077: import org.netbeans.modules.db.explorer.dlg.SchemaPanel;
078: import org.netbeans.api.db.explorer.JDBCDriver;
079: import org.netbeans.api.db.explorer.JDBCDriverManager;
080: import org.netbeans.lib.ddl.DDLException;
081: import org.netbeans.modules.db.explorer.driver.JDBCDriverSupport;
082: import org.netbeans.modules.db.explorer.infos.ConnectionNodeInfo;
083: import org.netbeans.modules.db.explorer.infos.DatabaseNodeInfo;
084: import org.netbeans.modules.db.explorer.infos.DriverNodeInfo;
085: import org.netbeans.modules.db.explorer.infos.RootNodeInfo;
086: import org.netbeans.modules.db.explorer.nodes.RootNode;
087: import org.openide.util.HelpCtx;
088:
089: public class ConnectUsingDriverAction extends DatabaseAction {
090: static final long serialVersionUID = 8245005834483564671L;
091:
092: protected boolean enable(Node[] activatedNodes) {
093: return (activatedNodes != null && activatedNodes.length == 1);
094: }
095:
096: public void performAction(Node[] activatedNodes) {
097: Node node = activatedNodes[0];
098: DriverNodeInfo info = (DriverNodeInfo) node
099: .getCookie(DatabaseNodeInfo.class);
100: JDBCDriver driver = info.getJDBCDriver();
101:
102: String driverName, driverClass;
103: if (driver != null) {
104: driverName = driver.getName();
105: driverClass = driver.getClassName();
106: } else {
107: // no JDBCDriver, have to resort to the info
108: driverName = info.getName();
109: // info.getURL() suprisingly returns the driver class
110: driverClass = info.getURL();
111: }
112: new NewConnectionDialogDisplayer().showDialog(driverName,
113: driverClass);
114: }
115:
116: public static final class NewConnectionDialogDisplayer extends
117: ConnectionDialogMediator {
118:
119: ConnectionDialog dlg;
120: ConnectionNodeInfo cni;
121: boolean advancedPanel = false;
122: boolean okPressed = false;
123:
124: public void showDialog(String driverName, String driverClass) {
125: showDialog(driverName, driverClass, null, null, null);
126: }
127:
128: public DatabaseConnection showDialog(JDBCDriver driver,
129: String databaseUrl, String user, String password) {
130: String driverName = (driver != null) ? driver.getName()
131: : null;
132: String driverClass = (driver != null) ? driver
133: .getClassName() : null;
134: return showDialog(driverName, driverClass, databaseUrl,
135: user, password);
136: }
137:
138: public DatabaseConnection showDialog(String driverName,
139: String driverClass, String databaseUrl, String user,
140: String password) {
141: String finalDriverClass = null;
142:
143: JDBCDriver[] drivers;
144: if ((null != databaseUrl) && (null != driverClass)) {
145: drivers = JDBCDriverManager.getDefault().getDrivers(
146: driverClass);
147: finalDriverClass = driverClass;
148: } else {
149: drivers = JDBCDriverManager.getDefault().getDrivers();
150: }
151:
152: // issue 74723: select the Derby network driver by default
153: // otherwise just select the first driver
154: String selectedDriverName = null;
155: String selectedDriverClass = null;
156: if (driverName == null || driverClass == null) {
157: for (int i = 0; i < drivers.length; i++) {
158: if (JDBCDriverSupport.isAvailable(drivers[i])) {
159: if (selectedDriverName == null) {
160: selectedDriverName = drivers[i].getName();
161: selectedDriverClass = drivers[i]
162: .getClassName();
163: }
164: if ("org.apache.derby.jdbc.ClientDriver"
165: .equals(drivers[i].getClassName())) { // NOI18N
166: selectedDriverName = drivers[i].getName();
167: selectedDriverClass = drivers[i]
168: .getClassName();
169: break;
170: }
171: }
172: }
173: } else {
174: selectedDriverName = driverName;
175: selectedDriverClass = driverClass;
176: }
177:
178: final DatabaseConnection cinfo = new DatabaseConnection();
179: cinfo.setDriverName(selectedDriverName);
180: cinfo.setDriver(selectedDriverClass);
181: if (user != null) {
182: cinfo.setUser(user);
183: }
184: if (password != null) {
185: cinfo.setPassword(password);
186: }
187:
188: if (null != databaseUrl) {
189: cinfo.setDatabase(databaseUrl);
190: }
191:
192: final NewConnectionPanel basePanel = new NewConnectionPanel(
193: this , finalDriverClass, cinfo);
194: final SchemaPanel schemaPanel = new SchemaPanel(this , cinfo);
195:
196: PropertyChangeListener argumentListener = new PropertyChangeListener() {
197: public void propertyChange(PropertyChangeEvent event) {
198: if (event.getPropertyName().equals(
199: "argumentChanged")) { //NOI18N
200: schemaPanel.setSchemas(new Vector(), ""); //NOI18N
201: schemaPanel.resetProgress();
202: try {
203: Connection conn = cinfo.getConnection();
204: if (conn != null && !conn.isClosed())
205: conn.close();
206: } catch (SQLException exc) {
207: //unable to close the connection
208: }
209:
210: }
211: }
212: };
213: basePanel.addPropertyChangeListener(argumentListener);
214:
215: final PropertyChangeListener connectionListener = new PropertyChangeListener() {
216: public void propertyChange(PropertyChangeEvent event) {
217: if (event.getPropertyName().equals("connecting")) { // NOI18N
218: fireConnectionStarted();
219: }
220: if (event.getPropertyName().equals("failed")) { // NOI18N
221: fireConnectionFailed();
222: }
223: if (event.getPropertyName().equals("connected")) { //NOI18N
224: if (retrieveSchemas(schemaPanel, cinfo, cinfo
225: .getUser()))
226: cinfo.setSchema(schemaPanel.getSchema());
227: else {
228: //switch to schema panel
229: fireConnectionFinished();
230: dlg.setSelectedComponent(schemaPanel);
231: return;
232: }
233:
234: fireConnectionFinished();
235:
236: //connected by "Get Schemas" button in the schema panel => don't create connection node
237: //and don't close the connect dialog
238: if (advancedPanel && !okPressed)
239: return;
240:
241: try {
242: ((RootNodeInfo) RootNode.getInstance()
243: .getInfo()).addConnection(cinfo);
244: } catch (DatabaseException exc) {
245: Logger.getLogger("global").log(Level.INFO,
246: null, exc);
247: DbUtilities.reportError(bundle().getString(
248: "ERR_UnableToAddConnection"), exc
249: .getMessage()); // NOI18N
250: try {
251: cinfo.getConnection().close();
252: } catch (SQLException e) {
253: //unable to close db connection
254: }
255: return;
256: }
257: if (dlg != null) {
258: dlg.close();
259: // removeListeners(cinfo);
260: }
261: } else
262: okPressed = false;
263: }
264: };
265:
266: final ExceptionListener excListener = new ExceptionListener() {
267: public void exceptionOccurred(Exception exc) {
268: if (exc instanceof DDLException) {
269: Logger.getLogger("global").log(Level.INFO,
270: null, exc.getCause());
271: } else {
272: Logger.getLogger("global").log(Level.INFO,
273: null, exc);
274: }
275:
276: String message = null;
277: if (exc instanceof ClassNotFoundException) {
278: message = MessageFormat.format(bundle()
279: .getString("EXC_ClassNotFound"),
280: new String[] { exc.getMessage() }); //NOI18N
281: } else {
282: StringBuffer buffer = new StringBuffer();
283: buffer.append(DbUtilities.formatError(
284: bundle().getString(
285: "ERR_UnableToAddConnection"),
286: exc.getMessage())); // NOI18N
287: if (exc instanceof DDLException
288: && exc.getCause() instanceof SQLException) {
289: SQLException sqlEx = ((SQLException) exc
290: .getCause()).getNextException();
291: while (sqlEx != null) {
292: buffer.append("\n\n"
293: + sqlEx.getMessage()); // NOI18N
294: sqlEx = sqlEx.getNextException();
295: }
296: }
297: message = buffer.toString();
298: }
299: DialogDisplayer.getDefault().notify(
300: new NotifyDescriptor.Message(message,
301: NotifyDescriptor.ERROR_MESSAGE));
302: }
303: };
304:
305: cinfo.addPropertyChangeListener(connectionListener);
306: cinfo.addExceptionListener(excListener);
307:
308: ActionListener actionListener = new ActionListener() {
309: public void actionPerformed(ActionEvent event) {
310: if (event.getSource() == DialogDescriptor.OK_OPTION) {
311: okPressed = true;
312: basePanel.setConnectionInfo();
313: try {
314: if (cinfo.getConnection() == null
315: || cinfo.getConnection().isClosed())
316: cinfo.connect();
317: else {
318: cinfo
319: .setSchema(schemaPanel
320: .getSchema());
321: ((RootNodeInfo) RootNode.getInstance()
322: .getInfo())
323: .addConnection(cinfo);
324: if (dlg != null)
325: dlg.close();
326: }
327: } catch (SQLException exc) {
328: //isClosed() method failed, try to connect
329: cinfo.connect();
330: } catch (DatabaseException exc) {
331: Logger.getLogger("global").log(Level.INFO,
332: null, exc);
333: DbUtilities.reportError(bundle().getString(
334: "ERR_UnableToAddConnection"), exc
335: .getMessage()); // NOI18N
336: try {
337: cinfo.getConnection().close();
338: cinfo.setConnection(null);
339: } catch (SQLException e) {
340: //unable to close db connection
341: cinfo.setConnection(null);
342: } finally {
343: }
344: }
345: return;
346: }
347: }
348: };
349:
350: ChangeListener changeTabListener = new ChangeListener() {
351: public void stateChanged(ChangeEvent e) {
352: if (((JTabbedPane) e.getSource())
353: .getSelectedComponent().equals(schemaPanel)) {
354: advancedPanel = true;
355: basePanel.setConnectionInfo();
356: } else
357: advancedPanel = false;
358: }
359: };
360:
361: dlg = new ConnectionDialog(this , basePanel, schemaPanel,
362: basePanel.getTitle(), new HelpCtx(
363: "new_db_save_password"), actionListener,
364: changeTabListener); // NOI18N
365: dlg.setVisible(true);
366:
367: return ConnectionList.getDefault().getConnection(cinfo);
368: }
369:
370: // private void removeListeners() {
371: // cinfo.removePropertyChangeListener(connectionListener);
372: // cinfo.removeExceptionListener(excListener);
373: // }
374:
375: protected boolean retrieveSchemas(SchemaPanel schemaPanel,
376: DatabaseConnection dbcon, String defaultSchema) {
377: fireConnectionStep(bundle().getString(
378: "ConnectionProgress_Schemas")); // NOI18N
379: Vector schemas = new Vector();
380: try {
381: ResultSet rs = dbcon.getConnection().getMetaData()
382: .getSchemas();
383: if (rs != null)
384: while (rs.next()) {
385: schemas.add(rs.getString(1).trim());
386: }
387: } catch (SQLException exc) {
388: //commented out for 3.6 release, need to solve for next Studio release
389: // hack for Pointbase Network Server
390: // if (dbcon.getDriver().equals(PointbasePlus.DRIVER))
391: // if (exc.getErrorCode() == PointbasePlus.ERR_SERVER_REJECTED) {
392: String message = MessageFormat.format(bundle()
393: .getString("ERR_UnableObtainSchemas"),
394: new String[] { exc.getMessage() }); // NOI18N
395: // message = MessageFormat.format(bundle().getString("EXC_PointbaseServerRejected"), new String[] {message, dbcon.getDatabase()}); // NOI18N
396: DialogDisplayer.getDefault().notify(
397: new NotifyDescriptor.Message(message,
398: NotifyDescriptor.ERROR_MESSAGE));
399: // schema will be set to null
400: // return true;
401: // }
402: }
403:
404: return schemaPanel.setSchemas(schemas, defaultSchema);
405: }
406: }
407: }
|