]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/actions/SelectionConverter.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / actions / SelectionConverter.java
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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.actions;
12
13 import java.lang.reflect.InvocationTargetException;
14 import java.util.Iterator;
15
16 import org.eclipse.swt.widgets.Shell;
17
18 import org.eclipse.core.runtime.IProgressMonitor;
19
20 import org.eclipse.jface.operation.IRunnableWithProgress;
21 import org.eclipse.jface.viewers.ISelection;
22 import org.eclipse.jface.viewers.ISelectionProvider;
23 import org.eclipse.jface.viewers.IStructuredSelection;
24 import org.eclipse.jface.viewers.StructuredSelection;
25 import org.eclipse.jface.window.Window;
26
27 import org.eclipse.jface.text.ITextSelection;
28
29 import org.eclipse.ui.IWorkbenchPart;
30 import org.eclipse.ui.PlatformUI;
31 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
32
33 import org.eclipse.jdt.core.IClassFile;
34 import org.eclipse.jdt.core.ICodeAssist;
35 import org.eclipse.jdt.core.ICompilationUnit;
36 import org.eclipse.jdt.core.IJavaElement;
37 import org.eclipse.jdt.core.ISourceRange;
38 import org.eclipse.jdt.core.ISourceReference;
39 import org.eclipse.jdt.core.IType;
40 import org.eclipse.jdt.core.ITypeRoot;
41 import org.eclipse.jdt.core.JavaModelException;
42
43 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
44
45 import org.eclipse.jdt.ui.JavaElementLabelProvider;
46
47 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
48 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
49
50 public class SelectionConverter {
51
52         private static final IJavaElement[] EMPTY_RESULT= new IJavaElement[0];
53
54         private SelectionConverter() {
55                 // no instance
56         }
57
58         /**
59          * Converts the selection provided by the given part into a structured selection. The following
60          * conversion rules are used:
61          * <ul>
62          * <li><code>part instanceof JavaEditor</code>: returns a structured selection using code
63          * resolve to convert the editor's text selection.</li>
64          * <li><code>part instanceof IWorkbenchPart</code>: returns the part's selection if it is a
65          * structured selection.</li>
66          * <li><code>default</code>: returns an empty structured selection.</li>
67          * </ul>
68          * 
69          * @param part the part
70          * @return the selection
71          * @throws JavaModelException thrown when the type root can not be accessed
72          */
73         public static IStructuredSelection getStructuredSelection(IWorkbenchPart part) throws JavaModelException {
74                 if (part instanceof JavaEditor)
75                         return new StructuredSelection(codeResolve((JavaEditor)part));
76                 ISelectionProvider provider= part.getSite().getSelectionProvider();
77                 if (provider != null) {
78                         ISelection selection= provider.getSelection();
79                         if (selection instanceof IStructuredSelection)
80                                 return (IStructuredSelection)selection;
81                 }
82                 return StructuredSelection.EMPTY;
83         }
84
85
86         /**
87          * Converts the given structured selection into an array of Java elements.
88          * An empty array is returned if one of the elements stored in the structured
89          * selection is not of type <code>IJavaElement</code>
90          * @param selection the selection
91          * @return the Java element contained in the selection
92          */
93         public static IJavaElement[] getElements(IStructuredSelection selection) {
94                 if (!selection.isEmpty()) {
95                         IJavaElement[] result= new IJavaElement[selection.size()];
96                         int i= 0;
97                         for (Iterator<?> iter= selection.iterator(); iter.hasNext(); i++) {
98                                 Object element= iter.next();
99                                 if (!(element instanceof IJavaElement))
100                                         return EMPTY_RESULT;
101                                 result[i]= (IJavaElement)element;
102                         }
103                         return result;
104                 }
105                 return EMPTY_RESULT;
106         }
107
108         public static boolean canOperateOn(JavaEditor editor) {
109                 if (editor == null)
110                         return false;
111                 return getInput(editor) != null;
112
113         }
114
115         public static IJavaElement[] codeResolveOrInputForked(JavaEditor editor) throws InvocationTargetException, InterruptedException {
116                 ITypeRoot input= getInput(editor);
117                 if (input == null)
118                         return EMPTY_RESULT;
119
120                 ITextSelection selection= (ITextSelection)editor.getSelectionProvider().getSelection();
121                 IJavaElement[] result= performForkedCodeResolve(input, selection);
122                 if (result.length == 0) {
123                         result= new IJavaElement[] {input};
124                 }
125                 return result;
126         }
127
128         /**
129          * Perform a code resolve at the current selection of an editor
130          * 
131          * @param editor the editor
132          * @return the resolved elements (only from primary working copies)
133          * @throws JavaModelException when the type root can not be accessed
134          */
135         public static IJavaElement[] codeResolve(JavaEditor editor) throws JavaModelException {
136                 return codeResolve(editor, true);
137         }
138
139         /**
140          * Perform a code resolve at the current selection of an editor
141          * 
142          * @param editor the editor
143          * @param primaryOnly if <code>true</code> only primary working copies will be returned
144          * @return the resolved elements
145          * @throws JavaModelException thrown when the type root can not be accessed
146          * @since 3.2
147          */
148         public static IJavaElement[] codeResolve(JavaEditor editor, boolean primaryOnly) throws JavaModelException {
149                 ITypeRoot input= getInput(editor, primaryOnly);
150                 if (input != null)
151                         return codeResolve(input, (ITextSelection) editor.getSelectionProvider().getSelection());
152                 return EMPTY_RESULT;
153         }
154
155         /**
156          * Perform a code resolve in a separate thread.
157          * 
158          * @param editor the editor
159          * @param primaryOnly if <code>true</code> only primary working copies will be returned
160          * @return the resolved elements
161          * @throws InvocationTargetException which wraps any exception or error which occurs while
162          *             running the runnable
163          * @throws InterruptedException propagated by the context if the runnable acknowledges
164          *             cancelation by throwing this exception
165          * @since 3.2
166          */
167         public static IJavaElement[] codeResolveForked(JavaEditor editor, boolean primaryOnly) throws InvocationTargetException, InterruptedException {
168                 ITypeRoot input= getInput(editor, primaryOnly);
169                 if (input != null)
170                         return performForkedCodeResolve(input, (ITextSelection) editor.getSelectionProvider().getSelection());
171                 return EMPTY_RESULT;
172         }
173
174         /**
175          * Returns the element surrounding the selection of the given editor.
176          * 
177          * @param editor the editor
178          * @return the element surrounding the current selection (only from primary working copies), or <code>null</code> if none
179          * @throws JavaModelException if the Java type root does not exist or if an exception occurs
180          *             while accessing its corresponding resource
181          */
182         public static IJavaElement getElementAtOffset(JavaEditor editor) throws JavaModelException {
183                 return getElementAtOffset(editor, true);
184         }
185
186         /**
187          * Returns the element surrounding the selection of the given editor.
188          * 
189          * @param editor the editor
190          * @param primaryOnly if <code>true</code> only primary working copies will be returned
191          * @return the element surrounding the current selection, or <code>null</code> if none
192          * @throws JavaModelException if the Java type root does not exist or if an exception occurs
193          *             while accessing its corresponding resource
194          * @since 3.2
195          */
196         public static IJavaElement getElementAtOffset(JavaEditor editor, boolean primaryOnly) throws JavaModelException {
197                 ITypeRoot input= getInput(editor, primaryOnly);
198                 if (input != null)
199                         return getElementAtOffset(input, (ITextSelection) editor.getSelectionProvider().getSelection());
200                 return null;
201         }
202
203         public static IType getTypeAtOffset(JavaEditor editor) throws JavaModelException {
204                 IJavaElement element= SelectionConverter.getElementAtOffset(editor);
205                 IType type= (IType)element.getAncestor(IJavaElement.TYPE);
206                 if (type == null) {
207                         ICompilationUnit unit= SelectionConverter.getInputAsCompilationUnit(editor);
208                         if (unit != null)
209                                 type= unit.findPrimaryType();
210                 }
211                 return type;
212         }
213
214         /**
215          * Returns the input element of the given editor.
216          *
217          * @param editor the Java editor
218          * @return the type root which is the editor input (only primary working copies), or <code>null</code> if none
219          */
220         public static ITypeRoot getInput(JavaEditor editor) {
221                 return getInput(editor, true);
222         }
223
224         /**
225          * Returns the input element of the given editor.
226          *
227          * @param editor the Java editor
228          * @param primaryOnly if <code>true</code> only primary working copies will be returned
229          * @return the type root which is the editor input, or <code>null</code> if none
230          * @since 3.2
231          */
232         private static ITypeRoot getInput(JavaEditor editor, boolean primaryOnly) {
233                 if (editor == null)
234                         return null;
235                 return EditorUtility.getEditorInputJavaElement(editor, primaryOnly);
236         }
237
238         public static ICompilationUnit getInputAsCompilationUnit(JavaEditor editor) {
239                 Object editorInput= SelectionConverter.getInput(editor);
240                 if (editorInput instanceof ICompilationUnit)
241                         return (ICompilationUnit)editorInput;
242                 return null;
243         }
244
245         public static IClassFile getInputAsClassFile(JavaEditor editor) {
246                 Object editorInput= SelectionConverter.getInput(editor);
247                 if (editorInput instanceof IClassFile)
248                         return (IClassFile)editorInput;
249                 return null;
250         }
251
252         private static IJavaElement[] performForkedCodeResolve(final ITypeRoot input, final ITextSelection selection) throws InvocationTargetException, InterruptedException {
253                 final class CodeResolveRunnable implements IRunnableWithProgress {
254                         IJavaElement[] result;
255                         public void run(IProgressMonitor monitor) throws InvocationTargetException {
256                                 try {
257                                         result= codeResolve(input, selection);
258                                 } catch (JavaModelException e) {
259                                         throw new InvocationTargetException(e);
260                                 }
261                         }
262                 }
263                 CodeResolveRunnable runnable= new CodeResolveRunnable();
264                 PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnable);
265                 return runnable.result;
266         }
267
268         public static IJavaElement[] codeResolve(IJavaElement input, ITextSelection selection) throws JavaModelException {
269                         if (input instanceof ICodeAssist) {
270                                 if (input instanceof ICompilationUnit) {
271                                         JavaModelUtil.reconcile((ICompilationUnit) input);
272                                 }
273                                 IJavaElement[] elements= ((ICodeAssist)input).codeSelect(selection.getOffset() + selection.getLength(), 0);
274                                 if (elements.length > 0) {
275                                         return elements;
276                                 }
277                         }
278                         return EMPTY_RESULT;
279         }
280
281         public static IJavaElement getElementAtOffset(ITypeRoot input, ITextSelection selection) throws JavaModelException {
282                 if (input instanceof ICompilationUnit) {
283                         JavaModelUtil.reconcile((ICompilationUnit) input);
284                 }
285                 IJavaElement ref= input.getElementAt(selection.getOffset());
286                 if (ref == null)
287                         return input;
288                 return ref;
289         }
290
291         public static IJavaElement resolveEnclosingElement(JavaEditor editor, ITextSelection selection) throws JavaModelException {
292                 ITypeRoot input= getInput(editor);
293                 if (input != null)
294                         return resolveEnclosingElement(input, selection);
295                 return null;
296         }
297
298         public static IJavaElement resolveEnclosingElement(IJavaElement input, ITextSelection selection) throws JavaModelException {
299                 IJavaElement atOffset= null;
300                 if (input instanceof ICompilationUnit) {
301                         ICompilationUnit cunit= (ICompilationUnit)input;
302                         JavaModelUtil.reconcile(cunit);
303                         atOffset= cunit.getElementAt(selection.getOffset());
304                 } else if (input instanceof IClassFile) {
305                         IClassFile cfile= (IClassFile)input;
306                         atOffset= cfile.getElementAt(selection.getOffset());
307                 } else {
308                         return null;
309                 }
310                 if (atOffset == null) {
311                         return input;
312                 } else {
313                         int selectionEnd= selection.getOffset() + selection.getLength();
314                         IJavaElement result= atOffset;
315                         if (atOffset instanceof ISourceReference) {
316                                 ISourceRange range= ((ISourceReference)atOffset).getSourceRange();
317                                 while (range.getOffset() + range.getLength() < selectionEnd) {
318                                         result= result.getParent();
319                                         if (! (result instanceof ISourceReference)) {
320                                                 result= input;
321                                                 break;
322                                         }
323                                         range= ((ISourceReference)result).getSourceRange();
324                                 }
325                         }
326                         return result;
327                 }
328         }
329
330         /**
331          * Shows a dialog for resolving an ambiguous Java element. Utility method that can be called by subclasses.
332          *
333          * @param elements the elements to select from
334          * @param shell the parent shell
335          * @param title the title of the selection dialog
336          * @param message the message of the selection dialog
337          * @return returns the selected element or <code>null</code> if the dialog has been cancelled
338          */
339         public static IJavaElement selectJavaElement(IJavaElement[] elements, Shell shell, String title, String message) {
340                 int nResults= elements.length;
341                 if (nResults == 0)
342                         return null;
343                 if (nResults == 1)
344                         return elements[0];
345
346                 int flags= JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT;
347
348                 ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, new JavaElementLabelProvider(flags));
349                 dialog.setTitle(title);
350                 dialog.setMessage(message);
351                 dialog.setElements(elements);
352
353                 if (dialog.open() == Window.OK) {
354                         return (IJavaElement) dialog.getFirstResult();
355                 }
356                 return null;
357         }
358 }