# HG changeset patch
# Parent bc7d23461f89dd178e4d5c25c5288011ddcb6f7f
#197408: Enable editting of connection properties for db connections
diff --git a/db/libsrc/org/netbeans/lib/ddl/DBConnection.java b/db/libsrc/org/netbeans/lib/ddl/DBConnection.java
--- a/db/libsrc/org/netbeans/lib/ddl/DBConnection.java
+++ b/db/libsrc/org/netbeans/lib/ddl/DBConnection.java
@@ -45,6 +45,7 @@
package org.netbeans.lib.ddl;
import java.sql.Connection;
+import java.util.Properties;
/**
* Connection information.
@@ -143,4 +144,7 @@
* driver or database does not exist or is inaccessible.
*/
public Connection createJDBCConnection() throws DDLException;
+
+ public void setConnectionProperties(Properties connectionProperties);
+ public Properties getConnectionProperties();
}
diff --git a/db/src/org/netbeans/api/db/explorer/node/Bundle.properties b/db/src/org/netbeans/api/db/explorer/node/Bundle.properties
--- a/db/src/org/netbeans/api/db/explorer/node/Bundle.properties
+++ b/db/src/org/netbeans/api/db/explorer/node/Bundle.properties
@@ -142,6 +142,8 @@
ForeignColumnDescription=Column
KeySeq=Keyseq
KeySeqDescription=Keyseq
+ConnectionProperties=Connection properties
+ConnectionPropertiesDescription=Connection properties
# Booleans
diff --git a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java b/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java
--- a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java
+++ b/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java
@@ -156,6 +156,10 @@
*/
private MetadataModel metadataModel = null;
+ /** Properties for connection
+ */
+ private Properties connectionProperties = new Properties();
+
/**
* The API DatabaseConnection (delegates to this instance)
*/
@@ -173,6 +177,7 @@
public static final String PROP_DRIVERNAME = "drivername"; //NOI18N
public static final String PROP_NAME = "name"; //NOI18N
public static final String PROP_DISPLAY_NAME = "displayName"; //NOI18N
+ public static final String PROP_CONNECTIONPROPERTIES = "connectionProperties";
public static final String DRIVER_CLASS_NET = "org.apache.derby.jdbc.ClientDriver"; // NOI18N
public static final int DERBY_UNICODE_ERROR_CODE = 20000;
private OpenConnectionInterface openConnection = null;
@@ -210,22 +215,34 @@
* @param password User password
*/
public DatabaseConnection(String driver, String database, String user, String password) {
- this(driver, null, database, null, user, password, null);
+ this(driver, null, database, null, user, password, null, null);
}
public DatabaseConnection(String driver, String driverName, String database,
String theschema, String user, String password) {
- this(driver, driverName, database, theschema, user, password, null);
+ this(driver, driverName, database, theschema, user, password, null, null);
}
public DatabaseConnection(String driver, String driverName, String database,
String theschema, String user) {
- this(driver, driverName, database, theschema, user, null, null);
+ this(driver, driverName, database, theschema, user, null, null, null);
+ }
+
+ public DatabaseConnection(String driver, String driverName, String database,
+ String theschema, String user, Properties connectionProperties) {
+ this(driver, driverName, database, theschema, user, null, null, connectionProperties);
}
public DatabaseConnection(String driver, String driverName, String database,
String theschema, String user, String password,
Boolean rememberPassword) {
+ this(driver, driverName, database, theschema, user, password,
+ rememberPassword, null);
+ }
+
+ public DatabaseConnection(String driver, String driverName, String database,
+ String theschema, String user, String password,
+ Boolean rememberPassword, Properties connectionProperties) {
this();
drv = driver;
drvname = driverName;
@@ -235,6 +252,7 @@
rpwd = rememberPassword == null ? null : Boolean.valueOf(rememberPassword);
schema = theschema;
name = getName();
+ setConnectionProperties(connectionProperties);
}
public JDBCDriver findJDBCDriver() {
@@ -548,6 +566,22 @@
}
}
+ @Override
+ public Properties getConnectionProperties() {
+ return (Properties) connectionProperties.clone();
+ }
+
+ @Override
+ public void setConnectionProperties(Properties connectionProperties) {
+ Properties old = this.connectionProperties;
+ if (connectionProperties == null) {
+ this.connectionProperties = new Properties();
+ } else {
+ this.connectionProperties = (Properties) connectionProperties.clone();
+ }
+ propertySupport.firePropertyChange(PROP_CONNECTIONPROPERTIES, old, connectionProperties);
+ }
+
/** Returns user schema name */
@Override
public String getSchema() {
@@ -732,9 +766,16 @@
throw new DDLException(NbBundle.getMessage(DatabaseConnection.class, "EXC_InsufficientConnInfo")); // NOI18N
}
- Properties dbprops = new Properties();
+ Properties dbprops;
+ if (connectionProperties != null) {
+ dbprops = getConnectionProperties();
+ } else {
+ dbprops = new Properties();
+ }
if ((usr != null) && (usr.length() > 0)) {
dbprops.put("user", usr); //NOI18N
+ }
+ if ((pwd != null) && (pwd.length() > 0)) {
dbprops.put("password", pwd); //NOI18N
}
@@ -812,11 +853,16 @@
sendException(new DDLException(NbBundle.getMessage(DatabaseConnection.class, "EXC_InsufficientConnInfo")));
}
- Properties dbprops = new Properties();
- if ( usr.length() > 0 ) {
+ Properties dbprops;
+ if (connectionProperties != null) {
+ dbprops = getConnectionProperties();
+ } else {
+ dbprops = new Properties();
+ }
+ if ((usr != null) && (usr.length() > 0)) {
dbprops.put("user", usr); //NOI18N
}
- if ((pwd != null && pwd.length() > 0)) {
+ if ((pwd != null) && (pwd.length() > 0)) {
dbprops.put("password", pwd); //NOI18N
}
@@ -1005,9 +1051,17 @@
*/
@Override
public boolean equals(Object obj) {
- if (obj instanceof DBConnection) {
- DBConnection conn = (DBConnection) obj;
- return toString().equals(conn.toString());
+ if (obj instanceof DatabaseConnection) {
+ DatabaseConnection conn = (DatabaseConnection) obj;
+ if (toString().equals(conn.toString())) {
+ if ((connectionProperties == null
+ && conn.getConnectionProperties() == null)) {
+ return true;
+ } else if (connectionProperties != null) {
+ return connectionProperties.equals(
+ conn.getConnectionProperties());
+ }
+ }
}
return false;
@@ -1029,6 +1083,11 @@
//IGNORE - drvname not stored in 3.6 and earlier
//IGNORE - displayName not stored in 6.7 and earlier
}
+ try {
+ connectionProperties = (Properties) in.readObject();
+ } catch (Exception ex) {
+ //IGNORE - connectionProperties not stored in 7.3 and earlier
+ }
// boston setting/pilsen setting?
if ((name != null) && (name.equals(DatabaseConnection.SUPPORT))) {
@@ -1052,6 +1111,7 @@
out.writeObject(DatabaseConnection.SUPPORT);
out.writeObject(drvname);
out.writeObject(displayName);
+ out.writeObject(connectionProperties);
}
@Override
diff --git a/db/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertor.java b/db/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertor.java
--- a/db/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertor.java
+++ b/db/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertor.java
@@ -60,6 +60,7 @@
import java.nio.charset.CoderResult;
import java.util.LinkedList;
import java.util.Map;
+import java.util.Properties;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
@@ -237,7 +238,8 @@
handler.driverName,
handler.connectionUrl,
handler.schema,
- handler.user);
+ handler.user,
+ handler.connectionProperties);
dbconn.setConnectionFileName(handler.connectionFileName);
if (handler.displayName != null) {
dbconn.setDisplayName(handler.displayName);
@@ -402,6 +404,19 @@
} else {
DatabaseConnection.deletePassword(name);
}
+ if (instance.getConnectionProperties() != null) {
+ Properties p = instance.getConnectionProperties();
+ for (String key : p.stringPropertyNames()) {
+ pw.println(" "); //NOI18N
+ pw.print(" "); //NOI18N
+ pw.print(XMLUtil.toElementContent(key));
+ pw.println(""); //NOI18N
+ pw.print(" "); //NOI18N
+ pw.print(XMLUtil.toElementContent(p.getProperty(key)));
+ pw.println(""); //NOI18N
+ pw.println(" "); //NOI18N
+ }
+ }
pw.println(""); //NOI18N
}
}
@@ -418,19 +433,29 @@
private static final String ELEMENT_USER = "user"; // NOI18N
private static final String ELEMENT_PASSWORD = "password"; // NOI18N
private static final String ELEMENT_DISPLAY_NAME = "display-name"; // NOI18N
+ private static final String ELEMENT_CONNECTION_PROPERTY = "connection-property"; // NOI18N
+ private static final String ELEMENT_CONNECTION_PROPERTY_NAME = "name"; // NOI18N
+ private static final String ELEMENT_CONNECTION_PROPERTY_VALUE = "value"; // NOI18N
private static final String ATTR_PROPERTY_VALUE = "value"; // NOI18N
final String connectionFileName;
+ private boolean readingProperty = false;
+ private String propertyName;
+ private String propertyValue;
+ private StringBuilder buffer = new StringBuilder();
+
String driverClass;
String driverName;
String connectionUrl;
String schema;
String user;
String displayName;
+ Properties connectionProperties;
public Handler(String connectionFileName) {
this.connectionFileName = connectionFileName;
+ this.connectionProperties = new Properties();
}
@Override
@@ -457,6 +482,14 @@
user = value;
} else if (ELEMENT_DISPLAY_NAME.equals(qName)) {
displayName = value;
+ } else if (ELEMENT_CONNECTION_PROPERTY.equals(qName)) {
+ readingProperty = true;
+ propertyName = ""; //NOI18N
+ propertyValue = ""; //NOI18N
+ } else if (readingProperty && ELEMENT_CONNECTION_PROPERTY_NAME.equals(qName)) {
+ buffer.setLength(0);
+ } else if (readingProperty && ELEMENT_CONNECTION_PROPERTY_VALUE.equals(qName)) {
+ buffer.setLength(0);
} else if (ELEMENT_PASSWORD.equals(qName)) {
// reading old settings
byte[] bytes = null;
@@ -482,6 +515,35 @@
}
}
}
+
+ @Override
+ public void ignorableWhitespace(char[] chars, int start, int length) throws SAXException {
+ if (readingProperty) {
+ buffer.append(chars, start, length);
+ }
+ }
+
+ @Override
+ public void characters(char[] chars, int start, int length) throws SAXException {
+ if (readingProperty) {
+ buffer.append(chars, start, length);
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (readingProperty && ELEMENT_CONNECTION_PROPERTY.equals(qName)) {
+ connectionProperties.put(propertyName, propertyValue);
+ readingProperty = false;
+ propertyName = "";
+ propertyValue = "";
+ buffer.setLength(0);
+ } else if (readingProperty && ELEMENT_CONNECTION_PROPERTY_NAME.equals(qName)) {
+ propertyName = buffer.toString();
+ } else if (readingProperty && ELEMENT_CONNECTION_PROPERTY_VALUE.equals(qName)) {
+ propertyValue = buffer.toString();
+ }
+ }
}
private final class PCL implements PropertyChangeListener, Runnable {
diff --git a/db/src/org/netbeans/modules/db/explorer/node/ConnectionNode.java b/db/src/org/netbeans/modules/db/explorer/node/ConnectionNode.java
--- a/db/src/org/netbeans/modules/db/explorer/node/ConnectionNode.java
+++ b/db/src/org/netbeans/modules/db/explorer/node/ConnectionNode.java
@@ -48,6 +48,7 @@
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
+import java.util.Properties;
import javax.swing.Action;
import org.netbeans.api.db.explorer.DatabaseException;
import org.netbeans.api.db.explorer.DatabaseMetaDataTransfer;
@@ -64,8 +65,11 @@
import org.netbeans.modules.db.explorer.metadata.MetadataModelManager;
import org.netbeans.modules.db.metadata.model.api.MetadataModel;
import org.netbeans.modules.db.metadata.model.api.MetadataModels;
+import org.netbeans.modules.db.util.PropertiesEditor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
+import org.openide.nodes.PropertySupport;
+import org.openide.nodes.Sheet;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
@@ -81,6 +85,8 @@
private static final String CONNECTEDICONBASE = "org/netbeans/modules/db/resources/connection.gif"; // NOI18N
private static final String DISCONNECTEDICONBASE = "org/netbeans/modules/db/resources/connectionDisconnected.gif"; // NOI18N
+ private static final String CONNECTIONPROPERTIES = "ConnectionProperties"; //NOI18N
+ private static final String CONNECTIONPROPERTIESDESC = "ConnectionPropertiesDescription"; //NOI18N
private static final String FOLDER = "Connection"; // NOI18N
private static final RequestProcessor RP = new RequestProcessor(ConnectionNode.class.getName());
@@ -160,6 +166,8 @@
} else if (nps.getName().equals(DISPLAYNAME)) {
setDisplayName(val.toString());
refreshNode = false;
+ } else if (nps.getName().equals(CONNECTIONPROPERTIES)) {
+ connection.setConnectionProperties((Properties) val);
}
super.setPropertyValue(nps, val);
@@ -181,6 +189,10 @@
addProperty(USER, USERDESC, String.class, !connected, connection.getUser());
addProperty(REMEMBERPW, REMEMBERPWDESC,
Boolean.class, !connected, connection.rememberPassword());
+ addProperty(CONNECTIONPROPERTIES, CONNECTIONPROPERTIESDESC, Properties.class, !connected, connection.getConnectionProperties());
+ Property> ps = getSheet().get(Sheet.PROPERTIES).get(CONNECTIONPROPERTIES);
+ ps.setValue("canEditAsText", Boolean.FALSE); //NOI18N
+ ps.setValue(NodePropertySupport.CUSTOM_EDITOR, PropertiesEditor.class);
if (connected) {
Specification spec = connection.getConnector().getDatabaseSpecification();
diff --git a/db/src/org/netbeans/modules/db/explorer/node/NodePropertySupport.java b/db/src/org/netbeans/modules/db/explorer/node/NodePropertySupport.java
--- a/db/src/org/netbeans/modules/db/explorer/node/NodePropertySupport.java
+++ b/db/src/org/netbeans/modules/db/explorer/node/NodePropertySupport.java
@@ -42,6 +42,7 @@
package org.netbeans.modules.db.explorer.node;
+import java.beans.PropertyEditor;
import java.lang.reflect.InvocationTargetException;
import org.netbeans.api.db.explorer.node.BaseNode;
import org.openide.nodes.PropertySupport;
@@ -51,6 +52,8 @@
* @author Rob Englander
*/
public class NodePropertySupport extends PropertySupport {
+ public static final String CUSTOM_EDITOR = "NodePropertySupport.customEditor"; //NOI18N
+ public static final String NODE = "NodePropertySupport.Node"; //NOI18N
private BaseNode node;
private String key;
@@ -59,6 +62,7 @@
super(name, type, displayName, shortDescription, true, writable);
key = name;
this.node = node;
+ setValue(NODE, node);
}
@Override
@@ -76,4 +80,37 @@
node.setPropertyValue(this, val);
}
+ /**
+ * PropertyEditor can be set via setValue - it can be either instanciated or
+ * a Class, that has a Default-Constructor and results in an object, that
+ * implements PropertyEditor
+ *
+ * @return
+ */
+ @Override
+ public PropertyEditor getPropertyEditor() {
+ PropertyEditor result = null;
+ Object potentialEditor = getValue(CUSTOM_EDITOR);
+
+ if (potentialEditor instanceof PropertyEditor) {
+ result = (PropertyEditor) potentialEditor;
+ } else if (potentialEditor instanceof Class) {
+ try {
+ potentialEditor = ((Class) potentialEditor).newInstance();
+ if (!(potentialEditor instanceof PropertyEditor)) {
+ throw new IllegalArgumentException(
+ "Editor class does not derive from property editor"); //NOI18N
+ }
+ return (PropertyEditor) potentialEditor;
+ } catch (InstantiationException ex) {
+ throw new RuntimeException(ex);
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ if (result == null) {
+ result = super.getPropertyEditor();
+ }
+ return result;
+ }
}
diff --git a/db/src/org/netbeans/modules/db/util/Bundle.properties b/db/src/org/netbeans/modules/db/util/Bundle.properties
--- a/db/src/org/netbeans/modules/db/util/Bundle.properties
+++ b/db/src/org/netbeans/modules/db/util/Bundle.properties
@@ -71,3 +71,9 @@
=TNS Name
=Additional Properties
ErrorInfoPanel.iconLabel.text=
+
+NoPropertiesSet=No properties set
+PropertiesCustomEditor.addRowButton.text=Add Property
+PropertiesCustomEditor.removeRowButton.text=Remove Property
+PropertiesCustomEditor.propertyTable.columnModel.title0=Property
+PropertiesCustomEditor.propertyTable.columnModel.title1=Value
diff --git a/db/src/org/netbeans/modules/db/util/PropertiesCustomEditor.form b/db/src/org/netbeans/modules/db/util/PropertiesCustomEditor.form
new file mode 100644
--- /dev/null
+++ b/db/src/org/netbeans/modules/db/util/PropertiesCustomEditor.form
@@ -0,0 +1,97 @@
+
+
+
diff --git a/db/src/org/netbeans/modules/db/util/PropertiesCustomEditor.java b/db/src/org/netbeans/modules/db/util/PropertiesCustomEditor.java
new file mode 100644
--- /dev/null
+++ b/db/src/org/netbeans/modules/db/util/PropertiesCustomEditor.java
@@ -0,0 +1,239 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+
+/*
+ * PropertiesCustomEditor.java
+ *
+ * Created on 01.04.2011, 20:25:24
+ */
+package org.netbeans.modules.db.util;
+
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.Vector;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * Custom implentation for a property editor, as the build in doesn't work to
+ * well with international characters
+ *
+ * @author Matthias Bläsing
+ */
+public class PropertiesCustomEditor extends javax.swing.JPanel {
+
+ PropertiesEditor editor;
+ boolean updateing;
+
+ public PropertiesCustomEditor(final PropertiesEditor editor) {
+ initComponents();
+ this.editor = editor;
+ updateTableFromEditor();
+ final TableModel tm = propertyTable.getModel();
+ tm.addTableModelListener(new TableModelListener() {
+ @Override
+ public void tableChanged(TableModelEvent tme) {
+ synchronized (PropertiesCustomEditor.this) {
+ if (updateing) {
+ return;
+ }
+ updateing = true;
+ Properties p = new Properties();
+ for (int i = 0; i < tm.getRowCount(); i++) {
+ p.setProperty((String) tm.getValueAt(i, 0), (String) tm.getValueAt(i, 1));
+ }
+ editor.setValue(p);
+ updateing = false;
+ }
+ }
+ });
+ propertyTable.getSelectionModel().addListSelectionListener(
+ new ListSelectionListener() {
+ @Override
+ public void valueChanged(ListSelectionEvent lse) {
+ updateRemoveButtonSensible();
+ }
+ });
+ updateAddButtonSensible();
+ updateRemoveButtonSensible();
+ }
+
+ private void updateAddButtonSensible() {
+ if (editor.isEditable()) {
+ addRowButton.setEnabled(true);
+ } else {
+ addRowButton.setEnabled(false);
+ }
+ }
+
+ private void updateRemoveButtonSensible() {
+ if (editor.isEditable() && propertyTable.getSelectedRowCount() > 0) {
+ removeRowButton.setEnabled(true);
+ } else {
+ removeRowButton.setEnabled(false);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateTableFromEditor() {
+ synchronized (this) {
+ if (updateing) {
+ return;
+ }
+ updateing = true;
+ Properties p = (Properties) editor.getValue();
+ DefaultTableModel dtm = (DefaultTableModel) propertyTable.getModel();
+ Vector columns = new Vector(2);
+ Vector values = new Vector();
+ columns.add(dtm.getColumnName(0));
+ columns.add(dtm.getColumnName(1));
+ for (String key : p.stringPropertyNames()) {
+ Vector row = new Vector(2);
+ row.add(key);
+ row.add(p.getProperty(key, ""));
+ values.add(row);
+ }
+ dtm.setDataVector(values, columns);
+ updateing = false;
+ }
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ buttonPanel = new javax.swing.JPanel();
+ addRowButton = new javax.swing.JButton();
+ removeRowButton = new javax.swing.JButton();
+ propertyScrollPane = new javax.swing.JScrollPane();
+ propertyTable = new javax.swing.JTable();
+
+ setLayout(new java.awt.BorderLayout());
+
+ buttonPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));
+
+ addRowButton.setText(org.openide.util.NbBundle.getMessage(PropertiesCustomEditor.class, "PropertiesCustomEditor.addRowButton.text")); // NOI18N
+ addRowButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ addRowButtonActionPerformed(evt);
+ }
+ });
+ buttonPanel.add(addRowButton);
+
+ removeRowButton.setText(org.openide.util.NbBundle.getMessage(PropertiesCustomEditor.class, "PropertiesCustomEditor.removeRowButton.text")); // NOI18N
+ removeRowButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ removeRowButtonActionPerformed(evt);
+ }
+ });
+ buttonPanel.add(removeRowButton);
+
+ add(buttonPanel, java.awt.BorderLayout.PAGE_END);
+
+ propertyTable.setAutoCreateRowSorter(true);
+ propertyTable.setModel(new javax.swing.table.DefaultTableModel(
+ new Object [][] {
+
+ },
+ new String [] {
+ "Property", "Value"
+ }
+ ) {
+ Class[] types = new Class [] {
+ java.lang.String.class, java.lang.String.class
+ };
+
+ public Class getColumnClass(int columnIndex) {
+ return types [columnIndex];
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return PropertiesCustomEditor.this.editor.isEditable();
+ }
+ });
+ propertyTable.setColumnSelectionAllowed(true);
+ propertyScrollPane.setViewportView(propertyTable);
+ propertyTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+ propertyTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(PropertiesCustomEditor.class, "PropertiesCustomEditor.propertyTable.columnModel.title0")); // NOI18N
+ propertyTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(PropertiesCustomEditor.class, "PropertiesCustomEditor.propertyTable.columnModel.title1")); // NOI18N
+
+ add(propertyScrollPane, java.awt.BorderLayout.CENTER);
+ }// //GEN-END:initComponents
+
+ private void addRowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addRowButtonActionPerformed
+ DefaultTableModel dtm = (DefaultTableModel) propertyTable.getModel();
+ dtm.addRow(new Object[]{"", ""});
+ }//GEN-LAST:event_addRowButtonActionPerformed
+
+ private void removeRowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeRowButtonActionPerformed
+ int[] viewRows = propertyTable.getSelectedRows();
+ int[] modelRows = new int[viewRows.length];
+
+ for (int i = 0; i < viewRows.length; i++) {
+ modelRows[i] = propertyTable.convertRowIndexToModel(viewRows[i]);
+ }
+
+ Arrays.sort(modelRows);
+
+ DefaultTableModel dtm = (DefaultTableModel) propertyTable.getModel();
+
+ for (int i = modelRows.length - 1; i >= 0; i--) {
+ dtm.removeRow(modelRows[i]);
+ }
+ }//GEN-LAST:event_removeRowButtonActionPerformed
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton addRowButton;
+ private javax.swing.JPanel buttonPanel;
+ private javax.swing.JScrollPane propertyScrollPane;
+ private javax.swing.JTable propertyTable;
+ private javax.swing.JButton removeRowButton;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/db/src/org/netbeans/modules/db/util/PropertiesEditor.java b/db/src/org/netbeans/modules/db/util/PropertiesEditor.java
new file mode 100644
--- /dev/null
+++ b/db/src/org/netbeans/modules/db/util/PropertiesEditor.java
@@ -0,0 +1,106 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2011 Sun Microsystems, Inc.
+ */
+package org.netbeans.modules.db.util;
+
+import java.beans.FeatureDescriptor;
+import java.beans.PropertyEditorSupport;
+import java.util.Properties;
+import org.openide.explorer.propertysheet.ExPropertyEditor;
+import org.openide.explorer.propertysheet.PropertyEnv;
+import org.openide.nodes.Node;
+import org.openide.util.NbBundle;
+
+/**
+ * Custom editor for properties - mainly exists to call custom editor
+ *
+ * @author Matthias Bläsing
+ */
+public class PropertiesEditor extends PropertyEditorSupport implements ExPropertyEditor {
+
+ private boolean canWrite = true;
+
+ @Override
+ public String getAsText() {
+ Properties value = (Properties) getValue();
+ if (value == null || value.size() == 0) {
+ return NbBundle.getMessage(PropertiesEditor.class,
+ "NoPropertiesSet"); //NOI18N
+ } else {
+ return value.toString();
+ }
+ }
+
+ /**
+ * Can't be called and throws IllegalArgumentException
+ */
+ @Override
+ public void setAsText(String text) throws IllegalArgumentException {
+ throw new IllegalArgumentException("Can't be set by setAsText");//NOI18N
+ }
+
+ @Override
+ public String getJavaInitializationString() {
+ return null; // does not generate any code
+ }
+
+ @Override
+ public boolean supportsCustomEditor() {
+ return true;
+ }
+
+ @Override
+ public java.awt.Component getCustomEditor() {
+ return new PropertiesCustomEditor(this);
+ }
+
+ @Override
+ public void attachEnv(PropertyEnv env) {
+ FeatureDescriptor d = env.getFeatureDescriptor();
+ if (d instanceof Node.Property) {
+ canWrite = ((Node.Property) d).canWrite();
+ }
+ }
+
+ public boolean isEditable() {
+ return canWrite;
+ }
+}
\ No newline at end of file
diff --git a/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertorTest.java b/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertorTest.java
--- a/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertorTest.java
+++ b/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertorTest.java
@@ -147,7 +147,7 @@
}
public void testSaveOnPropertyChange() throws Exception {
- DatabaseConnection dbconn = new DatabaseConnection("a", "b", "c", "d", "e", null);
+ DatabaseConnection dbconn = new DatabaseConnection("a", "b", "c", "d", "e", (String) null);
FileObject fo = DatabaseConnectionConvertor.create(dbconn).getPrimaryFile();
class FCL extends FileChangeAdapter {