Java tutorial
/** * Copyright (c) 2013, 2015 IBM Corporation 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 * * Contributors: * IBM Corporation - Initial Implementation * Patrick Tasse - [461541] fix handling of default attributes */ package org.eclipse.remote.internal.jsch.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.IRemoteConnection; import org.eclipse.remote.core.IRemoteConnectionHostService; import org.eclipse.remote.core.IRemoteConnectionType; import org.eclipse.remote.core.IRemoteConnectionWorkingCopy; import org.eclipse.remote.core.IRemotePortForwardingService; import org.eclipse.remote.core.IRemoteServicesManager; import org.eclipse.remote.core.exception.RemoteConnectionException; import org.eclipse.remote.internal.jsch.core.Activator; import org.eclipse.remote.internal.jsch.core.JSchConnection; import org.eclipse.remote.internal.jsch.ui.messages.Messages; import org.eclipse.remote.ui.widgets.RemoteConnectionWidget; 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 JSchConnectionPage 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 fUseLoginShellButton; private Text fHostText; private Text fUserText; private Text fPasswordText; private Text fPassphraseText; private Text fPortText; private Text fTimeoutText; private Text fLoginShellText; 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(); private RemoteConnectionWidget fProxyConnectionWidget; private Text fProxyCommandText; private static final String PREFS_PAGE_ID_NET_PROXY = "org.eclipse.ui.net.NetPreferences"; //$NON-NLS-1$ public JSchConnectionPage(IRemoteConnectionType connectionType) { super(Messages.JSchNewConnectionPage_New_Connection); 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.JSchNewConnectionPage_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.JSchConnectionPage_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.JSchNewConnectionPage_Port); fPortText = new Text(settingsComp, SWT.BORDER | SWT.SINGLE); fPortText.setText(Integer.toString(JSchConnection.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.JSchNewConnectionPage_Timeout); fTimeoutText = new Text(settingsComp, SWT.BORDER | SWT.SINGLE); fTimeoutText.setText(Integer.toString(JSchConnection.DEFAULT_TIMEOUT)); fTimeoutText.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); setTextFieldWidthInChars(fTimeoutText, 5); fUseLoginShellButton = new Button(settingsComp, SWT.CHECK); fUseLoginShellButton.setText(Messages.JSchConnectionPage_0); fUseLoginShellButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1)); fUseLoginShellButton.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 loginShellLabel = new Label(settingsComp, SWT.NONE); loginShellLabel.setText(Messages.JSchConnectionPage_1); fLoginShellText = new Text(settingsComp, SWT.BORDER | SWT.SINGLE); fLoginShellText.setText(JSchConnection.DEFAULT_LOGIN_SHELL_COMMAND); fLoginShellText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); fUseLoginShellButton.setSelection(JSchConnection.DEFAULT_USE_LOGIN_SHELL); Group proxyComp = new Group(advancedComp, SWT.NONE); proxyComp.setText(Messages.JSchConnectionPage_Proxy); proxyComp.setLayout(new GridLayout(1, false)); proxyComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); createProxyControls(proxyComp); 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.JSchNewConnectionPage_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.JSchNewConnectionPage_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.JSchNewConnectionPage_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.JSchConnectionPage_KeysAtSSH2); // Passphrase field Label passphraseLabel = new Label(controls, SWT.NONE); passphraseLabel.setText(Messages.JSchNewConnectionPage_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.JSchNewConnectionPage_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.JSchNewConnectionPage_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(JSchConnection.DEFAULT_IS_PASSWORD); fPublicKeyButton.setSelection(!JSchConnection.DEFAULT_IS_PASSWORD); controls.setTabList(new Control[] { fHostText, fUserText, fPublicKeyButton, fPassphraseText, fPasswordButton, fPasswordText }); } @Override public void createControl(Composite parent) { if (fConnection == null) { setDescription(Messages.JSchNewConnectionPage_New_connection_properties); setTitle(Messages.JSchNewConnectionPage_New_Connection); setMessage(Messages.JSchConnectionPage_Initial_Message); } else { setDescription(Messages.JSchConnectionPage_Edit_properties_of_an_existing_connection); setTitle(Messages.JSchConnectionPage_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.JSchNewConnectionPage_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.JSchNewConnectionPage_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(); } /** * Create controls for the bottom (hideable) proxy composite * * @param mold * */ private void createProxyControls(final Composite proxyComp) { Label lblConnection = new Label(proxyComp, SWT.WRAP); lblConnection.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); lblConnection.setText(Messages.JSchConnectionPage_SelectConnection); fProxyConnectionWidget = new RemoteConnectionWidget(proxyComp, SWT.NONE, null, 0); fProxyConnectionWidget.filterConnections(IRemoteConnectionHostService.class, IRemotePortForwardingService.class); Label lblCommand = new Label(proxyComp, SWT.WRAP); lblCommand.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); lblCommand.setText(Messages.JSchConnectionPage_SelectCommand); fProxyCommandText = new Text(proxyComp, SWT.BORDER); fProxyCommandText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Link link = new Link(proxyComp, SWT.WRAP); final GridData linkLayoutData = new GridData(GridData.FILL_HORIZONTAL); link.setLayoutData(linkLayoutData); link.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { PreferenceDialog dlg = PreferencesUtil.createPreferenceDialogOn(getShell(), PREFS_PAGE_ID_NET_PROXY, new String[] { PREFS_PAGE_ID_NET_PROXY }, null); dlg.open(); } @Override public void widgetDefaultSelected(SelectionEvent e) { // ignore } }); linkLayoutData.widthHint = 400; link.setText(Messages.JSchConnectionPage_Help); } 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(JSchConnection.ADDRESS_ATTR)); fUserText.setText(fConnection.getAttribute(JSchConnection.USERNAME_ATTR)); String portStr = fConnection.getAttribute(JSchConnection.PORT_ATTR); fPortText.setText(portStr.isEmpty() ? Integer.toString(JSchConnection.DEFAULT_PORT) : portStr); String timeoutStr = fConnection.getAttribute(JSchConnection.TIMEOUT_ATTR); fTimeoutText .setText(timeoutStr.isEmpty() ? Integer.toString(JSchConnection.DEFAULT_TIMEOUT) : timeoutStr); String isPwdStr = fConnection.getAttribute(JSchConnection.IS_PASSWORD_ATTR); boolean isPwd = isPwdStr.isEmpty() ? JSchConnection.DEFAULT_IS_PASSWORD : Boolean.parseBoolean(isPwdStr); fPasswordButton.setSelection(isPwd); fPublicKeyButton.setSelection(!isPwd); fPasswordText.setText(fConnection.getSecureAttribute(JSchConnection.PASSWORD_ATTR)); fPassphraseText.setText(fConnection.getSecureAttribute(JSchConnection.PASSPHRASE_ATTR)); String useLoginShellStr = fConnection.getAttribute(JSchConnection.USE_LOGIN_SHELL_ATTR); boolean useLoginShell = useLoginShellStr.isEmpty() ? JSchConnection.DEFAULT_USE_LOGIN_SHELL : Boolean.parseBoolean(useLoginShellStr); fUseLoginShellButton.setSelection(useLoginShell); String loginShellStr = fConnection.getAttribute(JSchConnection.LOGIN_SHELL_COMMAND_ATTR); fLoginShellText .setText(loginShellStr.isEmpty() ? JSchConnection.DEFAULT_LOGIN_SHELL_COMMAND : loginShellStr); fProxyCommandText.setText(fConnection.getAttribute(JSchConnection.PROXYCOMMAND_ATTR)); JSchConnection proxyConn = fConnection.getService(JSchConnection.class).getProxyConnection(); if (proxyConn == null) { // Use local connection fProxyConnectionWidget.setConnection(manager.getLocalConnectionType().getConnections().get(0)); } else { fProxyConnectionWidget.setConnection(proxyConn.getRemoteConnection()); } } else { fConnectionName.setText(fInitialName); String host = fInitialAttributes.get(JSchConnection.ADDRESS_ATTR); if (host != null) { fHostText.setText(host); } String username = fInitialAttributes.get(JSchConnection.USERNAME_ATTR); if (username != null) { fUserText.setText(username); } String port = fInitialAttributes.get(JSchConnection.PORT_ATTR); if (port != null) { fPortText.setText(port); } String timeout = fInitialAttributes.get(JSchConnection.TIMEOUT_ATTR); if (timeout != null) { fTimeoutText.setText(timeout); } String isPwd = fInitialAttributes.get(JSchConnection.IS_PASSWORD_ATTR); if (isPwd != null) { fPasswordButton.setSelection(Boolean.parseBoolean(isPwd)); } String password = fInitialAttributes.get(JSchConnection.PASSWORD_ATTR); if (password != null) { fPasswordText.setText(password); } String passphrase = fInitialAttributes.get(JSchConnection.PASSPHRASE_ATTR); if (passphrase != null) { fPassphraseText.setText(passphrase); } String useLoginShell = fInitialAttributes.get(JSchConnection.USE_LOGIN_SHELL_ATTR); if (useLoginShell != null) { fUseLoginShellButton.setSelection(Boolean.parseBoolean(useLoginShell)); } String loginShell = fInitialAttributes.get(JSchConnection.LOGIN_SHELL_COMMAND_ATTR); if (loginShell != null) { fLoginShellText.setText(loginShell); } fProxyConnectionWidget.setConnection(manager.getLocalConnectionType().getConnections().get(0)); } } private void registerListeners() { fConnectionName.addModifyListener(fDataModifyListener); fHostText.addModifyListener(fDataModifyListener); fUserText.addModifyListener(fDataModifyListener); fPasswordText.addModifyListener(fDataModifyListener); fPassphraseText.addModifyListener(fDataModifyListener); fPortText.addModifyListener(fDataModifyListener); fTimeoutText.addModifyListener(fDataModifyListener); fLoginShellText.addModifyListener(fDataModifyListener); fProxyCommandText.addModifyListener(fDataModifyListener); fProxyConnectionWidget.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { validateFields(); getContainer().updateButtons(); } }); } public void setAddress(String address) { fInitialAttributes.put(JSchConnection.ADDRESS_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(JSchConnection.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(JSchConnection.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(JSchConnection.ADDRESS_ATTR, fHostText.getText().trim()); fConnection.setAttribute(JSchConnection.USERNAME_ATTR, fUserText.getText().trim()); fConnection.setSecureAttribute(JSchConnection.PASSWORD_ATTR, fPasswordText.getText().trim()); fConnection.setSecureAttribute(JSchConnection.PASSPHRASE_ATTR, fPassphraseText.getText().trim()); fConnection.setAttribute(JSchConnection.IS_PASSWORD_ATTR, Boolean.toString(fPasswordButton.getSelection())); fConnection.setAttribute(JSchConnection.TIMEOUT_ATTR, fTimeoutText.getText().trim()); fConnection.setAttribute(JSchConnection.PORT_ATTR, fPortText.getText().trim()); fConnection.setAttribute(JSchConnection.PROXYCOMMAND_ATTR, fProxyCommandText.getText().trim()); fConnection.setAttribute(JSchConnection.USE_LOGIN_SHELL_ATTR, Boolean.toString(fUseLoginShellButton.getSelection())); fConnection.setAttribute(JSchConnection.LOGIN_SHELL_COMMAND_ATTR, fLoginShellText.getText().trim()); IRemoteConnection proxyConnection = fProxyConnectionWidget.getConnection(); IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class); String proxyConnectionName = ""; //$NON-NLS-1$ if (proxyConnection != null && proxyConnection.getConnectionType() != manager.getLocalConnectionType()) { proxyConnectionName = proxyConnection.getName(); } fConnection.setAttribute(JSchConnection.PROXYCONNECTION_ATTR, proxyConnectionName); } } private void updateEnablement() { boolean isPasswordAuth = fPasswordButton.getSelection(); fPasswordText.setEnabled(isPasswordAuth); fPassphraseText.setEnabled(!isPasswordAuth); fLoginShellText.setEnabled(fUseLoginShellButton.getSelection()); } private String validateAdvanced() { try { Integer.parseInt(fPortText.getText().trim()); } catch (NumberFormatException ne) { return Messages.JSchNewConnectionPage_Port_is_not_valid; } try { Integer.parseInt(fTimeoutText.getText().trim()); } catch (NumberFormatException ne) { return Messages.JSchNewConnectionPage_Timeout_is_not_valid; } return null; } private void validateFields() { String message = null; if (fConnectionName.getText().trim().length() == 0) { message = Messages.JSchNewConnectionPage_Please_enter_a_connection_name; } else if (isInvalidName(fConnectionName.getText().trim())) { message = Messages.JSchConnectionPage_A_connection_with_that_name_already_exists; } else if (fHostText.getText().trim().length() == 0) { message = Messages.JSchNewConnectionPage_Host_name_cannot_be_empty; } else if (fUserText.getText().trim().length() == 0) { message = Messages.JSchNewConnectionPage_User_name_cannot_be_empty; } else if (fUseLoginShellButton.getSelection() && fLoginShellText.getText().trim().length() == 0) { message = Messages.JSchConnectionPage_2; } else if (fProxyConnectionWidget.getConnection() == null) { message = Messages.JSchConnectionPage_selectProxyConnection; } if (message == null) { message = validateAdvanced(); } setErrorMessage(message); setPageComplete(message == null); } }