blob: a367993df9567479c72599910f878eb4b6e617a2 [file] [log] [blame]
/**
* Copyright (c) 2016 Oak Ridge National Laboratory and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.remote.internal.proxy.ui.wizards;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.remote.core.IRemoteServicesManager;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.internal.proxy.ui.Activator;
import org.eclipse.remote.internal.proxy.ui.messages.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.IExpansionListener;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
public class ProxyConnectionPage extends WizardPage {
private class DataModifyListener implements ModifyListener {
@Override
public synchronized void modifyText(ModifyEvent e) {
validateFields();
getContainer().updateButtons();
}
}
private Text fConnectionName;
private Button fPasswordButton;
private Button fPublicKeyButton;
private Button fDefaultServerButton;
private Text fHostText;
private Text fUserText;
private Text fPasswordText;
private Text fPassphraseText;
private Text fPortText;
private Text fTimeoutText;
private Text fServerCommandText;
private String fInitialName = "Remote Host"; //$NON-NLS-1$
private Set<String> fInvalidConnectionNames;
private final Map<String, String> fInitialAttributes = new HashMap<String, String>();
private IRemoteConnectionWorkingCopy fConnection;
private final IRemoteConnectionType fConnectionType;
private final DataModifyListener fDataModifyListener = new DataModifyListener();
public ProxyConnectionPage(IRemoteConnectionType connectionType) {
super(Messages.ProxyNewConnectionPage_New_connection_properties);
fConnectionType = connectionType;
setPageComplete(false);
}
/**
* Create controls for the bottom (hideable) advanced composite
*
* @param mold
*
*/
private void createAdvancedControls(final Composite parent) {
ExpandableComposite expComp = new ExpandableComposite(parent, ExpandableComposite.TWISTIE);
expComp.setText(Messages.ProxyNewConnectionPage_Advanced);
expComp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
expComp.setExpanded(false);
expComp.addExpansionListener(new IExpansionListener() {
@Override
public void expansionStateChanged(ExpansionEvent e) {
for (int i = 0; i < 2; i++) { // sometimes the size compute isn't correct on first try
Point newSize = parent.computeSize(SWT.DEFAULT, SWT.DEFAULT);
Point currentSize = parent.getSize();
int deltaY = newSize.y - currentSize.y;
Point shellSize = getShell().getSize();
shellSize.y += deltaY;
getShell().setSize(shellSize);
getShell().layout(true, true);
}
}
@Override
public void expansionStateChanging(ExpansionEvent e) {
// Ignore
}
});
Composite advancedComp = new Composite(expComp, SWT.NONE);
advancedComp.setLayout(new GridLayout(1, false));
advancedComp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Group settingsComp = new Group(advancedComp, SWT.NONE);
settingsComp.setText(Messages.ProxyConnectionPage_Settings0);
settingsComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
settingsComp.setLayout(new GridLayout(2, false));
Label portLabel = new Label(settingsComp, SWT.NONE);
portLabel.setText(Messages.ProxyNewConnectionPage_Port);
fPortText = new Text(settingsComp, SWT.BORDER | SWT.SINGLE);
fPortText.setText(Integer.toString(ProxyConnection.DEFAULT_PORT));
fPortText.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
setTextFieldWidthInChars(fPortText, 5);
Label timeoutLabel = new Label(settingsComp, SWT.NONE);
timeoutLabel.setText(Messages.ProxyNewConnectionPage_Timeout);
fTimeoutText = new Text(settingsComp, SWT.BORDER | SWT.SINGLE);
fTimeoutText.setText(Integer.toString(ProxyConnection.DEFAULT_TIMEOUT));
fDefaultServerButton = new Button(settingsComp, SWT.CHECK);
fDefaultServerButton.setText("Use default server");
fDefaultServerButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
fDefaultServerButton.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e) {
validateFields();
updateEnablement();
}
});
Label serverLabel = new Label(settingsComp, SWT.NONE);
serverLabel.setText("Server command");
fServerCommandText = new Text(settingsComp, SWT.BORDER | SWT.SINGLE);
fServerCommandText.setText(ProxyConnection.DEFAULT_SERVER_COMMAND);
fServerCommandText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
fDefaultServerButton.setSelection(ProxyConnection.DEFAULT_USE_DEFAULT_SERVER);
expComp.setClient(advancedComp);
}
private void createAuthControls(Composite parent) {
Composite controls = new Composite(parent, SWT.NONE);
controls.setLayout(new GridLayout(3, false));
controls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Label hostLabel = new Label(controls, SWT.NONE);
hostLabel.setText(Messages.ProxyNewConnectionPage_Host);
fHostText = new Text(controls, SWT.BORDER | SWT.SINGLE);
fHostText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
Label userLabel = new Label(controls, SWT.NONE);
userLabel.setText(Messages.ProxyNewConnectionPage_User);
fUserText = new Text(controls, SWT.BORDER | SWT.SINGLE);
fUserText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
// Key option box
fPublicKeyButton = new Button(controls, SWT.RADIO);
fPublicKeyButton.setText(Messages.ProxyNewConnectionPage_Public_key_based_authentication);
fPublicKeyButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
fPublicKeyButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
validateFields();
updateEnablement();
}
});
Link link = new Link(controls, SWT.WRAP);
final GridData linkLayoutData = new GridData(GridData.FILL_HORIZONTAL);
link.setLayoutData(linkLayoutData);
final String PREFS_PAGE_ID_NET_SSH = "org.eclipse.jsch.ui.SSHPreferences"; //$NON-NLS-1$
link.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
PreferenceDialog dlg = PreferencesUtil.createPreferenceDialogOn(getShell(), PREFS_PAGE_ID_NET_SSH,
new String[] { PREFS_PAGE_ID_NET_SSH }, null);
dlg.open();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignore
}
});
link.setText(Messages.ProxyConnectionPage_KeysAtSSH2);
// Passphrase field
Label passphraseLabel = new Label(controls, SWT.NONE);
passphraseLabel.setText(Messages.ProxyNewConnectionPage_Passphrase);
fPassphraseText = new Text(controls, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD);
fPassphraseText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
// User option box
fPasswordButton = new Button(controls, SWT.RADIO);
fPasswordButton.setText(Messages.ProxyNewConnectionPage_Password_based_authentication);
fPasswordButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 3, 1));
fPasswordButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
validateFields();
updateEnablement();
}
});
// Password field
Label passwordLabel = new Label(controls, SWT.NONE);
passwordLabel.setText(Messages.ProxyNewConnectionPage_Password);
fPasswordText = new Text(controls, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD);
fPasswordText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
fPasswordButton.setSelection(ProxyConnection.DEFAULT_USE_PASSWORD);
fPublicKeyButton.setSelection(!ProxyConnection.DEFAULT_USE_PASSWORD);
controls.setTabList(
new Control[] { fHostText, fUserText, fPublicKeyButton, fPassphraseText, fPasswordButton, fPasswordText });
}
@Override
public void createControl(Composite parent) {
if (fConnection == null) {
setDescription(Messages.ProxyNewConnectionPage_New_connection_properties);
setTitle(Messages.ProxyNewConnectionPage_New_connection_properties);
setMessage(Messages.ProxyConnectionPage_Initial_Message);
} else {
setDescription(Messages.ProxyConnectionPage_Edit_properties_of_an_existing_connection);
setTitle(Messages.ProxyConnectionPage_Edit_Connection);
}
setErrorMessage(null);
GridLayout topLayout = new GridLayout(2, false);
final Composite topControl = new Composite(parent, SWT.NONE);
setControl(topControl);
topControl.setLayout(topLayout);
Label label = new Label(topControl, SWT.NONE);
label.setText(Messages.ProxyNewConnectionPage_Connection_name);
fConnectionName = new Text(topControl, SWT.BORDER | SWT.SINGLE);
fConnectionName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
fConnectionName.setEnabled(fConnection == null);
final Group authGroup = new Group(topControl, SWT.NONE);
authGroup.setText(Messages.ProxyNewConnectionPage_Host_information);
authGroup.setLayout(new GridLayout(1, false));
authGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
createAuthControls(authGroup);
createAdvancedControls(authGroup);
try {
loadValues();
} catch (CoreException e) {
Activator.log(e.getStatus());
}
/*
* Register listeners after loading values so we don't trigger listeners
*/
registerListeners();
if (fConnection != null) {
validateFields();
}
updateEnablement();
}
public IRemoteConnectionWorkingCopy getConnection() {
return fConnection;
}
/**
* Check if the connection name is invalid. This only applies to new connections (when fConnection is null).
*
* @param name
* connection name
* @return true if the name is invalid, false otherwise
*/
private boolean isInvalidName(String name) {
if (fConnection == null) {
if (fInvalidConnectionNames == null) {
return fConnectionType.getConnection(name) != null;
}
return fInvalidConnectionNames.contains(name);
}
return false;
}
private void loadValues() throws CoreException {
IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class);
if (fConnection != null) {
fConnectionName.setText(fConnection.getName());
fHostText.setText(fConnection.getAttribute(ProxyConnection.HOSTNAME_ATTR));
fUserText.setText(fConnection.getAttribute(ProxyConnection.USERNAME_ATTR));
String portStr = fConnection.getAttribute(ProxyConnection.PORT_ATTR);
fPortText.setText(portStr.isEmpty() ? Integer.toString(ProxyConnection.DEFAULT_PORT) : portStr);
String timeoutStr = fConnection.getAttribute(ProxyConnection.TIMEOUT_ATTR);
fTimeoutText.setText(timeoutStr.isEmpty() ? Integer.toString(ProxyConnection.DEFAULT_TIMEOUT) : timeoutStr);
String isPwdStr = fConnection.getAttribute(ProxyConnection.USE_PASSWORD_ATTR);
boolean isPwd = isPwdStr.isEmpty() ? ProxyConnection.DEFAULT_USE_PASSWORD : Boolean.parseBoolean(isPwdStr);
fPasswordButton.setSelection(isPwd);
fPublicKeyButton.setSelection(!isPwd);
fPasswordText.setText(fConnection.getSecureAttribute(ProxyConnection.PASSWORD_ATTR));
fPassphraseText.setText(fConnection.getSecureAttribute(ProxyConnection.PASSPHRASE_ATTR));
String useDefaultServerStr = fConnection.getAttribute(ProxyConnection.USE_DEFAULT_SERVER_ATTR);
boolean useDefaultServer = useDefaultServerStr.isEmpty() ? ProxyConnection.DEFAULT_USE_DEFAULT_SERVER
: Boolean.parseBoolean(useDefaultServerStr);
fDefaultServerButton.setSelection(useDefaultServer);
String serverCommandStr = fConnection.getAttribute(ProxyConnection.SERVER_COMMAND_ATTR);
fServerCommandText.setText(serverCommandStr.isEmpty() ? ProxyConnection.DEFAULT_SERVER_COMMAND : serverCommandStr);
} else {
fConnectionName.setText(fInitialName);
String host = fInitialAttributes.get(ProxyConnection.HOSTNAME_ATTR);
if (host != null) {
fHostText.setText(host);
}
String username = fInitialAttributes.get(ProxyConnection.USERNAME_ATTR);
if (username != null) {
fUserText.setText(username);
}
String port = fInitialAttributes.get(ProxyConnection.PORT_ATTR);
if (port != null) {
fPortText.setText(port);
}
String timeout = fInitialAttributes.get(ProxyConnection.TIMEOUT_ATTR);
if (timeout != null) {
fTimeoutText.setText(timeout);
}
String isPwd = fInitialAttributes.get(ProxyConnection.USE_PASSWORD_ATTR);
if (isPwd != null) {
fPasswordButton.setSelection(Boolean.parseBoolean(isPwd));
}
String password = fInitialAttributes.get(ProxyConnection.PASSWORD_ATTR);
if (password != null) {
fPasswordText.setText(password);
}
String passphrase = fInitialAttributes.get(ProxyConnection.PASSPHRASE_ATTR);
if (passphrase != null) {
fPassphraseText.setText(passphrase);
}
String useDefaultServer = fInitialAttributes.get(ProxyConnection.USE_DEFAULT_SERVER_ATTR);
if (useDefaultServer != null) {
fDefaultServerButton.setSelection(Boolean.parseBoolean(useDefaultServer));
}
String serverCommand = fInitialAttributes.get(ProxyConnection.SERVER_COMMAND_ATTR);
if (serverCommand != null) {
fServerCommandText.setText(serverCommand);
}
}
}
private void registerListeners() {
fConnectionName.addModifyListener(fDataModifyListener);
fHostText.addModifyListener(fDataModifyListener);
fUserText.addModifyListener(fDataModifyListener);
fPasswordText.addModifyListener(fDataModifyListener);
fPassphraseText.addModifyListener(fDataModifyListener);
fPortText.addModifyListener(fDataModifyListener);
fTimeoutText.addModifyListener(fDataModifyListener);
fServerCommandText.addModifyListener(fDataModifyListener);
}
public void setAddress(String address) {
fInitialAttributes.put(ProxyConnection.HOSTNAME_ATTR, address);
}
public void setAttributes(Map<String, String> attributes) {
fInitialAttributes.putAll(attributes);
}
public void setConnection(IRemoteConnectionWorkingCopy connection) {
fConnection = connection;
}
public void setConnectionName(String name) {
fInitialName = name;
}
public void setInvalidConnectionNames(Set<String> names) {
fInvalidConnectionNames = names;
}
@Override
public void setPageComplete(boolean complete) {
super.setPageComplete(complete);
if (complete) {
storeValues();
}
}
public void setPort(int port) {
fInitialAttributes.put(ProxyConnection.PORT_ATTR, Integer.toString(port));
}
private void setTextFieldWidthInChars(Text text, int chars) {
text.setTextLimit(chars);
Object data = text.getLayoutData();
if (data instanceof GridData) {
GC gc = new GC(text);
FontMetrics fm = gc.getFontMetrics();
int width = chars * fm.getAverageCharWidth();
gc.dispose();
((GridData) data).widthHint = width;
}
}
public void setUsername(String username) {
fInitialAttributes.put(ProxyConnection.USERNAME_ATTR, username);
}
private void storeValues() {
if (fConnection == null) {
try {
fConnection = fConnectionType.newConnection(fConnectionName.getText().trim());
} catch (RemoteConnectionException e) {
Activator.log(e);
}
}
if (fConnection != null) {
fConnection.setName(fConnectionName.getText().trim());
fConnection.setAttribute(ProxyConnection.HOSTNAME_ATTR, fHostText.getText().trim());
fConnection.setAttribute(ProxyConnection.USERNAME_ATTR, fUserText.getText().trim());
fConnection.setSecureAttribute(ProxyConnection.PASSWORD_ATTR, fPasswordText.getText().trim());
fConnection.setSecureAttribute(ProxyConnection.PASSPHRASE_ATTR, fPassphraseText.getText().trim());
fConnection.setAttribute(ProxyConnection.USE_PASSWORD_ATTR, Boolean.toString(fPasswordButton.getSelection()));
fConnection.setAttribute(ProxyConnection.TIMEOUT_ATTR, fTimeoutText.getText().trim());
fConnection.setAttribute(ProxyConnection.PORT_ATTR, fPortText.getText().trim());
fConnection.setAttribute(ProxyConnection.USE_DEFAULT_SERVER_ATTR, Boolean.toString(fDefaultServerButton.getSelection()));
fConnection.setAttribute(ProxyConnection.SERVER_COMMAND_ATTR, fServerCommandText.getText().trim());
}
}
private void updateEnablement() {
boolean isPasswordAuth = fPasswordButton.getSelection();
fPasswordText.setEnabled(isPasswordAuth);
fPassphraseText.setEnabled(!isPasswordAuth);
fServerCommandText.setEnabled(!fDefaultServerButton.getSelection());
}
private String validateAdvanced() {
try {
Integer.parseInt(fPortText.getText().trim());
} catch (NumberFormatException ne) {
return Messages.ProxyNewConnectionPage_Port_is_not_valid;
}
try {
Integer.parseInt(fTimeoutText.getText().trim());
} catch (NumberFormatException ne) {
return Messages.ProxyNewConnectionPage_Timeout_is_not_valid;
}
return null;
}
private void validateFields() {
String message = null;
if (fConnectionName.getText().trim().length() == 0) {
message = Messages.ProxyNewConnectionPage_Please_enter_a_connection_name;
} else if (isInvalidName(fConnectionName.getText().trim())) {
message = Messages.ProxyConnectionPage_A_connection_with_that_name_already_exists;
} else if (fHostText.getText().trim().length() == 0) {
message = Messages.ProxyNewConnectionPage_Host_name_cannot_be_empty;
} else if (fUserText.getText().trim().length() == 0) {
message = Messages.ProxyNewConnectionPage_User_name_cannot_be_empty;
} else if (!fDefaultServerButton.getSelection() && fServerCommandText.getText().trim().length() == 0) {
message = "Server command cannot be empty";
}
if (message == null) {
message = validateAdvanced();
}
setErrorMessage(message);
setPageComplete(message == null);
}
}