1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.actions;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
17 import org.eclipse.osgi.util.TextProcessor;
19 import org.eclipse.swt.SWTError;
20 import org.eclipse.swt.dnd.Clipboard;
21 import org.eclipse.swt.dnd.DND;
22 import org.eclipse.swt.dnd.FileTransfer;
23 import org.eclipse.swt.dnd.TextTransfer;
24 import org.eclipse.swt.dnd.Transfer;
25 import org.eclipse.swt.graphics.Point;
27 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.resources.IResource;
31 import org.eclipse.jface.dialogs.MessageDialog;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.IStructuredSelection;
35 import org.eclipse.jface.text.ITextSelection;
36 import org.eclipse.jface.text.source.ISourceViewer;
38 import org.eclipse.ui.IWorkbenchSite;
39 import org.eclipse.ui.PlatformUI;
40 import org.eclipse.ui.part.ResourceTransfer;
42 import org.eclipse.jdt.core.IClassFile;
43 import org.eclipse.jdt.core.ICompilationUnit;
44 import org.eclipse.jdt.core.IImportDeclaration;
45 import org.eclipse.jdt.core.IJarEntryResource;
46 import org.eclipse.jdt.core.IJavaElement;
47 import org.eclipse.jdt.core.IJavaProject;
48 import org.eclipse.jdt.core.IMember;
49 import org.eclipse.jdt.core.IPackageDeclaration;
50 import org.eclipse.jdt.core.IPackageFragment;
51 import org.eclipse.jdt.core.IPackageFragmentRoot;
52 import org.eclipse.jdt.core.ITypeRoot;
53 import org.eclipse.jdt.core.JavaModelException;
54 import org.eclipse.jdt.core.dom.ASTNode;
55 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
56 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
57 import org.eclipse.jdt.core.dom.CompilationUnit;
58 import org.eclipse.jdt.core.dom.Expression;
59 import org.eclipse.jdt.core.dom.IBinding;
60 import org.eclipse.jdt.core.dom.ImportDeclaration;
61 import org.eclipse.jdt.core.dom.MemberRef;
62 import org.eclipse.jdt.core.dom.MemberValuePair;
63 import org.eclipse.jdt.core.dom.MethodDeclaration;
64 import org.eclipse.jdt.core.dom.MethodInvocation;
65 import org.eclipse.jdt.core.dom.Name;
66 import org.eclipse.jdt.core.dom.NodeFinder;
67 import org.eclipse.jdt.core.dom.PackageDeclaration;
68 import org.eclipse.jdt.core.dom.SimpleType;
69 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
70 import org.eclipse.jdt.core.dom.Type;
71 import org.eclipse.jdt.core.dom.TypeDeclaration;
72 import org.eclipse.jdt.core.dom.TypeParameter;
73 import org.eclipse.jdt.core.dom.VariableDeclaration;
75 import org.eclipse.jdt.ui.JavaElementLabels;
76 import org.eclipse.jdt.ui.JavaUI;
77 import org.eclipse.jdt.ui.SharedASTProvider;
78 import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
80 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
81 import org.eclipse.jdt.internal.ui.JavaPlugin;
82 import org.eclipse.jdt.internal.ui.JavaPluginImages;
83 import org.eclipse.jdt.internal.ui.browsing.LogicalPackage;
84 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
85 import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
88 public class CopyQualifiedNameAction extends SelectionDispatchAction {
90 private static final long LABEL_FLAGS= new Long(JavaElementLabels.F_FULLY_QUALIFIED | JavaElementLabels.M_FULLY_QUALIFIED | JavaElementLabels.I_FULLY_QUALIFIED
91 | JavaElementLabels.T_FULLY_QUALIFIED | JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED | JavaElementLabels.T_TYPE_PARAMETERS | JavaElementLabels.CU_QUALIFIED
92 | JavaElementLabels.CF_QUALIFIED).longValue();
95 public static final String ACTION_DEFINITION_ID= "org.eclipse.jdt.ui.edit.text.java.copy.qualified.name"; //$NON-NLS-1$
98 public static final String ACTION_HANDLER_ID= "org.eclipse.jdt.ui.actions.CopyQualifiedName"; //$NON-NLS-1$
100 private JavaEditor fEditor;
102 public CopyQualifiedNameAction(JavaEditor editor) {
103 this(editor.getSite());
108 public CopyQualifiedNameAction(IWorkbenchSite site) {
111 setText(ActionMessages.CopyQualifiedNameAction_ActionName);
112 setToolTipText(ActionMessages.CopyQualifiedNameAction_ToolTipText);
113 setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_COPY_QUALIFIED_NAME);
114 setImageDescriptor(JavaPluginImages.DESC_ELCL_COPY_QUALIFIED_NAME);
115 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.COPY_QUALIFIED_NAME_ACTION);
122 public void selectionChanged(IStructuredSelection selection) {
123 setEnabled(canEnable(selection.toArray()));
127 public void selectionChanged(ITextSelection selection) {
128 //Must not create an AST
131 private boolean canEnable(Object[] objects) {
132 for (int i= 0; i < objects.length; i++) {
133 Object element= objects[i];
134 if (isValidElement(element))
141 private boolean isValidElement(Object element) {
142 if (element instanceof IMember)
145 if (element instanceof IClassFile)
148 if (element instanceof ICompilationUnit)
151 if (element instanceof IPackageDeclaration)
154 if (element instanceof IImportDeclaration)
157 if (element instanceof IPackageFragment)
160 if (element instanceof IPackageFragmentRoot)
163 if (element instanceof IJavaProject)
166 if (element instanceof IJarEntryResource)
169 if (element instanceof IResource)
172 if (element instanceof LogicalPackage)
179 * @see org.eclipse.jface.action.Action#run()
185 Object[] elements= getSelectedElements();
186 if (elements == null) {
187 MessageDialog.openInformation(getShell(), ActionMessages.CopyQualifiedNameAction_InfoDialogTitel, ActionMessages.CopyQualifiedNameAction_NoElementToQualify);
192 Transfer[] dataTypes= null;
194 if (elements.length == 1) {
195 Object element= elements[0];
196 String qualifiedName= getQualifiedName(element);
197 IResource resource= null;
198 if (element instanceof IJavaElement) {
199 IJavaElement je= ((IJavaElement)element);
201 resource= je.getCorrespondingResource();
202 } else if (element instanceof IResource)
203 resource= (IResource)element;
205 if (resource != null) {
206 IPath location= resource.getLocation();
207 if (location != null) {
208 data= new Object[] { qualifiedName, resource, new String[] { location.toOSString() } };
209 dataTypes= new Transfer[] { TextTransfer.getInstance(), ResourceTransfer.getInstance(), FileTransfer.getInstance() };
211 data= new Object[] { qualifiedName, resource };
212 dataTypes= new Transfer[] { TextTransfer.getInstance(), ResourceTransfer.getInstance() };
215 data= new Object[] { qualifiedName };
216 dataTypes= new Transfer[] { TextTransfer.getInstance() };
219 StringBuffer buf= new StringBuffer();
220 buf.append(getQualifiedName(elements[0]));
221 for (int i= 1; i < elements.length; i++) {
222 String qualifiedName= getQualifiedName(elements[i]);
223 buf.append(System.getProperty("line.separator")).append(qualifiedName); //$NON-NLS-1$
225 data= new Object[] { buf.toString() };
226 dataTypes= new Transfer[] { TextTransfer.getInstance() };
229 Clipboard clipboard= new Clipboard(getShell().getDisplay());
231 clipboard.setContents(data, dataTypes);
232 } catch (SWTError e) {
233 if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
236 if (MessageDialog.openQuestion(getShell(), ActionMessages.CopyQualifiedNameAction_ErrorTitle, ActionMessages.CopyQualifiedNameAction_ErrorDescription)) {
237 clipboard.setContents(data, dataTypes);
242 } catch (JavaModelException e) {
247 private String getQualifiedName(Object element) throws JavaModelException {
248 if (element instanceof IResource)
249 return ((IResource)element).getFullPath().toString();
251 if (element instanceof IJarEntryResource)
252 return ((IJarEntryResource)element).getFullPath().toString();
254 if (element instanceof LogicalPackage)
255 return ((LogicalPackage)element).getElementName();
257 if (element instanceof IJavaProject || element instanceof IPackageFragmentRoot || element instanceof ITypeRoot) {
258 IResource resource= ((IJavaElement)element).getCorrespondingResource();
259 if (resource != null)
260 return getQualifiedName(resource);
263 if (element instanceof IBinding)
264 return BindingLabelProvider.getBindingLabel((IBinding)element, LABEL_FLAGS);
266 return TextProcessor.deprocess(JavaElementLabels.getTextLabel(element, LABEL_FLAGS));
269 private Object[] getSelectedElements() {
270 if (fEditor != null) {
271 Object element= getSelectedElement(fEditor);
275 return new Object[] { element };
278 ISelection selection= getSelection();
279 if (!(selection instanceof IStructuredSelection))
282 List<Object> result= new ArrayList<Object>();
283 for (Iterator<?> iter= ((IStructuredSelection)selection).iterator(); iter.hasNext();) {
284 Object element= iter.next();
285 if (isValidElement(element))
288 if (result.isEmpty())
291 return result.toArray(new Object[result.size()]);
294 private Object getSelectedElement(JavaEditor editor) {
295 ISourceViewer viewer= editor.getViewer();
299 Point selectedRange= viewer.getSelectedRange();
300 int length= selectedRange.y;
301 int offset= selectedRange.x;
303 ITypeRoot element= JavaUI.getEditorInputTypeRoot(editor.getEditorInput());
307 CompilationUnit ast= SharedASTProvider.getAST(element, SharedASTProvider.WAIT_YES, null);
311 NodeFinder finder= new NodeFinder(ast, offset, length);
312 ASTNode node= finder.getCoveringNode();
314 IBinding binding= null;
315 if (node instanceof Name) {
316 binding= getConstructorBindingIfAvailable((Name)node);
319 binding= ((Name)node).resolveBinding();
320 } else if (node instanceof MethodInvocation) {
321 binding= ((MethodInvocation)node).resolveMethodBinding();
322 } else if (node instanceof MethodDeclaration) {
323 binding= ((MethodDeclaration)node).resolveBinding();
324 } else if (node instanceof Type) {
325 binding= ((Type)node).resolveBinding();
326 } else if (node instanceof AnonymousClassDeclaration) {
327 binding= ((AnonymousClassDeclaration)node).resolveBinding();
328 } else if (node instanceof TypeDeclaration) {
329 binding= ((TypeDeclaration)node).resolveBinding();
330 } else if (node instanceof CompilationUnit) {
331 return ((CompilationUnit)node).getJavaElement();
332 } else if (node instanceof Expression) {
333 binding= ((Expression)node).resolveTypeBinding();
334 } else if (node instanceof ImportDeclaration) {
335 binding= ((ImportDeclaration)node).resolveBinding();
336 } else if (node instanceof MemberRef) {
337 binding= ((MemberRef)node).resolveBinding();
338 } else if (node instanceof MemberValuePair) {
339 binding= ((MemberValuePair)node).resolveMemberValuePairBinding();
340 } else if (node instanceof PackageDeclaration) {
341 binding= ((PackageDeclaration)node).resolveBinding();
342 } else if (node instanceof TypeParameter) {
343 binding= ((TypeParameter)node).resolveBinding();
344 } else if (node instanceof VariableDeclaration) {
345 binding= ((VariableDeclaration)node).resolveBinding();
349 return binding.getJavaElement();
355 * Checks whether the given name belongs to a {@link ClassInstanceCreation} and if so, returns
356 * its constructor binding.
358 * @param nameNode the name node
359 * @return the constructor binding or <code>null</code> if not found
362 private IBinding getConstructorBindingIfAvailable(Name nameNode) {
363 StructuralPropertyDescriptor loc= nameNode.getLocationInParent();
364 if (loc == SimpleType.NAME_PROPERTY) {
365 ASTNode parent= nameNode.getParent();
366 loc= parent.getLocationInParent();
367 if (loc == ClassInstanceCreation.TYPE_PROPERTY)
368 return ((ClassInstanceCreation)parent.getParent()).resolveConstructorBinding();