org.eclipse.tcf.te.launch.ui.viewer.dnd.CommonDnD.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.tcf.te.launch.ui.viewer.dnd.CommonDnD.java

Source

/*******************************************************************************
 * Copyright (c) 2012, 2015 Wind River Systems, Inc. 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:
 * Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tcf.te.launch.ui.viewer.dnd;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.cdt.utils.elf.Elf.Attribute;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
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.core.ILaunchMode;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.ILaunchGroup;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.tcf.te.core.cdt.elf.ElfUtils;
import org.eclipse.tcf.te.launch.core.bindings.LaunchConfigTypeBindingsManager;
import org.eclipse.tcf.te.launch.core.lm.LaunchConfigHelper;
import org.eclipse.tcf.te.launch.core.lm.LaunchManager;
import org.eclipse.tcf.te.launch.core.lm.interfaces.ILaunchManagerDelegate;
import org.eclipse.tcf.te.launch.core.lm.interfaces.ILaunchSpecification;
import org.eclipse.tcf.te.launch.core.persistence.launchcontext.LaunchContextsPersistenceDelegate;
import org.eclipse.tcf.te.launch.core.selection.LaunchSelection;
import org.eclipse.tcf.te.launch.core.selection.ProjectSelectionContext;
import org.eclipse.tcf.te.launch.core.selection.RemoteSelectionContext;
import org.eclipse.tcf.te.launch.core.selection.interfaces.ILaunchSelection;
import org.eclipse.tcf.te.launch.core.selection.interfaces.ISelectionContext;
import org.eclipse.tcf.te.launch.ui.activator.UIPlugin;
import org.eclipse.tcf.te.launch.ui.model.LaunchModel;
import org.eclipse.tcf.te.launch.ui.model.LaunchNode;
import org.eclipse.tcf.te.launch.ui.nls.Messages;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
import org.eclipse.tcf.te.ui.jface.dialogs.OptionalMessageDialog;
import org.eclipse.tcf.te.ui.views.Managers;
import org.eclipse.tcf.te.ui.views.ViewsUtil;
import org.eclipse.tcf.te.ui.views.interfaces.ICategory;
import org.eclipse.tcf.te.ui.views.interfaces.IRoot;
import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
import org.eclipse.ui.dialogs.ListDialog;
import org.eclipse.ui.navigator.CommonDropAdapter;

/**
 * Common DND operation implementations.
 */
public class CommonDnD {

