? DatasourceUISettings.java
Index: BrokenDatasourceAlertPanel.form
===================================================================
RCS file: BrokenDatasourceAlertPanel.form
diff -N BrokenDatasourceAlertPanel.form
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ BrokenDatasourceAlertPanel.form 15 Jun 2007 13:06:41 -0000
@@ -0,0 +1,78 @@
+
+
+
Index: BrokenDatasourceAlertPanel.java
===================================================================
RCS file: BrokenDatasourceAlertPanel.java
diff -N BrokenDatasourceAlertPanel.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ BrokenDatasourceAlertPanel.java 15 Jun 2007 13:06:41 -0000
@@ -0,0 +1,97 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (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.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.j2ee.common.ui;
+
+import javax.swing.JPanel;
+import org.openide.util.NbBundle;
+
+/**
+ * Broken/missing datasource alert panel.
+ *
+ * PLEASE NOTE! This is just a temporary solution. BrokenReferencesSupport from
+ * the java project support currently does not allow to plug in a check for missing
+ * datasources. Once BrokenReferencesSupport will support it, this class should be
+ * removed.
+ */
+public class BrokenDatasourceAlertPanel extends JPanel {
+
+ public BrokenDatasourceAlertPanel() {
+ initComponents();
+ notAgain.setSelected(!J2EEUISettings.getDefault().isShowAgainBrokenDatasourceAlert());
+ }
+
+ /** 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() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ notAgain = new javax.swing.JCheckBox();
+ message = new javax.swing.JLabel();
+
+ setLayout(new java.awt.GridBagLayout());
+
+ org.openide.awt.Mnemonics.setLocalizedText(notAgain, org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "MSG_Broken_Datasources_Again")); // NOI18N
+ notAgain.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ notAgain.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ notAgainActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(6, 11, 0, 0);
+ add(notAgain, gridBagConstraints);
+ notAgain.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "ACSN_BrokenDatasourcesAlertPanel_notAgain")); // NOI18N
+ notAgain.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "ACSD_BrokenDatasourcesAlertPanel_notAgain")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(message, org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "MSG_Broken_Datasources")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(11, 11, 0, 0);
+ add(message, gridBagConstraints);
+ message.getAccessibleContext().setAccessibleName(NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "ACSN_BrokenDatasourcesAlertPanel")); // NOI18N
+ message.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "ACSD_BrokenDatasourcesAlertPanel")); // NOI18N
+
+ getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "ACSN_BrokenDatasourceAlertPanel")); // NOI18N
+ getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "ACSD_BrokenDatasourcesAlertPanel")); // NOI18N
+ }// //GEN-END:initComponents
+
+ private void notAgainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_notAgainActionPerformed
+ J2EEUISettings.getDefault().setShowAgainBrokenDatasourceAlert(!notAgain.isSelected());
+ }//GEN-LAST:event_notAgainActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JLabel message;
+ private javax.swing.JCheckBox notAgain;
+ // End of variables declaration//GEN-END:variables
+
+}
Index: BrokenDatasourceSupport.java
===================================================================
RCS file: BrokenDatasourceSupport.java
diff -N BrokenDatasourceSupport.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ BrokenDatasourceSupport.java 15 Jun 2007 13:06:42 -0000
@@ -0,0 +1,194 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (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.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.j2ee.common.ui;
+
+import java.awt.Dialog;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import javax.swing.JButton;
+import javax.swing.SwingUtilities;
+import org.netbeans.api.db.explorer.ConnectionManager;
+import org.netbeans.api.db.explorer.DatabaseConnection;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException;
+import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
+import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+
+/**
+ * Support for managing broken/missing Databases.
+ *
+ * PLEASE NOTE! This is just a temporary solution. BrokenReferencesSupport from
+ * the java project support currently does not allow to plug in a check for missing
+ * Databases. Once BrokenReferencesSupport will support it, this class should be
+ * removed.
+ */
+public class BrokenDatasourceSupport {
+
+ /** Last time in ms when the Broken References alert was shown. */
+ private static long brokenAlertLastTime = 0;
+
+ /** Is Broken References alert shown now? */
+ private static boolean brokenAlertShown = false;
+
+ /** Timeout within which request to show alert will be ignored. */
+ private static int BROKEN_ALERT_TIMEOUT = 1000;
+
+ private BrokenDatasourceSupport() {}
+
+ /**
+ * Shows UI customizer which gives users chance to fix encountered problems,
+ * i.e. choose appropriate data source.
+ *
+ * @param project
+ *
+ */
+ public static void fixDatasources(final Project project) {
+ MissingDatabaseConnectionWarning.selectDatasources(
+ NbBundle.getMessage(BrokenDatasourceSupport.class,"LBL_Resolve_Missing_Datasources_Title"),org.openide.util.NbBundle.getMessage(BrokenDatasourceSupport.class, "ACSD_Resolve_Missing_Datasources"), project); // NOI18N
+ }
+
+ /**
+ * Show alert message box informing user that a project has missing
+ * database connections. This method can be safely called from any thread, e.g. during
+ * the project opening, and it will take care about showing message box only
+ * once for several subsequent calls during a timeout.
+ * The alert box has also "show this warning again" check box.
+ */
+ public static synchronized void showAlert() {
+ // Do not show alert if it is already shown or if it was shown
+ // in last BROKEN_ALERT_TIMEOUT milliseconds or if user do not wish it.
+ if (brokenAlertShown
+ || brokenAlertLastTime+BROKEN_ALERT_TIMEOUT > System.currentTimeMillis()
+ || !J2EEUISettings.getDefault().isShowAgainBrokenDatasourceAlert()) {
+ return;
+ }
+
+ brokenAlertShown = true;
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ BrokenDatasourceAlertPanel alert = new BrokenDatasourceAlertPanel();
+ JButton close = new JButton(
+ NbBundle.getMessage(BrokenDatasourceSupport.class, "LBL_BrokenDatasourcesCustomizer_Close"));
+ close.getAccessibleContext().setAccessibleDescription(
+ NbBundle.getMessage(BrokenDatasourceSupport.class, "ACSD_BrokenDatasourcesCustomizer_Close"));
+ DialogDescriptor dd = new DialogDescriptor(
+ alert,
+ NbBundle.getMessage(BrokenDatasourceAlertPanel.class, "MSG_Broken_Datasources_Title"),
+ true,
+ new Object[] {close},
+ close,
+ DialogDescriptor.DEFAULT_ALIGN,
+ null,
+ null);
+ dd.setMessageType(DialogDescriptor.WARNING_MESSAGE);
+ Dialog dlg = DialogDisplayer.getDefault().createDialog(dd);
+ dlg.setVisible(true);
+ } finally {
+ synchronized (BrokenDatasourceSupport.class) {
+ brokenAlertLastTime = System.currentTimeMillis();
+ brokenAlertShown = false;
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Returns set of broken datasources
+ *
+ * @param project
+ * @return Set returns a set of data sources that don't have corresponding database connections
+ */
+ public static Set getBrokenDatasources(Project project) {
+ J2eeModuleProvider jmp =
+ (J2eeModuleProvider)project.getLookup().lookup(J2eeModuleProvider.class);
+
+ Set dss = null;
+ try {
+ dss = jmp.getModuleDatasources();
+ } catch (ConfigurationException e) {
+ dss = new HashSet();
+ }
+
+ Set brokenDatasources = new HashSet();
+ Iterator it = dss.iterator();
+ while (it.hasNext()) {
+ Datasource ds = (Datasource)it.next();
+ if(!isFound(ds)){
+ brokenDatasources.add(ds);
+ }
+ }
+
+ return brokenDatasources;
+ }
+
+ private static boolean isFound(Datasource ds) {
+ boolean found = false;
+ String url = ds.getUrl();
+ String username = ds.getUsername();
+ DatabaseConnection[] dbConns = ConnectionManager.getDefault().getConnections();
+ for(int i=0; i
MSG_Broken_Server_Again=&Do not show this message again
+# BrokenDataSourceAlertPanel
+ACSN_BrokenDatasourcesAlertPanel=Broken Data Sources Panel
+ACSD_BrokenDatasourcesAlertPanel=N/A
+ACSN_BrokenDatasourcesAlertPanel_notAgain=Do not show this message again
+ACSD_BrokenDatasourcesAlertPanel_notAgain=N/A
+MSG_Broken_Datasources=One or more projects use database connections that have not been registered.
\
+ Right-click the project in the Projects window and choose
Resolve Data Source Problem \
+ to help register database connections.
+MSG_Broken_Datasources_Again=&Do not show this message again
+
# NoSelectedServerWarning
LBL_NoSuitableServerWarning_jLabel2=The problem cannot be resolved because there is no \
suitable server instance at the moment. Please add a suitable server instance in \
@@ -48,3 +65,12 @@
LBL_AddServer=&Add Server...
ACSN_AddServer=Add Server Button
ACSD_AddServer=N/A
+LBL_SelectDatasource=To resolve, select a Data Source name below then click Add Connection.
+LBL_MissingDatabaseConnectionWarning=Database Connections for the Data Sources referenced in this project could not be located.
+LBL_AddDatabaseConnection=&Add Connection...
+ACSN_BrokenDatasourceAlertPanel=Broken Data Sources Panel
+ACSD_AddDatabaseConnection=N/A
+
+ACSN_AddDatabaseConnection=Add Database Connection
+
+LBL_NoSuitableDatabaseConnectionWarning_jLabel2=LBL_MissingDatabaseConnectionWarning
Index: J2EEUISettings.java
===================================================================
RCS file: /cvs/j2ee/utilities/src/org/netbeans/modules/j2ee/common/ui/J2EEUISettings.java,v
retrieving revision 1.3
diff -u -r1.3 J2EEUISettings.java
--- J2EEUISettings.java 1 Nov 2006 15:26:12 -0000 1.3
+++ J2EEUISettings.java 15 Jun 2007 13:06:42 -0000
@@ -26,6 +26,7 @@
private static final J2EEUISettings INSTANCE = new J2EEUISettings();
private static final String SHOW_AGAIN_BROKEN_REF_ALERT = "showAgainBrokenRefAlert"; // NOI18N
private static final String SHOW_AGAIN_BROKEN_SERVER_ALERT = "showAgainBrokenServerAlert"; // NOI18N
+ private static final String SHOW_AGAIN_BROKEN_DATASOURCE_ALERT = "showAgainBrokenDatasourceAlert"; // NOI18N
public String displayName() {
return "J2EEUISettings"; // NOI18N (not shown in UI)
@@ -50,6 +51,15 @@
public void setShowAgainBrokenServerAlert(boolean again) {
getPreferences().putBoolean(SHOW_AGAIN_BROKEN_SERVER_ALERT, again);
}
+
+ public boolean isShowAgainBrokenDatasourceAlert() {
+ return getPreferences().getBoolean(SHOW_AGAIN_BROKEN_DATASOURCE_ALERT, true);
+ }
+
+ public void setShowAgainBrokenDatasourceAlert(boolean again) {
+ getPreferences().putBoolean(SHOW_AGAIN_BROKEN_DATASOURCE_ALERT, again);
+ }
+
public static J2EEUISettings getDefault() {
return INSTANCE;
Index: MissingDatabaseConnectionWarning.form
===================================================================
RCS file: MissingDatabaseConnectionWarning.form
diff -N MissingDatabaseConnectionWarning.form
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ MissingDatabaseConnectionWarning.form 15 Jun 2007 13:06:42 -0000
@@ -0,0 +1,104 @@
+
+
+
Index: MissingDatabaseConnectionWarning.java
===================================================================
RCS file: MissingDatabaseConnectionWarning.java
diff -N MissingDatabaseConnectionWarning.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ MissingDatabaseConnectionWarning.java 15 Jun 2007 13:06:42 -0000
@@ -0,0 +1,374 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (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.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.j2ee.common.ui;
+
+import java.awt.Component;
+import java.awt.Dialog;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Iterator;
+import java.util.Set;
+import javax.swing.AbstractListModel;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListCellRenderer;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.border.Border;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import org.netbeans.api.db.explorer.ConnectionListener;
+import org.netbeans.api.db.explorer.ConnectionManager;
+import org.netbeans.api.db.explorer.JDBCDriver;
+import org.netbeans.api.db.explorer.JDBCDriverManager;
+import org.netbeans.api.project.Project;
+import org.netbeans.modules.j2ee.deployment.common.api.Datasource;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.util.NbBundle;
+import org.openide.util.RequestProcessor;
+
+/**
+ * Displays a list of data sources for which database connections are not registered and helps the user to register
+ * database connections needed by the project's data source to resolve this problem.
+ *
+ * @author Pavel Buzek, John Baker
+ */
+public final class MissingDatabaseConnectionWarning extends JPanel {
+ public static final String OK_ENABLED = "ok_enabled"; //NOI18N
+ public static final String CANCEL_ENABLED = "cancel_enabled"; //NOI18N
+ private static Dialog dlg = null;
+ private final Border scrollPaneBorder;
+ private Project project;
+ private static RequestProcessor.Task task = null;
+
+ private MissingDatabaseConnectionWarning(Project project) {
+ initComponents();
+ this.project = project;
+ datasourceList.setModel(new DatasourceListModel());
+ scrollPaneBorder = jScrollPane2.getBorder();
+ initDatasourceList();
+ }
+
+ private void initDatasourceList() {
+ datasourceList.setCellRenderer(new DatasourceRenderer());
+ datasourceList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ datasourceList.addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e) {
+ if (!datasourceList.isSelectionEmpty()) { // something has been selected
+ jButtonAddConnection.setEnabled(true);
+ } else {
+ firePropertyChange(OK_ENABLED, false, true);
+ jButtonAddConnection.setEnabled(false);
+ }
+ }
+ }
+ );
+ }
+
+ /**
+ * Show the "Resolve Data Sources" dialog and let the user choose a datasource from
+ * the list.
+ *
+ * @param title dialog title
+ * @param description dialog accessible description
+ * @param project
+ *
+ *
+ */
+ public static void selectDatasources(String title, String description, Project project) {
+ MissingDatabaseConnectionWarning panel = new MissingDatabaseConnectionWarning(project);
+ Object[] options = new Object[] {
+ DialogDescriptor.OK_OPTION,
+ DialogDescriptor.CANCEL_OPTION
+ };
+ final DialogDescriptor desc = new DialogDescriptor(panel, title, true, options,
+ DialogDescriptor.OK_OPTION, DialogDescriptor.DEFAULT_ALIGN, null, null);
+ desc.setMessageType(DialogDescriptor.WARNING_MESSAGE);
+ dlg = DialogDisplayer.getDefault().createDialog(desc);
+ dlg.getAccessibleContext().setAccessibleDescription(description);
+ panel.addPropertyChangeListener(new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals(MissingDatabaseConnectionWarning.OK_ENABLED)) {
+ Object newvalue = evt.getNewValue();
+ if ((newvalue != null) && (newvalue instanceof Boolean)) {
+ desc.setValid(((Boolean)newvalue).booleanValue());
+ }
+ }
+ }
+ }
+ );
+ desc.setValid(panel.getSelectedDatasource() != null);
+ panel.setSize(panel.getPreferredSize());
+ dlg.pack();
+ dlg.setVisible(true);
+ }
+
+ /** Returns the selected datasource or null if no datasource was selected.
+ *
+ * @return datasource or null if no datasource was selected
+ */
+ public String getSelectedDatasource() {
+ if ((datasourceList.getSelectedIndex() == -1) || (datasourceList.getFirstVisibleIndex() == -1)) {
+ return null;
+ } else {
+ return ((Datasource)datasourceList.getSelectedValue()).getJndiName();
+ }
+ }
+
+ /** 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() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ jScrollPane2 = new javax.swing.JScrollPane();
+ datasourceList = new javax.swing.JList();
+ jTextArea1 = new javax.swing.JTextArea();
+ jTextArea2 = new javax.swing.JTextArea();
+ jButtonAddConnection = new javax.swing.JButton();
+
+ setLayout(new java.awt.GridBagLayout());
+
+ jScrollPane2.setMinimumSize(new java.awt.Dimension(200, 100));
+
+ datasourceList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
+ datasourceList.setPreferredSize(null);
+ datasourceList.setVerifyInputWhenFocusTarget(false);
+ datasourceList.setVisibleRowCount(4);
+ jScrollPane2.setViewportView(datasourceList);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(6, 12, 12, 12);
+ add(jScrollPane2, gridBagConstraints);
+
+ jTextArea1.setColumns(25);
+ jTextArea1.setEditable(false);
+ jTextArea1.setLineWrap(true);
+ jTextArea1.setText(NbBundle.getMessage(MissingDatabaseConnectionWarning.class, "LBL_SelectDatasource")); // NOI18N
+ jTextArea1.setWrapStyleWord(true);
+ jTextArea1.setFocusable(false);
+ jTextArea1.setOpaque(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(12, 12, 6, 12);
+ add(jTextArea1, gridBagConstraints);
+ jTextArea1.getAccessibleContext().setAccessibleName("Resolve Datasource");
+
+ jTextArea2.setEditable(false);
+ jTextArea2.setLineWrap(true);
+ jTextArea2.setText(org.openide.util.NbBundle.getMessage(MissingDatabaseConnectionWarning.class, "LBL_MissingDatabaseConnectionWarning")); // NOI18N
+ jTextArea2.setWrapStyleWord(true);
+ jTextArea2.setFocusable(false);
+ jTextArea2.setOpaque(false);
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(12, 12, 6, 12);
+ add(jTextArea2, gridBagConstraints);
+
+ org.openide.awt.Mnemonics.setLocalizedText(jButtonAddConnection, org.openide.util.NbBundle.getMessage(MissingDatabaseConnectionWarning.class, "LBL_AddDatabaseConnection")); // NOI18N
+ jButtonAddConnection.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ jButtonAddConnectionActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
+ gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.LAST_LINE_START;
+ gridBagConstraints.insets = new java.awt.Insets(0, 12, 5, 0);
+ add(jButtonAddConnection, gridBagConstraints);
+ jButtonAddConnection.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(MissingDatabaseConnectionWarning.class, "ACSN_AddDatabaseConnection")); // NOI18N
+ jButtonAddConnection.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(MissingDatabaseConnectionWarning.class, "ACSD_AddDatabaseConnection")); // NOI18N
+ }// //GEN-END:initComponents
+
+ private void jButtonAddConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddConnectionActionPerformed
+ Datasource brokenDatasource = (Datasource)datasourceList.getSelectedValue();
+ addDatabaseConnection(brokenDatasource);
+
+ // enable the scrollbar
+ if (datasourceList.getModel().getSize() > 0) {
+ jScrollPane2.setBorder(scrollPaneBorder);
+ jTextArea2.setText(org.openide.util.NbBundle.getMessage(MissingDatabaseConnectionWarning.class, "LBL_SelectDatasource"));
+ }
+
+ // refresh the jList
+ datasourceList.setCellRenderer(new DatasourceRenderer());
+}//GEN-LAST:event_jButtonAddConnectionActionPerformed
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JList datasourceList;
+ private javax.swing.JButton jButtonAddConnection;
+ private javax.swing.JScrollPane jScrollPane2;
+ private javax.swing.JTextArea jTextArea1;
+ private javax.swing.JTextArea jTextArea2;
+ // End of variables declaration//GEN-END:variables
+
+
+ private final class DatasourceListModel extends AbstractListModel implements Runnable, ConnectionListener {
+ private final RequestProcessor BROKEN_DATASOURCE_RP = new RequestProcessor("WebLogicalViewProvider.BROKEN_DATASOURCE_RP"); //NOI18N
+ private Set datasources;
+
+ public DatasourceListModel() {
+ datasources = BrokenDatasourceSupport.getBrokenDatasources(project);
+ addConnectionListener();
+ }
+
+ public synchronized int getSize() {
+ return datasources.size();
+ }
+
+ /*
+ *
+ * Return the datasource corresponding to the selected position in datasourceList
+ */
+ public synchronized Object getElementAt(int index) {
+ Iterator it = datasources.iterator();
+ int i = 0;
+ while (it.hasNext()) {
+ if (index >= 0 && index <= datasources.size()) {
+ if (i == index) {
+ return it.next();
+ }
+
+ // get the next datasource from the set of datasources
+ it.next();
+ i++;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * Refresh model to be done in RP thread for checking database connections
+ * checking connections might be done by another thread at the same time.
+ */
+ public synchronized void refreshModel() {
+ if (task == null) {
+ task = BROKEN_DATASOURCE_RP.create(this);
+ }
+ task.schedule(50);
+ }
+
+ public synchronized void run() {
+ datasources = BrokenDatasourceSupport.getBrokenDatasources(project);
+ if (datasources.isEmpty()) {
+ removeConnectionListener();
+ dlg.dispose();
+ }
+ }
+
+ // Listen for any connections changed in DB Explorer and refresh model accordingly
+ public void connectionsChanged() {
+ initDatasourceList();
+ refreshModel();
+ }
+
+ private void addConnectionListener() {
+ ConnectionManager.getDefault().addConnectionListener(this);
+ }
+
+ private void removeConnectionListener() {
+ ConnectionManager.getDefault().removeConnectionListener(this);
+ }
+ }
+
+ private static final class DatasourceRenderer extends JLabel implements ListCellRenderer {
+
+ DatasourceRenderer() {
+ setOpaque(true);
+ }
+
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ if (value instanceof Datasource) {
+ String jndiName = ((Datasource)value).getJndiName();
+ setText(jndiName.substring(jndiName.indexOf("/")+1));
+ }
+
+ if (isSelected) {
+ setBackground(list.getSelectionBackground());
+ setForeground(list.getSelectionForeground());
+ } else {
+ setBackground(list.getBackground());
+ setForeground(list.getForeground());
+ }
+
+ return this;
+ }
+ }
+
+ /**
+ * Post the Add Database Connection dialog passing the data source information for populating the dialgo
+ * @param brokenDatasource data source that requires a registered database connection
+ */
+ private static void addDatabaseConnection(Datasource brokenDatasource) {
+ // next check to see if the driver has been added
+ String driverName = brokenDatasource.getDriverClassName();
+ final JDBCDriver matchingDriver = findMatchingDriver(driverName);
+ final Datasource edtDS = brokenDatasource;
+
+ // if matchingDriver is null, user can add a driver in the Add Connection dialog
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ ConnectionManager.getDefault().showAddConnectionDialogFromEventThread(matchingDriver, edtDS.getUrl(), edtDS.getUsername(), edtDS.getPassword());
+ }
+ });
+ }
+
+ /*
+ * Find a matching driver registered with the IDE
+ * public: to-be-used outside this class
+ */
+ private static JDBCDriver findMatchingDriver(String driverClass) {
+ int i = 0;
+ JDBCDriver[] newDrivers;
+ newDrivers = JDBCDriverManager.getDefault().getDrivers();
+
+ for (i = 0; i