]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
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.ui.actions; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.Arrays; | |
15 | import java.util.Iterator; | |
16 | import java.util.List; | |
17 | ||
18 | import org.eclipse.core.runtime.IStatus; | |
19 | import org.eclipse.core.runtime.Status; | |
20 | ||
21 | import org.eclipse.jface.dialogs.ErrorDialog; | |
22 | import org.eclipse.jface.viewers.ISelectionProvider; | |
23 | import org.eclipse.jface.viewers.IStructuredSelection; | |
24 | ||
25 | import org.eclipse.jface.text.ITextSelection; | |
26 | ||
27 | import org.eclipse.ui.IWorkbenchSite; | |
28 | import org.eclipse.ui.PlatformUI; | |
29 | ||
30 | import org.eclipse.jdt.core.IClassFile; | |
31 | import org.eclipse.jdt.core.ICompilationUnit; | |
32 | import org.eclipse.jdt.core.IImportDeclaration; | |
33 | import org.eclipse.jdt.core.IJavaElement; | |
34 | import org.eclipse.jdt.core.IPackageFragment; | |
35 | import org.eclipse.jdt.core.IPackageFragmentRoot; | |
36 | import org.eclipse.jdt.core.IType; | |
37 | import org.eclipse.jdt.core.JavaModelException; | |
38 | import org.eclipse.jdt.core.Signature; | |
39 | ||
40 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
41 | ||
42 | import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; | |
43 | import org.eclipse.jdt.internal.ui.IJavaStatusConstants; | |
44 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
45 | import org.eclipse.jdt.internal.ui.actions.ActionMessages; | |
46 | import org.eclipse.jdt.internal.ui.actions.ActionUtil; | |
47 | import org.eclipse.jdt.internal.ui.actions.SelectionConverter; | |
48 | import org.eclipse.jdt.internal.ui.browsing.LogicalPackage; | |
49 | import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; | |
50 | import org.eclipse.jdt.internal.ui.util.OpenTypeHierarchyUtil; | |
51 | ||
52 | /** | |
53 | * This action opens a type hierarchy on the selected type. | |
54 | * <p> | |
55 | * The action is applicable to selections containing elements of type | |
56 | * <code>IType</code>. | |
57 | * | |
58 | * <p> | |
59 | * This class may be instantiated; it is not intended to be subclassed. | |
60 | * </p> | |
61 | * | |
62 | * @since 2.0 | |
63 | * | |
64 | * @noextend This class is not intended to be subclassed by clients. | |
65 | */ | |
66 | public class OpenTypeHierarchyAction extends SelectionDispatchAction { | |
67 | ||
68 | public JavaEditor fEditor; | |
69 | ||
70 | /** | |
71 | * Creates a new <code>OpenTypeHierarchyAction</code>. The action requires | |
72 | * that the selection provided by the site's selection provider is of type <code> | |
73 | * org.eclipse.jface.viewers.IStructuredSelection</code>. | |
74 | * | |
75 | * @param site the site providing context information for this action | |
76 | */ | |
77 | public OpenTypeHierarchyAction(IWorkbenchSite site) { | |
78 | super(site); | |
79 | setText(ActionMessages.OpenTypeHierarchyAction_label); | |
80 | setToolTipText(ActionMessages.OpenTypeHierarchyAction_tooltip); | |
81 | setDescription(ActionMessages.OpenTypeHierarchyAction_description); | |
82 | PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.OPEN_TYPE_HIERARCHY_ACTION); | |
83 | } | |
84 | ||
85 | /** | |
86 | * Creates a new <code>OpenTypeHierarchyAction</code>. The action requires | |
87 | * that the selection provided by the given selection provider is of type <code> | |
88 | * org.eclipse.jface.viewers.IStructuredSelection</code>. | |
89 | * | |
90 | * @param site the site providing context information for this action | |
91 | * @param provider a special selection provider which is used instead | |
92 | * of the site's selection provider or <code>null</code> to use the site's | |
93 | * selection provider | |
94 | * | |
95 | * @since 3.2 | |
96 | * @deprecated Use {@link #setSpecialSelectionProvider(ISelectionProvider)} instead. This API will be | |
97 | * removed after 3.2 M5. | |
98 | */ | |
99 | public OpenTypeHierarchyAction(IWorkbenchSite site, ISelectionProvider provider) { | |
100 | this(site); | |
101 | setSpecialSelectionProvider(provider); | |
102 | } | |
103 | ||
104 | ||
105 | /** | |
106 | * Note: This constructor is for internal use only. Clients should not call this constructor. | |
107 | * @param editor the Java editor | |
108 | * | |
109 | * @noreference This constructor is not intended to be referenced by clients. | |
110 | */ | |
111 | public OpenTypeHierarchyAction(JavaEditor editor) { | |
112 | this(editor.getEditorSite()); | |
113 | fEditor= editor; | |
114 | setEnabled(SelectionConverter.canOperateOn(fEditor)); | |
115 | } | |
116 | ||
117 | /* (non-Javadoc) | |
118 | * Method declared on SelectionDispatchAction. | |
119 | */ | |
120 | @Override | |
121 | public void selectionChanged(ITextSelection selection) { | |
122 | } | |
123 | ||
124 | /* (non-Javadoc) | |
125 | * Method declared on SelectionDispatchAction. | |
126 | */ | |
127 | @Override | |
128 | public void selectionChanged(IStructuredSelection selection) { | |
129 | setEnabled(isEnabled(selection)); | |
130 | } | |
131 | ||
132 | private boolean isEnabled(IStructuredSelection selection) { | |
133 | Object[] elements= selection.toArray(); | |
134 | if (elements.length == 0) | |
135 | return false; | |
136 | ||
137 | if (elements.length == 1) { | |
138 | Object input= elements[0]; | |
139 | if (input instanceof LogicalPackage) | |
140 | return true; | |
141 | if (!(input instanceof IJavaElement)) | |
142 | return false; | |
143 | ||
144 | switch (((IJavaElement)input).getElementType()) { | |
145 | case IJavaElement.INITIALIZER: | |
146 | case IJavaElement.METHOD: | |
147 | case IJavaElement.FIELD: | |
148 | case IJavaElement.TYPE: | |
149 | case IJavaElement.IMPORT_DECLARATION: | |
150 | case IJavaElement.CLASS_FILE: | |
151 | case IJavaElement.COMPILATION_UNIT: | |
152 | return true; | |
153 | case IJavaElement.LOCAL_VARIABLE: | |
154 | case IJavaElement.TYPE_PARAMETER: | |
155 | case IJavaElement.ANNOTATION: | |
156 | return false; | |
157 | default: | |
158 | // continue below | |
159 | } | |
160 | } | |
161 | ||
162 | // strategy: allow non-IJavaElements (e.g. an IResource), but stop for invalid IJavaElements | |
163 | boolean hasValidElement= false; | |
164 | for (int j= 0; j < elements.length; j++) { | |
165 | Object input= elements[j]; | |
166 | if (input instanceof LogicalPackage) { | |
167 | hasValidElement= true; | |
168 | continue; | |
169 | } | |
170 | if (!(input instanceof IJavaElement)) | |
171 | continue; | |
172 | ||
173 | switch (((IJavaElement)input).getElementType()) { | |
174 | case IJavaElement.PACKAGE_FRAGMENT_ROOT: | |
175 | case IJavaElement.JAVA_PROJECT: | |
176 | case IJavaElement.PACKAGE_FRAGMENT: | |
177 | case IJavaElement.PACKAGE_DECLARATION: | |
178 | hasValidElement= true; | |
179 | continue; | |
180 | default: | |
181 | return false; | |
182 | } | |
183 | } | |
184 | return hasValidElement; | |
185 | } | |
186 | ||
187 | /* (non-Javadoc) | |
188 | * Method declared on SelectionDispatchAction. | |
189 | */ | |
190 | @Override | |
191 | public void run(ITextSelection selection) { | |
192 | fEditor.generated_8681648799826861795(this); | |
193 | } | |
194 | ||
195 | /* (non-Javadoc) | |
196 | * Method declared on SelectionDispatchAction. | |
197 | */ | |
198 | @Override | |
199 | public void run(IStructuredSelection selection) { | |
200 | List<IJavaElement> validElements= new ArrayList<IJavaElement>(); | |
201 | Object[] selectedElements= selection.toArray(); | |
202 | ||
203 | for (int i= 0; i < selectedElements.length; i++) { | |
204 | Object input= selectedElements[i]; | |
205 | if (input instanceof LogicalPackage) { | |
206 | IPackageFragment[] fragments= ((LogicalPackage)input).getFragments(); | |
207 | if (fragments.length == 0) | |
208 | continue; | |
209 | for (int j= 0; j < fragments.length; j++) { | |
210 | validElements.add(fragments[j]); | |
211 | } | |
212 | } else if (input instanceof IPackageFragment) { | |
213 | IPackageFragment fragment= (IPackageFragment)input; | |
214 | IPackageFragmentRoot[] roots; | |
215 | try { | |
216 | roots= fragment.getJavaProject().getPackageFragmentRoots(); | |
217 | } catch (JavaModelException e) { | |
218 | JavaPlugin.log(e); | |
219 | continue; | |
220 | } | |
221 | String name= fragment.getElementName(); | |
222 | for (int j= 0; j < roots.length; j++) { | |
223 | IPackageFragment pack= roots[j].getPackageFragment(name); | |
224 | if (pack.exists()) | |
225 | validElements.add(pack); | |
226 | } | |
227 | } else { | |
228 | if (!(input instanceof IJavaElement) || !ActionUtil.isProcessable(getShell(), (IJavaElement)input)) | |
229 | continue; | |
230 | IJavaElement element= (IJavaElement)input; | |
231 | validElements.add(element); | |
232 | } | |
233 | } | |
234 | if (validElements.size() == 0) { | |
235 | IStatus status= createStatus(ActionMessages.OpenTypeHierarchyAction_messages_no_java_elements); | |
236 | ErrorDialog.openError(getShell(), getDialogTitle(), ActionMessages.OpenTypeHierarchyAction_messages_title, status); | |
237 | return; | |
238 | } | |
239 | List<IJavaElement> result= new ArrayList<IJavaElement>(); | |
240 | IStatus status= compileCandidates(result, validElements); | |
241 | if (status.isOK()) { | |
242 | run(result.toArray(new IJavaElement[result.size()])); | |
243 | } else { | |
244 | ErrorDialog.openError(getShell(), getDialogTitle(), ActionMessages.OpenTypeHierarchyAction_messages_title, status); | |
245 | } | |
246 | } | |
247 | ||
248 | /* | |
249 | * No Javadoc since the method isn't meant to be public but is | |
250 | * since the beginning | |
251 | */ | |
252 | public void run(IJavaElement[] elements) { | |
253 | if (elements.length == 0) { | |
254 | getShell().getDisplay().beep(); | |
255 | return; | |
256 | } | |
257 | OpenTypeHierarchyUtil.open(elements, getSite().getWorkbenchWindow()); | |
258 | } | |
259 | ||
260 | public static String getDialogTitle() { | |
261 | return ActionMessages.OpenTypeHierarchyAction_dialog_title; | |
262 | } | |
263 | ||
264 | private static IStatus compileCandidates(List<IJavaElement> result, List<IJavaElement> elements) { | |
265 | IStatus ok= Status.OK_STATUS; | |
266 | boolean onlyContainers= true; | |
267 | for (Iterator<IJavaElement> iter= elements.iterator(); iter.hasNext();) { | |
268 | IJavaElement elem= iter.next(); | |
269 | try { | |
270 | switch (elem.getElementType()) { | |
271 | case IJavaElement.INITIALIZER: | |
272 | case IJavaElement.METHOD: | |
273 | case IJavaElement.FIELD: | |
274 | case IJavaElement.TYPE: | |
275 | onlyContainers= false; | |
276 | //$FALL-THROUGH$ | |
277 | case IJavaElement.PACKAGE_FRAGMENT_ROOT: | |
278 | case IJavaElement.JAVA_PROJECT: | |
279 | result.add(elem); | |
280 | break; | |
281 | case IJavaElement.PACKAGE_FRAGMENT: | |
282 | if (((IPackageFragment)elem).containsJavaResources()) | |
283 | result.add(elem); | |
284 | break; | |
285 | case IJavaElement.PACKAGE_DECLARATION: | |
286 | result.add(elem.getAncestor(IJavaElement.PACKAGE_FRAGMENT)); | |
287 | break; | |
288 | case IJavaElement.IMPORT_DECLARATION: | |
289 | IImportDeclaration decl= (IImportDeclaration)elem; | |
290 | if (decl.isOnDemand()) | |
291 | elem= JavaModelUtil.findTypeContainer(elem.getJavaProject(), Signature.getQualifier(elem.getElementName())); | |
292 | else | |
293 | elem= elem.getJavaProject().findType(elem.getElementName()); | |
294 | if (elem != null) { | |
295 | onlyContainers= false; | |
296 | result.add(elem); | |
297 | } | |
298 | break; | |
299 | case IJavaElement.CLASS_FILE: | |
300 | onlyContainers= false; | |
301 | result.add(((IClassFile)elem).getType()); | |
302 | break; | |
303 | case IJavaElement.COMPILATION_UNIT: | |
304 | ICompilationUnit cu= (ICompilationUnit)elem; | |
305 | IType[] types= cu.getTypes(); | |
306 | if (types.length > 0) { | |
307 | onlyContainers= false; | |
308 | result.addAll(Arrays.asList(types)); | |
309 | } | |
310 | } | |
311 | } catch (JavaModelException e) { | |
312 | return e.getStatus(); | |
313 | } | |
314 | } | |
315 | int size= result.size(); | |
316 | if (size == 0 || (size > 1 && !onlyContainers)) | |
317 | return createStatus(ActionMessages.OpenTypeHierarchyAction_messages_no_valid_java_element); | |
318 | return ok; | |
319 | } | |
320 | ||
321 | private static IStatus createStatus(String message) { | |
322 | return new Status(IStatus.INFO, JavaPlugin.getPluginId(), IJavaStatusConstants.INTERNAL_ERROR, message, null); | |
323 | } | |
324 | } |