    /**
     * If the current selection is draggable.
     *
     * @param selection The currently selected nodes.
     * @return true if it is draggable.
     */
    public boolean isDraggable(IStructuredSelection selection) {
        if (selection == null || selection.isEmpty()) {
            return false;
        }
        Object[] objects = selection.toArray();
        for (Object object : objects) {
            if (!isDraggableObject(translateObject(object))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Translate the object.
     * @param object
     * @return
     */
    private Object translateObject(Object object) {
        if (object == null || object instanceof LaunchNode || object instanceof IModelNode
                || object instanceof ICategory) {
            return object;
        }
        IResource resource = (IResource) Platform.getAdapterManager().loadAdapter(object,
                IResource.class.getName());
        if (resource != null) {
            IPath location = resource.getLocation();
            if (location != null) {
                try {
                    int elfType = ElfUtils.getELFType(location.toFile());
                    if (elfType == Attribute.ELF_TYPE_EXE || elfType == Attribute.ELF_TYPE_OBJ) {
                        return resource;
                    }
                } catch (Exception e) {
                }
            }
        }
        return null;
    }

    /**
     * If the specified object is a draggable element.
     *
     * @param object The object to be dragged.
     * @return true if it is draggable.
     */
    private boolean isDraggableObject(Object object) {
        return (object instanceof LaunchNode && ((LaunchNode) object).getLaunchConfiguration() != null)
                || (!(object instanceof LaunchNode) && object instanceof IModelNode) || object instanceof IResource;
    }

    /**
     * Validate dropping when the elements being dragged are local selection.
     *
     * @param dropAdapter The common drop adapter.
     * @param target The target object.
     * @param operation The DnD operation.
     * @param transferType The transfered data type.
     *
     * @return true if it is valid for dropping.
     */
    public boolean isValidDnD(CommonDropAdapter dropAdapter, Object target, int operation,
            TransferData transferType) {
        boolean valid = false;

        int overrideOperation = -1;

        IStructuredSelection selection = null;
        if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
            LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer();
            selection = (IStructuredSelection) transfer.getSelection();
        }
        if (selection == null) {
            return false;
        }

        boolean allow = true;
        target = translateObject(target);
        Iterator<?> iterator = selection.iterator();
        boolean isCopy = (operation & DND.DROP_COPY) != 0;
        while (iterator.hasNext() && allow) {
            Object from = translateObject(iterator.next());
            if (from instanceof LaunchNode) {
                LaunchNode fromNode = (LaunchNode) from;
                if (target instanceof LaunchNode) {
                    //               LaunchNode toNode = (LaunchNode)target;
                    allow = false;
                } else if (target instanceof IModelNode) {
                    IModelNode toContext = (IModelNode) target;
                    allow &= internalValidate(fromNode, null, toContext, true, isCopy);
                } else if (target instanceof IResource) {
                    IResource toResource = (IResource) target;
                    allow &= internalValidate(fromNode, toResource, null, true, isCopy);
                } else if (target instanceof ICategory) {
                    ICategory toCategory = (ICategory) target;
                    overrideOperation = DND.DROP_LINK;
                    allow &= fromNode.getLaunchConfiguration() != null
                            && IUIConstants.ID_CAT_FAVORITES.equals(toCategory.getId())
                            && !Managers.getCategoryManager().belongsTo(toCategory.getId(),
                                    LaunchModel.getCategoryId(fromNode.getLaunchConfiguration()));
                } else if (target instanceof IRoot) {
                    allow &= fromNode.getModel().getModelRoot() instanceof ICategory
                            && fromNode.getLaunchConfiguration() != null
                            && Managers.getCategoryManager().belongsTo(
                                    ((ICategory) fromNode.getModel().getModelRoot()).getId(),
                                    LaunchModel.getCategoryId(fromNode.getLaunchConfiguration()));
                } else {
                    allow = false;
                }
            } else if (from instanceof IModelNode) {
                IModelNode fromContext = (IModelNode) from;
                if (target instanceof LaunchNode) {
                    LaunchNode toNode = (LaunchNode) target;
                    overrideOperation = DND.DROP_MOVE;
                    allow &= internalValidate(toNode, null, fromContext, true, false);
                } else {
                    allow = false;
                }
            } else if (from instanceof IResource) {
                IResource fromResource = (IResource) from;
                if (target instanceof LaunchNode) {
                    LaunchNode toNode = (LaunchNode) target;
                    allow &= internalValidate(toNode, fromResource, null, !isCopy, false);
                } else if (target instanceof IModelNode) {
                    IModelNode toContext = (IModelNode) target;
                    ILaunchSelection launchSel = new LaunchSelection(null,
                            new ISelectionContext[] {
                                    new RemoteSelectionContext(toContext, new Object[] { toContext }, true),
                                    new ProjectSelectionContext(fromResource.getProject(),
                                            new Object[] { fromResource.getLocation() }, true) });
                    String[] typeIds = LaunchConfigTypeBindingsManager.getInstance()
                            .getValidLaunchConfigTypes(launchSel);
                    allow &= typeIds != null && typeIds.length > 0;
                } else {
                    allow = false;
                }
            } else {
                allow = false;
            }
        }
        valid = allow;

        if (dropAdapter != null && valid) {
            if (overrideOperation > -1) {
                dropAdapter.overrideOperation(overrideOperation);
            }
        }

        return valid;
    }

    private boolean internalValidate(LaunchNode node, IResource resource, IModelNode context, boolean replaceData,
            boolean duplicateConfig) {
        if (node.getLaunchConfiguration() == null) {
            return false;
        }
        if (resource != null) {
            if (!LaunchConfigTypeBindingsManager.getInstance().isValidLaunchConfigType(
                    node.getLaunchConfigurationType().getIdentifier(),
                    new LaunchSelection(null, new ProjectSelectionContext(resource.getProject(),
                            new Object[] { resource.getLocation() }, true)))) {
                return false;
            }
        }
        if (context != null) {
            if (!LaunchConfigTypeBindingsManager.getInstance().isValidLaunchConfigType(
                    node.getLaunchConfigurationType().getIdentifier(),
                    new LaunchSelection(null, new RemoteSelectionContext(context, true)))) {
                return false;
            }
            IModelNode[] oldContexts = LaunchContextsPersistenceDelegate
                    .getLaunchContexts(node.getLaunchConfiguration());
            if (oldContexts != null && Arrays.asList(oldContexts).contains(context) && !duplicateConfig) {
                return false;
            }
        }

        return true;

    }

    /**
     * Perform the drop operation over dragged selection.
     *
     * @param dropAdapter The common drop adapter.
     * @param target The target Object to be moved to.
     * @param operation The current DnD operation.
     * @param selection The local selection being dropped.
     * @return true if the dropping is successful.
     */
    public boolean doDnD(CommonDropAdapter dropAdapter, Object target, int operation,
            IStructuredSelection selection) {
        boolean success = true;
        target = translateObject(target);
        Iterator<?> iterator = selection.iterator();
        boolean isCopy = (operation & DND.DROP_COPY) != 0;
        while (iterator.hasNext()) {
            Object from = translateObject(iterator.next());
            if (from instanceof LaunchNode) {
                LaunchNode fromNode = (LaunchNode) from;
                if (target instanceof LaunchNode) {
                    //               LaunchNode toNode = (LaunchNode)target;
                    success = false;
                } else if (target instanceof IModelNode) {
                    IModelNode toContext = (IModelNode) target;
                    success &= internalDrop(fromNode, null, toContext, true, isCopy);
                } else if (target instanceof IResource) {
                    IResource toResource = (IResource) target;
                    success &= internalDrop(fromNode, toResource, null, true, isCopy);
                } else if (target instanceof ICategory) {
                    ICategory toCategory = (ICategory) target;
                    success &= Managers.getCategoryManager().add(toCategory.getId(),
                            LaunchModel.getCategoryId(fromNode.getLaunchConfiguration()));
                } else if (target instanceof IRoot) {
                    success &= Managers.getCategoryManager().remove(
                            ((ICategory) fromNode.getModel().getModelRoot()).getId(),
                            LaunchModel.getCategoryId(fromNode.getLaunchConfiguration()));
                } else {
                    success = false;
                }
            } else if (from instanceof IModelNode) {
                IModelNode fromContext = (IModelNode) from;
                if (target instanceof LaunchNode) {
                    LaunchNode toNode = (LaunchNode) target;
                    success &= internalDrop(toNode, null, fromContext, true, false);
                } else {
                    success = false;
                }
            } else if (from instanceof IResource) {
                IResource fromResource = (IResource) from;
                if (target instanceof LaunchNode) {
                    LaunchNode toNode = (LaunchNode) target;
                    success &= internalDrop(toNode, fromResource, null, !isCopy, false);
                } else if (target instanceof IModelNode) {
                    IModelNode toContext = (IModelNode) target;
                    ILaunchSelection launchSel = new LaunchSelection(null,
                            new ISelectionContext[] {
                                    new RemoteSelectionContext(toContext, new Object[] { toContext }, true),
                                    new ProjectSelectionContext(fromResource.getProject(),
                                            new Object[] { fromResource.getLocation() }, true) });
                    String[] typeIds = LaunchConfigTypeBindingsManager.getInstance()
                            .getValidLaunchConfigTypes(launchSel);
                    if (typeIds != null && typeIds.length > 0) {
                        String typeId = null;
                        if (typeIds.length == 1) {
                            typeId = typeIds[0];
                        } else {
                            typeId = askForLaunchType(typeIds);
                        }
                        if (typeId != null) {
                            ILaunchConfigurationType type = DebugPlugin.getDefault().getLaunchManager()
                                    .getLaunchConfigurationType(typeId);
                            String[] modes = LaunchConfigHelper.getLaunchConfigTypeModes(type, false);
                            if (modes != null && modes.length > 0) {
                                String mode = null;
                                if (modes.length == 1) {
                                    mode = modes[0];
                                } else {
                                    mode = askForLaunchMode(type, modes);
                                }
                                if (mode != null) {
                                    success &= openLaunchConfigDialog(type, mode,
                                            new LaunchSelection(mode, launchSel.getSelectedContexts()));
                                }
                            }
                        }
                    }
                } else {
                    success = false;
                }
            } else {
                success = false;
            }
        }
        // Fire a refresh of the view
        ViewsUtil.refresh(IUIConstants.ID_EXPLORER);
        return success;
    }

    private String askForLaunchType(String[] typeIds) {
        List<ILaunchConfigurationType> types = new ArrayList<ILaunchConfigurationType>();
        for (String typeId : typeIds) {
            types.add(DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(typeId));
        }
        ListDialog dialog = new ListDialog(
                UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell());
        dialog.setTitle(Messages.CommonDnD_launchType_dialog_title);
        dialog.setMessage(Messages.CommonDnD_launchType_dialog_message);
        dialog.setInput(types.toArray());
        dialog.setContentProvider(new ArrayContentProvider());
        dialog.setLabelProvider(new LabelProvider() {
            @Override
            public String getText(Object element) {
                return ((ILaunchConfigurationType) element).getName();
            }
        });
        dialog.setInitialSelections(new Object[] { types.get(0) });
        if (dialog.open() == Window.OK) {
            return ((ILaunchConfigurationType) dialog.getResult()[0]).getIdentifier();
        }
        return null;
    }

    private String askForLaunchMode(ILaunchConfigurationType type, String[] modes) {
        List<String> modeLabels = new ArrayList<String>();
        int defaultIndex = 0;
        for (String mode : modes) {
            ILaunchMode launchMode = DebugPlugin.getDefault().getLaunchManager().getLaunchMode(mode);
            modeLabels.add(launchMode.getLabel());
            if (mode.equals(ILaunchManager.DEBUG_MODE)) {
                defaultIndex = modeLabels.size() - 1;
            }
        }
        if (modeLabels.size() > 0) {
            modeLabels.add(IDialogConstants.CANCEL_LABEL);
            OptionalMessageDialog dialog = new OptionalMessageDialog(
                    UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),
                    Messages.CommonDnD_launchMode_dialog_title, null,
                    NLS.bind(Messages.CommonDnD_launchMode_dialog_message, type.getName()), MessageDialog.QUESTION,
                    modeLabels.toArray(new String[modeLabels.size()]), defaultIndex, null, null);
            int result = dialog.open();
            if (result >= IDialogConstants.INTERNAL_ID) {
                return modes[result - IDialogConstants.INTERNAL_ID];
            }
        }
        return null;
    }

    private boolean openLaunchConfigDialog(ILaunchConfigurationType type, String mode, ILaunchSelection launchSel) {
        try {
            ILaunchManagerDelegate delegate = LaunchManager.getInstance().getLaunchManagerDelegate(type, mode);
            if (delegate != null) {
                // create an empty launch configuration specification to initialize all attributes with their default defaults.
                ILaunchSpecification launchSpec = delegate.getLaunchSpecification(type.getIdentifier(), launchSel);
                // initialize the new launch config.
                // ignore validation result of launch spec - init as much attributes as possible
                if (launchSpec != null) {
                    ILaunchConfiguration[] launchConfigs = DebugPlugin.getDefault().getLaunchManager()
                            .getLaunchConfigurations(type);
                    launchConfigs = delegate.getMatchingLaunchConfigurations(launchSpec, launchConfigs);

                    ILaunchConfiguration config = launchConfigs != null && launchConfigs.length > 0
                            ? launchConfigs[0]
                            : null;
                    config = LaunchManager.getInstance().createOrUpdateLaunchConfiguration(config, launchSpec);

                    ILaunchGroup launchGroup = DebugUITools.getLaunchGroup(config, mode);
                    DebugUITools.openLaunchConfigurationDialogOnGroup(
                            UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),
                            new StructuredSelection(config), launchGroup.getIdentifier());
                    return true;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    private boolean internalDrop(LaunchNode node, IResource resource, IModelNode context, boolean replaceData,
            boolean duplicateConfig) {
        try {
            ILaunchManagerDelegate delegate = LaunchManager.getInstance()
                    .getLaunchManagerDelegate(node.getLaunchConfigurationType(), ""); //$NON-NLS-1$
            ILaunchConfigurationWorkingCopy wc = node.getLaunchConfiguration().getWorkingCopy();
            if (resource != null) {
                delegate.updateLaunchConfig(wc, new ProjectSelectionContext(resource.getProject(),
                        new Object[] { resource.getLocation() }, true), replaceData);
            }
            if (context != null) {
                delegate.updateLaunchConfig(wc, new RemoteSelectionContext(context, new Object[] { context }, true),
                        replaceData);
            }
            if (duplicateConfig) {
                wc = wc.copy(LaunchConfigHelper.getUniqueLaunchConfigName(delegate.getDefaultLaunchName(wc)));
            } else {
                String newName = LaunchConfigHelper.getUniqueLaunchConfigName(delegate.getDefaultLaunchName(wc))
                        .replaceAll("\\([0-9]+\\)$", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
                String oldName = wc.getName().replaceAll("\\([0-9]+\\)$", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$;
                if (!newName.equals(oldName)) {
                    wc.rename(LaunchConfigHelper.getUniqueLaunchConfigName(newName));
                }
            }
            wc.doSave();
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}