ext.org.eclipse.jdt.internal.ui.actions.CopyQualifiedNameAction.java Source code

Java tutorial

Introduction

Here is the source code for ext.org.eclipse.jdt.internal.ui.actions.CopyQualifiedNameAction.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2011 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
 *******************************************************************************/
package ext.org.eclipse.jdt.internal.ui.actions;

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

import org.eclipse.osgi.util.TextProcessor;

import org.eclipse.swt.SWTError;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Point;

import org.eclipse.core.runtime.IPath;

import org.eclipse.core.resources.IResource;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;

import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.source.ISourceViewer;

import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ResourceTransfer;

import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJarEntryResource;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MemberRef;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.SharedASTProvider;
import patch.org.eclipse.jdt.ui.actions.SelectionDispatchAction;

import patch.org.eclipse.jdt.internal.ui.JavaPlugin;

import ext.org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import ext.org.eclipse.jdt.internal.ui.JavaPluginImages;
import ext.org.eclipse.jdt.internal.ui.browsing.LogicalPackage;
import ext.org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import ext.org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;

public class CopyQualifiedNameAction extends SelectionDispatchAction {

    private static final long LABEL_FLAGS = new Long(JavaElementLabels.F_FULLY_QUALIFIED
            | JavaElementLabels.M_FULLY_QUALIFIED | JavaElementLabels.I_FULLY_QUALIFIED
            | JavaElementLabels.T_FULLY_QUALIFIED | JavaElementLabels.M_PARAMETER_TYPES
            | JavaElementLabels.USE_RESOLVED | JavaElementLabels.T_TYPE_PARAMETERS | JavaElementLabels.CU_QUALIFIED
            | JavaElementLabels.CF_QUALIFIED).longValue();

    //TODO: Make API
    public static final String ACTION_DEFINITION_ID = "org.eclipse.jdt.ui.edit.text.java.copy.qualified.name"; //$NON-NLS-1$

    //TODO: Make API
    public static final String ACTION_HANDLER_ID = "org.eclipse.jdt.ui.actions.CopyQualifiedName"; //$NON-NLS-1$

    private JavaEditor fEditor;

    public CopyQualifiedNameAction(JavaEditor editor) {
        this(editor.getSite());
        fEditor = editor;
        setEnabled(true);
    }

