| /******************************************************************************* |
| * 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.ui.actions; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IWorkbenchSite; |
| import org.eclipse.ui.PlatformUI; |
| 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.core.compiler.InvalidInputException; |
| import org.eclipse.wst.jsdt.internal.corext.refactoring.nls.NLSElement; |
| import org.eclipse.wst.jsdt.internal.corext.refactoring.nls.NLSLine; |
| import org.eclipse.wst.jsdt.internal.corext.refactoring.nls.NLSRefactoring; |
| import org.eclipse.wst.jsdt.internal.corext.refactoring.nls.NLSScanner; |
| import org.eclipse.wst.jsdt.internal.corext.refactoring.reorg.ReorgUtils; |
| 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.IJavaHelpContextIds; |
| import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin; |
| import org.eclipse.wst.jsdt.internal.ui.actions.ActionMessages; |
| import org.eclipse.wst.jsdt.internal.ui.refactoring.RefactoringSaveHelper; |
| import org.eclipse.wst.jsdt.internal.ui.refactoring.actions.ListDialog; |
| import org.eclipse.wst.jsdt.internal.ui.refactoring.actions.RefactoringStarter; |
| import org.eclipse.wst.jsdt.internal.ui.refactoring.nls.ExternalizeWizard; |
| import org.eclipse.wst.jsdt.internal.ui.util.ExceptionHandler; |
| import org.eclipse.wst.jsdt.ui.JavaScriptElementLabelProvider; |
| |
| /** |
| * Find all strings in a package or project that are not externalized yet. |
| * <p> |
| * The action is applicable to selections containing projects or packages. |
| * |
| * <p> |
| * This class may be instantiated; it is not intended to be subclassed. |
| * </p> |
| * |
| * |
| * Provisional API: This class/interface is part of an interim API that is still under development and expected to |
| * change significantly before reaching stability. It is being made available at this early stage to solicit feedback |
| * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken |
| * (repeatedly) as the API evolves. |
| * @deprecated use {@link ExternalizeStringsAction} instead |
| */ |
| public class FindStringsToExternalizeAction extends SelectionDispatchAction { |
| |
| private NonNLSElement[] fElements; |
| |
| /** |
| * Creates a new <code>FindStringsToExternalizeAction</code>. The action |
| * requires that the selection provided by the site's selection provider is of type |
| * <code>org.eclipse.jface.viewers.IStructuredSelection</code>. |
| * |
| * @param site the site providing context information for this action |
| */ |
| public FindStringsToExternalizeAction(IWorkbenchSite site) { |
| super(site); |
| setText(ActionMessages.FindStringsToExternalizeAction_label); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.FIND_STRINGS_TO_EXTERNALIZE_ACTION); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on SelectionDispatchAction. |
| */ |
| public void selectionChanged(IStructuredSelection selection) { |
| try { |
| setEnabled(computeEnablementState(selection)); |
| } catch (JavaScriptModelException e) { |
| if (JavaModelUtil.isExceptionToBeLogged(e)) |
| JavaScriptPlugin.log(e); |
| setEnabled(false);//no UI - happens on selection changes |
| } |
| } |
| |
| private boolean computeEnablementState(IStructuredSelection selection) throws JavaScriptModelException { |
| if (selection.isEmpty()) |
| return false; |
| for (Iterator iter= selection.iterator(); iter.hasNext();) { |
| Object element= iter.next(); |
| if (!(element instanceof IJavaScriptElement)) |
| return false; |
| IJavaScriptElement javaElement= (IJavaScriptElement)element; |
| if (! javaElement.exists() || javaElement.isReadOnly()) |
| return false; |
| int elementType= javaElement.getElementType(); |
| if (elementType != IJavaScriptElement.PACKAGE_FRAGMENT && |
| elementType != IJavaScriptElement.PACKAGE_FRAGMENT_ROOT && |
| elementType != IJavaScriptElement.JAVASCRIPT_PROJECT) |
| return false; |
| if (elementType == IJavaScriptElement.PACKAGE_FRAGMENT_ROOT){ |
| IPackageFragmentRoot root= (IPackageFragmentRoot)javaElement; |
| if (root.isExternal() || ReorgUtils.isClassFolder(root)) |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on SelectionDispatchAction. |
| */ |
| public void run(final IStructuredSelection selection) { |
| try { |
| PlatformUI.getWorkbench().getProgressService().run(true, true, createRunnable(selection)); |
| } catch(InvocationTargetException e) { |
| ExceptionHandler.handle(e, getShell(), |
| ActionMessages.FindStringsToExternalizeAction_dialog_title, |
| ActionMessages.FindStringsToExternalizeAction_error_message); |
| return; |
| } catch(InterruptedException e) { |
| // OK |
| return; |
| } |
| showResults(); |
| } |
| |
| private IRunnableWithProgress createRunnable(final IStructuredSelection selection) { |
| return new IRunnableWithProgress() { |
| public void run(IProgressMonitor pm) throws InvocationTargetException { |
| try { |
| fElements= doRun(selection, pm); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| }; |
| } |
| |
| private NonNLSElement[] doRun(IStructuredSelection selection, IProgressMonitor pm) throws CoreException { |
| List elements= getSelectedElementList(selection); |
| if (elements == null || elements.isEmpty()) |
| return new NonNLSElement[0]; |
| |
| pm.beginTask(ActionMessages.FindStringsToExternalizeAction_find_strings, elements.size()); |
| |
| try{ |
| List l= new ArrayList(); |
| for (Iterator iter= elements.iterator(); iter.hasNext();) { |
| IJavaScriptElement element= (IJavaScriptElement) iter.next(); |
| if (element.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT) |
| l.addAll(analyze((IPackageFragment) element, new SubProgressMonitor(pm, 1))); |
| else if (element.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT_ROOT) |
| l.addAll(analyze((IPackageFragmentRoot) element, new SubProgressMonitor(pm, 1))); |
| if (element.getElementType() == IJavaScriptElement.JAVASCRIPT_PROJECT) |
| l.addAll(analyze((IJavaScriptProject) element, new SubProgressMonitor(pm, 1))); |
| } |
| return (NonNLSElement[]) l.toArray(new NonNLSElement[l.size()]); |
| } finally{ |
| pm.done(); |
| } |
| } |
| |
| private void showResults() { |
| if (noStrings()) |
| MessageDialog.openInformation(getShell(), getDialogTitle(), ActionMessages.FindStringsToExternalizeAction_noStrings); |
| else |
| new NonNLSListDialog(getShell(), fElements, countStrings()).open(); |
| } |
| |
| private boolean noStrings() { |
| if (fElements != null) { |
| for (int i= 0; i < fElements.length; i++) { |
| if (fElements[i].count != 0) |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /* |
| * returns List of Strings |
| */ |
| private List analyze(IPackageFragment pack, IProgressMonitor pm) throws CoreException { |
| try{ |
| if (pack == null) |
| return new ArrayList(0); |
| |
| IJavaScriptUnit[] cus= pack.getJavaScriptUnits(); |
| |
| pm.beginTask("", cus.length); //$NON-NLS-1$ |
| pm.setTaskName(pack.getElementName()); |
| |
| List l= new ArrayList(cus.length); |
| for (int i= 0; i < cus.length; i++){ |
| pm.subTask(cus[i].getElementName()); |
| NonNLSElement element= analyze(cus[i]); |
| if (element != null) |
| l.add(element); |
| pm.worked(1); |
| if (pm.isCanceled()) |
| throw new OperationCanceledException(); |
| } |
| return l; |
| } finally { |
| pm.done(); |
| } |
| } |
| |
| /* |
| * returns List of Strings |
| */ |
| private List analyze(IPackageFragmentRoot sourceFolder, IProgressMonitor pm) throws CoreException { |
| try{ |
| IJavaScriptElement[] children= sourceFolder.getChildren(); |
| pm.beginTask("", children.length); //$NON-NLS-1$ |
| pm.setTaskName(sourceFolder.getElementName()); |
| List result= new ArrayList(); |
| for (int i= 0; i < children.length; i++) { |
| IJavaScriptElement iJavaElement= children[i]; |
| if (iJavaElement.getElementType() == IJavaScriptElement.PACKAGE_FRAGMENT){ |
| IPackageFragment pack= (IPackageFragment)iJavaElement; |
| if (! pack.isReadOnly()) |
| result.addAll(analyze(pack, new SubProgressMonitor(pm, 1))); |
| else |
| pm.worked(1); |
| } else |
| pm.worked(1); |
| } |
| return result; |
| } finally{ |
| pm.done(); |
| } |
| } |
| |
| /* |
| * returns List of Strings |
| */ |
| private List analyze(IJavaScriptProject project, IProgressMonitor pm) throws CoreException { |
| try{ |
| IPackageFragment[] packs= project.getPackageFragments(); |
| pm.beginTask("", packs.length); //$NON-NLS-1$ |
| List result= new ArrayList(); |
| for (int i= 0; i < packs.length; i++) { |
| if (! packs[i].isReadOnly()) |
| result.addAll(analyze(packs[i], new SubProgressMonitor(pm, 1))); |
| else |
| pm.worked(1); |
| } |
| return result; |
| } finally{ |
| pm.done(); |
| } |
| } |
| |
| private int countStrings() { |
| int found= 0; |
| if (fElements != null) { |
| for (int i= 0; i < fElements.length; i++) |
| found+= fElements[i].count; |
| } |
| return found; |
| } |
| |
| private NonNLSElement analyze(IJavaScriptUnit cu) throws CoreException { |
| int count= countNonExternalizedStrings(cu); |
| if (count == 0) |
| return null; |
| else |
| return new NonNLSElement(cu, count); |
| } |
| |
| private int countNonExternalizedStrings(IJavaScriptUnit cu) throws CoreException { |
| try{ |
| NLSLine[] lines= NLSScanner.scan(cu); |
| int result= 0; |
| for (int i= 0; i < lines.length; i++) { |
| result += countNonExternalizedStrings(lines[i]); |
| } |
| return result; |
| } catch (InvalidInputException e) { |
| throw new CoreException(new Status(IStatus.ERROR, JavaScriptPlugin.getPluginId(), IStatus.ERROR, |
| Messages.format(ActionMessages.FindStringsToExternalizeAction_error_cannotBeParsed, cu.getElementName()), |
| e)); |
| } |
| } |
| |
| private int countNonExternalizedStrings(NLSLine line){ |
| int result= 0; |
| NLSElement[] elements= line.getElements(); |
| for (int i= 0; i < elements.length; i++){ |
| if (! elements[i].hasTag()) |
| result++; |
| } |
| return result; |
| } |
| |
| /** |
| * returns <code>List</code> of <code>IPackageFragments</code>, <code>IPackageFragmentRoots</code> or |
| * <code>IJavaProjects</code> (all entries are of the same kind) |
| */ |
| private static List getSelectedElementList(IStructuredSelection selection) { |
| if (selection == null) |
| return null; |
| |
| return selection.toList(); |
| } |
| |
| //-------private classes -------------- |
| |
| private static class NonNLSListDialog extends ListDialog { |
| |
| private static final int OPEN_BUTTON_ID= IDialogConstants.CLIENT_ID + 1; |
| |
| private Button fOpenButton; |
| |
| NonNLSListDialog(Shell parent, NonNLSElement[] input, int count) { |
| super(parent); |
| setInput(Arrays.asList(input)); |
| setTitle(ActionMessages.FindStringsToExternalizeAction_dialog_title); |
| setMessage(Messages.format(ActionMessages.FindStringsToExternalizeAction_non_externalized, new Object[] {new Integer(count)} )); |
| setContentProvider(new ArrayContentProvider()); |
| setLabelProvider(createLabelProvider()); |
| } |
| |
| public void create() { |
| setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN); |
| super.create(); |
| } |
| |
| protected Point getInitialSize() { |
| return getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); |
| } |
| |
| protected Control createDialogArea(Composite parent) { |
| Composite result= (Composite)super.createDialogArea(parent); |
| getTableViewer().addSelectionChangedListener(new ISelectionChangedListener(){ |
| public void selectionChanged(SelectionChangedEvent event){ |
| if (fOpenButton != null){ |
| fOpenButton.setEnabled(! getTableViewer().getSelection().isEmpty()); |
| } |
| } |
| }); |
| getTableViewer().getTable().addSelectionListener(new SelectionAdapter(){ |
| public void widgetDefaultSelected(SelectionEvent e) { |
| NonNLSElement element= (NonNLSElement)e.item.getData(); |
| openWizard(element.cu); |
| } |
| }); |
| getTableViewer().getTable().setFocus(); |
| applyDialogFont(result); |
| return result; |
| } |
| |
| protected void createButtonsForButtonBar(Composite parent) { |
| fOpenButton= createButton(parent, OPEN_BUTTON_ID, ActionMessages.FindStringsToExternalizeAction_button_label, true); |
| fOpenButton.setEnabled(false); |
| |
| //looks like a 'close' but it a 'cancel' |
| createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CLOSE_LABEL, false); |
| } |
| |
| protected void buttonPressed(int buttonId) { |
| if (buttonId != OPEN_BUTTON_ID){ |
| super.buttonPressed(buttonId); |
| return; |
| } |
| ISelection s= getTableViewer().getSelection(); |
| if (s instanceof IStructuredSelection){ |
| IStructuredSelection ss= (IStructuredSelection)s; |
| if (ss.getFirstElement() instanceof NonNLSElement) |
| openWizard(((NonNLSElement)ss.getFirstElement()).cu); |
| } |
| } |
| |
| private void openWizard(IJavaScriptUnit unit) { |
| try { |
| if (unit != null && unit.exists()) { |
| NLSRefactoring refactoring= NLSRefactoring.create(unit); |
| if (refactoring != null) |
| new RefactoringStarter().activate(refactoring, new ExternalizeWizard(refactoring), getShell(), ActionMessages.ExternalizeStringsAction_dialog_title, RefactoringSaveHelper.SAVE_NON_JAVA_UPDATES); |
| } |
| } catch (JavaScriptModelException e) { |
| ExceptionHandler.handle(e, |
| ActionMessages.FindStringsToExternalizeAction_dialog_title, |
| ActionMessages.FindStringsToExternalizeAction_error_message); |
| } |
| } |
| |
| private static LabelProvider createLabelProvider() { |
| return new JavaScriptElementLabelProvider(JavaScriptElementLabelProvider.SHOW_DEFAULT){ |
| public String getText(Object element) { |
| NonNLSElement nlsel= (NonNLSElement)element; |
| String elementName= nlsel.cu.getResource().getFullPath().toString(); |
| return Messages.format( |
| ActionMessages.FindStringsToExternalizeAction_foundStrings, |
| new Object[] {new Integer(nlsel.count), elementName} ); |
| } |
| public Image getImage(Object element) { |
| return super.getImage(((NonNLSElement)element).cu); |
| } |
| }; |
| } |
| |
| /* |
| * @see org.eclipse.jface.window.Window#configureShell(Shell) |
| */ |
| protected void configureShell(Shell newShell) { |
| super.configureShell(newShell); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IJavaHelpContextIds.NONNLS_DIALOG); |
| } |
| |
| |
| } |
| |
| private static class NonNLSElement{ |
| IJavaScriptUnit cu; |
| int count; |
| NonNLSElement(IJavaScriptUnit cu, int count){ |
| this.cu= cu; |
| this.count= count; |
| } |
| } |
| |
| private String getDialogTitle() { |
| return ActionMessages.FindStringsToExternalizeAction_dialog_title; |
| } |
| } |