Index: j2ee/utilities/apichanges.xml =================================================================== RCS file: /cvs/j2ee/utilities/apichanges.xml,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.1.6.2 diff -c -r1.1.2.1 -r1.1.2.1.6.2 *** j2ee/utilities/apichanges.xml 15 Sep 2005 18:59:01 -0000 1.1.2.1 --- j2ee/utilities/apichanges.xml 17 Mar 2006 15:53:29 -0000 1.1.2.1.6.2 *************** *** 121,126 **** --- 121,143 ---- + + + + + Added two customizers: for . + + + + + +

+ Added the DatasourceUIHelper class for listing and managing data sources + in the combobox given by a client. +

+
+ +
Index: j2ee/utilities/arch.xml =================================================================== RCS file: /cvs/j2ee/utilities/arch.xml,v retrieving revision 1.3.2.1.2.1 retrieving revision 1.3.2.1.2.1.4.1 diff -c -r1.3.2.1.2.1 -r1.3.2.1.2.1.4.1 *** j2ee/utilities/arch.xml 9 Feb 2006 13:15:19 -0000 1.3.2.1.2.1 --- j2ee/utilities/arch.xml 17 Mar 2006 09:41:18 -0000 1.3.2.1.2.1.4.1 *************** *** 93,98 **** --- 93,106 ---- --> + +

+ DatasourceUIHelper + populates and manages the content of the combobox given by a client. + The combobox content consists of data sources in the alphabetical order + and items allowing data sources management. +

