/*
* Copyright 2017 Nokia Solutions and Networks
* Licensed under the Apache License, Version 2.0,
* see license.txt file for details.
*/
package org.robotframework.ide.eclipse.main.plugin.launch.local;
import static com.google.common.collect.Lists.newArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.ILaunchShortcut2;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.part.FileEditorInput;
import org.robotframework.ide.eclipse.main.plugin.model.RobotCase;
import org.robotframework.ide.eclipse.main.plugin.model.RobotCasesSection;
import org.robotframework.ide.eclipse.main.plugin.propertytester.SelectionsPropertyTester;
import org.robotframework.red.jface.dialogs.DetailedErrorDialog;
import org.robotframework.red.viewers.Selections;
public class RobotLaunchConfigurationShortcut implements ILaunchShortcut2 {
@Override
public void launch(final ISelection selection, final String mode) {
if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
if (SelectionsPropertyTester.allElementsAreFromSameProject(structuredSelection)) {
final List<IResource> resources = Selections.getAdaptableElements(structuredSelection, IResource.class);
for (final Object o : structuredSelection.toList()) {
if (o instanceof RobotCasesSection) {
resources.add(((RobotCasesSection) o).getSuiteFile().getFile());
}
}
if (!resources.isEmpty()) {
createAndLaunchConfiguration(resources, mode);
} else {
createAndLaunchConfigurationForSelectedTestCases(structuredSelection, mode);
}
} else {
DetailedErrorDialog.openErrorDialog("Cannot generate Robot Launch Configuration",
"All selected elements need to be members of only one project.");
}
}
}
private void createAndLaunchConfiguration(final List<IResource> resources, final String mode) {
try {
final ILaunchConfigurationWorkingCopy config = RobotLaunchConfiguration.prepareDefault(resources);
final ILaunchConfiguration sameConfig = RobotLaunchConfigurationFinder.findSameAs(config);
if (sameConfig != null) {
doLaunchConfiguration(sameConfig, mode);
} else {
doLaunchConfiguration(config, mode);
}
} catch (final CoreException e) {
DetailedErrorDialog.openErrorDialog("Cannot generate Robot Launch Configuration",
"RED was unable to create Robot Launch Configuration from selection.");
}
}
private void doLaunchConfiguration(final ILaunchConfiguration config, final String mode) {
final WorkspaceJob job = new WorkspaceJob("Launching Robot Tests") {
@Override
public IStatus runInWorkspace(final IProgressMonitor monitor) throws CoreException {
config.launch(mode, monitor);
return Status.OK_STATUS;
}
};
job.setUser(false);
job.schedule();
}
private void createAndLaunchConfigurationForSelectedTestCases(final IStructuredSelection selection,
final String mode) {
final Optional<Map<IResource, List<String>>> resourcesToTests = mapResourcesToTestCases(selection);
if (resourcesToTests.isPresent()) {
try {
final ILaunchConfiguration config = RobotLaunchConfiguration
.prepareForSelectedTestCases(resourcesToTests.get());
final ILaunchConfiguration sameConfig = RobotLaunchConfigurationFinder.findSameAs(config);
if (sameConfig != null) {
doLaunchConfiguration(sameConfig, mode);
} else {
doLaunchConfiguration(config, mode);
}
} catch (final CoreException e) {
DetailedErrorDialog.openErrorDialog("Cannot generate Robot Launch Configuration",
"RED was unable to create Robot Launch Configuration from selection.");
}
}
}
@Override
public ILaunchConfiguration[] getLaunchConfigurations(final ISelection selection) {
ILaunchConfiguration config = null;
if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
try {
final IStructuredSelection ss = (IStructuredSelection) selection;
if (SelectionsPropertyTester.allElementsAreFromSameProject(ss)) {
final List<IResource> resources = Selections.getAdaptableElements(ss, IResource.class);
if (!resources.isEmpty()) {
config = RobotLaunchConfigurationFinder
.getLaunchConfigurationExceptSelectedTestCases(resources);
} else {
final Optional<Map<IResource, List<String>>> resourcesToTests = mapResourcesToTestCases(ss);
if (resourcesToTests.isPresent()) {
config = RobotLaunchConfigurationFinder
.getLaunchConfigurationForSelectedTestCases(resourcesToTests.get());
new RobotLaunchConfiguration(config).updateTestCases(resourcesToTests.get());
}
}
}
} catch (final CoreException e) {
// nothing to do
}
}
return config == null ? null : new ILaunchConfiguration[] { config };
}
private static Optional<Map<IResource, List<String>>> mapResourcesToTestCases(
final IStructuredSelection selection) {
final Iterator<?> selectedElements = selection.iterator();
final Map<IResource, List<String>> resourcesToTests = new HashMap<>();
while (selectedElements.hasNext()) {
final Object o = selectedElements.next();
if (o instanceof RobotCase) {
addRobotCaseToMap(resourcesToTests, (RobotCase) o);
} else {
// There is a selection element that should not be launched with others
return Optional.empty();
}
}
return Optional.of(resourcesToTests);
}
private static void addRobotCaseToMap(final Map<IResource, List<String>> map, final RobotCase robotCase) {
final IResource res = robotCase.getSuiteFile().getFile();
if (map.containsKey(res)) {
map.get(res).add(robotCase.getName());
} else {
map.put(res, newArrayList(robotCase.getName()));
}
}
@Override
public void launch(final IEditorPart editor, final String mode) {
final IEditorInput input = editor.getEditorInput();
if (input instanceof FileEditorInput) {
final IResource file = ((FileEditorInput) input).getFile();
createAndLaunchConfiguration(newArrayList(file), mode);
}
}
@Override
public ILaunchConfiguration[] getLaunchConfigurations(final IEditorPart editorpart) {
final IEditorInput input = editorpart.getEditorInput();
if (input instanceof FileEditorInput) {
try {
final IResource file = ((FileEditorInput) input).getFile();
final ILaunchConfigurationWorkingCopy config = RobotLaunchConfiguration
.prepareDefault(newArrayList(file));
final ILaunchConfiguration sameConfig = RobotLaunchConfigurationFinder.findSameAs(config);
return new ILaunchConfiguration[] { sameConfig != null ? sameConfig : config };
} catch (final CoreException e) {
return null;
}
}
return null;
}
@Override
public IResource getLaunchableResource(final ISelection selection) {
return null;
}
@Override
public IResource getLaunchableResource(final IEditorPart editorpart) {
return null;
}
}