package bndtools.launch.ui;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.bndtools.api.BndtoolsConstants;
import org.bndtools.api.ILogger;
import org.bndtools.api.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
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.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import aQute.bnd.build.Project;
import aQute.bnd.build.Workspace;
import bndtools.Plugin;
import bndtools.central.Central;
import bndtools.launch.LaunchConstants;
import bndtools.utils.FileExtensionFilter;
public class ProjectLaunchTabPiece extends AbstractLaunchTabPiece {
private static final ILogger logger = Logger.getLogger(ProjectLaunchTabPiece.class);
private static final String PROP_LAUNCH_TARGET = "targetName";
private static final String PROP_ENABLE_TRACE = "enableTrace";
// Model State
private String targetName = null;
private boolean enableTrace = false;
// View
private Text launchTargetTxt;
private Button enableTraceBtn;
@SuppressWarnings("unused")
public Control createControl(Composite parent) {
Group projectGroup = new Group(parent, SWT.NONE);
projectGroup.setText("Launch:");
launchTargetTxt = new Text(projectGroup, SWT.BORDER);
Button projectNameBrowseBtn = new Button(projectGroup, SWT.PUSH);
projectNameBrowseBtn.setText("Browse Projects");
new Label(projectGroup, SWT.NONE); // Spacer
Button bndrunBrowseBtn = new Button(projectGroup, SWT.PUSH);
bndrunBrowseBtn.setText("Browse Run Files");
enableTraceBtn = new Button(projectGroup, SWT.CHECK);
enableTraceBtn.setText("Enable launcher tracing.");
// LISTENERS
projectNameBrowseBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
doBrowseProject();
}
});
bndrunBrowseBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
doBrowseBndrun();
}
});
launchTargetTxt.addListener(SWT.Modify, new Listener() {
public void handleEvent(Event event) {
String oldName = targetName;
targetName = launchTargetTxt.getText();
setDirty(true);
firePropertyChange(PROP_LAUNCH_TARGET, oldName, targetName);
}
});
enableTraceBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean oldValue = enableTrace;
enableTrace = enableTraceBtn.getSelection();
setDirty(true);
firePropertyChange(PROP_ENABLE_TRACE, oldValue, enableTrace);
}
});
// LAYOUT
GridLayout layout = new GridLayout(2, false);
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
projectGroup.setLayout(layout);
launchTargetTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
projectNameBrowseBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
bndrunBrowseBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
return projectGroup;
}
void doBrowseProject() {
ElementListSelectionDialog dialog = new ElementListSelectionDialog(launchTargetTxt.getShell(), new WorkbenchLabelProvider());
dialog.setTitle("Project Selection");
dialog.setMessage("Select a project to constrain your search.");
List<IProject> projects = loadProjects();
dialog.setElements(projects.toArray(new IProject[projects.size()]));
if (Window.OK == dialog.open()) {
IProject selected = (IProject) dialog.getFirstResult();
launchTargetTxt.setText(selected.getName());
}
}
void doBrowseBndrun() {
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(launchTargetTxt.getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
dialog.setValidator(new ISelectionStatusValidator() {
public IStatus validate(Object[] selection) {
if (selection.length > 0 && selection[0] instanceof IFile) {
return new Status(IStatus.OK, Plugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
}
return new Status(IStatus.ERROR, Plugin.PLUGIN_ID, IStatus.ERROR, "", null); //$NON-NLS-1$
}
});
dialog.setAllowMultiple(false);
dialog.setTitle("Run File Selection");
dialog.setMessage("Select the Run File to launch.");
dialog.addFilter(new FileExtensionFilter(LaunchConstants.EXT_BNDRUN));
dialog.setInput(ResourcesPlugin.getWorkspace());
if (dialog.open() == Window.OK) {
Object[] files = dialog.getResult();
if (files != null && files.length == 1) {
IPath path = ((IResource) files[0]).getFullPath().makeRelative();
launchTargetTxt.setText(path.toString());
} else {
launchTargetTxt.setText("");
}
}
}
static List<IProject> loadProjects() {
Collection<Project> projects;
try {
Workspace workspace = Central.getWorkspace();
projects = workspace.getAllProjects();
} catch (Exception e) {
logger.logError("Internal error querying projects.", e);
return Collections.emptyList();
}
List<IProject> result = new ArrayList<IProject>(projects.size());
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
for (Project project : projects) {
IProject iproject = workspaceRoot.getProject(project.getName());
if (iproject != null && iproject.isOpen()) {
result.add(iproject);
}
}
return result;
}
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(LaunchConstants.ATTR_LAUNCH_TARGET, launchTargetTxt.getText());
IResource targetResource = ResourcesPlugin.getWorkspace().getRoot().findMember(launchTargetTxt.getText());
if (targetResource != null && targetResource.exists()) {
IProject project = targetResource.getProject();
if (project != null)
configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName());
else
configuration.removeAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME);
}
configuration.setAttribute(LaunchConstants.ATTR_TRACE, enableTrace);
configuration.removeAttribute(LaunchConstants.ATTR_LOGLEVEL);
}
public void initializeFrom(ILaunchConfiguration configuration) throws CoreException {
targetName = configuration.getAttribute(LaunchConstants.ATTR_LAUNCH_TARGET, (String) null);
if (targetName == null)
targetName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null);
if (targetName != null) {
launchTargetTxt.setText(targetName);
}
enableTrace = configuration.getAttribute(LaunchConstants.ATTR_TRACE, LaunchConstants.DEFAULT_TRACE);
enableTraceBtn.setSelection(enableTrace);
}
@Override
public String checkForError() {
if (targetName == null || targetName.length() == 0) {
return "Launch target must be specified";
}
IResource targetResource = ResourcesPlugin.getWorkspace().getRoot().findMember(targetName);
if (targetResource == null || !targetResource.exists()) {
return MessageFormat.format("Launch target {0} does not exist.", targetName);
}
if (targetResource.getType() == IResource.PROJECT) {
IProject project = (IProject) targetResource;
if (!project.isOpen()) {
return MessageFormat.format("Project {0} is closed.", targetName);
}
try {
if (!project.hasNature(BndtoolsConstants.NATURE_ID)) {
return MessageFormat.format("Project {0} is not a Bnd OSGi project.", targetName);
}
} catch (CoreException e) {
logger.logError("Error checking for Bnd OSGi project nature", e);
return "Error checking for Bnd OSGi project nature";
}
} else if (targetResource.getType() == IResource.FILE) {
if (!targetResource.getName().endsWith(LaunchConstants.EXT_BNDRUN)) {
return MessageFormat.format("Selected file {0} is not a .bndrun file.", targetName);
}
}
return null;
}
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
configuration.setAttribute(LaunchConstants.ATTR_TRACE, LaunchConstants.DEFAULT_TRACE);
}
}