Skip to content

Commit 0d5eb7e

Browse files
committed
[NETBEANS-3878] add delete buton for the SSH Connection Dialog
fix problem when connection isn't saved in a list of recent connections
1 parent 2c92300 commit 0d5eb7e

File tree

6 files changed

+135
-36
lines changed

6 files changed

+135
-36
lines changed

ide/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/api/util/ConnectionManager.java

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.concurrent.CopyOnWriteArrayList;
3535
import java.util.concurrent.ExecutionException;
3636
import java.util.logging.Level;
37+
import java.util.prefs.BackingStoreException;
3738
import java.util.prefs.Preferences;
3839
import javax.swing.AbstractAction;
3940
import javax.swing.Action;
@@ -183,6 +184,38 @@ public void removeConnectionListener(ConnectionListener listener) {
183184
// No need to lock - use thread-safe collection
184185
connectionListeners.remove(listener);
185186
}
187+
188+
/**
189+
* Remove a connection from list of recent connections. Any stored settings will be removed
190+
* @param execEnv environment
191+
*/
192+
public void deleteConnectionFromRecentConnections(ExecutionEnvironment execEnv) {
193+
synchronized (recentConnections) {
194+
recentConnections.remove(execEnv);
195+
forget(execEnv);
196+
storeRecentConnectionsList(true);
197+
}
198+
}
199+
200+
201+
/**
202+
* Add a connection to a recent connection list.
203+
* @param execEnv environment
204+
* @return true if a connection was added to a list
205+
*/
206+
public boolean addConnectionToRecentConnections(ExecutionEnvironment execEnv) {
207+
if (execEnv.isLocal()) {
208+
return false;
209+
}
210+
synchronized (recentConnections) {
211+
if (recentConnections.contains(execEnv)) {
212+
return false;
213+
}
214+
recentConnections.add(0, execEnv);
215+
storeRecentConnectionsList(false);
216+
return true;
217+
}
218+
}
186219

