/*******************************************************************************
* Copyright (c) 2005 Vlad Dumitrescu 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: Vlad Dumitrescu
*******************************************************************************/
package org.erlide.ui.launch;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
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.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.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import org.erlide.backend.BackendCore;
import org.erlide.backend.api.ErlRuntimeAttributes;
import org.erlide.runtime.api.RuntimeData;
import org.erlide.runtime.runtimeinfo.RuntimeInfo;
import org.erlide.util.HostnameChecker;
import org.erlide.util.NodeHostClassifier;
import org.erlide.util.NodeHostClassifier.HostnameType;
import org.erlide.util.NodeHostClassifier.NodeType;
public class RuntimeTab extends AbstractLaunchConfigurationTab {
private Button shortNameButton;
private Button longNameButton;
private Text argsText;
private Text workingDirText;
private Combo runtimesCombo;
private Button startNodeCheckbox;
private Text cookieText;
private Text nameText;
private Button distributedLoadCheck;
private Collection<RuntimeInfo> runtimes;
private Label nodeHostLabel;
private Label lblHoverMouseOver;
/**
* @wbp.parser.entryPoint
*/
@Override
public void createControl(final Composite parent) {
runtimes = BackendCore.getRuntimeInfoCatalog().getRuntimes();
final Composite comp = new Composite(parent, SWT.NONE);
setControl(comp);
final GridLayout topLayout = new GridLayout();
topLayout.numColumns = 3;
comp.setLayout(topLayout);
final Label runtimeLabel = new Label(comp, SWT.NONE);
runtimeLabel.setText("Runtime");
final List<String> rtl = new ArrayList<>();
for (final RuntimeInfo r : runtimes) {
rtl.add(r.getName());
}
final String[] rts = rtl.toArray(new String[] {});
final RuntimeInfo defaultRuntime = BackendCore.getRuntimeInfoCatalog()
.getDefaultRuntime();
final int db = defaultRuntime == null ? 0
: Arrays.binarySearch(rts, defaultRuntime.getName());
runtimesCombo = new Combo(comp, SWT.READ_ONLY);
final GridData gd_runtimesCombo = new GridData(174, SWT.DEFAULT);
gd_runtimesCombo.horizontalAlignment = SWT.FILL;
runtimesCombo.setLayoutData(gd_runtimesCombo);
runtimesCombo.addSelectionListener(new SelectionAdapter() {
@SuppressWarnings("synthetic-access")
@Override
public void widgetSelected(final SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
runtimesCombo.setItems(rts);
runtimesCombo.select(db);
new Label(comp, SWT.NONE);
new Label(comp, SWT.NONE);
lblHoverMouseOver = new Label(comp, SWT.NONE);
lblHoverMouseOver
.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblHoverMouseOver.setAlignment(SWT.RIGHT);
lblHoverMouseOver.setFont(SWTResourceManager.getFont("Segoe UI", 7, SWT.NORMAL));
lblHoverMouseOver.setText("hover mouse over fields for more info");
new Label(comp, SWT.NONE);
final Label nodeNameLabel = new Label(comp, SWT.NONE);
nodeNameLabel.setText("Node name");
nameText = new Text(comp, SWT.BORDER);
nameText.setToolTipText(
"Enter a node name without host for a local node.\r\n\r\nEnter a node name with host to override the local names or to connect to a remote node.\r\n");
final GridData gd_nameText = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1,
1);
gd_nameText.widthHint = 241;
nameText.setLayoutData(gd_nameText);
nameText.addModifyListener(new ModifyListener() {
@Override
@SuppressWarnings("synthetic-access")
public void modifyText(final ModifyEvent e) {
updateLaunchConfigurationDialog();
}
});
nodeHostLabel = new Label(comp, SWT.NONE);
nodeHostLabel.setText("@");
new Label(comp, SWT.NONE);
longNameButton = new Button(comp, SWT.RADIO);
longNameButton
.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
longNameButton.addSelectionListener(new SelectionAdapter() {
@SuppressWarnings("synthetic-access")
@Override
public void widgetSelected(final SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
longNameButton.setSelection(true);
longNameButton.setText("long name (-name)");
new Label(comp, SWT.NONE);
shortNameButton = new Button(comp, SWT.RADIO);
shortNameButton
.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
shortNameButton.addSelectionListener(new SelectionAdapter() {
@SuppressWarnings("synthetic-access")
@Override
public void widgetSelected(final SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
shortNameButton.setText("short name (-sname)");
final Label cookieLabel = new Label(comp, SWT.NONE);
cookieLabel.setToolTipText("Leave empty to use default one");
cookieLabel.setText("Cookie");
cookieText = new Text(comp, SWT.BORDER);
final GridData gd_cookieText = new GridData(SWT.FILL, SWT.CENTER, false, false, 2,
1);
gd_cookieText.widthHint = 232;
cookieText.setLayoutData(gd_cookieText);
cookieText.addModifyListener(new ModifyListener() {
@Override
@SuppressWarnings("synthetic-access")
public void modifyText(final ModifyEvent e) {
updateLaunchConfigurationDialog();
}
});
cookieText.setToolTipText("Leave empty to use default one");
startNodeCheckbox = new Button(comp, SWT.CHECK);
startNodeCheckbox
.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
startNodeCheckbox.setSelection(true);
startNodeCheckbox.setText("Start the Erlang node if not running already");
startNodeCheckbox.addSelectionListener(new SelectionAdapter() {
@SuppressWarnings("synthetic-access")
@Override
public void widgetSelected(final SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
final Label workingDirectoryLabel = new Label(comp, SWT.NONE);
workingDirectoryLabel.setText("Working directory");
workingDirText = new Text(comp, SWT.BORDER);
workingDirText.setToolTipText("may be relative to the workspace");
workingDirText
.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
workingDirText.addModifyListener(new ModifyListener() {
@Override
@SuppressWarnings("synthetic-access")
public void modifyText(final ModifyEvent e) {
updateLaunchConfigurationDialog();
}
});
final Label extraArgumentsLabel = new Label(comp, SWT.NONE);
extraArgumentsLabel
.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
extraArgumentsLabel.setText("Extra arguments");
argsText = new Text(comp, SWT.BORDER | SWT.MULTI);
argsText.setToolTipText(
"as on the command line\nBe careful about proper quoting!");
final GridData gd_argsText = new GridData(SWT.FILL, SWT.CENTER, true, false, 2,
1);
gd_argsText.heightHint = 35;
argsText.setLayoutData(gd_argsText);
argsText.addModifyListener(new ModifyListener() {
@Override
@SuppressWarnings("synthetic-access")
public void modifyText(final ModifyEvent e) {
updateLaunchConfigurationDialog();
}
});
new Label(comp, SWT.NONE);
final Label extraArgumentsLabel2 = new Label(comp, SWT.NONE);
extraArgumentsLabel2.setText("(overrides runtime settings)");
extraArgumentsLabel2
.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
distributedLoadCheck = new Button(comp, SWT.CHECK);
distributedLoadCheck.setText("Load project code on all connected nodes");
distributedLoadCheck
.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
new Label(comp, SWT.NONE);
distributedLoadCheck.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(final SelectionEvent e) {
updateLaunchConfigurationDialog();
}
@Override
public void widgetSelected(final SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
updateLaunchConfigurationDialog();
}
@Override
public void setDefaults(final ILaunchConfigurationWorkingCopy config) {
config.setAttribute(ErlRuntimeAttributes.START_ME, true);
config.setAttribute(ErlRuntimeAttributes.RUNTIME_NAME,
ErlRuntimeAttributes.DEFAULT_RUNTIME_NAME);
config.setAttribute(ErlRuntimeAttributes.NODE_NAME, "");
config.setAttribute(ErlRuntimeAttributes.COOKIE, "");
config.setAttribute(ErlRuntimeAttributes.WORKING_DIR,
ErlRuntimeAttributes.DEFAULT_WORKING_DIR);
config.setAttribute(ErlRuntimeAttributes.EXTRA_ARGS, "");
config.setAttribute(ErlRuntimeAttributes.LOAD_ALL_NODES, false);
}
@Override
public void initializeFrom(final ILaunchConfiguration config) {
try {
final String runtimeName = config
.getAttribute(ErlRuntimeAttributes.RUNTIME_NAME, "");
runtimesCombo.select(runtimesCombo.indexOf(runtimeName));
} catch (final CoreException e) {
runtimesCombo.setText("");
}
try {
final String node = config.getAttribute(ErlRuntimeAttributes.NODE_NAME, "");
nameText.setText(node);
} catch (final CoreException e) {
nameText.setText("");
}
try {
final boolean longName = config
.getAttribute(ErlRuntimeAttributes.USE_LONG_NAME, true);
longNameButton.setSelection(longName);
shortNameButton.setSelection(!longName);
} catch (final CoreException e) {
nameText.setText("");
}
try {
final String cookie = config.getAttribute(ErlRuntimeAttributes.COOKIE, "");
cookieText.setText(cookie);
} catch (final CoreException e) {
cookieText.setText("");
}
try {
final boolean startMe = config.getAttribute(ErlRuntimeAttributes.START_ME,
true);
startNodeCheckbox.setSelection(startMe);
} catch (final CoreException e) {
startNodeCheckbox.setSelection(false);
}
try {
final String wdir = config.getAttribute(ErlRuntimeAttributes.WORKING_DIR,
ErlRuntimeAttributes.DEFAULT_WORKING_DIR);
workingDirText.setText(wdir);
} catch (final CoreException e) {
workingDirText.setText(ErlRuntimeAttributes.DEFAULT_WORKING_DIR);
}
try {
final String xtra = config.getAttribute(ErlRuntimeAttributes.EXTRA_ARGS, "");
argsText.setText(xtra);
} catch (final CoreException e) {
argsText.setText("");
}
try {
final boolean loadAll = config
.getAttribute(ErlRuntimeAttributes.LOAD_ALL_NODES, false);
distributedLoadCheck.setSelection(loadAll);
} catch (final CoreException e) {
distributedLoadCheck.setSelection(true);
}
}
@Override
public void performApply(final ILaunchConfigurationWorkingCopy config) {
config.setAttribute(ErlRuntimeAttributes.RUNTIME_NAME, runtimesCombo.getText());
config.setAttribute(ErlRuntimeAttributes.START_ME,
startNodeCheckbox.getSelection());
config.setAttribute(ErlRuntimeAttributes.NODE_NAME, nameText.getText().trim());
config.setAttribute(ErlRuntimeAttributes.USE_LONG_NAME,
longNameButton.getSelection());
config.setAttribute(ErlRuntimeAttributes.COOKIE, cookieText.getText().trim());
config.setAttribute(ErlRuntimeAttributes.WORKING_DIR, workingDirText.getText());
config.setAttribute(ErlRuntimeAttributes.EXTRA_ARGS, argsText.getText().trim());
config.setAttribute(ErlRuntimeAttributes.LOAD_ALL_NODES,
distributedLoadCheck.getSelection());
}
@Override
public String getName() {
return "Runtime";
}
@Override
public boolean isValid(final ILaunchConfiguration config) {
setErrorMessage(null);
final String name = nameText.getText().trim();
if (!"".equals(name) && !RuntimeData.validateNodeName(name)) {
setErrorMessage(String.format("Node name '%s' is invalid.", name));
return false;
}
String workingDir = workingDirText.getText();
if (workingDir.equals(".")) {
workingDir = "";
}
final File d = new File(workingDir);
if (!d.isAbsolute()) {
final String wspace = ResourcesPlugin.getWorkspace().getRoot().getLocation()
.toPortableString();
workingDir = wspace + "/" + workingDir;
workingDirText.setText(workingDir);
}
if (!d.exists()) {
setErrorMessage(String.format("Working dir '%s' doesn't exist.", workingDir));
return false;
}
return true;
}
@Override
protected void updateLaunchConfigurationDialog() {
updateDialogStatus();
super.updateLaunchConfigurationDialog();
}
private void updateDialogStatus() {
setMessage(null);
final NodeHostClassifier state = new NodeHostClassifier(
nameText.getText().trim());
longNameButton.setEnabled(!(state.mode == NodeType.LOCAL_STANDALONE)
&& state.host == HostnameType.NONE
&& HostnameChecker.getInstance().canUseLongNames());
shortNameButton.setEnabled(!(state.mode == NodeType.LOCAL_STANDALONE)
&& state.host == HostnameType.NONE
&& HostnameChecker.getInstance().canUseShortNames());
switch (state.host) {
case LONG:
longNameButton.setSelection(true);
shortNameButton.setSelection(false);
break;
case SHORT:
longNameButton.setSelection(false);
shortNameButton.setSelection(true);
break;
case NONE:
if (!HostnameChecker.getInstance().canUseShortNames()) {
longNameButton.setSelection(true);
shortNameButton.setSelection(false);
}
if (!HostnameChecker.getInstance().canUseLongNames()) {
longNameButton.setSelection(false);
shortNameButton.setSelection(true);
}
break;
}
final boolean isLong = longNameButton.getSelection();
if (state.host == HostnameType.NONE) {
nodeHostLabel.setText(
"@" + HostnameChecker.getInstance().getErlangHostName(isLong));
} else {
nodeHostLabel.setText("");
}
cookieText.setEnabled(!(state.mode == NodeType.LOCAL_STANDALONE));
startNodeCheckbox.setEnabled(!(state.mode == NodeType.REMOTE));
workingDirText.setEnabled(
!(state.mode == NodeType.REMOTE) && startNodeCheckbox.getSelection());
argsText.setEnabled(
!(state.mode == NodeType.REMOTE) && startNodeCheckbox.getSelection());
distributedLoadCheck.setEnabled(!(state.mode == NodeType.LOCAL_STANDALONE));
distributedLoadCheck.setSelection(true);
if (state.mode == NodeType.LOCAL_STANDALONE) {
setMessage("NOTE: The Erlang node will be started as not distributed. "
+ "Some functionality (like Eclipse debugger) won't work. "
+ "If you want a distributed node, enter a node name in the field below.");
}
}
}