/********************************************************************** * Copyright (c) 2012, 2015 Ericsson * * 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: * Bernd Hufmann - Initial API and implementation * Markus Schorn - Bug 448058: Use org.eclipse.remote in favor of RSE **********************************************************************/ package org.eclipse.tracecompass.internal.lttng2.control.ui.views.dialogs; import static java.text.MessageFormat.format; import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; 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.IRemoteServicesManager; import org.eclipse.remote.core.exception.RemoteConnectionException; import org.eclipse.remote.ui.IRemoteUIConnectionService; import org.eclipse.remote.ui.IRemoteUIConnectionWizard; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.tracecompass.internal.lttng2.control.ui.Activator; import org.eclipse.tracecompass.internal.lttng2.control.ui.views.messages.Messages; import org.eclipse.tracecompass.tmf.remote.core.proxy.TmfRemoteConnectionFactory; /** * <p> * Dialog box for connection information. * </p> * * @author Bernd Hufmann */ public class NewConnectionDialog extends Dialog implements INewConnectionDialog { private static final int BUTTONS_NUMBER_OF_COLUMNS = 3; private static final int LABEL_WIDTH_CHARS = 4; private static final int CONNECTIONTREE_HEIGHT_CHARS = 10; private static final int CONNECTIONTREE_WIDTH_CHARS = 40; // ------------------------------------------------------------------------ // Constants // ------------------------------------------------------------------------ private static final String TARGET_NEW_CONNECTION_ICON_FILE = "icons/elcl16/target_add.gif"; //$NON-NLS-1$ private static final String PROVIDERS_ICON_FILE = "icons/obj16/providers.gif"; //$NON-NLS-1$ private static final String CONNECTION_ICON_FILE = "icons/obj16/target_connected.gif"; //$NON-NLS-1$ private final class ConnectionTreeLabelProvider extends LabelProvider { @Override public String getText(Object element) { if (element instanceof IRemoteConnection) { IRemoteConnection rc = (IRemoteConnection) element; return getConnectionLabel(rc); } else if (element instanceof IRemoteConnectionType) { IRemoteConnectionType rs = (IRemoteConnectionType) element; return rs.getName(); } return Messages.TraceControl_UnknownNode; } @Override public Image getImage(Object element) { if (element instanceof IRemoteConnection) { return Activator.getDefault().loadIcon(CONNECTION_ICON_FILE); } return Activator.getDefault().loadIcon(PROVIDERS_ICON_FILE); } } private static final class ConnectionContentProvider implements ITreeContentProvider { private static final Object[] NO_CHILDREN = {}; @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public void dispose() { } @Override public Object[] getElements(Object inputElement) { List<Object> children = new ArrayList<>(); IRemoteServicesManager manager = TmfRemoteConnectionFactory.getService(IRemoteServicesManager.class); if (manager != null) { children.addAll(manager.getAllConnectionTypes()); } return children.toArray(); } @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof IRemoteConnectionType) { return getConnections((IRemoteConnectionType) parentElement); } return NO_CHILDREN; } private static IRemoteConnection[] getConnections(IRemoteConnectionType parentElement) { List<IRemoteConnection> connectionList = parentElement.getConnections(); IRemoteConnection[] result = connectionList.toArray(new IRemoteConnection[connectionList.size()]); Arrays.sort(result, new Comparator<IRemoteConnection>() { @Override public int compare(IRemoteConnection o1, IRemoteConnection o2) { return getConnectionLabel(o1).compareTo(getConnectionLabel(o2)); } }); return result; } @Override public Object getParent(Object element) { if (element instanceof IRemoteConnection) { return ((IRemoteConnection) element).getConnectionType(); } return null; } @Override public boolean hasChildren(Object element) { return getChildren(element).length > 0; } } // ------------------------------------------------------------------------ // Attributes // ------------------------------------------------------------------------ /** * The host combo box. */ private TreeViewer fConnectionTree = null; /** * The push button for creating a new connection. */ private Button fNewButton = null; /** * The push button for editing a connection. */ private Button fEditButton = null; private IRemoteConnection fConnection; // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ /** * Constructor * * @param shell * The shell */ public NewConnectionDialog(Shell shell) { super(shell); setShellStyle(SWT.RESIZE | getShellStyle()); } // ------------------------------------------------------------------------ // Operations // ------------------------------------------------------------------------ @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(Messages.TraceControl_NewDialogTitle); newShell.setImage(Activator.getDefault().loadIcon(TARGET_NEW_CONNECTION_ICON_FILE)); } @Override protected Control createContents(Composite parent) { Control result = super.createContents(parent); fConnectionTree.setAutoExpandLevel(2); fConnectionTree.setInput(this); IRemoteServicesManager manager = TmfRemoteConnectionFactory.getService(IRemoteServicesManager.class); if (manager == null) { return result; } List<IRemoteConnectionType> providers = manager.getAllConnectionTypes(); if (!providers.isEmpty()) { IRemoteConnectionType provider = providers.get(0); IRemoteConnection[] connections = ConnectionContentProvider.getConnections(provider); if (connections.length > 0) { fConnectionTree.setSelection(new StructuredSelection(connections[0])); } else { fConnectionTree.setSelection(new StructuredSelection(provider)); } } else { onSelectionChanged(); } return result; } @Override protected Control createDialogArea(Composite parent) { // Main dialog panel GridData gd; Composite dialogComposite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(1, true); dialogComposite.setLayout(layout); dialogComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); Label label = new Label(dialogComposite, SWT.NONE); label.setText(Messages.TraceControl_NewNodeExistingConnectionGroupName); gd = new GridData(); label.setLayoutData(gd ); gd.widthHint = label.computeSize(-1, -1).x + convertWidthInCharsToPixels(LABEL_WIDTH_CHARS); // Existing connections group fConnectionTree = new TreeViewer(dialogComposite); gd = new GridData(SWT.FILL, SWT.FILL, true, true); fConnectionTree.getTree().setLayoutData(gd); gd.widthHint = convertWidthInCharsToPixels(CONNECTIONTREE_WIDTH_CHARS); gd.heightHint = convertHeightInCharsToPixels(CONNECTIONTREE_HEIGHT_CHARS); fConnectionTree.setLabelProvider(new ConnectionTreeLabelProvider()); fConnectionTree.setContentProvider(new ConnectionContentProvider()); fConnectionTree.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { onSelectionChanged(); } }); fConnectionTree.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { okPressed(); } }); Composite buttons = new Composite(dialogComposite, SWT.NONE); layout = new GridLayout(BUTTONS_NUMBER_OF_COLUMNS, true); layout.marginHeight = 0; layout.marginWidth = 0; buttons.setLayout(layout); buttons.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false)); new Label(buttons, SWT.NONE); fEditButton = new Button(buttons, SWT.PUSH); fEditButton.setText(Messages.TraceControl_NewNodeEditButtonName); setButtonLayoutData(fEditButton); fEditButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onEditConnection(); } }); fNewButton = new Button(buttons, SWT.PUSH); fNewButton.setText(Messages.TraceControl_NewNodeCreateButtonText); setButtonLayoutData(fNewButton); fNewButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onNewConnection(); } }); return dialogComposite; } private void onSelectionChanged() { setConnection(); getButton(OK).setEnabled(fConnection != null); fEditButton.setEnabled(canEdit(fConnection)); fNewButton.setEnabled(getServiceForCreation() != null); } private IRemoteConnectionType getServiceForCreation() { Object o = ((IStructuredSelection) fConnectionTree.getSelection()).getFirstElement(); IRemoteConnectionType result = null; if (o instanceof IRemoteConnectionType) { result = (IRemoteConnectionType) o; } else if (o instanceof IRemoteConnection) { result = ((IRemoteConnection) o).getConnectionType(); } else { return null; } if (!result.canAdd()) { return null; } return result; } private static boolean canEdit(IRemoteConnection conn) { if (conn == null) { return false; } return conn.getConnectionType().canEdit(); } private void onNewConnection() { IRemoteConnectionType rs = getServiceForCreation(); if (rs != null) { IRemoteUIConnectionService uiService = rs.getService(IRemoteUIConnectionService.class); if (uiService != null) { IRemoteUIConnectionWizard wiz = uiService.getConnectionWizard(getShell()); if (wiz != null) { IRemoteConnectionWorkingCopy wc = wiz.open(); if (wc != null) { IRemoteConnection conn = null; try { conn = wc.save(); } catch (RemoteConnectionException e) { Activator.getDefault().logWarning("Connection configuration could not be saved for " + fConnection.getName() , e); //$NON-NLS-1$ } if (conn != null) { fConnectionTree.refresh(); fConnectionTree.setSelection(new StructuredSelection(conn), true); } } } } } } private void onEditConnection() { setConnection(); if (fConnection != null) { IRemoteUIConnectionService ui = fConnection.getConnectionType().getService(IRemoteUIConnectionService.class); if (ui != null) { IRemoteUIConnectionWizard wiz = ui.getConnectionWizard(getShell()); wiz.setConnection(fConnection.getWorkingCopy()); IRemoteConnectionWorkingCopy result = wiz.open(); if (result != null) { try { result.save(); } catch (RemoteConnectionException e) { Activator.getDefault().logWarning("Connection configuration could not be saved for " + fConnection.getName() , e); //$NON-NLS-1$ } fConnectionTree.refresh(); } } } } @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.CANCEL_ID, "&Cancel", true); //$NON-NLS-1$ createButton(parent, IDialogConstants.OK_ID, "&Ok", true); //$NON-NLS-1$ } @Override protected void okPressed() { setConnection(); if (fConnection != null) { super.okPressed(); } } private void setConnection() { Object o = ((IStructuredSelection) fConnectionTree.getSelection()).getFirstElement(); fConnection = o instanceof IRemoteConnection ? (IRemoteConnection) o : null; } @Override public IRemoteConnection getConnection() { return fConnection; } private static String getConnectionLabel(IRemoteConnection rc) { StringBuffer label = new StringBuffer(); label.append(rc.getName()); if (rc.hasService(IRemoteConnectionHostService.class)) { IRemoteConnectionHostService service = checkNotNull(rc.getService(IRemoteConnectionHostService.class)); label.append(format(" [{0}]", service.getHostname())); //$NON-NLS-1$ } return label.toString(); } }