org.eclipse.ant.internal.ui.launchConfigurations.AntTargetsTab.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ant.internal.ui.launchConfigurations.AntTargetsTab.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation 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:
 *     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();
    }
}