| /******************************************************************************* |
| * 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 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 org.eclipse.jdt.ui.actions.SelectionDispatchAction; |
| |
| import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.JavaPluginImages; |
| import org.eclipse.jdt.internal.ui.browsing.LogicalPackage; |
| import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; |
| import 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; |
| } |
| |
| } |