KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.core.runtime.MultiStatus;
25 import org.eclipse.core.runtime.NullProgressMonitor;
26 import org.eclipse.core.runtime.OperationCanceledException;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.core.runtime.SubProgressMonitor;
29
30 import org.eclipse.core.filebuffers.FileBuffers;
31 import org.eclipse.core.filebuffers.ITextFileBuffer;
32 import org.eclipse.core.filebuffers.ITextFileBufferManager;
33 import org.eclipse.core.filebuffers.LocationKind;
34
35 import org.eclipse.core.resources.IResource;
36 import org.eclipse.core.resources.IWorkspaceRunnable;
37
38 import org.eclipse.jface.action.IAction;
39 import org.eclipse.jface.dialogs.ErrorDialog;
40 import org.eclipse.jface.dialogs.IDialogConstants;
41 import org.eclipse.jface.dialogs.MessageDialog;
42 import org.eclipse.jface.viewers.ISelection;
43 import org.eclipse.jface.viewers.IStructuredSelection;
44 import org.eclipse.jface.window.Window;
45
46 import org.eclipse.jface.text.DocumentRewriteSession;
47 import org.eclipse.jface.text.DocumentRewriteSessionType;
48 import org.eclipse.jface.text.IDocument;
49 import org.eclipse.jface.text.IDocumentExtension;
50 import org.eclipse.jface.text.IDocumentExtension4;
51 import org.eclipse.jface.text.ITextSelection;
52 import org.eclipse.jface.text.formatter.FormattingContextProperties;
53 import org.eclipse.jface.text.formatter.IFormattingContext;
54 import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
55
56 import org.eclipse.ui.IObjectActionDelegate;
57 import org.eclipse.ui.IWorkbenchPart;
58 import org.eclipse.ui.IWorkbenchSite;
59 import org.eclipse.ui.PlatformUI;
60
61 import org.eclipse.jdt.core.ICompilationUnit;
62 import org.eclipse.jdt.core.IJavaElement;
63 import org.eclipse.jdt.core.IJavaProject;
64 import org.eclipse.jdt.core.IPackageFragment;
65 import org.eclipse.jdt.core.IPackageFragmentRoot;
66 import org.eclipse.jdt.core.JavaModelException;
67
68 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
69 import org.eclipse.jdt.internal.corext.util.Messages;
70 import org.eclipse.jdt.internal.corext.util.Resources;
71
72 import org.eclipse.jdt.ui.JavaUI;
73 import org.eclipse.jdt.ui.text.IJavaPartitions;
74
75 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
76 import org.eclipse.jdt.internal.ui.JavaPlugin;
77 import org.eclipse.jdt.internal.ui.actions.ActionMessages;
78 import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
79 import org.eclipse.jdt.internal.ui.browsing.LogicalPackage;
80 import org.eclipse.jdt.internal.ui.dialogs.OptionalMessageDialog;
81 import org.eclipse.jdt.internal.ui.text.comment.CommentFormattingContext;
82 import org.eclipse.jdt.internal.ui.text.comment.CommentFormattingStrategy;
83 import org.eclipse.jdt.internal.ui.text.java.JavaFormattingStrategy;
84 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
85
86 /**
87  * Formats the code of the compilation units contained in the selection.
88  * <p>
89  * The action is applicable to selections containing elements of
90  * type <code>ICompilationUnit</code>, <code>IPackage
91  * </code>, <code>IPackageFragmentRoot/code> and
92  * <code>IJavaProject</code>.
93  * </p>
94  * <p>
95  * This class may be instantiated; it is not intended to be subclassed.
96  * </p>
97  *
98  * @since 3.0
99  */

100 public class FormatAllAction extends SelectionDispatchAction {
101     
102     private DocumentRewriteSession fRewriteSession;
103     
104     /* (non-Javadoc)
105      * Class implements IObjectActionDelegate
106      */

107     public static class ObjectDelegate implements IObjectActionDelegate {
108         private FormatAllAction fAction;
109         public void setActivePart(IAction action, IWorkbenchPart targetPart) {
110             fAction= new FormatAllAction(targetPart.getSite());
111         }
112         public void run(IAction action) {
113             fAction.run();
114         }
115         public void selectionChanged(IAction action, ISelection selection) {
116             if (fAction == null)
117                 action.setEnabled(false);
118         }
119     }
120
121     /**
122      * Creates a new <code>FormatAllAction</code>. The action requires
123      * that the selection provided by the site's selection provider is of type <code>
124      * org.eclipse.jface.viewers.IStructuredSelection</code>.
125      *
126      * @param site the site providing context information for this action
127      */

128     public FormatAllAction(IWorkbenchSite site) {
129         super(site);
130         setText(ActionMessages.FormatAllAction_label);
131         setToolTipText(ActionMessages.FormatAllAction_tooltip);
132         setDescription(ActionMessages.FormatAllAction_description);
133
134         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.FORMAT_ALL);
135     }
136     
137     
138     /* (non-Javadoc)
139      * Method declared on SelectionDispatchAction.
140      */

