KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > ui > actions > OrganizeImportsAction


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 com.ibm.icu.text.Collator;
14
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.util.Comparator JavaDoc;
17
18 import org.eclipse.core.runtime.CoreException;
19
20 import org.eclipse.jface.action.IAction;
21 import org.eclipse.jface.action.IStatusLineManager;
22 import org.eclipse.jface.dialogs.MessageDialog;
23 import org.eclipse.jface.operation.IRunnableContext;
24 import org.eclipse.jface.viewers.ILabelProvider;
25 import org.eclipse.jface.viewers.ISelection;
26 import org.eclipse.jface.viewers.IStructuredSelection;
27 import org.eclipse.jface.viewers.StructuredSelection;
28 import org.eclipse.jface.window.Window;
29
30 import org.eclipse.jface.text.DocumentEvent;
31 import org.eclipse.jface.text.IEditingSupport;
32 import org.eclipse.jface.text.IEditingSupportRegistry;
33 import org.eclipse.jface.text.IRegion;
34 import org.eclipse.jface.text.IRewriteTarget;
35 import org.eclipse.jface.text.ITextSelection;
36 import org.eclipse.jface.text.source.ISourceViewer;
37
38 import org.eclipse.ui.IEditorPart;
39 import org.eclipse.ui.IObjectActionDelegate;
40 import org.eclipse.ui.IWorkbenchPart;
41 import org.eclipse.ui.IWorkbenchSite;
42 import org.eclipse.ui.PlatformUI;
43 import org.eclipse.ui.progress.IProgressService;
44
45 import org.eclipse.jdt.core.ICompilationUnit;
46 import org.eclipse.jdt.core.IJavaElement;
47 import org.eclipse.jdt.core.ISourceRange;
48 import org.eclipse.jdt.core.compiler.IProblem;
49 import org.eclipse.jdt.core.dom.CompilationUnit;
50 import org.eclipse.jdt.core.search.TypeNameMatch;
51
52 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
53 import org.eclipse.jdt.internal.corext.codemanipulation.OrganizeImportsOperation;
54 import org.eclipse.jdt.internal.corext.codemanipulation.OrganizeImportsOperation.IChooseImportQuery;
55 import org.eclipse.jdt.internal.corext.util.History;
56 import org.eclipse.jdt.internal.corext.util.Messages;
57 import org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory;
58
59 import org.eclipse.jdt.ui.JavaUI;
60
61 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
62 import org.eclipse.jdt.internal.ui.JavaPlugin;
63 import org.eclipse.jdt.internal.ui.actions.ActionMessages;
64 import org.eclipse.jdt.internal.ui.actions.ActionUtil;
65 import org.eclipse.jdt.internal.ui.actions.MultiOrganizeImportAction;
66 import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
67 import org.eclipse.jdt.internal.ui.dialogs.MultiElementListSelectionDialog;
68 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
69 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
70 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
71 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
72 import org.eclipse.jdt.internal.ui.util.ElementValidator;
73 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
74 import org.eclipse.jdt.internal.ui.util.TypeNameMatchLabelProvider;
75
76 /**
77  * Organizes the imports of a compilation unit.
78  * <p>
79  * The action is applicable to selections containing elements of
80  * type <code>ICompilationUnit</code> or <code>IPackage
81  * </code>.
82  *
83  * <p>
84  * This class may be instantiated; it is not intended to be subclassed.
85  * </p>
86  *
87  * @since 2.0
88  */