    public CopyQualifiedNameAction(IWorkbenchSite site) {
        super(site);

        setText(ActionMessages.CopyQualifiedNameAction_ActionName);
        setToolTipText(ActionMessages.CopyQualifiedNameAction_ToolTipText);
        setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_COPY_QUALIFIED_NAME);
        setImageDescriptor(JavaPluginImages.DESC_ELCL_COPY_QUALIFIED_NAME);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.COPY_QUALIFIED_NAME_ACTION);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void selectionChanged(IStructuredSelection selection) {
        setEnabled(canEnable(selection.toArray()));
    }

    @Override
    public void selectionChanged(ITextSelection selection) {
        //Must not create an AST
    }

    private boolean canEnable(Object[] objects) {
        for (int i = 0; i < objects.length; i++) {
            Object element = objects[i];
            if (isValidElement(element))
                return true;
        }

        return false;
    }

    private boolean isValidElement(Object element) {
        if (element instanceof IMember)
            return true;

        if (element instanceof IClassFile)
            return true;

        if (element instanceof ICompilationUnit)
            return true;

        if (element instanceof IPackageDeclaration)
            return true;

        if (element instanceof IImportDeclaration)
            return true;

        if (element instanceof IPackageFragment)
            return true;

        if (element instanceof IPackageFragmentRoot)
            return true;

        if (element instanceof IJavaProject)
            return true;

        if (element instanceof IJarEntryResource)
            return true;

        if (element instanceof IResource)
            return true;

        if (element instanceof LogicalPackage)
            return true;

        return false;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.action.Action#run()
     */
    @Override
    public void run() {

        try {
            Object[] elements = getSelectedElements();
            if (elements == null) {
                MessageDialog.openInformation(getShell(), ActionMessages.CopyQualifiedNameAction_InfoDialogTitel,
                        ActionMessages.CopyQualifiedNameAction_NoElementToQualify);
                return;
            }

            Object[] data = null;
            Transfer[] dataTypes = null;

            if (elements.length == 1) {
                Object element = elements[0];
                String qualifiedName = getQualifiedName(element);
                IResource resource = null;
                if (element instanceof IJavaElement) {
                    IJavaElement je = ((IJavaElement) element);
                    if (je.exists())
                        resource = je.getCorrespondingResource();
                } else if (element instanceof IResource)
                    resource = (IResource) element;

                if (resource != null) {
                    IPath location = resource.getLocation();
                    if (location != null) {
                        data = new Object[] { qualifiedName, resource, new String[] { location.toOSString() } };
                        dataTypes = new Transfer[] { TextTransfer.getInstance(), ResourceTransfer.getInstance(),
                                FileTransfer.getInstance() };
                    } else {
                        data = new Object[] { qualifiedName, resource };
                        dataTypes = new Transfer[] { TextTransfer.getInstance(), ResourceTransfer.getInstance() };
                    }
                } else {
                    data = new Object[] { qualifiedName };
                    dataTypes = new Transfer[] { TextTransfer.getInstance() };
                }
            } else {
                StringBuffer buf = new StringBuffer();
                buf.append(getQualifiedName(elements[0]));
                for (int i = 1; i < elements.length; i++) {
                    String qualifiedName = getQualifiedName(elements[i]);
                    buf.append(System.getProperty("line.separator")).append(qualifiedName); //$NON-NLS-1$
                }
                data = new Object[] { buf.toString() };
                dataTypes = new Transfer[] { TextTransfer.getInstance() };
            }

            Clipboard clipboard = new Clipboard(getShell().getDisplay());
            try {
                clipboard.setContents(data, dataTypes);
            } catch (SWTError e) {
                if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
                    throw e;
                }
                if (MessageDialog.openQuestion(getShell(), ActionMessages.CopyQualifiedNameAction_ErrorTitle,
                        ActionMessages.CopyQualifiedNameAction_ErrorDescription)) {
                    clipboard.setContents(data, dataTypes);
                }
            } finally {
                clipboard.dispose();
            }
        } catch (JavaModelException e) {
            JavaPlugin.log(e);
        }
    }

    private String getQualifiedName(Object element) throws JavaModelException {
        if (element instanceof IResource)
            return ((IResource) element).getFullPath().toString();

        if (element instanceof IJarEntryResource)
            return ((IJarEntryResource) element).getFullPath().toString();

        if (element instanceof LogicalPackage)
            return ((LogicalPackage) element).getElementName();

        if (element instanceof IJavaProject || element instanceof IPackageFragmentRoot
                || element instanceof ITypeRoot) {
            IResource resource = ((IJavaElement) element).getCorrespondingResource();
            if (resource != null)
                return getQualifiedName(resource);
        }

        if (element instanceof IBinding)
            return BindingLabelProvider.getBindingLabel((IBinding) element, LABEL_FLAGS);

        return TextProcessor.deprocess(JavaElementLabels.getTextLabel(element, LABEL_FLAGS));
    }

    private Object[] getSelectedElements() {
        if (fEditor != null) {
            Object element = getSelectedElement(fEditor);
            if (element == null)
                return null;

            return new Object[] { element };
        }

        ISelection selection = getSelection();
        if (!(selection instanceof IStructuredSelection))
            return null;

        List<Object> result = new ArrayList<Object>();
        for (Iterator<?> iter = ((IStructuredSelection) selection).iterator(); iter.hasNext();) {
            Object element = iter.next();
            if (isValidElement(element))
                result.add(element);
        }
        if (result.isEmpty())
            return null;

        return result.toArray(new Object[result.size()]);
    }

    private Object getSelectedElement(JavaEditor editor) {
        ISourceViewer viewer = editor.getViewer();
        if (viewer == null)
            return null;

        Point selectedRange = viewer.getSelectedRange();
        int length = selectedRange.y;
        int offset = selectedRange.x;

        ITypeRoot element = JavaUI.getEditorInputTypeRoot(editor.getEditorInput());
        if (element == null)
            return null;

        CompilationUnit ast = SharedASTProvider.getAST(element, SharedASTProvider.WAIT_YES, null);
        if (ast == null)
            return null;

        NodeFinder finder = new NodeFinder(ast, offset, length);
        ASTNode node = finder.getCoveringNode();

        IBinding binding = null;
        if (node instanceof Name) {
            binding = getConstructorBindingIfAvailable((Name) node);
            if (binding != null)
                return binding;
            binding = ((Name) node).resolveBinding();
        } else if (node instanceof MethodInvocation) {
            binding = ((MethodInvocation) node).resolveMethodBinding();
        } else if (node instanceof MethodDeclaration) {
            binding = ((MethodDeclaration) node).resolveBinding();
        } else if (node instanceof Type) {
            binding = ((Type) node).resolveBinding();
        } else if (node instanceof AnonymousClassDeclaration) {
            binding = ((AnonymousClassDeclaration) node).resolveBinding();
        } else if (node instanceof TypeDeclaration) {
            binding = ((TypeDeclaration) node).resolveBinding();
        } else if (node instanceof CompilationUnit) {
            return ((CompilationUnit) node).getJavaElement();
        } else if (node instanceof Expression) {
            binding = ((Expression) node).resolveTypeBinding();
        } else if (node instanceof ImportDeclaration) {
            binding = ((ImportDeclaration) node).resolveBinding();
        } else if (node instanceof MemberRef) {
            binding = ((MemberRef) node).resolveBinding();
        } else if (node instanceof MemberValuePair) {
            binding = ((MemberValuePair) node).resolveMemberValuePairBinding();
        } else if (node instanceof PackageDeclaration) {
            binding = ((PackageDeclaration) node).resolveBinding();
        } else if (node instanceof TypeParameter) {
            binding = ((TypeParameter) node).resolveBinding();
        } else if (node instanceof VariableDeclaration) {
            binding = ((VariableDeclaration) node).resolveBinding();
        }

        if (binding != null)
            return binding.getJavaElement();

        return null;
    }

    /**
     * Checks whether the given name belongs to a {@link ClassInstanceCreation} and if so, returns
     * its constructor binding.
     * 
     * @param nameNode the name node
     * @return the constructor binding or <code>null</code> if not found
     * @since 3.7
     */
    private IBinding getConstructorBindingIfAvailable(Name nameNode) {
        StructuralPropertyDescriptor loc = nameNode.getLocationInParent();
        if (loc == SimpleType.NAME_PROPERTY) {
            ASTNode parent = nameNode.getParent();
            loc = parent.getLocationInParent();
            if (loc == ClassInstanceCreation.TYPE_PROPERTY)
                return ((ClassInstanceCreation) parent.getParent()).resolveConstructorBinding();
        }
        return null;
    }

}