141     public void selectionChanged(ITextSelection selection) {
142         // do nothing
143
}
144     
145     /* (non-Javadoc)
146      * Method declared on SelectionDispatchAction.
147      */

148     public void selectionChanged(IStructuredSelection selection) {
149         setEnabled(isEnabled(selection));
150     }
151     
152     private ICompilationUnit[] getCompilationUnits(IStructuredSelection selection) {
153         HashSet JavaDoc result= new HashSet JavaDoc();
154         Object JavaDoc[] selected= selection.toArray();
155         for (int i= 0; i < selected.length; i++) {
156             try {
157                 if (selected[i] instanceof IJavaElement) {
158                     IJavaElement elem= (IJavaElement) selected[i];
159                     if (elem.exists()) {
160                     
161                         switch (elem.getElementType()) {
162                             case IJavaElement.TYPE:
163                                 if (elem.getParent().getElementType() == IJavaElement.COMPILATION_UNIT) {
164                                     result.add(elem.getParent());
165                                 }
166                                 break;
167                             case IJavaElement.COMPILATION_UNIT:
168                                 result.add(elem);
169                                 break;
170                             case IJavaElement.PACKAGE_FRAGMENT:
171                                 collectCompilationUnits((IPackageFragment) elem, result);
172                                 break;
173                             case IJavaElement.PACKAGE_FRAGMENT_ROOT:
174                                 collectCompilationUnits((IPackageFragmentRoot) elem, result);
175                                 break;
176                             case IJavaElement.JAVA_PROJECT:
177                                 IPackageFragmentRoot[] roots= ((IJavaProject) elem).getPackageFragmentRoots();
178                                 for (int k= 0; k < roots.length; k++) {
179                                     collectCompilationUnits(roots[k], result);
180                                 }
181                                 break;
182                         }
183                     }
184                 } else if (selected[i] instanceof LogicalPackage) {
185                     IPackageFragment[] packageFragments= ((LogicalPackage)selected[i]).getFragments();
186                     for (int k= 0; k < packageFragments.length; k++) {
187                         IPackageFragment pack= packageFragments[k];
188                         if (pack.exists()) {
189                             collectCompilationUnits(pack, result);
190                         }
191                     }
192                 }
193             } catch (JavaModelException e) {
194                 JavaPlugin.log(e);
195             }
196         }
197         return (ICompilationUnit[]) result.toArray(new ICompilationUnit[result.size()]);
198     }
199     
200     private void collectCompilationUnits(IPackageFragment pack, Collection JavaDoc result) throws JavaModelException {
201         result.addAll(Arrays.asList(pack.getCompilationUnits()));
202     }
203
204     private void collectCompilationUnits(IPackageFragmentRoot root, Collection JavaDoc result) throws JavaModelException {
205         if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
206             IJavaElement[] children= root.getChildren();
207             for (int i= 0; i < children.length; i++) {
208                 collectCompilationUnits((IPackageFragment) children[i], result);
209             }
210         }
211     }
212     
213     private boolean isEnabled(IStructuredSelection selection) {
214         Object JavaDoc[] selected= selection.toArray();
215         for (int i= 0; i < selected.length; i++) {
216             try {
217                 if (selected[i] instanceof IJavaElement) {
218                     IJavaElement elem= (IJavaElement) selected[i];
219                     if (elem.exists()) {
220                         switch (elem.getElementType()) {
221                             case IJavaElement.TYPE:
222                                 return elem.getParent().getElementType() == IJavaElement.COMPILATION_UNIT; // for browsing perspective
223
case IJavaElement.COMPILATION_UNIT:
224                                 return true;
225                             case IJavaElement.PACKAGE_FRAGMENT:
226                             case IJavaElement.PACKAGE_FRAGMENT_ROOT:
227                                 IPackageFragmentRoot root= (IPackageFragmentRoot) elem.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
228                                 return (root.getKind() == IPackageFragmentRoot.K_SOURCE);
229                             case IJavaElement.JAVA_PROJECT:
230                                 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=65638
231
return true;
232                         }
233                     }
234                 } else if (selected[i] instanceof LogicalPackage) {
235                     return true;
236                 }
237             } catch (JavaModelException e) {
238                 if (JavaModelUtil.isExceptionToBeLogged(e))
239                     JavaPlugin.log(e);
240             }
241         }
242         return false;
243     }
244     
245     /* (non-Javadoc)
246      * Method declared on SelectionDispatchAction.
247      */

