/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.ui.actions; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.wst.jsdt.core.IJavaScriptUnit; import org.eclipse.wst.jsdt.core.IJavaScriptElement; import org.eclipse.wst.jsdt.core.IJavaScriptProject; import org.eclipse.wst.jsdt.core.IPackageFragment; import org.eclipse.wst.jsdt.core.IPackageFragmentRoot; import org.eclipse.wst.jsdt.core.JavaScriptModelException; import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringExecutionStarter; import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil; import org.eclipse.wst.jsdt.internal.corext.util.Messages; import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin; import org.eclipse.wst.jsdt.internal.ui.browsing.LogicalPackage; import org.eclipse.wst.jsdt.internal.ui.fix.ICleanUp; import org.eclipse.wst.jsdt.internal.ui.javaeditor.JavaEditor; import org.eclipse.wst.jsdt.internal.ui.util.ElementValidator; import org.eclipse.wst.jsdt.ui.JavaScriptUI; import org.eclipse.wst.jsdt.ui.actions.SelectionDispatchAction; public abstract class CleanUpAction extends SelectionDispatchAction { private JavaEditor fEditor; public CleanUpAction(IWorkbenchSite site) { super(site); } /** * Note: This constructor is for internal use only. Clients should not call * this constructor. * * @param editor * the Java editor */ public CleanUpAction(JavaEditor editor) { this(editor.getEditorSite()); fEditor= editor; setEnabled(getCompilationUnit(fEditor) != null); } /** * @return the name of this action, not <b>null</b> */ protected abstract String getActionName(); /** * @param units * the units to clean up * @return the clean ups to be performed or <b>null</b> if none to be * performed */ protected abstract ICleanUp[] createCleanUps(IJavaScriptUnit[] units); /** * @param units * to clean up * @param cleanUps * clean ups to execute on units * * @throws JavaScriptModelException * @throws InvocationTargetException */ protected void performRefactoring(IJavaScriptUnit[] units, ICleanUp[] cleanUps) throws JavaScriptModelException, InvocationTargetException { RefactoringExecutionStarter.startCleanupRefactoring(units, cleanUps, getShell(), false, getActionName()); } public void run(ITextSelection selection) { IJavaScriptUnit cu= getCompilationUnit(fEditor); if (cu != null) { run(cu); } } public void run(IStructuredSelection selection) { IJavaScriptUnit[] cus= getCompilationUnits(selection); if (cus.length == 0) { MessageDialog.openInformation(getShell(), getActionName(), ActionMessages.CleanUpAction_EmptySelection_description); } else if (cus.length == 1) { run(cus[0]); } else { runOnMultiple(cus); } } public void selectionChanged(ITextSelection selection) { setEnabled(getCompilationUnit(fEditor) != null); } public void selectionChanged(IStructuredSelection selection) { setEnabled(isEnabled(selection)); } private boolean isEnabled(IStructuredSelection selection) { Object[] selected= selection.toArray(); for (int i= 0; i < selected.length; i++) { try { if (selected[i] instanceof IJavaScriptElement) { IJavaScriptElement elem= (IJavaScriptElement)selected[i]; if (elem.exists()) { switch (elem.getElementType()) { case IJavaScriptElement.TYPE: return elem.getParent().getElementType() == IJavaScriptElement.JAVASCRIPT_UNIT; // for browsing perspective case IJavaScriptElement.JAVASCRIPT_UNIT: return true; case IJavaScriptElement.IMPORT_CONTAINER: return true; case IJavaScriptElement.PACKAGE_FRAGMENT: case IJavaScriptElement.PACKAGE_FRAGMENT_ROOT: IPackageFragmentRoot root= (IPackageFragmentRoot)elem.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT_ROOT); return (root.getKind() == IPackageFragmentRoot.K_SOURCE); case IJavaScriptElement.JAVASCRIPT_PROJECT: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=65638 return true; } } } else if (selected[i] instanceof LogicalPackage) { return true; } } catch (JavaScriptModelException e) { if (!e.isDoesNotExist()) { JavaScriptPlugin.log(e); } } } return false; } private void run(IJavaScriptUnit cu) { if (!ActionUtil.isEditable(fEditor, getShell(), cu)) return; ICleanUp[] cleanUps= createCleanUps(new IJavaScriptUnit[] { cu }); if (cleanUps == null) return; if (!ElementValidator.check(cu, getShell(), getActionName(), fEditor != null)) return; try { performRefactoring(new IJavaScriptUnit[] { cu }, cleanUps); } catch (InvocationTargetException e) { JavaScriptPlugin.log(e); if (e.getCause() instanceof CoreException) showUnexpectedError((CoreException)e.getCause()); } catch (JavaScriptModelException e) { showUnexpectedError(e); } } private void runOnMultiple(final IJavaScriptUnit[] cus) { ICleanUp[] cleanUps= createCleanUps(cus); if (cleanUps == null) return; MultiStatus status= new MultiStatus(JavaScriptUI.ID_PLUGIN, IStatus.OK, ActionMessages.CleanUpAction_MultiStateErrorTitle, null); for (int i= 0; i < cus.length; i++) { IJavaScriptUnit cu= cus[i]; if (!ActionUtil.isOnBuildPath(cu)) { String cuLocation= cu.getPath().makeRelative().toString(); String message= Messages.format(ActionMessages.CleanUpAction_CUNotOnBuildpathMessage, cuLocation); status.add(new Status(IStatus.INFO, JavaScriptUI.ID_PLUGIN, IStatus.ERROR, message, null)); } } if (!status.isOK()) { ErrorDialog.openError(getShell(), getActionName(), null, status); return; } try { performRefactoring(cus, cleanUps); } catch (InvocationTargetException e) { JavaScriptPlugin.log(e); if (e.getCause() instanceof CoreException) showUnexpectedError((CoreException)e.getCause()); } catch (JavaScriptModelException e) { showUnexpectedError(e); } } private void showUnexpectedError(CoreException e) { String message2= Messages.format(ActionMessages.CleanUpAction_UnexpectedErrorMessage, e.getStatus().getMessage()); IStatus status= new Status(IStatus.ERROR, JavaScriptUI.ID_PLUGIN, IStatus.ERROR, message2, null); ErrorDialog.openError(getShell(), getActionName(), null, status); } public IJavaScriptUnit[] getCompilationUnits(IStructuredSelection selection) { HashSet result= new HashSet(); Object[] selected= selection.toArray(); for (int i= 0; i < selected.length; i++) { try { if (selected[i] instanceof IJavaScriptElement) { IJavaScriptElement elem= (IJavaScriptElement)selected[i]; if (elem.exists()) { switch (elem.getElementType()) { case IJavaScriptElement.TYPE: if (elem.getParent().getElementType() == IJavaScriptElement.JAVASCRIPT_UNIT) { result.add(elem.getParent()); } break; case IJavaScriptElement.JAVASCRIPT_UNIT: result.add(elem); break; case IJavaScriptElement.IMPORT_CONTAINER: result.add(elem.getParent()); break; case IJavaScriptElement.PACKAGE_FRAGMENT: collectCompilationUnits((IPackageFragment)elem, result); break; case IJavaScriptElement.PACKAGE_FRAGMENT_ROOT: collectCompilationUnits((IPackageFragmentRoot)elem, result); break; case IJavaScriptElement.JAVASCRIPT_PROJECT: IPackageFragmentRoot[] roots= ((IJavaScriptProject)elem).getPackageFragmentRoots(); for (int k= 0; k < roots.length; k++) { collectCompilationUnits(roots[k], result); } break; } } } else if (selected[i] instanceof LogicalPackage) { IPackageFragment[] packageFragments= ((LogicalPackage)selected[i]).getFragments(); for (int k= 0; k < packageFragments.length; k++) { IPackageFragment pack= packageFragments[k]; if (pack.exists()) { collectCompilationUnits(pack, result); } } } } catch (JavaScriptModelException e) { if (JavaModelUtil.isExceptionToBeLogged(e)) JavaScriptPlugin.log(e); } } return (IJavaScriptUnit[])result.toArray(new IJavaScriptUnit[result.size()]); } private void collectCompilationUnits(IPackageFragment pack, Collection result) throws JavaScriptModelException { result.addAll(Arrays.asList(pack.getJavaScriptUnits())); } private void collectCompilationUnits(IPackageFragmentRoot root, Collection result) throws JavaScriptModelException { if (root.getKind() == IPackageFragmentRoot.K_SOURCE) { IJavaScriptElement[] children= root.getChildren(); for (int i= 0; i < children.length; i++) { collectCompilationUnits((IPackageFragment)children[i], result); } } } private static IJavaScriptUnit getCompilationUnit(JavaEditor editor) { IJavaScriptElement element= JavaScriptUI.getEditorInputJavaElement(editor.getEditorInput()); if (!(element instanceof IJavaScriptUnit)) return null; return (IJavaScriptUnit)element; } }