/******************************************************************************* * 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.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; 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.ui.ILaunchShortcut; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.erlide.backend.api.ErlRuntimeAttributes; import org.erlide.backend.launch.IErlangLaunchDelegateConstants; import org.erlide.engine.ErlangEngine; import org.erlide.engine.model.ErlModelException; import org.erlide.engine.model.IErlElement; import org.erlide.engine.model.root.IErlModule; import org.erlide.engine.model.root.IErlProject; import org.erlide.ui.editors.erl.AbstractErlangEditor; import org.erlide.util.ErlLogger; import org.erlide.util.HostnameChecker; import org.erlide.util.ListsUtils; import org.erlide.util.StringUtils; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; public class ErlangNodeLaunchShortcut implements ILaunchShortcut { private static final String CONSOLE_VIEW_ID = "org.eclipse.ui.console.ConsoleView"; public static final String PROJECT_NAME_SEPARATOR = ";"; @Override public void launch(final ISelection selection, final String mode) { ErlLogger.debug("** Launch:: " + selection.toString()); if (selection.isEmpty()) { return; } if (!(selection instanceof IStructuredSelection)) { return; } final Set<IErlProject> projects = Sets.newHashSet(); final IStructuredSelection structuredSelection = (IStructuredSelection) selection; for (final Object element : structuredSelection.toArray()) { if (!(element instanceof IResource)) { return; } final IErlElement erlElement = ErlangEngine.getInstance().getModel() .findElement((IResource) element); final IErlProject project = ErlangEngine.getInstance().getModelUtilService() .getProject(erlElement); if (project != null) { projects.add(project); } } if (projects.isEmpty()) { return; } projects.addAll(getDependentProjects(projects)); final List<IErlProject> projectList = Lists.newArrayList(projects); Collections.sort(projectList, new Comparator<IErlProject>() { @Override public int compare(final IErlProject o1, final IErlProject o2) { return o1.getName().compareTo(o2.getName()); } }); try { doLaunch(mode, projectList); } catch (final CoreException e) { final IWorkbench workbench = PlatformUI.getWorkbench(); final Shell shell = workbench.getActiveWorkbenchWindow().getShell(); MessageDialog.openError(shell, "Error", e.getStatus().getMessage()); } } private Collection<IErlProject> getDependentProjects( final Set<IErlProject> projects) { final Set<IErlProject> depProjects = Sets.newHashSet(); for (final IErlProject project : projects) { try { depProjects.addAll(project.getReferencedProjects()); } catch (final ErlModelException e) { } } return depProjects; } @Override public void launch(final IEditorPart editor, final String mode) { ErlLogger.debug("** Launch :: " + editor.getTitle()); if (editor instanceof AbstractErlangEditor) { final AbstractErlangEditor erlangEditor = (AbstractErlangEditor) editor; final IErlProject project = erlangEditor.getProject(); if (project != null) { try { doLaunch(mode, Lists.newArrayList(project)); } catch (final CoreException e) { final IWorkbench workbench = PlatformUI.getWorkbench(); final Shell shell = workbench.getActiveWorkbenchWindow().getShell(); MessageDialog.openError(shell, "Error", e.getStatus().getMessage()); } } } } private void doLaunch(final String mode, final Collection<IErlProject> projects) throws CoreException { final ILaunchConfiguration launchConfiguration = getLaunchConfiguration(projects, mode); bringConsoleViewToFront(); launchConfiguration.launch(mode, null); } private void bringConsoleViewToFront() throws PartInitException { final IWorkbenchPage activePage = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); activePage.showView(CONSOLE_VIEW_ID); } private ILaunchConfiguration getLaunchConfiguration( final Collection<IErlProject> projects, final String mode) throws CoreException { final ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); final List<String> projectNames = getProjectNames(projects); String name = ListsUtils.packList(projectNames, "_"); if (name.length() > 15) { name = ListsUtils.packList(StringUtils.removeCommonPrefixes(projectNames), "_"); } // try and find one final ILaunchConfiguration[] launchConfigurations = launchManager .getLaunchConfigurations(); for (final ILaunchConfiguration launchConfiguration : launchConfigurations) { if (launchConfiguration.getName().equals(name)) { if (mode.equals(ILaunchManager.DEBUG_MODE)) { return addInterpretedModules(projects, launchConfiguration); } return launchConfiguration; } } // try and make one final ILaunchConfigurationType launchConfigurationType = launchManager .getLaunchConfigurationType( IErlangLaunchDelegateConstants.CONFIGURATION_TYPE); ILaunchConfigurationWorkingCopy wc = null; wc = launchConfigurationType.newInstance(null, name); wc.setAttribute(ErlRuntimeAttributes.PROJECTS, ListsUtils.packList(projectNames, PROJECT_NAME_SEPARATOR)); wc.setAttribute(ErlRuntimeAttributes.RUNTIME_NAME, projects.iterator().next().getRuntimeInfo().getName()); wc.setAttribute(ErlRuntimeAttributes.NODE_NAME, name); wc.setAttribute(ErlRuntimeAttributes.USE_LONG_NAME, !HostnameChecker.getInstance().canUseShortNames()); // prefer short names wc.setAttribute(ErlRuntimeAttributes.CONSOLE, true); wc.setAttribute(ErlRuntimeAttributes.INTERNAL, false); wc.setAttribute(ErlRuntimeAttributes.LOAD_ALL_NODES, false); wc.setAttribute(ErlRuntimeAttributes.COOKIE, "erlide"); final Map<String, String> map = Maps.newHashMap(); wc.setAttribute("org.eclipse.debug.core.environmentVariables", map); if ("debug".equals(mode)) { final List<String> moduleNames = getProjectAndModuleNames(projects); wc.setAttribute(ErlRuntimeAttributes.DEBUG_INTERPRET_MODULES, moduleNames); } wc.setMappedResources(getProjectResources(projects)); return wc.doSave(); } private IResource[] getProjectResources(final Collection<IErlProject> projects) { final List<IResource> result = Lists.newArrayListWithCapacity(projects.size()); for (final IErlProject project : projects) { result.add(project.getResource()); } return result.toArray(new IResource[result.size()]); } private List<String> getProjectNames(final Collection<IErlProject> projects) { final List<String> result = Lists.newArrayListWithCapacity(projects.size()); for (final IErlProject project : projects) { String name = project.getName(); if (name.startsWith("org.erlide.")) { name = name.substring("org.erlide.".length()); } result.add(name.replaceAll("\\.", "")); } return result; } private List<String> getProjectAndModuleNames(final Collection<IErlProject> projects) throws ErlModelException { final List<String> moduleNames = Lists.newArrayList(); for (final IErlProject project : projects) { final Collection<IErlModule> modules = project.getModules(); final String projectNameColon = project.getName() + ":"; for (final IErlModule module : modules) { moduleNames.add(projectNameColon + module.getName()); } } return moduleNames; } private ILaunchConfiguration addInterpretedModules( final Collection<IErlProject> projects, final ILaunchConfiguration launchConfiguration) throws CoreException { final List<String> moduleNames = getProjectAndModuleNames(projects); final ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy(); wc.setAttribute(ErlRuntimeAttributes.DEBUG_INTERPRET_MODULES, moduleNames); return wc.doSave(); } }