248     public void run(ITextSelection selection) {
249     }
250     
251     /* (non-Javadoc)
252      * Method declared on SelectionDispatchAction.
253      */

254     public void run(IStructuredSelection selection) {
255         ICompilationUnit[] cus= getCompilationUnits(selection);
256         if (cus.length == 0) {
257             MessageDialog.openInformation(getShell(), ActionMessages.FormatAllAction_EmptySelection_title, ActionMessages.FormatAllAction_EmptySelection_description);
258             return;
259         }
260         try {
261             if (cus.length == 1) {
262                 JavaUI.openInEditor(cus[0]);
263             } else {
264                 int returnCode= OptionalMessageDialog.open("FormatAll", //$NON-NLS-1$
265
getShell(),
266                         ActionMessages.FormatAllAction_noundo_title,
267                         null,
268                         ActionMessages.FormatAllAction_noundo_message,
269                         MessageDialog.WARNING,
270                         new String JavaDoc[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL},
271                         0);
272                 if (returnCode != OptionalMessageDialog.NOT_SHOWN && returnCode != Window.OK )
273                     return;
274             }
275         } catch (CoreException e) {
276             ExceptionHandler.handle(e, getShell(), ActionMessages.FormatAllAction_error_title, ActionMessages.FormatAllAction_error_message);
277         }
278         runOnMultiple(cus);
279     }
280
281     private IResource[] getResources(ICompilationUnit[] cus) {
282         IResource[] res= new IResource[cus.length];
283         for (int i= 0; i < res.length; i++) {
284             res[i]= cus[i].getResource();
285         }
286         return res;
287     }
288
289     /**
290      * Perform format all on the given compilation units.
291      * @param cus The compilation units to format.
292      */

