001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Alex Blewitt - Bug 133277 Allow Sort Members to be performed on package and project levels
011: *******************************************************************************/package org.eclipse.jdt.internal.ui.actions;
012:
013: import java.lang.reflect.InvocationTargetException;
014: import java.util.Arrays;
015: import java.util.Collection;
016: import java.util.HashSet;
017:
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IAdaptable;
020: import org.eclipse.core.runtime.IStatus;
021: import org.eclipse.core.runtime.MultiStatus;
022: import org.eclipse.core.runtime.Status;
023:
024: import org.eclipse.jface.dialogs.ErrorDialog;
025: import org.eclipse.jface.dialogs.MessageDialog;
026: import org.eclipse.jface.viewers.IStructuredSelection;
027:
028: import org.eclipse.jface.text.ITextSelection;
029:
030: import org.eclipse.ui.IWorkbenchSite;
031: import org.eclipse.ui.IWorkingSet;
032:
033: import org.eclipse.jdt.core.ICompilationUnit;
034: import org.eclipse.jdt.core.IJavaElement;
035: import org.eclipse.jdt.core.IJavaProject;
036: import org.eclipse.jdt.core.IPackageFragment;
037: import org.eclipse.jdt.core.IPackageFragmentRoot;
038: import org.eclipse.jdt.core.JavaModelException;
039:
040: import org.eclipse.jdt.internal.corext.refactoring.RefactoringExecutionStarter;
041: import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
042: import org.eclipse.jdt.internal.corext.util.Messages;
043:
044: import org.eclipse.jdt.ui.JavaUI;
045: import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
046:
047: import org.eclipse.jdt.internal.ui.JavaPlugin;
048: import org.eclipse.jdt.internal.ui.browsing.LogicalPackage;
049: import org.eclipse.jdt.internal.ui.fix.ICleanUp;
050: import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
051: import org.eclipse.jdt.internal.ui.util.ElementValidator;
052: import org.eclipse.jdt.internal.ui.workingsets.JavaWorkingSetUpdater;
053:
054: public abstract class CleanUpAction extends SelectionDispatchAction {
055:
056: private JavaEditor fEditor;
057:
058: public CleanUpAction(IWorkbenchSite site) {
059: super (site);
060: }
061:
062: /**
063: * Note: This constructor is for internal use only. Clients should not call
064: * this constructor.
065: *
066: * @param editor
067: * the Java editor
068: */
069: public CleanUpAction(JavaEditor editor) {
070: this (editor.getEditorSite());
071: fEditor = editor;
072: setEnabled(getCompilationUnit(fEditor) != null);
073: }
074:
075: /**
076: * @return the name of this action, not <b>null</b>
077: */
078: protected abstract String getActionName();
079:
080: /**
081: * @param units
082: * the units to clean up
083: * @return the clean ups to be performed or <b>null</b> if none to be
084: * performed
085: */
086: protected abstract ICleanUp[] createCleanUps(
087: ICompilationUnit[] units);
088:
089: /**
090: * @param units
091: * to clean up
092: * @param cleanUps
093: * clean ups to execute on units
094: *
095: * @throws JavaModelException
096: * @throws InvocationTargetException
097: */
098: protected void performRefactoring(ICompilationUnit[] units,
099: ICleanUp[] cleanUps) throws JavaModelException,
100: InvocationTargetException {
101: RefactoringExecutionStarter.startCleanupRefactoring(units,
102: cleanUps, getShell(), false, getActionName());
103: }
104:
105: public void run(ITextSelection selection) {
106: ICompilationUnit cu = getCompilationUnit(fEditor);
107: if (cu != null) {
108: run(cu);
109: }
110: }
111:
112: public void run(IStructuredSelection selection) {
113: ICompilationUnit[] cus = getCompilationUnits(selection);
114: if (cus.length == 0) {
115: MessageDialog
116: .openInformation(
117: getShell(),
118: getActionName(),
119: ActionMessages.CleanUpAction_EmptySelection_description);
120: } else if (cus.length == 1) {
121: run(cus[0]);
122: } else {
123: runOnMultiple(cus);
124: }
125: }
126:
127: public void selectionChanged(ITextSelection selection) {
128: setEnabled(getCompilationUnit(fEditor) != null);
129: }
130:
131: public void selectionChanged(IStructuredSelection selection) {
132: setEnabled(isEnabled(selection));
133: }
134:
135: private boolean isEnabled(IStructuredSelection selection) {
136: Object[] selected = selection.toArray();
137: for (int i = 0; i < selected.length; i++) {
138: try {
139: if (selected[i] instanceof IJavaElement) {
140: IJavaElement elem = (IJavaElement) selected[i];
141: if (elem.exists()) {
142: switch (elem.getElementType()) {
143: case IJavaElement.TYPE:
144: return elem.getParent().getElementType() == IJavaElement.COMPILATION_UNIT; // for browsing perspective
145: case IJavaElement.COMPILATION_UNIT:
146: return true;
147: case IJavaElement.IMPORT_CONTAINER:
148: return true;
149: case IJavaElement.PACKAGE_FRAGMENT:
150: case IJavaElement.PACKAGE_FRAGMENT_ROOT:
151: IPackageFragmentRoot root = (IPackageFragmentRoot) elem
152: .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
153: return (root.getKind() == IPackageFragmentRoot.K_SOURCE);
154: case IJavaElement.JAVA_PROJECT:
155: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=65638
156: return true;
157: }
158: }
159: } else if (selected[i] instanceof LogicalPackage) {
160: return true;
161: } else if (selected[i] instanceof IWorkingSet) {
162: IWorkingSet workingSet = (IWorkingSet) selected[i];
163: return JavaWorkingSetUpdater.ID.equals(workingSet
164: .getId());
165: }
166: } catch (JavaModelException e) {
167: if (!e.isDoesNotExist()) {
168: JavaPlugin.log(e);
169: }
170: }
171: }
172: return false;
173: }
174:
175: private void run(ICompilationUnit cu) {
176: if (!ActionUtil.isEditable(fEditor, getShell(), cu))
177: return;
178:
179: ICleanUp[] cleanUps = createCleanUps(new ICompilationUnit[] { cu });
180: if (cleanUps == null)
181: return;
182:
183: if (!ElementValidator.check(cu, getShell(), getActionName(),
184: fEditor != null))
185: return;
186:
187: try {
188: performRefactoring(new ICompilationUnit[] { cu }, cleanUps);
189: } catch (InvocationTargetException e) {
190: JavaPlugin.log(e);
191: if (e.getCause() instanceof CoreException)
192: showUnexpectedError((CoreException) e.getCause());
193: } catch (JavaModelException e) {
194: showUnexpectedError(e);
195: }
196: }
197:
198: private void runOnMultiple(final ICompilationUnit[] cus) {
199: ICleanUp[] cleanUps = createCleanUps(cus);
200: if (cleanUps == null)
201: return;
202:
203: MultiStatus status = new MultiStatus(JavaUI.ID_PLUGIN,
204: IStatus.OK,
205: ActionMessages.CleanUpAction_MultiStateErrorTitle, null);
206: for (int i = 0; i < cus.length; i++) {
207: ICompilationUnit cu = cus[i];
208:
209: if (!ActionUtil.isOnBuildPath(cu)) {
210: String cuLocation = cu.getPath().makeRelative()
211: .toString();
212: String message = Messages
213: .format(
214: ActionMessages.CleanUpAction_CUNotOnBuildpathMessage,
215: cuLocation);
216: status.add(new Status(IStatus.INFO, JavaUI.ID_PLUGIN,
217: IStatus.ERROR, message, null));
218: }
219: }
220: if (!status.isOK()) {
221: ErrorDialog.openError(getShell(), getActionName(), null,
222: status);
223: return;
224: }
225:
226: try {
227: performRefactoring(cus, cleanUps);
228: } catch (InvocationTargetException e) {
229: JavaPlugin.log(e);
230: if (e.getCause() instanceof CoreException)
231: showUnexpectedError((CoreException) e.getCause());
232: } catch (JavaModelException e) {
233: showUnexpectedError(e);
234: }
235: }
236:
237: private void showUnexpectedError(CoreException e) {
238: String message2 = Messages.format(
239: ActionMessages.CleanUpAction_UnexpectedErrorMessage, e
240: .getStatus().getMessage());
241: IStatus status = new Status(IStatus.ERROR, JavaUI.ID_PLUGIN,
242: IStatus.ERROR, message2, null);
243: ErrorDialog
244: .openError(getShell(), getActionName(), null, status);
245: }
246:
247: public ICompilationUnit[] getCompilationUnits(
248: IStructuredSelection selection) {
249: HashSet result = new HashSet();
250: Object[] selected = selection.toArray();
251: for (int i = 0; i < selected.length; i++) {
252: Object element = selected[i];
253: collectCompilationUnits(element, result);
254: }
255: return (ICompilationUnit[]) result
256: .toArray(new ICompilationUnit[result.size()]);
257: }
258:
259: private void collectCompilationUnits(Object element,
260: Collection result) {
261: try {
262: if (element instanceof IJavaElement) {
263: IJavaElement elem = (IJavaElement) element;
264: if (elem.exists()) {
265: switch (elem.getElementType()) {
266: case IJavaElement.TYPE:
267: if (elem.getParent().getElementType() == IJavaElement.COMPILATION_UNIT) {
268: result.add(elem.getParent());
269: }
270: break;
271: case IJavaElement.COMPILATION_UNIT:
272: result.add(elem);
273: break;
274: case IJavaElement.IMPORT_CONTAINER:
275: result.add(elem.getParent());
276: break;
277: case IJavaElement.PACKAGE_FRAGMENT:
278: collectCompilationUnits(
279: (IPackageFragment) elem, result);
280: break;
281: case IJavaElement.PACKAGE_FRAGMENT_ROOT:
282: collectCompilationUnits(
283: (IPackageFragmentRoot) elem, result);
284: break;
285: case IJavaElement.JAVA_PROJECT:
286: IPackageFragmentRoot[] roots = ((IJavaProject) elem)
287: .getPackageFragmentRoots();
288: for (int k = 0; k < roots.length; k++) {
289: collectCompilationUnits(roots[k], result);
290: }
291: break;
292: }
293: }
294: } else if (element instanceof LogicalPackage) {
295: IPackageFragment[] packageFragments = ((LogicalPackage) element)
296: .getFragments();
297: for (int k = 0; k < packageFragments.length; k++) {
298: IPackageFragment pack = packageFragments[k];
299: if (pack.exists()) {
300: collectCompilationUnits(pack, result);
301: }
302: }
303: } else if (element instanceof IWorkingSet) {
304: IWorkingSet workingSet = (IWorkingSet) element;
305: IAdaptable[] elements = workingSet.getElements();
306: for (int j = 0; j < elements.length; j++) {
307: collectCompilationUnits(elements[j], result);
308: }
309: }
310: } catch (JavaModelException e) {
311: if (JavaModelUtil.isExceptionToBeLogged(e))
312: JavaPlugin.log(e);
313: }
314: }
315:
316: private void collectCompilationUnits(IPackageFragment pack,
317: Collection result) throws JavaModelException {
318: result.addAll(Arrays.asList(pack.getCompilationUnits()));
319: }
320:
321: private void collectCompilationUnits(IPackageFragmentRoot root,
322: Collection result) throws JavaModelException {
323: if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
324: IJavaElement[] children = root.getChildren();
325: for (int i = 0; i < children.length; i++) {
326: collectCompilationUnits((IPackageFragment) children[i],
327: result);
328: }
329: }
330: }
331:
332: private static ICompilationUnit getCompilationUnit(JavaEditor editor) {
333: IJavaElement element = JavaUI.getEditorInputJavaElement(editor
334: .getEditorInput());
335: if (!(element instanceof ICompilationUnit))
336: return null;
337:
338: return (ICompilationUnit) element;
339: }
340:
341: }
|