89 public class OrganizeImportsAction extends SelectionDispatchAction {
90
91     private static final OrganizeImportComparator ORGANIZE_IMPORT_COMPARATOR= new OrganizeImportComparator();
92     
93     private JavaEditor fEditor;
94     /** <code>true</code> if the query dialog is showing. */
95     private boolean fIsQueryShowing= false;
96     private final MultiOrganizeImportAction fCleanUpDelegate;
97
98     /* (non-Javadoc)
99      * Class implements IObjectActionDelegate
100      */

101     public static class ObjectDelegate implements IObjectActionDelegate {
102         private OrganizeImportsAction fAction;
103         public void setActivePart(IAction action, IWorkbenchPart targetPart) {
104             fAction= new OrganizeImportsAction(targetPart.getSite());
105         }
106         public void run(IAction action) {
107             fAction.run();
108         }
109         public void selectionChanged(IAction action, ISelection selection) {
110             if (fAction == null)
111                 action.setEnabled(false);
112         }
113     }
114     
115     private static final class OrganizeImportComparator implements Comparator JavaDoc {
116         
117         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
118             if (((String JavaDoc)o1).equals(o2))
119                 return 0;
120             
121             History history= QualifiedTypeNameHistory.getDefault();
122             
123             int pos1= history.getPosition(o1);
124             int pos2= history.getPosition(o2);
125             
126             if (pos1 == pos2)
127                 return Collator.getInstance().compare(o1, o2);
128             
129             if (pos1 > pos2) {
130                 return -1;
131             } else {
132                 return 1;
133             }
134         }
135         
136     }
137
138     /**
139      * Creates a new <code>OrganizeImportsAction</code>. The action requires
140      * that the selection provided by the site's selection provider is of type <code>
141      * org.eclipse.jface.viewers.IStructuredSelection</code>.
142      *
143      * @param site the site providing context information for this action
144      */

145     public OrganizeImportsAction(IWorkbenchSite site) {
146         super(site);
147         
148         fCleanUpDelegate= new MultiOrganizeImportAction(site);
149         
150         setText(ActionMessages.OrganizeImportsAction_label);
151         setToolTipText(ActionMessages.OrganizeImportsAction_tooltip);
152         setDescription(ActionMessages.OrganizeImportsAction_description);
153
154         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.ORGANIZE_IMPORTS_ACTION);
155     }
156     
157     /**
158      * Note: This constructor is for internal use only. Clients should not call this constructor.
159      * @param editor the Java editor
160      */

161     public OrganizeImportsAction(JavaEditor editor) {
162         super(editor.getEditorSite());
163         
164         fEditor= editor;
165         fCleanUpDelegate= new MultiOrganizeImportAction(editor);
166         
167         setText(ActionMessages.OrganizeImportsAction_label);
168         setToolTipText(ActionMessages.OrganizeImportsAction_tooltip);
169         setDescription(ActionMessages.OrganizeImportsAction_description);
170
171         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.ORGANIZE_IMPORTS_ACTION);
172
173         setEnabled(fCleanUpDelegate.isEnabled());
174     }
175     
176     /* (non-Javadoc)
177      * Method declared on SelectionDispatchAction.
178      */

179     public void selectionChanged(ITextSelection selection) {
180         fCleanUpDelegate.selectionChanged(selection);
181         setEnabled(fCleanUpDelegate.isEnabled());
182     }
183     
184     /* (non-Javadoc)
185      * Method declared on SelectionDispatchAction.
186      */

187     public void selectionChanged(IStructuredSelection selection) {
188         fCleanUpDelegate.selectionChanged(selection);
189         setEnabled(fCleanUpDelegate.isEnabled());
190     }
191     
192     /* (non-Javadoc)
193      * Method declared on SelectionDispatchAction.
194      */

195     public void run(ITextSelection selection) {
196         ICompilationUnit cu= getCompilationUnit(fEditor);
197         if (cu != null) {
198             run(cu);
199         }
200     }
201
202     private static ICompilationUnit getCompilationUnit(JavaEditor editor) {
203         IJavaElement element= JavaUI.getEditorInputJavaElement(editor.getEditorInput());
204         if (!(element instanceof ICompilationUnit))
205             return null;
206         
207         return (ICompilationUnit)element;
208     }
209     
210     /* (non-Javadoc)
211      * Method declared on SelectionDispatchAction.
212      */

213     public void run(IStructuredSelection selection) {
214         ICompilationUnit[] cus= fCleanUpDelegate.getCompilationUnits(selection);
215         if (cus.length == 0) {
216             MessageDialog.openInformation(getShell(), ActionMessages.OrganizeImportsAction_EmptySelection_title, ActionMessages.OrganizeImportsAction_EmptySelection_description);
217         } else if (cus.length == 1) {
218             run(cus[0]);
219         } else {
220             fCleanUpDelegate.run(selection);
221         }
222     }
223     
224     /**
225      * Perform organize import on multiple compilation units. No editors are opened.
226      * @param cus The compilation units to run on
227      */