187220
public List<ExecutionEnvironment> getRecentConnections() {
188221
synchronized (recentConnections) {
@@ -194,13 +227,24 @@ public List<ExecutionEnvironment> getRecentConnections() {
194227
synchronized (recentConnections) {
195228
recentConnections.remove(execEnv);
196229
recentConnections.add(0, execEnv);
197-
storeRecentConnectionsList();
230+
storeRecentConnectionsList(false);
198231
}
199232
}
200233

201-
/*package-local for test purposes*/ void storeRecentConnectionsList() {
234+
/**
235+
* Store recent connection list.
236+
* @param clear true if settings is cleared before stored
237+
*/
238+
/*package-local for test purposes*/ void storeRecentConnectionsList(boolean clear) {
202239
Preferences prefs = NbPreferences.forModule(ConnectionManager.class);
203240
synchronized (recentConnections) {
241+
if (clear) {
242+
try {
243+
prefs.clear();
244+
} catch (BackingStoreException ex) {
245+
log.log(Level.WARNING,"Cannot clear ConnectionManager preferences", ex);
246+
}
247+
}
204248
for (int i = 0; i < recentConnections.size(); i++) {
205249
prefs.put(getConnectoinsHistoryKey(i), ExecutionEnvironmentFactory.toUniqueID(recentConnections.get(i)));
206250
}
@@ -302,6 +346,7 @@ public boolean isConnectedTo(final ExecutionEnvironment execEnv) {
302346
if (checkHostInfo) {
303347
return HostInfoUtils.isHostInfoAvailable(execEnv);
304348
} else {
349+
updateRecentConnectionsList(execEnv);
305350
return true;
306351
}
307352
} else {

ide/dlight.nativeexecution/test/unit/src/org/netbeans/modules/nativeexecution/api/util/ConnectionManagerTest.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@
2222
import java.util.ArrayList;
2323
import java.util.Collection;
2424
import java.util.List;
25-
import junit.framework.Test;
26-
import org.junit.AfterClass;
27-
import org.junit.BeforeClass;
25+
import org.junit.Test;
2826
import org.netbeans.junit.RandomlyFails;
2927
import org.netbeans.modules.nativeexecution.ConcurrentTasksSupport;
3028
import org.netbeans.modules.nativeexecution.ConcurrentTasksSupport.Counters;
3129
import org.netbeans.modules.nativeexecution.test.NativeExecutionBaseTestCase;
3230
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment;
31+
import org.netbeans.modules.nativeexecution.api.ExecutionEnvironmentFactory;
3332
import org.netbeans.modules.nativeexecution.test.ForAllEnvironments;
3433
import org.netbeans.modules.nativeexecution.test.NativeExecutionBaseTestSuite;
3534
import org.netbeans.modules.nativeexecution.test.NativeExecutionTestSupport;
@@ -50,26 +49,22 @@ public ConnectionManagerTest(String name, ExecutionEnvironment testExecutionEnvi
5049
super(name, testExecutionEnvironment);
5150
}
5251

53-
@BeforeClass
54-
public static void setUpClass() throws Exception {
55-
}
56-
57-
@AfterClass
58-
public static void tearDownClass() throws Exception {
59-
}
60-
61-
@Override
62-
public void setUp() throws Exception {
63-
}
64-
65-
@Override
66-
public void tearDown() throws Exception {
67-
}
68-
69-
public static Test suite() {
52+
public static junit.framework.Test suite() {
7053
return new NativeExecutionBaseTestSuite(ConnectionManagerTest.class);
7154
}
55+
56+
@Test
57+
public void testDeleteConnection() throws Exception {
58+
ExecutionEnvironment env = ExecutionEnvironmentFactory.createNew("test","127.0.0.1");
59+
ConnectionManager.getInstance().updateRecentConnectionsList(env);
60+
List<ExecutionEnvironment> ret = ConnectionManager.getInstance().getRecentConnections();
61+
assertTrue(!ret.isEmpty());
62+
ConnectionManager.getInstance().deleteConnectionFromRecentConnections(env);
63+
List<ExecutionEnvironment> ret2 = ConnectionManager.getInstance().getRecentConnections();
64+
assertTrue(ret2.isEmpty());
65+
}
7266

67+
@Test
7368
public void testGetRecentConnections() throws Exception {
7469
String section = "remote.platforms";
7570
ExecutionEnvironment[] envs = NativeExecutionTestSupport.getTestExecutionEnvironmentsFromSection(section);
@@ -90,6 +85,7 @@ public void testGetRecentConnections() throws Exception {
9085

9186
@RandomlyFails
9287
@ForAllEnvironments(section = "remote.platforms")
88+
@Test
9389
public void testConnectDisconnect() throws Exception {
9490
final ExecutionEnvironment execEnv = getTestExecutionEnvironment();
9591
assert (execEnv != null);
@@ -122,6 +118,7 @@ public void testConnectDisconnect() throws Exception {
122118
System.out.println(getName() + " finished");
123119
}
124120

121+
@Test
125122
public void testGetConnectToAction() throws Exception {
126123
final int threadsNum = 10;
127124
RcFile rcFile = NativeExecutionTestSupport.getRcFile();

ide/dlight.terminal/src/org/netbeans/modules/dlight/terminal/action/TerminalSupportImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ private void doWork() {
201201
// (exception supressed in FetchHostInfoTask.compute)
202202
if (!ConnectionManager.getInstance().isConnectedTo(env)) {
203203
return;
204+
} else {
205+
// because we can reuse an existing connection we need to try update a recent connection list
206+
ConnectionManager.getInstance().addConnectionToRecentConnections(env);
204207
}
205208

206209
try {

ide/dlight.terminal/src/org/netbeans/modules/dlight/terminal/ui/Bundle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ RemoteInfoDialog.hostField.AccessibleContext.accessibleName=Remote Host Name
3333
NewHostInfoTitle=Connection Information:
3434
RemoteInfoDialog.btnKnownHosts.text=&Known Hosts
3535
RemoteInfoDialog.btnNewHost.text=&Other Host
36+
RemoteInfoDialog.btnDeleteHost.text=Delete

ide/dlight.terminal/src/org/netbeans/modules/dlight/terminal/ui/RemoteInfoDialog.form

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.1" encoding="UTF-8" ?>
1+
<?xml version="1.0" encoding="UTF-8" ?>
22

33
<!--
44
@@ -44,13 +44,19 @@
4444
<Group type="102" alignment="0" attributes="0">
4545
<EmptySpace max="-2" attributes="0"/>
4646
<Group type="103" groupAlignment="0" attributes="0">
47-
<Component id="pnlConnectionInfo" alignment="0" max="32767" attributes="0"/>
48-
<Group type="102" alignment="0" attributes="0">
49-
<Component id="btnKnownHosts" min="-2" max="-2" attributes="0"/>
47+
<Component id="pnlConnectionInfo" max="32767" attributes="0"/>
48+
<Group type="102" attributes="0">
49+
<Group type="103" groupAlignment="0" attributes="0">
50+
<Group type="102" alignment="0" attributes="0">
51+
<Component id="btnKnownHosts" min="-2" max="-2" attributes="0"/>
52+
<EmptySpace max="-2" attributes="0"/>
53+
<Component id="cbKnownHosts" pref="254" max="32767" attributes="0"/>
54+
</Group>
55+
<Component id="btnNewHost" alignment="0" min="-2" max="-2" attributes="0"/>
56+
</Group>
5057
<EmptySpace max="-2" attributes="0"/>
51-
<Component id="cbKnownHosts" pref="224" max="32767" attributes="0"/>
58+
<Component id="btnDeleteHost" min="-2" max="-2" attributes="0"/>
5259
</Group>
53-
<Component id="btnNewHost" alignment="0" min="-2" max="-2" attributes="0"/>
5460
</Group>
5561
<EmptySpace max="-2" attributes="0"/>
5662
</Group>
@@ -63,6 +69,7 @@
6369
<Group type="103" groupAlignment="3" attributes="0">
6470
<Component id="cbKnownHosts" alignment="3" min="-2" max="-2" attributes="0"/>
6571
<Component id="btnKnownHosts" alignment="3" min="-2" max="-2" attributes="0"/>
72+
<Component id="btnDeleteHost" alignment="3" min="-2" max="-2" attributes="0"/>
6673
</Group>
6774
<EmptySpace max="-2" attributes="0"/>
6875
<Component id="btnNewHost" min="-2" max="-2" attributes="0"/>
@@ -128,7 +135,7 @@
128135
<Layout>
129136
<DimensionLayout dim="0">
130137
<Group type="103" groupAlignment="0" attributes="0">
131-
<EmptySpace min="0" pref="324" max="32767" attributes="0"/>
138+
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
132139
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
133140
<Group type="102" alignment="0" attributes="0">
134141
<EmptySpace max="-2" attributes="0"/>
@@ -139,7 +146,7 @@
139146
</Group>
140147
<EmptySpace max="-2" attributes="0"/>
141148
<Group type="103" groupAlignment="0" attributes="0">
142-
<Component id="userField" alignment="0" pref="226" max="32767" attributes="2"/>
149+
<Component id="userField" alignment="0" pref="364" max="32767" attributes="2"/>
143150
<Component id="hostField" alignment="0" pref="226" max="32767" attributes="2"/>
144151
<Component id="portField" alignment="0" min="-2" max="-2" attributes="1"/>
145152
</Group>
@@ -271,5 +278,15 @@
271278
</Component>
272279
</SubComponents>
273280
</Container>
281+
<Component class="javax.swing.JButton" name="btnDeleteHost">
282+
<Properties>
283+
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
284+
<ResourceString bundle="org/netbeans/modules/dlight/terminal/ui/Bundle.properties" key="RemoteInfoDialog.btnDeleteHost.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
285+
</Property>
286+
</Properties>
287+
<Events>
288+
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnDeleteHostActionPerformed"/>
289+
</Events>
290+
</Component>
274291
</SubComponents>
275292
</Form>

ide/dlight.terminal/src/org/netbeans/modules/dlight/terminal/ui/RemoteInfoDialog.java

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ private void initComponents() {
6969
hostField = new javax.swing.JTextField();
7070
jLabel3 = new javax.swing.JLabel();
7171
portField = new javax.swing.JTextField();
72+
btnDeleteHost = new javax.swing.JButton();
7273

7374
buttonGroup1.add(btnKnownHosts);
7475
btnKnownHosts.setSelected(true);
@@ -115,7 +116,7 @@ public void itemStateChanged(java.awt.event.ItemEvent evt) {
115116
pnlConnectionInfo.setLayout(pnlConnectionInfoLayout);
116117
pnlConnectionInfoLayout.setHorizontalGroup(
117118
pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
118-
.addGap(0, 324, Short.MAX_VALUE)
119+
.addGap(0, 0, Short.MAX_VALUE)
119120
.addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
120121
.addGroup(pnlConnectionInfoLayout.createSequentialGroup()
121122
.addContainerGap()
@@ -125,7 +126,7 @@ public void itemStateChanged(java.awt.event.ItemEvent evt) {
125126
.addComponent(jLabel3))
126127
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
127128
.addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
128-
.addComponent(userField, javax.swing.GroupLayout.DEFAULT_SIZE, 226, Short.MAX_VALUE)
129+
.addComponent(userField, javax.swing.GroupLayout.DEFAULT_SIZE, 364, Short.MAX_VALUE)
129130
.addComponent(hostField, javax.swing.GroupLayout.DEFAULT_SIZE, 226, Short.MAX_VALUE)
130131
.addComponent(portField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
131132
.addContainerGap()))
@@ -154,6 +155,13 @@ public void itemStateChanged(java.awt.event.ItemEvent evt) {
154155
hostField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.hostField.AccessibleContext.accessibleName")); // NOI18N
155156
portField.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.portField.AccessibleContext.accessibleName")); // NOI18N
156157

158+
btnDeleteHost.setText(org.openide.util.NbBundle.getMessage(RemoteInfoDialog.class, "RemoteInfoDialog.btnDeleteHost.text")); // NOI18N
159+
btnDeleteHost.addActionListener(new java.awt.event.ActionListener() {
160+
public void actionPerformed(java.awt.event.ActionEvent evt) {
161+
btnDeleteHostActionPerformed(evt);
162+
}
163+
});
164+
157165
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
158166
this.setLayout(layout);
159167
layout.setHorizontalGroup(
@@ -163,10 +171,14 @@ public void itemStateChanged(java.awt.event.ItemEvent evt) {
163171
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
164172
.addComponent(pnlConnectionInfo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
165173
.addGroup(layout.createSequentialGroup()
166-
.addComponent(btnKnownHosts)
174+
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
175+
.addGroup(layout.createSequentialGroup()
176+
.addComponent(btnKnownHosts)
177+
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
178+
.addComponent(cbKnownHosts, 0, 254, Short.MAX_VALUE))
179+
.addComponent(btnNewHost))
167180
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
168-
.addComponent(cbKnownHosts, 0, 224, Short.MAX_VALUE))
169-
.addComponent(btnNewHost))
181+
.addComponent(btnDeleteHost)))
170182
.addContainerGap())
171183
);
172184
layout.setVerticalGroup(
@@ -175,7 +187,8 @@ public void itemStateChanged(java.awt.event.ItemEvent evt) {
175187
.addContainerGap()
176188
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
177189
.addComponent(cbKnownHosts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
178-
.addComponent(btnKnownHosts))
190+
.addComponent(btnKnownHosts)
191+
.addComponent(btnDeleteHost))
179192
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
180193
.addComponent(btnNewHost)
181194
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -196,7 +209,29 @@ private void btnNewHostItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIR
196209
}
197210
}//GEN-LAST:event_btnNewHostItemStateChanged
198211

212+
private void btnDeleteHostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeleteHostActionPerformed
213+
ExecutionEnvironment selected = (ExecutionEnvironment) cbKnownHosts.getSelectedItem();
214+
if (selected != null) {
215+
ConnectionManager.getInstance().deleteConnectionFromRecentConnections(selected);
216+
cbKnownHosts.removeItem(selected);
217+
if (cbKnownHosts.getItemCount() == 0) {
218+
btnKnownHosts.setEnabled(false);
219+
btnNewHost.setSelected(true);
220+
}
221+
Preferences prefs = NbPreferences.forModule(RemoteInfoDialog.class);
222+
String eeID = prefs.get(LAST_SELECTED_HOST, "");
223+
if (!eeID.isEmpty()) {
224+
ExecutionEnvironment ee = ExecutionEnvironmentFactory.fromUniqueID(eeID);
225+
if (ee.equals(selected)) {
226+
prefs.remove(LAST_SELECTED_HOST);
227+
last = null;
228+
}
229+
}
230+
}
231+
}//GEN-LAST:event_btnDeleteHostActionPerformed
232+
199233
// Variables declaration - do not modify//GEN-BEGIN:variables
234+
private javax.swing.JButton btnDeleteHost;
200235
private javax.swing.JRadioButton btnKnownHosts;
201236
private javax.swing.JRadioButton btnNewHost;
202237
private javax.swing.ButtonGroup buttonGroup1;
@@ -255,6 +290,7 @@ private void fillHosts() {
255290

256291
private void selectMode(boolean knownHosts) {
257292
cbKnownHosts.setEnabled(knownHosts);
293+
btnDeleteHost.setEnabled(knownHosts);
258294
Component[] components = pnlConnectionInfo.getComponents();
259295
for (Component component : components) {
260296
component.setEnabled(!knownHosts);

0 commit comments

Comments
 (0)