/******************************************************************************* * Copyright (c) 2000, 2010 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 API and implementation * JBoss by Red Hat *******************************************************************************/ package org.jboss.tools.common.jdt.debug.ui.launching.xpl; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; import org.eclipse.jdt.internal.debug.ui.launcher.AbstractJavaMainTab; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IVMConnector; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; 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.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PreferencesUtil; import org.jboss.tools.common.jdt.debug.IPropertyKeys; import org.jboss.tools.common.jdt.debug.RemoteDebugActivator; import org.jboss.tools.common.jdt.debug.VmModel; import org.jboss.tools.common.jdt.debug.ui.Messages; import org.jboss.tools.common.jdt.debug.ui.RemoteDebugUIActivator; import org.jboss.tools.common.jdt.debug.ui.preferences.RemoteDebug; /** * A launch configuration tab that displays and edits the project associated * with a remote connection and the connector used to connect to a remote * VM. * <p> * This class may be instantiated. * </p> * @since 2.0 * @noextend This class is not intended to be subclassed by clients. */ public class JavaConnectTab extends AbstractJavaMainTab { private static final String HOST_NAMES = "hostNames"; //$NON-NLS-1$ private static final String DEFAULT_HOST = "defaultHost"; //$NON-NLS-1$ // UI widgets private Button fAllowTerminateButton; private Composite fArgumentComposite; private IVMConnector fConnector; private Combo hostCombo; private Combo portCombo; private String[] items; private VmModel[] models; private Button defaultButton; private Group messageGroup; private void updateConnector() { getSelectedConnector(); IDialogSettings dialogSettings = RemoteDebugUIActivator.getDefault().getDialogSettings(); String names = dialogSettings.get(HOST_NAMES); String[] hostNames; if (names == null) { names = RemoteDebugActivator.LOCALHOST; dialogSettings.put(HOST_NAMES, names); hostNames = new String[] {names}; } else { StringTokenizer tokenizer = new StringTokenizer(names, ","); //$NON-NLS-1$ Set<String> hostSets = new HashSet<String>(); hostSets.add(RemoteDebugActivator.LOCALHOST); while (tokenizer.hasMoreTokens()) { hostSets.add(tokenizer.nextToken()); } hostNames = hostSets.toArray(new String[0]); } // create editors // host Composite hostComposite = new Composite(fArgumentComposite, SWT.NONE); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd.horizontalSpan = 2; hostComposite.setLayoutData(gd); hostComposite.setLayout(new GridLayout(2, false)); Label hostLabel = new Label(hostComposite, SWT.NONE); gd = new GridData(SWT.FILL, SWT.FILL, false, false); hostLabel.setLayoutData(gd); hostLabel.setText(Messages.JavaConnectTab_Host); // FIXME hostCombo = new Combo(hostComposite, SWT.READ_ONLY); gd = new GridData(SWT.FILL, SWT.FILL, true, false); hostCombo.setLayoutData(gd); hostCombo.setItems(hostNames); String defaultHost = dialogSettings.get(DEFAULT_HOST); if (defaultHost == null) { defaultHost = RemoteDebugActivator.LOCALHOST; dialogSettings.put(DEFAULT_HOST, defaultHost); } hostCombo.setText(defaultHost); hostCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { updateLaunchConfigurationDialog(); } }); // port Composite portComposite = new Composite(fArgumentComposite, SWT.NONE); gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd.horizontalSpan = 2; portComposite.setLayoutData(gd); portComposite.setLayout(new GridLayout(3, false)); Label portLabel = new Label(portComposite, SWT.NONE); gd = new GridData(SWT.FILL, SWT.FILL, false, false); portLabel.setLayoutData(gd); portLabel.setText(Messages.JavaConnectTab_Port); // FIXME portCombo = new Combo(portComposite, SWT.READ_ONLY); gd = new GridData(SWT.FILL, SWT.FILL, true, false); portCombo.setLayoutData(gd); refresh(defaultHost, false); portCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { updateLaunchConfigurationDialog(); } }); Button refreshButton = new Button(portComposite, SWT.PUSH); gd = new GridData(SWT.FILL, SWT.FILL, false, false); refreshButton.setLayoutData(gd); refreshButton.setText(Messages.JavaConnectTab_Refresh); refreshButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { refresh(hostCombo.getText(), true); updateLaunchConfigurationDialog(); } }); updateLaunchConfigurationDialog(); } private void refresh(String defaultHost, boolean discover) { if (!discover) { boolean oldDiscoverPreferences = RemoteDebugUIActivator.getDefault().isDiscoverRemoteApplication(); RemoteDebugUIActivator.getDefault().getPreferences().putBoolean(RemoteDebugUIActivator.DISCOVER_REMOTE_APPLICATION, false); models = RemoteDebugUIActivator.getDefault().getDebugModels(new NullProgressMonitor()); RemoteDebugUIActivator.getDefault().getPreferences().putBoolean(RemoteDebugUIActivator.DISCOVER_REMOTE_APPLICATION, oldDiscoverPreferences); } else { RemoteDebugUIActivator.getDefault() .discoverRemoteApplication(new NullProgressMonitor()); models = RemoteDebugUIActivator.getDefault().getDebugModels(new NullProgressMonitor()); } refreshCombo(); } private void refreshCombo() { items = new String[models.length]; int i = 0; for (VmModel model:models) { List<RemoteDebug> remoteDebugs = RemoteDebugUIActivator.getDefault() .getValidRemoteDebugs(); RemoteDebug remoteDebug = RemoteDebugUIActivator.findRemoteDebug(remoteDebugs, model.getPort()); String displayText; if (remoteDebug != null) { if (remoteDebug.isShow()) { StringBuffer buffer = new StringBuffer(); if (remoteDebug.getDescription() != null && !remoteDebug.getDescription().isEmpty()) { if (buffer.length() > 0) { buffer.append(","); //$NON-NLS-1$ } buffer.append(remoteDebug.getDescription()); } String text = model.getMainClass(); if (text != null && !RemoteDebugActivator.UNKNOWN.equals(text)) { if (buffer.length() > 0) { buffer.append(",main="); //$NON-NLS-1$ } buffer.append(text); } String pid = model.getPid(); if (pid != null) { if (buffer.length() > 0) { buffer.append(",pid="); //$NON-NLS-1$ } buffer.append(pid); } String port = model.getPort(); if (port != null) { if (buffer.length() > 0) { buffer.append(",port="); //$NON-NLS-1$ } buffer.append(port); } displayText = buffer.toString(); } else { displayText = model.getDisplayName(); } } else { displayText = model.getDisplayName(); } items[i++] = displayText; } Display.getDefault().syncExec(new Runnable() { @Override public void run() { portCombo.setItems(items); if (items.length > 0) { portCombo.select(0); portCombo.setText(items[0]); } } }); } /* (non-Javadoc) * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { Font font = parent.getFont(); Composite comp = SWTFactory.createComposite(parent, font, 1, 1, GridData.FILL_BOTH); GridLayout layout = new GridLayout(); layout.verticalSpacing = 0; comp.setLayout(layout); createProjectEditor(comp); createVerticalSpacer(comp, 1); //connection properties Group group = SWTFactory.createGroup(comp, Messages.JavaConnectTab_Connection_Properties_1, 2, 1, GridData.FILL_HORIZONTAL); Composite cgroup = SWTFactory.createComposite(group, font, 2, 1, GridData.FILL_HORIZONTAL); fArgumentComposite = cgroup; updateConnector(); createVerticalSpacer(comp, 2); fAllowTerminateButton = createCheckButton(comp, Messages.JavaConnectTab__Allow_termination_of_remote_VM_6); fAllowTerminateButton.addSelectionListener(getDefaultListener()); createVerticalSpacer(comp, 2); defaultButton = createCheckButton(comp, Messages.JavaConnectTab_SetAsDefault); defaultButton.addSelectionListener(getDefaultListener()); createVerticalSpacer(comp, 2); messageGroup = new Group(comp, SWT.NONE); messageGroup.setText(Messages.JavaConnectTab_Warning); messageGroup.setLayout(new GridLayout(3, false)); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false); messageGroup.setLayoutData(gd); Label noteLabel = new Label(messageGroup,SWT.NONE); gd=new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false); noteLabel.setLayoutData(gd); Image image = JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING); image.setBackground(noteLabel.getBackground()); noteLabel.setImage(image); Text noteText = new Text(messageGroup, SWT.WRAP | SWT.READ_ONLY); gd = new GridData(SWT.FILL, SWT.FILL, true, false); GC gc = new GC(parent); gd.heightHint = Dialog.convertHeightInCharsToPixels(gc .getFontMetrics(), 3); gc.dispose(); noteText.setLayoutData(gd); noteText.setText(Messages.JavaConnectTab_JDK_Required); messageGroup.setVisible(!RemoteDebugActivator.getDefault().isJdk()); Button addJDK = new Button(messageGroup, SWT.PUSH); addJDK.setText(Messages.JavaConnectTab_Add_JDK); gd=new GridData(SWT.BEGINNING, SWT.CENTER, false, false); addJDK.setLayoutData(gd); addJDK.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String preferenceId = "org.eclipse.jdt.debug.ui.preferences.VMPreferencePage"; //$NON-NLS-1$ PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(getShell(),preferenceId, null, null); dialog.open(); refresh(hostCombo.getText(), false); updateLaunchConfigurationDialog(); messageGroup.setVisible(!RemoteDebugActivator.getDefault().isJdk()); } }); setControl(comp); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_CONNECT_TAB); } /* (non-Javadoc) * @see org.eclipse.jdt.internal.debug.ui.launcher.AbstractJavaMainTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) */ public void initializeFrom(ILaunchConfiguration config) { super.initializeFrom(config); updateAllowTerminateFromConfig(config); updateSetAsDefaultFromConfig(config); } private void updateSetAsDefaultFromConfig(ILaunchConfiguration config) { ILaunchConfiguration[] configs = RemoteDebugActivator.getDefault().getLaunchConfigurations(); if (configs != null && configs.length == 1) { if (config instanceof ILaunchConfigurationWorkingCopy) { ILaunchConfigurationWorkingCopy wc = (ILaunchConfigurationWorkingCopy) config; try { boolean isDefault = config.getAttribute(IPropertyKeys.SET_AS_DEFAULT, false); if (!isDefault) { wc.setAttribute(IPropertyKeys.SET_AS_DEFAULT, true); wc.doSave(); } } catch (CoreException e) { // ignore } } } boolean isDefault = false; try { isDefault = config.getAttribute(IPropertyKeys.SET_AS_DEFAULT, false); } catch (CoreException ce) { JDIDebugUIPlugin.log(ce); } defaultButton.setSelection(isDefault); } /** * Updates the state of the allow terminate check button from the specified configuration * @param config the config to load from */ private void updateAllowTerminateFromConfig(ILaunchConfiguration config) { boolean allowTerminate = false; try { allowTerminate = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, false); } catch (CoreException ce) {JDIDebugUIPlugin.log(ce);} fAllowTerminateButton.setSelection(allowTerminate); } /* (non-Javadoc) * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ public void performApply(ILaunchConfigurationWorkingCopy config) { config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, fProjText.getText().trim()); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, fAllowTerminateButton.getSelection()); config.setAttribute(IPropertyKeys.SET_AS_DEFAULT, defaultButton.getSelection()); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, getSelectedConnector().getIdentifier()); mapResources(config); Map attrMap = new HashMap(2); attrMap.put("hostname", hostCombo.getText()); //$NON-NLS-1$ String port = getPort(); if (port != null) { attrMap.put("port", port); //$NON-NLS-1$ } else { attrMap.put("port", ""); //$NON-NLS-1$ //$NON-NLS-2$ } config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, attrMap); if (defaultButton.getSelection()) { ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); ILaunchConfigurationType type = manager.getLaunchConfigurationType(RemoteDebugActivator.LAUNCH_CONFIGURATION_ID); ILaunchConfiguration[] configs = null; try { configs = manager.getLaunchConfigurations(type); } catch (CoreException e) { return; } for (ILaunchConfiguration configuration:configs) { try { boolean isDefault = configuration.getAttribute(IPropertyKeys.SET_AS_DEFAULT, false); if (isDefault && !config.getName().equals(configuration.getName())) { ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy(); wc.setAttribute(IPropertyKeys.SET_AS_DEFAULT, false); wc.doSave(); } } catch (CoreException e) { RemoteDebugUIActivator.log(e); } } } } private String getPort() { int portIndex = portCombo.getSelectionIndex(); String port = null; if (models != null && models.length > portIndex && portIndex >= 0) { port = models[portIndex].getPort(); } return port; } /** * Initialize default settings for the given Java element */ private void initializeDefaults(IJavaElement javaElement, ILaunchConfigurationWorkingCopy config) { initializeJavaProject(javaElement, config); //initializeName(javaElement, config); initializeHardCodedDefaults(config); } /* (non-Javadoc) * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) */ public void setDefaults(ILaunchConfigurationWorkingCopy config) { IJavaElement javaElement = getContext(); if (javaElement == null) { initializeHardCodedDefaults(config); } else { initializeDefaults(javaElement, config); } } /** * Find the first instance of a type, compilation unit, class file or project in the * specified element's parental hierarchy, and use this as the default name. */ private void initializeName(IJavaElement javaElement, ILaunchConfigurationWorkingCopy config) { String name = EMPTY_STRING; try { IResource resource = javaElement.getUnderlyingResource(); if (resource != null) { name = resource.getName(); int index = name.lastIndexOf('.'); if (index > 0) { name = name.substring(0, index); } } else { name= javaElement.getElementName(); } name = getLaunchConfigurationDialog().generateName(name); } catch (JavaModelException jme) {JDIDebugUIPlugin.log(jme);} config.rename(name); } /** * Initialize those attributes whose default values are independent of any context. */ private void initializeHardCodedDefaults(ILaunchConfigurationWorkingCopy config) { config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, false); config.setAttribute(IPropertyKeys.SET_AS_DEFAULT, false); config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, getSelectedConnector().getIdentifier()); } /* (non-Javadoc) * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration) */ public boolean isValid(ILaunchConfiguration config) { setErrorMessage(null); setMessage(null); String name = fProjText.getText().trim(); if (name.length() > 0) { if (!ResourcesPlugin.getWorkspace().getRoot().getProject(name).exists()) { setErrorMessage(Messages.JavaConnectTab_Project_does_not_exist_14); return false; } } if (hostCombo.getText().isEmpty()) { setErrorMessage(Messages.JavaConnectTab_Invalid_Host); return false; } String port = getPort(); if (port == null || port.isEmpty()) { setErrorMessage(Messages.JavaConnectTab_Invalid_Port); return false; } try { new Integer(port); } catch (NumberFormatException e) { setErrorMessage(Messages.JavaConnectTab_Invalid_Port); return false; } return true; } /* (non-Javadoc) * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() */ public String getName() { return Messages.JavaConnectTab_Conn_ect_20; } /* (non-Javadoc) * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getImage() */ public Image getImage() { return DebugUITools.getImage(IDebugUIConstants.IMG_LCL_DISCONNECT); } /** * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId() * * @since 3.3 */ public String getId() { return "org.jboss.tools.common.jdt.debug.ui.javaConnectTab"; //$NON-NLS-1$ } /** * Returns the selected connector */ private IVMConnector getSelectedConnector() { if (fConnector == null) { fConnector = RemoteDebugActivator.getDefaultVMConnector(); } return fConnector; } }