293     public void runOnMultiple(final ICompilationUnit[] cus) {
294         try {
295             final MultiStatus status= new MultiStatus(JavaUI.ID_PLUGIN, IStatus.OK, ActionMessages.FormatAllAction_status_description, null);
296             
297             IStatus valEditStatus= Resources.makeCommittable(getResources(cus), getShell());
298             if (valEditStatus.matches(IStatus.CANCEL)) {
299                 return;
300             }
301             status.merge(valEditStatus);
302             if (!status.matches(IStatus.ERROR)) {
303                 PlatformUI.getWorkbench().getProgressService().run(true, true, new WorkbenchRunnableAdapter(new IWorkspaceRunnable() {
304                     public void run(IProgressMonitor monitor) {
305                         doRunOnMultiple(cus, status, monitor);
306                     }
307                 })); // workspace lock
308
}
309             if (!status.isOK()) {
310                 String JavaDoc title= ActionMessages.FormatAllAction_multi_status_title;
311                 ErrorDialog.openError(getShell(), title, null, status);
312             }
313         } catch (InvocationTargetException JavaDoc e) {
314             ExceptionHandler.handle(e, getShell(), ActionMessages.FormatAllAction_error_title, ActionMessages.FormatAllAction_error_message);
315         } catch (InterruptedException JavaDoc e) {
316             // Canceled by user
317
}
318     }
319     
320     private static Map JavaDoc getFomatterSettings(IJavaProject project) {
321         return new HashMap JavaDoc(project.getOptions(true));
322     }
323     
324     private void doFormat(IDocument document, Map JavaDoc options) {
325         final IFormattingContext context = new CommentFormattingContext();
326         try {
327             context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, options);
328             context.setProperty(FormattingContextProperties.CONTEXT_DOCUMENT, Boolean.valueOf(true));
329             
330             final MultiPassContentFormatter formatter= new MultiPassContentFormatter(IJavaPartitions.JAVA_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);
331             
332             formatter.setMasterStrategy(new JavaFormattingStrategy());
333             formatter.setSlaveStrategy(new CommentFormattingStrategy(), IJavaPartitions.JAVA_DOC);
334             formatter.setSlaveStrategy(new CommentFormattingStrategy(), IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
335             formatter.setSlaveStrategy(new CommentFormattingStrategy(), IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
336
337             try {
338                 startSequentialRewriteMode(document);
339                 formatter.format(document, context);
340             } finally {
341                 stopSequentialRewriteMode(document);
342             }
343         } finally {
344             context.dispose();
345         }
346     }
347
348     private void startSequentialRewriteMode(IDocument document) {
349         if (document instanceof IDocumentExtension4) {
350             IDocumentExtension4 extension= (IDocumentExtension4) document;
351             fRewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
352         } else if (document instanceof IDocumentExtension) {
353             IDocumentExtension extension= (IDocumentExtension) document;
354             extension.startSequentialRewrite(false);
355         }
356     }
357     
358     private void stopSequentialRewriteMode(IDocument document) {
359         if (document instanceof IDocumentExtension4) {
360             IDocumentExtension4 extension= (IDocumentExtension4) document;
361             extension.stopRewriteSession(fRewriteSession);
362         } else if (document instanceof IDocumentExtension) {
363             IDocumentExtension extension= (IDocumentExtension)document;
364             extension.stopSequentialRewrite();
365         }
366     }
367     
368     private void doRunOnMultiple(ICompilationUnit[] cus, MultiStatus status, IProgressMonitor monitor) throws OperationCanceledException {
369         if (monitor == null) {
370             monitor= new NullProgressMonitor();
371         }
372         monitor.setTaskName(ActionMessages.FormatAllAction_operation_description);
373     
374         monitor.beginTask("", cus.length * 4); //$NON-NLS-1$
375
try {
376             Map JavaDoc lastOptions= null;
377             IJavaProject lastProject= null;
378             
379             for (int i= 0; i < cus.length; i++) {
380                 ICompilationUnit cu= cus[i];
381                 IPath path= cu.getPath();
382                 if (lastProject == null || !lastProject.equals(cu.getJavaProject())) {
383                     lastProject= cu.getJavaProject();
384                     lastOptions= getFomatterSettings(lastProject);
385                 }
386                 if (monitor.isCanceled()) {
387                     throw new OperationCanceledException();
388                 }
389                 if (cu.getResource().getResourceAttributes().isReadOnly()) {
390                     String JavaDoc message= Messages.format(ActionMessages.FormatAllAction_read_only_skipped, path.toString());
391                     status.add(new Status(IStatus.WARNING, JavaUI.ID_PLUGIN, IStatus.WARNING, message, null));
392                     continue;
393                 }
394                 
395                 ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
396                 try {
397                     try {
398                         manager.connect(path, LocationKind.IFILE, new SubProgressMonitor(monitor, 1));
399         
400                         monitor.subTask(path.makeRelative().toString());
401                         ITextFileBuffer fileBuffer= manager.getTextFileBuffer(path, LocationKind.IFILE);
402                         
403                         formatCompilationUnit(fileBuffer, lastOptions);
404                         
405                         if (fileBuffer.isDirty() && !fileBuffer.isShared()) {
406                             fileBuffer.commit(new SubProgressMonitor(monitor, 2), false);
407                         } else {
408                             monitor.worked(2);
409                         }
410                     } finally {
411                         manager.disconnect(path, LocationKind.IFILE, new SubProgressMonitor(monitor, 1));
412                     }
413                 } catch (CoreException e) {
414                     String JavaDoc message= Messages.format(ActionMessages.FormatAllAction_problem_accessing, new String JavaDoc[] { path.toString(), e.getLocalizedMessage() });
415                     status.add(new Status(IStatus.WARNING, JavaUI.ID_PLUGIN, IStatus.WARNING, message, e));
416                 }
417             }
418         } finally {
419             monitor.done();
420         }
421     }
422     
423     private void formatCompilationUnit(final ITextFileBuffer fileBuffer, final Map JavaDoc options) {
424         if (fileBuffer.isShared()) {
425             getShell().getDisplay().syncExec(new Runnable JavaDoc() {
426                 public void run() {
427                     doFormat(fileBuffer.getDocument(), options);
428                 }
429             });
430         } else {
431             doFormat(fileBuffer.getDocument(), options); // run in context thread
432
}
433     }
434     
435 }
436
Popular Tags