228     public void runOnMultiple(final ICompilationUnit[] cus) {
229         if (cus.length == 0)
230             return;
231         
232         fCleanUpDelegate.run(new StructuredSelection(cus));
233     }
234
235     /**
236      * Note: This method is for internal use only. Clients should not call this method.
237      * @param cu The compilation unit to process
238      */

239     public void run(ICompilationUnit cu) {
240         if (!ElementValidator.check(cu, getShell(), ActionMessages.OrganizeImportsAction_error_title, fEditor != null))
241             return;
242         if (!ActionUtil.isEditable(fEditor, getShell(), cu))
243             return;
244         
245         IEditingSupport helper= createViewerHelper();
246         try {
247             CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(cu.getJavaProject());
248             
249             JavaEditor editor= null;
250             if (fEditor == null) {
251                 IEditorPart openEditor= EditorUtility.isOpenInEditor(cu);
252                 if (openEditor == null)
253                     openEditor= JavaUI.openInEditor(cu);
254
255                 if (openEditor instanceof JavaEditor)
256                     editor= (JavaEditor) openEditor;
257             } else {
258                 editor= fEditor;
259             }
260             
261             CompilationUnit astRoot= JavaPlugin.getDefault().getASTProvider().getAST(cu, ASTProvider.WAIT_ACTIVE_ONLY, null);
262             
263             OrganizeImportsOperation op= new OrganizeImportsOperation(cu, astRoot, settings.importIgnoreLowercase, !cu.isWorkingCopy(), true, createChooseImportQuery(editor));
264         
265             IRewriteTarget target= null;
266             if (editor != null) {
267                 target= (IRewriteTarget) editor.getAdapter(IRewriteTarget.class);
268                 if (target != null) {
269                     target.beginCompoundChange();
270                 }
271             }
272             
273             IProgressService progressService= PlatformUI.getWorkbench().getProgressService();
274             IRunnableContext context= getSite().getWorkbenchWindow();
275             if (context == null) {
276                 context= progressService;
277             }
278             try {
279                 registerHelper(helper, editor);
280                 progressService.runInUI(context, new WorkbenchRunnableAdapter(op, op.getScheduleRule()), op.getScheduleRule());
281                 IProblem parseError= op.getParseError();
282                 if (parseError != null) {
283                     String JavaDoc message= Messages.format(ActionMessages.OrganizeImportsAction_single_error_parse, parseError.getMessage());
284                     MessageDialog.openInformation(getShell(), ActionMessages.OrganizeImportsAction_error_title, message);
285                     if (editor != null && parseError.getSourceStart() != -1) {
286                         editor.selectAndReveal(parseError.getSourceStart(), parseError.getSourceEnd() - parseError.getSourceStart() + 1);
287                     }
288                 } else {
289                     if (editor != null) {
290                         setStatusBarMessage(getOrganizeInfo(op), editor);
291                     }
292                 }
293             } catch (InvocationTargetException JavaDoc e) {
294                 ExceptionHandler.handle(e, getShell(), ActionMessages.OrganizeImportsAction_error_title, ActionMessages.OrganizeImportsAction_error_message);
295             } catch (InterruptedException JavaDoc e) {
296             } finally {
297                 deregisterHelper(helper, editor);
298                 if (target != null) {
299                     target.endCompoundChange();
300                 }
301             }
302         } catch (CoreException e) {
303             ExceptionHandler.handle(e, getShell(), ActionMessages.OrganizeImportsAction_error_title, ActionMessages.OrganizeImportsAction_error_message);
304         }
305     }
306     
307     private String JavaDoc getOrganizeInfo(OrganizeImportsOperation op) {
308         int nImportsAdded= op.getNumberOfImportsAdded();
309         if (nImportsAdded >= 0) {
310             return Messages.format(ActionMessages.OrganizeImportsAction_summary_added, String.valueOf(nImportsAdded));
311         } else {
312             return Messages.format(ActionMessages.OrganizeImportsAction_summary_removed, String.valueOf(-nImportsAdded));
313         }
314     }
315         
316     private IChooseImportQuery createChooseImportQuery(final JavaEditor editor) {
317         return new IChooseImportQuery() {
318             public TypeNameMatch[] chooseImports(TypeNameMatch[][] openChoices, ISourceRange[] ranges) {
319                 return doChooseImports(openChoices, ranges, editor);
320             }
321         };
322     }
323     
324     private TypeNameMatch[] doChooseImports(TypeNameMatch[][] openChoices, final ISourceRange[] ranges, final JavaEditor editor) {
325         // remember selection
326
ISelection sel= editor != null ? editor.getSelectionProvider().getSelection() : null;
327         TypeNameMatch[] result= null;
328         ILabelProvider labelProvider= new TypeNameMatchLabelProvider(TypeNameMatchLabelProvider.SHOW_FULLYQUALIFIED);
329         
330         MultiElementListSelectionDialog dialog= new MultiElementListSelectionDialog(getShell(), labelProvider) {
331             protected void handleSelectionChanged() {
332                 super.handleSelectionChanged();
333                 // show choices in editor
334
doListSelectionChanged(getCurrentPage(), ranges, editor);
335             }
336         };
337         fIsQueryShowing= true;
338         dialog.setTitle(ActionMessages.OrganizeImportsAction_selectiondialog_title);
339         dialog.setMessage(ActionMessages.OrganizeImportsAction_selectiondialog_message);
340         dialog.setElements(openChoices);
341         dialog.setComparator(ORGANIZE_IMPORT_COMPARATOR);
342         if (dialog.open() == Window.OK) {
343             Object JavaDoc[] res= dialog.getResult();
344             result= new TypeNameMatch[res.length];
345             for (int i= 0; i < res.length; i++) {
346                 Object JavaDoc[] array= (Object JavaDoc[]) res[i];
347                 if (array.length > 0) {
348                     result[i]= (TypeNameMatch) array[0];
349                     QualifiedTypeNameHistory.remember(result[i].getFullyQualifiedName());
350                 }
351             }
352         }
353         // restore selection
354
if (sel instanceof ITextSelection) {
355             ITextSelection textSelection= (ITextSelection) sel;
356             editor.selectAndReveal(textSelection.getOffset(), textSelection.getLength());
357         }
358         fIsQueryShowing= false;
359         return result;
360     }
361     
362     private void doListSelectionChanged(int page, ISourceRange[] ranges, JavaEditor editor) {
363         if (editor != null && ranges != null && page >= 0 && page < ranges.length) {
364             ISourceRange range= ranges[page];
365             editor.selectAndReveal(range.getOffset(), range.getLength());
366         }
367     }
368     
369     private void setStatusBarMessage(String JavaDoc message, JavaEditor editor) {
370         IStatusLineManager manager= editor.getEditorSite().getActionBars().getStatusLineManager();
371         manager.setMessage(message);
372     }
373     
374     private IEditingSupport createViewerHelper() {
375         return new IEditingSupport() {
376             public boolean isOriginator(DocumentEvent event, IRegion subjectRegion) {
377                 return true; // assume true, since we only register while we are active
378
}
379             public boolean ownsFocusShell() {
380                 return fIsQueryShowing;
381             }
382             
383         };
384     }
385     
386     private void registerHelper(IEditingSupport helper, JavaEditor editor) {
387         if (editor == null)
388             return;
389         ISourceViewer viewer= editor.getViewer();
390         if (viewer instanceof IEditingSupportRegistry) {
391             IEditingSupportRegistry registry= (IEditingSupportRegistry) viewer;
392             registry.register(helper);
393         }
394     }
395
396     private void deregisterHelper(IEditingSupport helper, JavaEditor editor) {
397         if (editor == null)
398             return;
399         ISourceViewer viewer= editor.getViewer();
400         if (viewer instanceof IEditingSupportRegistry) {
401             IEditingSupportRegistry registry= (IEditingSupportRegistry) viewer;
402             registry.unregister(helper);
403         }
404     }
405 }
406
Popular Tags