+
Index: j2ee/utilities/manifest.mf =================================================================== RCS file: /cvs/j2ee/utilities/manifest.mf,v retrieving revision 1.6.2.3.2.1 retrieving revision 1.6.2.3.2.1.4.1 diff -c -r1.6.2.3.2.1 -r1.6.2.3.2.1.4.1 *** j2ee/utilities/manifest.mf 9 Feb 2006 13:15:19 -0000 1.6.2.3.2.1 --- j2ee/utilities/manifest.mf 17 Mar 2006 09:41:18 -0000 1.6.2.3.2.1.4.1 *************** *** 1,5 **** Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.j2ee.common/1 ! OpenIDE-Module-Specification-Version: 1.5 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/j2ee/common/Bundle.properties --- 1,5 ---- Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.j2ee.common/1 ! OpenIDE-Module-Specification-Version: 1.6 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/j2ee/common/Bundle.properties Index: j2ee/utilities/nbproject/project.properties =================================================================== RCS file: /cvs/j2ee/utilities/nbproject/project.properties,v retrieving revision 1.9.2.1 retrieving revision 1.9.2.1.6.2 diff -c -r1.9.2.1 -r1.9.2.1.6.2 *** j2ee/utilities/nbproject/project.properties 2 Nov 2005 03:14:58 -0000 1.9.2.1 --- j2ee/utilities/nbproject/project.properties 22 Mar 2006 14:54:31 -0000 1.9.2.1.6.2 *************** *** 9,14 **** --- 9,18 ---- # Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun # Microsystems, Inc. All Rights Reserved. + javac.source=1.5 javadoc.title=J2ee Project Support API javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml + + test.unit.run.cp.extra=\ + ${j2eeserver.dir}/modules/ext/jsr88javax.jar Index: j2ee/utilities/nbproject/project.xml =================================================================== RCS file: /cvs/j2ee/utilities/nbproject/project.xml,v retrieving revision 1.19.2.3.2.2 retrieving revision 1.19.2.3.2.2.2.2 diff -c -r1.19.2.3.2.2 -r1.19.2.3.2.2.2.2 *** j2ee/utilities/nbproject/project.xml 21 Feb 2006 15:08:05 -0000 1.19.2.3.2.2 --- j2ee/utilities/nbproject/project.xml 15 Mar 2006 15:37:25 -0000 1.19.2.3.2.2.2.2 *************** *** 246,251 **** --- 246,278 ---- 6.2 + + org.netbeans.modules.j2eeserver + + + + 4 + 1.14.0 + + + + org.jdesktop.layout + + + + 1 + 1.1 + + + + org.netbeans.modules.db + + + + 0 + 1.17.0 + + org.netbeans.modules.j2ee.ddloaders *************** *** 258,263 **** --- 285,291 ---- org.netbeans.modules.websvc.dev org.netbeans.modules.e2e.end2end org.netbeans.modules.j2ee.verification + org.netbeans.modules.j2ee.persistence org.netbeans.modules.j2ee.common org.netbeans.modules.j2ee.common.ui.nodes Index: j2ee/utilities/src/org/netbeans/modules/j2ee/common/Bundle.properties =================================================================== RCS file: /cvs/j2ee/utilities/src/org/netbeans/modules/j2ee/common/Bundle.properties,v retrieving revision 1.9.2.1 retrieving revision 1.9.2.1.6.3 diff -c -r1.9.2.1 -r1.9.2.1.6.3 *** j2ee/utilities/src/org/netbeans/modules/j2ee/common/Bundle.properties 15 Sep 2005 18:59:02 -0000 1.9.2.1 --- j2ee/utilities/src/org/netbeans/modules/j2ee/common/Bundle.properties 22 Mar 2006 14:58:42 -0000 1.9.2.1.6.3 *************** *** 21,24 **** LBL_FQN_Title=Find class LBL_FQN_OK=OK ! ERR_ErrorOpeningEditor=Error opening editor \ No newline at end of file --- 21,39 ---- LBL_FQN_Title=Find class LBL_FQN_OK=OK ! ERR_ErrorOpeningEditor=Error opening editor ! ! LBL_DatasourceCustomizer=Create Datasource ! LBL_DSC_JndiName=&JNDI Name\: ! ! ERR_DS_EXISTS=Datasource with the specified JNDI name already exists. ! ! ERR_JNDI_NAME_EMPTY=JNDI name cannot be empty. ! ! ERR_NO_CONN_SELECTED=No connection selected. ! ! LBL_NEW_DATASOURCE=New Data Source... ! ! LBL_DSC_DbConn=&Database Connection\: ! ! ERR_DsConflict=Data source(s) with the same JNDI name already exists:\n{0} Index: j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.form =================================================================== RCS file: j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.form diff -N j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.form *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.form 15 Mar 2006 15:37:25 -0000 1.1.2.2 *************** *** 0 **** --- 1,96 ---- + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index: j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.java =================================================================== RCS file: j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.java diff -N j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.java *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceCustomizer.java 27 Mar 2006 12:49:36 -0000 1.1.2.5 *************** *** 0 **** --- 1,289 ---- + /* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + + package org.netbeans.modules.j2ee.common; + + import java.awt.Color; + import java.awt.Dialog; + import java.awt.event.ActionEvent; + import java.awt.event.ActionListener; + import java.awt.event.ItemEvent; + import java.awt.event.ItemListener; + import java.beans.PropertyChangeEvent; + import java.beans.PropertyChangeListener; + import java.util.HashMap; + import java.util.Iterator; + import java.util.List; + import javax.swing.UIManager; + import javax.swing.event.DocumentEvent; + import javax.swing.event.DocumentListener; + import org.netbeans.api.db.explorer.ConnectionManager; + import org.netbeans.api.db.explorer.DatabaseConnection; + import org.netbeans.api.db.explorer.support.DatabaseExplorerUIs; + import org.netbeans.modules.j2ee.deployment.common.api.Datasource; + import org.openide.DialogDescriptor; + import org.openide.DialogDisplayer; + import org.openide.util.HelpCtx; + import org.openide.util.NbBundle; + + /** + * + * @author Libor Kotouc + */ + class DatasourceCustomizer extends javax.swing.JPanel { + + private Color nbErrorForeground; + + private Dialog dialog = null; + private DialogDescriptor descriptor = null; + private boolean dialogOK = false; + + private HashMap datasources; + + private String jndiName; + private String url; + private String username; + private String password; + private String driverClassName; + + public DatasourceCustomizer(List datasources) { + if (datasources != null) { // transform Set to Map for faster searching + this.datasources = new HashMap(); + for (Iterator it = datasources.iterator(); it.hasNext();) { + Datasource ds = (Datasource) it.next(); + if (ds.getJndiName() != null) + this.datasources.put(ds.getJndiName(), ds); + } + } + initComponents(); + + DatabaseExplorerUIs.connect(connCombo, ConnectionManager.getDefault()); + + connCombo.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + verify(); + } + }); + connCombo.addPropertyChangeListener("model", new PropertyChangeListener() { // NOI18N + public void propertyChange(PropertyChangeEvent evt) { + verify(); + } + }); + + jTextField1.getDocument().addDocumentListener(new DocumentListener() { + public void changedUpdate(DocumentEvent e) { + verify(); + } + public void insertUpdate(DocumentEvent e) { + verify(); + } + public void removeUpdate(DocumentEvent e) { + verify(); + } + }); + + nbErrorForeground = UIManager.getColor("nb.errorForeground"); //NOI18N + if (nbErrorForeground == null) + nbErrorForeground = new Color(255, 0, 0); + + jLabel6.setForeground(nbErrorForeground); + } + + public boolean showDialog() { + + descriptor = new DialogDescriptor + (this, NbBundle.getMessage(DatasourceCustomizer.class, "LBL_DatasourceCustomizer"), true, + DialogDescriptor.OK_CANCEL_OPTION, DialogDescriptor.OK_OPTION, + DialogDescriptor.DEFAULT_ALIGN, + new HelpCtx("PersistenceUnitWizardPanel_DatasourceCustomizer"), // NOI18N + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (descriptor.getValue().equals(DialogDescriptor.OK_OPTION)) { + handleConfirmation(); + } + else + dialog.dispose(); + } + } + ); + + verify(); + + dialog = DialogDisplayer.getDefault().createDialog(descriptor); + dialog.setVisible(true); + repaint(); + + return dialogOK; + } + + private void handleConfirmation() { + + boolean ok = true; + String msg = ""; + + jndiName = jTextField1.getText().trim(); + + Object o = connCombo.getSelectedItem(); + if (o instanceof DatabaseConnection) { + DatabaseConnection conn = (DatabaseConnection)o; + url = conn.getDatabaseURL(); + username = conn.getUser(); + password = conn.getPassword(); + driverClassName = conn.getDriverClass(); + } + + dialogOK = true; + dialog.dispose(); + } + + private boolean verify() { + + boolean isValid = verifyJndiName(); + if (isValid) + isValid = verifyConnection(); + + return isValid; + } + + private boolean verifyJndiName() { + + boolean valid = true; + + String jndiName = jTextField1.getText().trim(); + if (jndiName.length() == 0) { + jLabel6.setText(NbBundle.getMessage(DatasourceCustomizer.class, "ERR_JNDI_NAME_EMPTY")); // NOI18N + valid = false; + } + else + if (datasourceAlreadyExists(jndiName)) { + jLabel6.setText(NbBundle.getMessage(DatasourceCustomizer.class, "ERR_DS_EXISTS")); // NOI18N + valid = false; + } + else { + jLabel6.setText(""); // NOI18N + } + + descriptor.setValid(valid); + + return valid; + } + + private boolean verifyConnection() { + + boolean valid = true; + + if (!(connCombo.getSelectedItem() instanceof DatabaseConnection)) { + jLabel6.setText(NbBundle.getMessage(DatasourceCustomizer.class, "ERR_NO_CONN_SELECTED")); // NOI18N + valid = false; + } + else { + jLabel6.setText(""); // NOI18N + } + + descriptor.setValid(valid); + + return valid; + } + + private boolean datasourceAlreadyExists(String jndiName) { + return datasources.containsKey(jndiName); + } + + String getJndiName() { + return jndiName; + } + + String getUrl() { + return url; + } + + String getUsername() { + return username; + } + + String getPassword() { + return password; + } + + String getDriverClassName() { + return driverClassName; + } + + /** 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. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jTextField1 = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + connCombo = new javax.swing.JComboBox(); + + setForeground(new java.awt.Color(255, 0, 0)); + jLabel1.setLabelFor(jTextField1); + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(DatasourceCustomizer.class, "LBL_DSC_JndiName")); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(DatasourceCustomizer.class, "LBL_DSC_DbConn")); + + org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(jLabel1) + .add(jLabel2)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(jTextField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)) + .add(connCombo, 0, 359, Short.MAX_VALUE))) + .add(jLabel6)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .addContainerGap() + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) + .add(jLabel1) + .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) + .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) + .add(layout.createSequentialGroup() + .add(jLabel2) + .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 39, Short.MAX_VALUE) + .add(jLabel6)) + .add(layout.createSequentialGroup() + .add(connCombo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) + .addContainerGap()))) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox connCombo; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel6; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables + + } Index: j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceUIHelper.java =================================================================== RCS file: j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceUIHelper.java diff -N j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceUIHelper.java *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/src/org/netbeans/modules/j2ee/common/DatasourceUIHelper.java 27 Mar 2006 14:56:42 -0000 1.1.2.9 *************** *** 0 **** --- 1,337 ---- + /* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + + package org.netbeans.modules.j2ee.common; + + import java.awt.Color; + import java.awt.Component; + import java.awt.Dimension; + import java.awt.event.ActionEvent; + import java.awt.event.ActionListener; + import java.awt.event.InputEvent; + import java.awt.event.KeyAdapter; + import java.awt.event.KeyEvent; + import java.util.Arrays; + import java.util.Comparator; + import java.util.LinkedList; + import java.util.List; + import java.util.Set; + import javax.swing.AbstractListModel; + import javax.swing.ComboBoxModel; + import javax.swing.DefaultListCellRenderer; + import javax.swing.JComboBox; + import javax.swing.JList; + import javax.swing.JSeparator; + import javax.swing.SwingUtilities; + import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; + import org.netbeans.modules.j2ee.deployment.common.api.Datasource; + import org.netbeans.modules.j2ee.deployment.common.api.DatasourceAlreadyExistsException; + import org.openide.ErrorManager; + import org.openide.util.NbBundle; + + /** + * + * DatasourceUIHelper populates and manages the content of the combobox for a data sources management. + * + * @author Libor Kotouc + * + * @since 1.6 + */ + public final class DatasourceUIHelper { + + private static final class Separator extends JSeparator { + Separator() { + setPreferredSize(new Dimension(getWidth(), 1)); + setForeground(Color.BLACK); + } + } + + static final Separator SEPARATOR_ITEM = new Separator(); + static final Object NEW_ITEM = new Object() { + public String toString() { + return NbBundle.getMessage(DatasourceUIHelper.class, "LBL_NEW_DATASOURCE"); // NOI18N + } + }; + static final Object EMPTY_ITEM = new Object() { + public String toString() { + return " "; // NOI18N + } + }; + + private static class DatasourceComboBoxModel extends AbstractListModel implements ComboBoxModel { + + private Object[] items; + private Object selectedItem; + private List datasources; + private Object previousItem; + + DatasourceComboBoxModel(List datasources, Object[] items) { + assert(items.length > 0); + this.datasources = datasources; + this.items = items; + selectedItem = this.items[0]; + } + + public void setSelectedItem(Object anItem) { + assert(anItem != null); + previousItem = selectedItem; + selectedItem = anItem; + } + + public Object getSelectedItem() { + return selectedItem;// instanceof Datasource ? selectedItem : null; + } + + public Object getElementAt(int index) { + return items[index]; + } + + public int getSize() { + return items.length; + } + + Object getPreviousItem() { + return previousItem; + } + + List getDatasources() { + return datasources; + } + } + + private static class DatasourceListCellRenderer extends DefaultListCellRenderer { + + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + + if (value instanceof Datasource) { + Datasource ds = (Datasource) value; + setText(ds != null ? ds.getDisplayName() : ""); + setToolTipText(ds.toString()); + } + else + if (value == SEPARATOR_ITEM) { + return SEPARATOR_ITEM; + } + else { + if (value != null) + setText(value.toString()); + setToolTipText(""); // NOI18N + } + + return this; + } + + } + + private static class DatasourceComparator implements Comparator { + + public int compare(Datasource ds1, Datasource ds2) { + + if (ds1 == null) { + return ds2 == null ? 0 : -1; + } + else { + if (ds2 == null) { + return 1; + } + else { + String dispName1 = ds1.getDisplayName(); + String dispName2 = ds2.getDisplayName(); + if (dispName1 == null) { + return dispName2 == null ? 0 : -1; + } + else { + return dispName2 == null ? 1 : dispName1.compareToIgnoreCase(dispName2); + } + } + } + } + } + + private DatasourceUIHelper() { + } + + /** + * Entry point for the combobox initialization. It connects combobox with its content and + * add items for the combobox content management. + * + * @param combo combobox to manage + */ + public static void connect(J2eeModuleProvider provider, JComboBox combo) { + connect(provider, combo, null); + } + + private static final void connect(final J2eeModuleProvider provider, final JComboBox combo, Datasource selectedDatasource) { + + assert(provider != null); + + combo.setEditable(false); + combo.setRenderer(new DatasourceListCellRenderer()); + + populate(provider, combo, selectedDatasource, false); + + combo.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + int keyCode = e.getKeyCode(); + if (KeyEvent.VK_ENTER == keyCode) { + Object selectedItem = combo.getSelectedItem(); + if (selectedItem == NEW_ITEM) { + Datasource ds = performCreateDsAction(provider, combo); + combo.setPopupVisible(false); + e.consume(); + if (ds != null) + populate(provider, combo, ds, false); + } + } + } + }); + + combo.addActionListener(new ActionListener() { + + Object previousItem; + int previousIndex = combo.getSelectedIndex(); + + public void actionPerformed(ActionEvent e) { + + Object selectedItem = combo.getSelectedItem(); + // skipping of separator + if (selectedItem == SEPARATOR_ITEM) { + int selectedIndex = combo.getSelectedIndex(); + if (selectedIndex > previousIndex) { + previousIndex = selectedIndex + 1; + previousItem = combo.getItemAt(previousIndex); + } else { + previousIndex = selectedIndex - 1; + previousItem = combo.getItemAt(previousIndex); + } + combo.setSelectedItem(previousItem); + // handling mouse click, see KeyEvent.getKeyModifiersText(e.getModifiers()) + } else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) { + if (selectedItem == NEW_ITEM) { + Datasource ds = performCreateDsAction(provider, combo); + combo.setPopupVisible(false); + if (ds != null) + populate(provider, combo, ds, true); + } + } + } + }); + + } + + private static Datasource performCreateDsAction(J2eeModuleProvider provider, final JComboBox combo) { + + final DatasourceComboBoxModel model = (DatasourceComboBoxModel)combo.getModel(); + + DatasourceCustomizer dsc = new DatasourceCustomizer(model.getDatasources()); + boolean accept = dsc.showDialog(); + Datasource ds = null; + if (accept) { + try { + ds = provider.createDatasource( + dsc.getJndiName(), + dsc.getUrl(), + dsc.getUsername(), + dsc.getPassword(), + dsc.getDriverClassName()); + } + catch (DatasourceAlreadyExistsException daee) { // it should not occur bcs it should be already handled in DatasourceCustomizer + StringBuffer sb = new StringBuffer(); + for (Object conflict : daee.getDatasources()) { + sb.append(conflict.toString() + "\n"); // NOI18N + } + ErrorManager.getDefault().annotate(daee, NbBundle.getMessage(DatasourceUIHelper.class, "ERR_DsConflict", sb.toString())); // NOI18N + ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, daee); + } + } + else { + SwingUtilities.invokeLater(new Runnable() { // postpone item selection to enable event firing from JCombobox.setSelectedItem() + public void run() { + if (model.getPreviousItem() != null) { + combo.setSelectedItem(model.getPreviousItem()); + } + else { + combo.setSelectedItem(model.getElementAt(0)); + } + } + }); + } + + return ds; + } + + private static List populate(J2eeModuleProvider provider, final JComboBox combo, final Datasource selectedDatasource, boolean selectItemLater) { + + Set projectDS = provider.getServerDatasources(); + Set serverDS = provider.getModuleDatasources(); + + List datasources = merge(projectDS, serverDS); + + List items = (datasources == null ? new LinkedList() : new LinkedList(datasources)); + + if (items.size() == 0) + items.add(EMPTY_ITEM); + + if (provider.isDatasourceCreationSupported()) { + items.add(SEPARATOR_ITEM); + items.add(NEW_ITEM); + } + + Object[] itemsArray = items.toArray(); + DatasourceComboBoxModel model = new DatasourceComboBoxModel(datasources, itemsArray); + + combo.setModel(model); + + if (selectedDatasource != null) { + if (selectItemLater) { + SwingUtilities.invokeLater(new Runnable() { // postpone item selection to enable event firing from JCombobox.setSelectedItem() + public void run() { + combo.setSelectedItem(selectedDatasource); + } + }); + } + else { + combo.setSelectedItem(selectedDatasource); + } + } + + return datasources; + } + + private static List merge(Set source, Set target) { + + Set m = (target == null ? source : target); + + if (m != null && source != null) { + m.addAll(source); + } + + List all = new LinkedList(); + if (m != null) { + Datasource[] datasources = (Datasource[])m.toArray(new Datasource[0]); + Arrays.sort(datasources, new DatasourceComparator()); + all = new LinkedList(Arrays.asList(datasources)); + } + + return all; + } + + } Index: j2ee/utilities/test/.cvsignore =================================================================== RCS file: j2ee/utilities/test/.cvsignore diff -N j2ee/utilities/test/.cvsignore *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/.cvsignore 17 Mar 2006 09:41:16 -0000 1.1.2.1 *************** *** 0 **** --- 1,3 ---- + lib + results + work Index: j2ee/utilities/test/build-unit.xml =================================================================== RCS file: j2ee/utilities/test/build-unit.xml diff -N j2ee/utilities/test/build-unit.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/build-unit.xml 17 Mar 2006 09:41:16 -0000 1.1.2.1 *************** *** 0 **** --- 1,18 ---- + + + + + + Index: j2ee/utilities/test/build.xml =================================================================== RCS file: j2ee/utilities/test/build.xml diff -N j2ee/utilities/test/build.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/build.xml 17 Mar 2006 09:41:16 -0000 1.1.2.1 *************** *** 0 **** --- 1,25 ---- + + + + + + + + + + + + + + Index: j2ee/utilities/test/cfg-unit.xml =================================================================== RCS file: j2ee/utilities/test/cfg-unit.xml diff -N j2ee/utilities/test/cfg-unit.xml *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/cfg-unit.xml 17 Mar 2006 09:41:17 -0000 1.1.2.1 *************** *** 0 **** --- 1,29 ---- + + + + + + + + + + + + + + + + + Index: j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceImpl.java =================================================================== RCS file: j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceImpl.java diff -N j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceImpl.java *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceImpl.java 24 Mar 2006 17:41:40 -0000 1.1.2.2 *************** *** 0 **** --- 1,115 ---- + /* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + + package org.netbeans.modules.j2ee.common; + + import org.netbeans.modules.j2ee.deployment.common.api.Datasource; + import org.openide.util.NbBundle; + + + /** + * + * @author Libor Kotouc + */ + public final class DatasourceImpl implements Datasource { + + private String jndiName; + private String url; + private String username; + private String password; + private String driverClassName; + private String description; + + private volatile int hash = -1; + + public DatasourceImpl(String jndiName, String url, String username, String password, String driverClassName) { + this.jndiName = jndiName; + this.url = url; + this.username = username; + this.password = password; + this.driverClassName = driverClassName; + } + + public String getJndiName() { + return jndiName; + } + + public String getUrl() { + return url; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getDriverClassName() { + return driverClassName; + } + + public String getDisplayName() { + if (description == null) { + //TODO implement some meaningful description + description = getJndiName() + " [" + getUrl() + "]"; + } + return description; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof DatasourceImpl)) + return false; + + DatasourceImpl ds = (DatasourceImpl)obj; + if (jndiName == null && ds.getJndiName() != null || jndiName != null && !jndiName.equals(ds.getJndiName())) + return false; + if (url == null && ds.getUrl() != null || url != null && !url.equals(ds.getUrl())) + return false; + if (username == null && ds.getUsername() != null || username != null && !username.equals(ds.getUsername())) + return false; + if (password == null && ds.getPassword() != null || password != null && !password.equals(ds.getPassword())) + return false; + if (driverClassName == null && ds.getDriverClassName() != null || driverClassName != null && !driverClassName.equals(ds.getDriverClassName())) + return false; + + return true; + } + + public int hashCode() { + if (hash == -1) { + int result = 17; + result += 37 * result + (jndiName == null ? 0 : jndiName.hashCode()); + result += 37 * result + (url == null ? 0 : url.hashCode()); + result += 37 * result + (username == null ? 0 : username.hashCode()); + result += 37 * result + (password == null ? 0 : password.hashCode()); + result += 37 * result + (driverClassName == null ? 0 : driverClassName.hashCode()); + + hash = result; + } + + return hash; + } + + public String toString() { + return "[ " + // NOI18N + NbBundle.getMessage(DatasourceImpl.class, "LBL_DS_JNDI") + ": '" + jndiName + "', " + // NOI18N + NbBundle.getMessage(DatasourceImpl.class, "LBL_DS_URL") + ": '" + url + "', " + // NOI18N + NbBundle.getMessage(DatasourceImpl.class, "LBL_DS_USER") + ": '" + username + "', " + // NOI18N + NbBundle.getMessage(DatasourceImpl.class, "LBL_DS_PASS") + ": '" + password + "', " + // NOI18N + NbBundle.getMessage(DatasourceImpl.class, "LBL_DS_DRV") + ": '" + driverClassName + " ]"; // NOI18N + } + } Index: j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceUIHelperTest.java =================================================================== RCS file: j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceUIHelperTest.java diff -N j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceUIHelperTest.java *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/DatasourceUIHelperTest.java 24 Mar 2006 17:41:40 -0000 1.1.2.2 *************** *** 0 **** --- 1,110 ---- + /* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + + package org.netbeans.modules.j2ee.common; + + import java.util.HashSet; + import java.util.Set; + import javax.swing.JComboBox; + import org.netbeans.junit.NbTestCase; + import org.netbeans.modules.j2ee.deployment.common.api.Datasource; + + /** + * + * @author Libor Kotouc + */ + public class DatasourceUIHelperTest extends NbTestCase { + + private DatasourceImpl mds1; + private DatasourceImpl mds2; + private DatasourceImpl mds3; + private DatasourceImpl sds1; + private DatasourceImpl sds2; + private DatasourceImpl sds3; + private DatasourceImpl sds4; + + J2eeModuleProviderImpl provider; + + public DatasourceUIHelperTest(String testName) { + super(testName); + } + + protected void setUp() throws Exception { + } + + private void initDatasources() { + mds1 = new DatasourceImpl("mds1", "mds1_url", "mds1_user", "mds1_pass", "mds1_clz"); // NOI18N + mds2 = new DatasourceImpl("mds2", "mds2_url", "mds2_user", "mds2_pass", "mds2_clz"); // NOI18N + mds3 = new DatasourceImpl("mds3", "mds3_url", "mds3_user", "mds3_pass", "mds3_clz"); // NOI18N + Set moduleDatasources = new HashSet(); + moduleDatasources.add(mds1); + moduleDatasources.add(mds2); + moduleDatasources.add(mds3); + sds1 = new DatasourceImpl("sds1", "sds1_url", "sds1_user", "sds1_pass", "sds1_clz"); // NOI18N + sds2 = new DatasourceImpl("sds2", "sds2_url", "sds2_user", "sds2_pass", "sds2_clz"); // NOI18N + sds3 = new DatasourceImpl("sds3", "sds3_url", "sds3_user", "sds3_pass", "sds3_clz"); // NOI18N + //copy of mds3 for merging verification + sds4 = new DatasourceImpl("mds3", "mds3_url", "mds3_user", "mds3_pass", "mds3_clz"); // NOI18N + Set serverDatasources = new HashSet(); + serverDatasources.add(sds1); + serverDatasources.add(sds2); + serverDatasources.add(sds3); + serverDatasources.add(sds4); + + provider = new J2eeModuleProviderImpl(moduleDatasources, serverDatasources); + } + + private JComboBox connect() { + JComboBox combo = new JComboBox(); + DatasourceUIHelper.connect(provider, combo); + return combo; + } + + public void testEmptyComboboxContentWithCreation() { + provider = new J2eeModuleProviderImpl(null, null); + + JComboBox combo = connect(); + + assertTrue("Wrong number of items in the empty combobox", combo.getItemCount() == 3); + assertTrue("EMPTY_ITEM is not selected by default.", combo.getSelectedItem() == DatasourceUIHelper.EMPTY_ITEM); + assertTrue("EMPTY_ITEM must be followed by SEPARATOR_ITEM.", combo.getItemAt(1) == DatasourceUIHelper.SEPARATOR_ITEM); + assertTrue("SEPARATOR_ITEM must be followed by NEW_ITEM", combo.getItemAt(2) == DatasourceUIHelper.NEW_ITEM); + + } + + public void testEmptyComboboxContentWithoutCreation() { + provider = new J2eeModuleProviderImpl(null, null, false);//do not allow creation of new data source + + JComboBox combo = connect(); + + assertTrue("Wrong number of items in the empty combobox", combo.getItemCount() == 1); + assertTrue("EMPTY_ITEM is not selected by default.", combo.getSelectedItem() == DatasourceUIHelper.EMPTY_ITEM); + + } + + public void testNonEmptyCombobox() { + + initDatasources(); + + JComboBox combo = connect(); + + assertTrue("Wrong number of items in the empty combobox", combo.getItemCount() == 8); + for (int i = 0; i < 5; i++) { // number of items w/o separator and add new... == 6 + String jndiName_i = ((Datasource)combo.getItemAt(i)).getJndiName(); + String jndiName_ipp = ((Datasource)combo.getItemAt(i+1)).getJndiName(); + assertTrue("Items in combobox are not alphabetically ordered by JNDI name", jndiName_i.compareToIgnoreCase(jndiName_ipp) < 0); + } + + } + + } Index: j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/J2eeModuleProviderImpl.java =================================================================== RCS file: j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/J2eeModuleProviderImpl.java diff -N j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/J2eeModuleProviderImpl.java *** /dev/null 1 Jan 1970 00:00:00 -0000 --- j2ee/utilities/test/unit/src/org/netbeans/modules/j2ee/common/J2eeModuleProviderImpl.java 17 Mar 2006 09:41:17 -0000 1.1.2.1 *************** *** 0 **** --- 1,78 ---- + /* + * Sun Public License Notice + * + * The contents of this file are subject to the Sun Public License + * Version 1.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://www.sun.com/ + * + * The Original Code is NetBeans. The Initial Developer of the Original + * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ + + package org.netbeans.modules.j2ee.common; + + import java.io.File; + import java.util.Set; + import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; + import org.netbeans.modules.j2ee.deployment.devmodules.api.ModuleChangeReporter; + import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; + import org.openide.filesystems.FileObject; + + /** + * + * @author Libor Kotouc + */ + public class J2eeModuleProviderImpl extends J2eeModuleProvider { + + private Set moduleDatasources; + private Set serverDatasources; + private boolean creationAllowed; + + public J2eeModuleProviderImpl(Set moduleDatasources, Set serverDatasources) { + this(moduleDatasources, serverDatasources, true); + } + + public J2eeModuleProviderImpl(Set moduleDatasources, Set serverDatasources, boolean creationAllowed) { + this.moduleDatasources = moduleDatasources; + this.serverDatasources = serverDatasources; + this.creationAllowed = creationAllowed; + } + + // J2eeModuleProvider abstract methods implementation + + public void setServerInstanceID(String severInstanceID) { + } + + public File getDeploymentConfigurationFile(String name) { + return null; + } + + public FileObject findDeploymentConfigurationFile(String name) { + return null; + } + + public ModuleChangeReporter getModuleChangeReporter() { + return null; + } + + public J2eeModule getJ2eeModule() { + return null; + } + + // J2eeModuleProvider DS API methods + + public Set getModuleDatasources() { + return moduleDatasources; + } + + public Set getServerDatasources() { + return serverDatasources; + } + + public boolean isDatasourceCreationSupported() { + return creationAllowed; + } + + }