| /******************************************************************************* |
| * Copyright (c) 2000, 2013 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Martin Karpisek (martin.karpisek@gmail.com) - bug 229474 |
| *******************************************************************************/ |
| package org.eclipse.ant.internal.ui.launchConfigurations; |
| |
| import java.io.File; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.ant.internal.ui.AntUIImages; |
| import org.eclipse.ant.internal.ui.AntUIPlugin; |
| import org.eclipse.ant.internal.ui.AntUtil; |
| import org.eclipse.ant.internal.ui.IAntUIConstants; |
| import org.eclipse.ant.internal.ui.IAntUIHelpContextIds; |
| import org.eclipse.ant.internal.ui.model.AntElementNode; |
| import org.eclipse.ant.internal.ui.model.AntModelContentProvider; |
| import org.eclipse.ant.internal.ui.model.AntProjectNode; |
| import org.eclipse.ant.internal.ui.model.AntTargetNode; |
| import org.eclipse.ant.internal.ui.model.InternalTargetFilter; |
| import org.eclipse.ant.launching.IAntLaunchConstants; |
| import org.eclipse.core.externaltools.internal.IExternalToolConstants; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.core.variables.IStringVariableManager; |
| import org.eclipse.core.variables.VariablesPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.operation.IRunnableContext; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.CheckboxTableViewer; |
| import org.eclipse.jface.viewers.ColumnWeightData; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.ICheckStateListener; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.TableLayout; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerComparator; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| 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.events.ShellAdapter; |
| import org.eclipse.swt.events.ShellEvent; |
| import org.eclipse.swt.graphics.Font; |
| 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.Composite; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| /** |
| * Launch configuration tab which allows the user to choose the targets from an Ant buildfile that will be executed when the configuration is |
| * launched. |
| */ |
| public class AntTargetsTab extends AbstractLaunchConfigurationTab { |
| |
| private AntTargetNode fDefaultTarget = null; |
| private AntTargetNode[] fAllTargets = null; |
| private List<AntTargetNode> fOrderedTargets = null; |
| |
| private CheckboxTableViewer fTableViewer = null; |
| private Label fSelectionCountLabel = null; |
| private Text fTargetOrderText = null; |
| private Button fOrderButton = null; |
| private Button fFilterInternalTargets; |
| private InternalTargetFilter fInternalTargetFilter = null; |
| private Button fSortButton; |
| |
| private ILaunchConfiguration fLaunchConfiguration; |
| private int fSortDirection = 0; |
| private boolean fInitializing = false; |
| |
| /** |
| * Sort direction constants. |
| */ |
| public final static int SORT_NONE = 0; |
| public final static int SORT_NAME = 1; |
| public final static int SORT_NAME_REVERSE = -1; |
| public final static int SORT_DESCRIPTION = 2; |
| public final static int SORT_DESCRIPTION_REVERSE = -2; |
| |
| /** |
| * A comparator which can sort targets by name or description, in forward or reverse order. |
| */ |
| private class AntTargetsComparator extends ViewerComparator { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) |
| */ |
| @Override |
| public int compare(Viewer viewer, Object e1, Object e2) { |
| if (!(e1 instanceof AntTargetNode && e2 instanceof AntTargetNode)) { |
| return super.compare(viewer, e1, e2); |
| } |
| if (fSortDirection == SORT_NONE) { |
| return 0; |
| } |
| String string1, string2; |
| int result = 0; |
| if (fSortDirection == SORT_NAME || fSortDirection == SORT_NAME_REVERSE) { |
| string1 = ((AntTargetNode) e1).getLabel(); |
| string2 = ((AntTargetNode) e2).getLabel(); |
| } else { |
| string1 = ((AntTargetNode) e1).getTarget().getDescription(); |
| string2 = ((AntTargetNode) e2).getTarget().getDescription(); |
| } |
| if (string1 != null && string2 != null) { |
| result = getComparator().compare(string1, string2); |
| } else if (string1 == null) { |
| result = 1; |
| } else if (string2 == null) { |
| result = -1; |
| } |
| if (fSortDirection < 0) { // reverse sort |
| if (result == 0) { |
| result = -1; |
| } else { |
| result = -result; |
| } |
| } |
| return result; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) |
| */ |
| @Override |
| public void createControl(Composite parent) { |
| Font font = parent.getFont(); |
| |
| Composite comp = new Composite(parent, SWT.NONE); |
| setControl(comp); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IAntUIHelpContextIds.ANT_TARGETS_TAB); |
| GridLayout topLayout = new GridLayout(); |
| comp.setLayout(topLayout); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| comp.setLayoutData(gd); |
| comp.setFont(font); |
| |
| createTargetsTable(comp); |
| createSelectionCount(comp); |
| |
| Composite buttonComposite = new Composite(comp, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.verticalSpacing = 0; |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| buttonComposite.setLayout(layout); |
| buttonComposite.setFont(font); |
| |
| createSortTargets(buttonComposite); |
| createFilterInternalTargets(buttonComposite); |
| |
| createVerticalSpacer(comp, 1); |
| createTargetOrder(comp); |
| Dialog.applyDialogFont(parent); |
| } |
| |
| /** |
| * Creates the selection count widget |
| * |
| * @param parent |
| * the parent composite |
| */ |
| private void createSelectionCount(Composite parent) { |
| fSelectionCountLabel = new Label(parent, SWT.NONE); |
| fSelectionCountLabel.setFont(parent.getFont()); |
| fSelectionCountLabel.setText(AntLaunchConfigurationMessages.AntTargetsTab_0_out_of_0_selected_2); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| fSelectionCountLabel.setLayoutData(gd); |
| } |
| |
| /** |
| * Creates the widgets that display the target order |
| * |
| * @param parent |
| * the parent composite |
| */ |
| private void createTargetOrder(Composite parent) { |
| Font font = parent.getFont(); |
| |
| Label label = new Label(parent, SWT.NONE); |
| label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Target_execution_order__3); |
| label.setFont(font); |
| |
| Composite orderComposite = new Composite(parent, SWT.NONE); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| orderComposite.setLayoutData(gd); |
| GridLayout layout = new GridLayout(2, false); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| orderComposite.setLayout(layout); |
| orderComposite.setFont(font); |
| |
| fTargetOrderText = new Text(orderComposite, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); |
| fTargetOrderText.setFont(font); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.heightHint = 40; |
| gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; |
| fTargetOrderText.setLayoutData(gd); |
| |
| fOrderButton = createPushButton(orderComposite, AntLaunchConfigurationMessages.AntTargetsTab__Order____4, null); |
| gd = (GridData) fOrderButton.getLayoutData(); |
| gd.verticalAlignment = GridData.BEGINNING; |
| fOrderButton.setFont(font); |
| fOrderButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| handleOrderPressed(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the toggle to filter internal targets from the table |
| * |
| * @param parent |
| * the parent composite |
| */ |
| private void createFilterInternalTargets(Composite parent) { |
| fFilterInternalTargets = createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_12); |
| fFilterInternalTargets.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| handleFilterTargetsSelected(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the toggle to sort targets in the table |
| * |
| * @param parent |
| * the parent composite |
| */ |
| private void createSortTargets(Composite parent) { |
| fSortButton = createCheckButton(parent, AntLaunchConfigurationMessages.AntTargetsTab_14); |
| fSortButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| handleSortTargetsSelected(); |
| } |
| }); |
| } |
| |
| /** |
| * The filter targets button has been toggled. If it's been turned on, filter out internal targets. Else, restore internal targets to the table. |
| */ |
| private void handleFilterTargetsSelected() { |
| boolean filter = fFilterInternalTargets.getSelection(); |
| if (filter) { |
| fTableViewer.addFilter(getInternalTargetsFilter()); |
| } else { |
| fTableViewer.removeFilter(getInternalTargetsFilter()); |
| } |
| |
| // Must refresh before updating selection count because the selection |
| // count's "hidden" reporting needs the content provider to be queried |
| // first to count how many targets are hidden. |
| updateSelectionCount(); |
| if (!fInitializing) { |
| updateLaunchConfigurationDialog(); |
| } |
| } |
| |
| private ViewerFilter getInternalTargetsFilter() { |
| if (fInternalTargetFilter == null) { |
| fInternalTargetFilter = new InternalTargetFilter(); |
| } |
| return fInternalTargetFilter; |
| } |
| |
| /** |
| * The button to sort targets has been toggled. Set the tab's sorting as appropriate. |
| */ |
| private void handleSortTargetsSelected() { |
| setSort(fSortButton.getSelection() ? SORT_NAME : SORT_NONE); |
| } |
| |
| /** |
| * Sets the sorting of targets in this tab. See the sort constants defined above. |
| * |
| * @param column |
| * the column which should be sorted on |
| */ |
| private void setSort(int column) { |
| fSortDirection = column; |
| fTableViewer.refresh(); |
| if (!fInitializing) { |
| updateLaunchConfigurationDialog(); |
| } |
| } |
| |
| /** |
| * The target order button has been pressed. Prompt the user to reorder the selected targets. |
| */ |
| private void handleOrderPressed() { |
| TargetOrderDialog dialog = new TargetOrderDialog(getShell(), fOrderedTargets.toArray(new AntTargetNode[fOrderedTargets.size()])); |
| int ok = dialog.open(); |
| if (ok == Window.OK) { |
| fOrderedTargets.clear(); |
| Object[] targets = dialog.getTargets(); |
| for (int i = 0; i < targets.length; i++) { |
| fOrderedTargets.add((AntTargetNode) targets[i]); |
| updateSelectionCount(); |
| updateLaunchConfigurationDialog(); |
| } |
| } |
| } |
| |
| /** |
| * Creates the table which displays the available targets |
| * |
| * @param parent |
| * the parent composite |
| */ |
| private void createTargetsTable(Composite parent) { |
| Font font = parent.getFont(); |
| Label label = new Label(parent, SWT.NONE); |
| label.setFont(font); |
| label.setText(AntLaunchConfigurationMessages.AntTargetsTab_Check_targets_to_e_xecute__1); |
| |
| final Table table = new Table(parent, SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION); |
| |
| GridData data = new GridData(GridData.FILL_BOTH); |
| int availableRows = availableRows(parent); |
| data.heightHint = table.getItemHeight() * (availableRows / 20); |
| data.widthHint = 250; |
| table.setLayoutData(data); |
| table.setFont(font); |
| |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| |
| TableLayout tableLayout = new TableLayout(); |
| ColumnWeightData weightData = new ColumnWeightData(30, true); |
| tableLayout.addColumnData(weightData); |
| weightData = new ColumnWeightData(70, true); |
| tableLayout.addColumnData(weightData); |
| table.setLayout(tableLayout); |
| |
| final TableColumn column1 = new TableColumn(table, SWT.NULL); |
| column1.setText(AntLaunchConfigurationMessages.AntTargetsTab_Name_5); |
| |
| final TableColumn column2 = new TableColumn(table, SWT.NULL); |
| column2.setText(AntLaunchConfigurationMessages.AntTargetsTab_Description_6); |
| |
| // TableLayout only sizes columns once. If showing the targets |
| // tab as the initial tab, the dialog isn't open when the layout |
| // occurs and the column size isn't computed correctly. Need to |
| // recompute the size of the columns once all the parent controls |
| // have been created/sized. |
| // HACK Bug 139190 |
| getShell().addShellListener(new ShellAdapter() { |
| @Override |
| public void shellActivated(ShellEvent e) { |
| if (!table.isDisposed()) { |
| int tableWidth = table.getSize().x; |
| if (tableWidth > 0) { |
| int c1 = tableWidth / 3; |
| column1.setWidth(c1); |
| column2.setWidth(tableWidth - c1); |
| } |
| getShell().removeShellListener(this); |
| } |
| } |
| }); |
| |
| fTableViewer = new CheckboxTableViewer(table); |
| fTableViewer.setLabelProvider(new TargetTableLabelProvider()); |
| fTableViewer.setContentProvider(new AntModelContentProvider()); |
| fTableViewer.setComparator(new AntTargetsComparator()); |
| |
| fTableViewer.addDoubleClickListener(new IDoubleClickListener() { |
| @Override |
| public void doubleClick(DoubleClickEvent event) { |
| ISelection selection = event.getSelection(); |
| if (!selection.isEmpty() && selection instanceof IStructuredSelection) { |
| IStructuredSelection ss = (IStructuredSelection) selection; |
| Object element = ss.getFirstElement(); |
| boolean checked = !fTableViewer.getChecked(element); |
| fTableViewer.setChecked(element, checked); |
| updateOrderedTargets(element, checked); |
| } |
| } |
| }); |
| |
| fTableViewer.addCheckStateListener(new ICheckStateListener() { |
| @Override |
| public void checkStateChanged(CheckStateChangedEvent event) { |
| updateOrderedTargets(event.getElement(), event.getChecked()); |
| } |
| }); |
| |
| TableColumn[] columns = fTableViewer.getTable().getColumns(); |
| for (int i = 0; i < columns.length; i++) { |
| final int index = i; |
| columns[index].addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| if (fSortButton.getSelection()) { |
| // index 0 => sort_name (1) |
| // index 1 => sort_description (2) |
| int column = index + 1; |
| if (column == fSortDirection) { |
| column = -column; // invert the sort when the same column is selected twice in a row |
| } |
| setSort(column); |
| } |
| } |
| }); |
| } |
| } |
| |
| /** |
| * Return the number of rows available in the current display using the current font. |
| * |
| * @param parent |
| * The Composite whose Font will be queried. |
| * @return int The result of the display size divided by the font size. |
| */ |
| private int availableRows(Composite parent) { |
| |
| int fontHeight = (parent.getFont().getFontData())[0].getHeight(); |
| int displayHeight = parent.getDisplay().getClientArea().height; |
| |
| return displayHeight / fontHeight; |
| } |
| |
| /** |
| * Updates the ordered targets list in response to an element being checked or unchecked. When the element is checked, it's added to the list. |
| * When unchecked, it's removed. |
| * |
| * @param element |
| * the element in question |
| * @param checked |
| * whether the element has been checked or unchecked |
| */ |
| private void updateOrderedTargets(Object element, boolean checked) { |
| if (checked) { |
| fOrderedTargets.add((AntTargetNode) element); |
| } else { |
| fOrderedTargets.remove(element); |
| } |
| updateSelectionCount(); |
| updateLaunchConfigurationDialog(); |
| } |
| |
| /** |
| * Updates the selection count widget to display how many targets are selected (example, "1 out of 6 selected") and filtered. |
| */ |
| private void updateSelectionCount() { |
| Object[] checked = fTableViewer.getCheckedElements(); |
| String numSelected = Integer.toString(checked.length); |
| |
| int all = fAllTargets == null ? 0 : fAllTargets.length; |
| int visible = fTableViewer.getTable().getItemCount(); |
| String total = Integer.toString(visible); |
| int numHidden = all - visible; |
| if (numHidden > 0) { |
| fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab_13, new Object[] { numSelected, |
| String.valueOf(all), String.valueOf(numHidden) })); |
| } else { |
| fSelectionCountLabel.setText(MessageFormat.format(AntLaunchConfigurationMessages.AntTargetsTab__0__out_of__1__selected_7, new Object[] { |
| numSelected, total })); |
| } |
| |
| fOrderButton.setEnabled(checked.length > 1); |
| |
| StringBuffer buffer = new StringBuffer(); |
| Iterator<AntTargetNode> iter = fOrderedTargets.iterator(); |
| while (iter.hasNext()) { |
| buffer.append(iter.next().getTargetName()); |
| buffer.append(", "); //$NON-NLS-1$ |
| } |
| if (buffer.length() > 2) { |
| // remove trailing comma |
| buffer.setLength(buffer.length() - 2); |
| } |
| fTargetOrderText.setText(buffer.toString()); |
| } |
| |
| /** |
| * Returns all targets in the buildfile. |
| * |
| * @return all targets in the buildfile |
| */ |
| private AntTargetNode[] getTargets() { |
| if (fAllTargets == null || isDirty()) { |
| fAllTargets = null; |
| fDefaultTarget = null; |
| setDirty(false); |
| setErrorMessage(null); |
| setMessage(null); |
| |
| final String expandedLocation = validateLocation(); |
| if (expandedLocation == null) { |
| return fAllTargets; |
| } |
| final CoreException[] exceptions = new CoreException[1]; |
| try { |
| IRunnableWithProgress operation = new IRunnableWithProgress() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public void run(IProgressMonitor monitor) { |
| try { |
| fAllTargets = AntUtil.getTargets(expandedLocation, fLaunchConfiguration); |
| } |
| catch (CoreException ce) { |
| exceptions[0] = ce; |
| } |
| } |
| }; |
| |
| IRunnableContext context = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| if (context == null) { |
| context = getLaunchConfigurationDialog(); |
| } |
| |
| ISchedulingRule rule = null; |
| if (!ResourcesPlugin.getWorkspace().isTreeLocked()) { |
| // only set a scheduling rule if not in a resource change callback |
| rule = AntUtil.getFileForLocation(expandedLocation, null); |
| } |
| PlatformUI.getWorkbench().getProgressService().runInUI(context, operation, rule); |
| } |
| catch (InvocationTargetException e) { |
| AntUIPlugin.log("Internal error occurred retrieving targets", e.getTargetException()); //$NON-NLS-1$ |
| setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1); |
| fAllTargets = null; |
| return null; |
| } |
| catch (InterruptedException e) { |
| AntUIPlugin.log("Internal error occurred retrieving targets", e); //$NON-NLS-1$ |
| setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_1); |
| fAllTargets = null; |
| return null; |
| } |
| |
| if (exceptions[0] != null) { |
| IStatus exceptionStatus = exceptions[0].getStatus(); |
| IStatus[] children = exceptionStatus.getChildren(); |
| StringBuffer message = new StringBuffer(exceptions[0].getMessage()); |
| for (int i = 0; i < children.length; i++) { |
| message.append(' '); |
| IStatus childStatus = children[i]; |
| message.append(childStatus.getMessage()); |
| } |
| setErrorMessage(message.toString()); |
| fAllTargets = null; |
| return fAllTargets; |
| } |
| |
| if (fAllTargets == null) { |
| // if an error was not thrown during parsing then having no targets is valid (Ant 1.6.*) |
| return fAllTargets; |
| } |
| |
| AntTargetNode target = fAllTargets[0]; |
| AntProjectNode projectNode = target.getProjectNode(); |
| setErrorMessageFromNode(projectNode); |
| for (int i = 0; i < fAllTargets.length; i++) { |
| target = fAllTargets[i]; |
| if (target.isDefaultTarget()) { |
| fDefaultTarget = target; |
| } |
| setErrorMessageFromNode(target); |
| } |
| } |
| |
| return fAllTargets; |
| } |
| |
| private void setErrorMessageFromNode(AntElementNode node) { |
| if (getErrorMessage() != null) { |
| return; |
| } |
| if (node.isErrorNode() || node.isWarningNode()) { |
| String message = node.getProblemMessage(); |
| if (message != null) { |
| setErrorMessage(message); |
| } else { |
| setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_0); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| @Override |
| public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { |
| // do nothing |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) |
| */ |
| @Override |
| public void initializeFrom(ILaunchConfiguration configuration) { |
| fInitializing = true; |
| fLaunchConfiguration = configuration; |
| fOrderedTargets = new ArrayList<>(); |
| setErrorMessage(null); |
| setMessage(null); |
| setDirty(true); |
| boolean hideInternal = false; |
| try { |
| hideInternal = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, false); |
| } |
| catch (CoreException e) { |
| AntUIPlugin.log(e); |
| } |
| fFilterInternalTargets.setSelection(hideInternal); |
| handleFilterTargetsSelected(); |
| int sort = SORT_NONE; |
| try { |
| sort = fLaunchConfiguration.getAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, sort); |
| } |
| catch (CoreException e) { |
| AntUIPlugin.log(e); |
| } |
| fSortButton.setSelection(sort != SORT_NONE); |
| setSort(sort); |
| String configTargets = null; |
| String newLocation = null; |
| |
| try { |
| configTargets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null); |
| newLocation = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); |
| } |
| catch (CoreException ce) { |
| AntUIPlugin.log(AntLaunchConfigurationMessages.AntTargetsTab_Error_reading_configuration_12, ce); |
| } |
| |
| if (newLocation == null) { |
| fAllTargets = null; |
| initializeForNoTargets(); |
| return; |
| } |
| |
| AntTargetNode[] allTargetNodes = getTargets(); |
| if (allTargetNodes == null) { |
| initializeForNoTargets(); |
| return; |
| } |
| |
| String[] targetNames = AntUtil.parseRunTargets(configTargets); |
| if (targetNames.length == 0) { |
| fTableViewer.setAllChecked(false); |
| setExecuteInput(allTargetNodes); |
| if (fDefaultTarget != null) { |
| fOrderedTargets.add(fDefaultTarget); |
| fTableViewer.setChecked(fDefaultTarget, true); |
| updateSelectionCount(); |
| updateLaunchConfigurationDialog(); |
| } |
| fInitializing = false; |
| return; |
| } |
| |
| setExecuteInput(allTargetNodes); |
| fTableViewer.setAllChecked(false); |
| for (int i = 0; i < targetNames.length; i++) { |
| for (int j = 0; j < fAllTargets.length; j++) { |
| if (targetNames[i].equals(fAllTargets[j].getTargetName())) { |
| fOrderedTargets.add(fAllTargets[j]); |
| fTableViewer.setChecked(fAllTargets[j], true); |
| } |
| } |
| } |
| updateSelectionCount(); |
| fInitializing = false; |
| } |
| |
| private void initializeForNoTargets() { |
| setExecuteInput(new AntTargetNode[0]); |
| fTableViewer.setInput(new AntTargetNode[0]); |
| fInitializing = false; |
| } |
| |
| /** |
| * Sets the execute table's input to the given input. |
| */ |
| private void setExecuteInput(Object input) { |
| fTableViewer.setInput(input); |
| updateSelectionCount(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| @Override |
| public void performApply(ILaunchConfigurationWorkingCopy configuration) { |
| // attribute added in 3.0, so null must be used instead of false for backwards compatibility |
| if (fFilterInternalTargets.getSelection()) { |
| configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, true); |
| } else { |
| configuration.setAttribute(IAntLaunchConstants.ATTR_HIDE_INTERNAL_TARGETS, (String) null); |
| } |
| // attribute added in 3.0, so null must be used instead of 0 for backwards compatibility |
| if (fSortDirection != SORT_NONE) { |
| configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, fSortDirection); |
| } else { |
| configuration.setAttribute(IAntLaunchConstants.ATTR_SORT_TARGETS, (String) null); |
| } |
| |
| if (fOrderedTargets.size() == 1) { |
| AntTargetNode item = fOrderedTargets.get(0); |
| if (item.isDefaultTarget()) { |
| configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null); |
| return; |
| } |
| } else if (fOrderedTargets.size() == 0) { |
| configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null); |
| return; |
| } |
| |
| StringBuffer buff = new StringBuffer(); |
| Iterator<AntTargetNode> iter = fOrderedTargets.iterator(); |
| String targets = null; |
| while (iter.hasNext()) { |
| AntTargetNode item = iter.next(); |
| buff.append(item.getTargetName()); |
| buff.append(','); |
| } |
| if (buff.length() > 0) { |
| targets = buff.toString(); |
| } |
| |
| configuration.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, targets); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName() |
| */ |
| @Override |
| public String getName() { |
| return AntLaunchConfigurationMessages.AntTargetsTab_Tar_gets_14; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage() |
| */ |
| @Override |
| public Image getImage() { |
| return AntUIImages.getImage(IAntUIConstants.IMG_TAB_ANT_TARGETS); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration) |
| */ |
| @Override |
| public boolean isValid(ILaunchConfiguration launchConfig) { |
| if (fAllTargets == null || isDirty()) { |
| if (getErrorMessage() != null && !isDirty()) { |
| // error in parsing; |
| return false; |
| } |
| // targets not up to date and no error message...we have not parsed recently |
| initializeFrom(launchConfig); |
| if (getErrorMessage() != null) { |
| // error in parsing; |
| return false; |
| } |
| } |
| |
| setErrorMessage(null); |
| return super.isValid(launchConfig); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#setDirty(boolean) |
| */ |
| @Override |
| protected void setDirty(boolean dirty) { |
| // provide package visibility |
| super.setDirty(dirty); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| @Override |
| public void activated(ILaunchConfigurationWorkingCopy workingCopy) { |
| if (isDirty()) { |
| super.activated(workingCopy); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) |
| */ |
| @Override |
| public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) { |
| if (fOrderedTargets.size() == 0) { |
| // set the dirty flag so that the state will be reinitialized on activation |
| setDirty(true); |
| } |
| } |
| |
| private String validateLocation() { |
| String expandedLocation = null; |
| String location = null; |
| IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); |
| try { |
| location = fLaunchConfiguration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); |
| if (location == null) { |
| return null; |
| } |
| |
| expandedLocation = manager.performStringSubstitution(location); |
| if (expandedLocation == null) { |
| return null; |
| } |
| File file = new File(expandedLocation); |
| if (!file.exists()) { |
| setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_15); |
| return null; |
| } |
| if (!file.isFile()) { |
| setErrorMessage(AntLaunchConfigurationMessages.AntTargetsTab_16); |
| return null; |
| } |
| |
| return expandedLocation; |
| |
| } |
| catch (CoreException e1) { |
| if (location != null) { |
| try { |
| manager.validateStringVariables(location); |
| setMessage(AntLaunchConfigurationMessages.AntTargetsTab_17); |
| return null; |
| } |
| catch (CoreException e2) {// invalid variable |
| setErrorMessage(e2.getStatus().getMessage()); |
| return null; |
| } |
| } |
| |
| setErrorMessage(e1.getStatus().getMessage()); |
| return null; |
| } |
| } |
| |
| protected boolean isTargetSelected() { |
| return !fOrderedTargets.isEmpty(); |
| } |
| } |