KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.ArrayList JavaDoc;
15 import java.util.Arrays JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.OperationCanceledException;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.core.runtime.SubProgressMonitor;
25
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.custom.BusyIndicator;
28 import org.eclipse.swt.events.SelectionAdapter;
29 import org.eclipse.swt.events.SelectionEvent;
30 import org.eclipse.swt.graphics.Image;
31 import org.eclipse.swt.graphics.Point;
32 import org.eclipse.swt.widgets.Button;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.Control;
35 import org.eclipse.swt.widgets.Shell;
36
37 import org.eclipse.jface.dialogs.IDialogConstants;
38 import org.eclipse.jface.dialogs.MessageDialog;
39 import org.eclipse.jface.operation.IRunnableWithProgress;
40 import org.eclipse.jface.viewers.ArrayContentProvider;
41 import org.eclipse.jface.viewers.ISelection;
42 import org.eclipse.jface.viewers.ISelectionChangedListener;
43 import org.eclipse.jface.viewers.IStructuredSelection;
44 import org.eclipse.jface.viewers.LabelProvider;
45 import org.eclipse.jface.viewers.SelectionChangedEvent;
46
47 import org.eclipse.jface.text.ITextSelection;
48
49 import org.eclipse.ui.IWorkbenchSite;
50 import org.eclipse.ui.PlatformUI;
51
52 import org.eclipse.jdt.core.ICompilationUnit;
53 import org.eclipse.jdt.core.IJavaElement;
54 import org.eclipse.jdt.core.IJavaProject;
55 import org.eclipse.jdt.core.IPackageFragment;
56 import org.eclipse.jdt.core.IPackageFragmentRoot;
57 import org.eclipse.jdt.core.IType;
58 import org.eclipse.jdt.core.JavaModelException;
59 import org.eclipse.jdt.core.compiler.InvalidInputException;
60
61 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
62 import org.eclipse.jdt.internal.corext.refactoring.nls.NLSElement;
63 import org.eclipse.jdt.internal.corext.refactoring.nls.NLSLine;
64 import org.eclipse.jdt.internal.corext.refactoring.nls.NLSRefactoring;
65 import org.eclipse.jdt.internal.corext.refactoring.nls.NLSScanner;
66 import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
67 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
68 import org.eclipse.jdt.internal.corext.util.Messages;
69
70 import org.eclipse.jdt.ui.JavaElementLabelProvider;
71
72 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
73 import org.eclipse.jdt.internal.ui.JavaPlugin;
74 import org.eclipse.jdt.internal.ui.actions.ActionMessages;
75 import org.eclipse.jdt.internal.ui.actions.ActionUtil;
76 import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
77 import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
78 import org.eclipse.jdt.internal.ui.refactoring.RefactoringSaveHelper;
79 import org.eclipse.jdt.internal.ui.refactoring.actions.ListDialog;
80 import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter;
81 import org.eclipse.jdt.internal.ui.refactoring.nls.ExternalizeWizard;
82 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
83
84 /**
85  * Externalizes the strings of a compilation unit or find all strings
86  * in a package or project that are not externalized yet. Opens a wizard that
87  * gathers additional information to externalize the strings.
88  * <p>
89  * The action is applicable to structured selections containing elements
90  * of type <code>ICompilationUnit</code>, <code>IType</code>, <code>IJavaProject</code>,
91  * <code>IPackageFragment</code>, and <code>IPackageFragmentRoot</code>
92  *
93  * <p>
94  * This class may be instantiated; it is not intended to be subclassed.
95  * </p>
96  *
97  * @since 2.0
98  */

99 public class ExternalizeStringsAction extends SelectionDispatchAction {
100
101     private CompilationUnitEditor fEditor;
102     
103     private NonNLSElement[] fElements;
104
105     /**
106      * Creates a new <code>ExternalizeStringsAction</code>. The action requires
107      * that the selection provided by the site's selection provider is of type <code>
108      * org.eclipse.jface.viewers.IStructuredSelection</code>.
109      *
110      * @param site the site providing context information for this action
111      */

112     public ExternalizeStringsAction(IWorkbenchSite site) {
113         super(site);
114         setText(ActionMessages.ExternalizeStringsAction_label);
115         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.EXTERNALIZE_STRINGS_ACTION);
116     }
117
118     /**
119      * Note: This constructor is for internal use only. Clients should not call this constructor.
120      * @param editor the compilation unit editor
121      */

122     public ExternalizeStringsAction(CompilationUnitEditor editor) {
123         this(editor.getEditorSite());
124         fEditor= editor;
125         setEnabled(fEditor != null && SelectionConverter.canOperateOn(fEditor));
126     }
127     
128     /* (non-Javadoc)
129      * Method declared on SelectionDispatchAction.
130      */

131     public void selectionChanged(ITextSelection selection) {
132     }
133     
134     /* (non-Javadoc)
135      * Method declared on SelectionDispatchAction.
136      */

137     public void selectionChanged(IStructuredSelection selection) {
138         try {
139             setEnabled(RefactoringAvailabilityTester.isExternalizeStringsAvailable(selection));
140         } catch (JavaModelException e) {
141             if (JavaModelUtil.isExceptionToBeLogged(e))
142                 JavaPlugin.log(e);
143             setEnabled(false);//no UI - happens on selection changes
144
}
145     }
146
147     /* (non-Javadoc)
148      * Method declared on SelectionDispatchAction.
149      */

150     public void run(ITextSelection selection) {
151         IJavaElement element= SelectionConverter.getInput(fEditor);
152         if (!(element instanceof ICompilationUnit))
153             return;
154         run((ICompilationUnit)element);
155     }
156     
157     /* (non-Javadoc)
158      * Method declared on SelectionDispatchAction.
159      */

160     public void run(IStructuredSelection selection) {
161         ICompilationUnit unit= getCompilationUnit(selection);
162         if (unit != null) {//run on cu
163
run(unit);
164         } else {
165             //run on multiple
166
try {
167                 PlatformUI.getWorkbench().getProgressService().run(true, true, createRunnable(selection));
168             } catch(InvocationTargetException JavaDoc e) {
169                 ExceptionHandler.handle(e, getShell(),
170                     ActionMessages.ExternalizeStringsAction_dialog_title,
171                     ActionMessages.FindStringsToExternalizeAction_error_message);
172                 return;
173             } catch(InterruptedException JavaDoc e) {
174                 // OK
175
return;
176             }
177             showResults();
178         }
179     }
180     
181     /**
182      * Note: this method is for internal use only. Clients should not call this method.
183      */

184     public void run(final ICompilationUnit unit) {
185         if (!ActionUtil.isEditable(fEditor, getShell(), unit))
186             return;
187         
188         BusyIndicator.showWhile(getShell().getDisplay(), new Runnable JavaDoc() {
189             public void run() {
190                 try {
191                     if (unit != null && unit.exists()) {
192                         NLSRefactoring refactoring= NLSRefactoring.create(unit);
193                         if (refactoring != null)
194                             new RefactoringStarter().activate(refactoring, new ExternalizeWizard(refactoring), getShell(), ActionMessages.ExternalizeStringsAction_dialog_title, RefactoringSaveHelper.SAVE_NON_JAVA_UPDATES);
195                     }
196                 } catch(JavaModelException e) {
197                     ExceptionHandler.handle(e, getShell(), ActionMessages.ExternalizeStringsAction_dialog_title, ActionMessages.ExternalizeStringsAction_dialog_message);
198                 }
199             }
200         });
201     }
202
203     private static ICompilationUnit getCompilationUnit(IStructuredSelection selection) {
204         if (selection.isEmpty() || selection.size() != 1)
205             return null;
206         Object JavaDoc first= selection.getFirstElement();
207         if (first instanceof ICompilationUnit)
208             return (ICompilationUnit) first;
209         if (first instanceof IType)
210             return ((IType) first).getCompilationUnit();
211         return null;
212     }
213     
214     private IRunnableWithProgress createRunnable(final IStructuredSelection selection) {
215         return new IRunnableWithProgress() {
216             public void run(IProgressMonitor pm) throws InvocationTargetException JavaDoc {
217                 try {
218                     fElements= doRun(selection, pm);
219                 } catch (CoreException e) {
220                     throw new InvocationTargetException JavaDoc(e);
221                 }
222             }
223         };
224     }
225
226     private NonNLSElement[] doRun(IStructuredSelection selection, IProgressMonitor pm) throws CoreException {
227         List JavaDoc elements= getSelectedElementList(selection);
228         if (elements == null || elements.isEmpty())
229             return new NonNLSElement[0];
230
231         pm.beginTask(ActionMessages.FindStringsToExternalizeAction_find_strings, elements.size());
232                     
233         try{
234             List JavaDoc result= new ArrayList JavaDoc();
235             for (Iterator JavaDoc iter= elements.iterator(); iter.hasNext();) {
236                 Object JavaDoc obj= iter.next();
237                 if (obj instanceof IJavaElement) {
238                     IJavaElement element= (IJavaElement) obj;
239                     int elementType= element.getElementType();
240                     
241                     if (elementType == IJavaElement.PACKAGE_FRAGMENT) {
242                         result.addAll(analyze((IPackageFragment) element, new SubProgressMonitor(pm, 1)));
243                     } else if (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
244                         IPackageFragmentRoot root= (IPackageFragmentRoot)element;
245                         if (!root.isExternal() && !ReorgUtils.isClassFolder(root)) {
246                             result.addAll(analyze((IPackageFragmentRoot) element, new SubProgressMonitor(pm, 1)));
247                         } else {
248                             pm.worked(1);
249                         }
250                     } else if (elementType == IJavaElement.JAVA_PROJECT) {
251                         result.addAll(analyze((IJavaProject) element, new SubProgressMonitor(pm, 1)));
252                     } else if (elementType == IJavaElement.COMPILATION_UNIT) {
253                         ICompilationUnit cu= (ICompilationUnit)element;
254                         if (cu.exists()) {
255                             NonNLSElement nlsElement= analyze(cu);
256                             if (nlsElement != null) {
257                                 result.add(nlsElement);
258                             }
259                         }
260                         pm.worked(1);
261                     } else if (elementType == IJavaElement.TYPE) {
262                         IType type= (IType)element;
263                         ICompilationUnit cu= type.getCompilationUnit();
264                         if (cu != null && cu.exists()) {
265                             NonNLSElement nlsElement= analyze(cu);
266                             if (nlsElement != null) {
267                                 result.add(nlsElement);
268                             }
269                         }
270                         pm.worked(1);
271                     } else {
272                         pm.worked(1);
273                     }
274                 } else {
275                     pm.worked(1);
276                 }
277             }
278             return (NonNLSElement[]) result.toArray(new NonNLSElement[result.size()]);
279         } finally{
280             pm.done();
281         }
282     }
283
284     private void showResults() {
285         if (noStrings())
286             MessageDialog.openInformation(getShell(), ActionMessages.ExternalizeStringsAction_dialog_title, ActionMessages.FindStringsToExternalizeAction_noStrings);
287         else
288             new NonNLSListDialog(getShell(), fElements, countStrings()).open();
289     }
290
291     private boolean noStrings() {
292         if (fElements != null) {
293             for (int i= 0; i < fElements.length; i++) {
294                 if (fElements[i].count != 0)
295                     return false;
296             }
297         }
298         return true;
299     }
300
301     /*
302      * returns List of Strings
303      */

304     private List JavaDoc analyze(IPackageFragment pack, IProgressMonitor pm) throws CoreException {
305         try{
306             if (pack == null)
307                 return new ArrayList JavaDoc(0);
308                 
309             ICompilationUnit[] cus= pack.getCompilationUnits();
310     
311             pm.beginTask("", cus.length); //$NON-NLS-1$
312
pm.setTaskName(pack.getElementName());
313             
314             List JavaDoc l= new ArrayList JavaDoc(cus.length);
315             for (int i= 0; i < cus.length; i++){
316                 pm.subTask(cus[i].getElementName());
317                 NonNLSElement element= analyze(cus[i]);
318                 if (element != null)
319                     l.add(element);
320                 pm.worked(1);
321                 if (pm.isCanceled())
322                     throw new OperationCanceledException();
323             }
324             return l;
325         } finally {
326             pm.done();
327         }
328     }
329
330     /*
331      * returns List of Strings
332      */

333     private List JavaDoc analyze(IPackageFragmentRoot sourceFolder, IProgressMonitor pm) throws CoreException {
334         try{
335             IJavaElement[] children= sourceFolder.getChildren();
336             pm.beginTask("", children.length); //$NON-NLS-1$
337
pm.setTaskName(sourceFolder.getElementName());
338             List JavaDoc result= new ArrayList JavaDoc();
339             for (int i= 0; i < children.length; i++) {
340                 IJavaElement iJavaElement= children[i];
341                 if (iJavaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT){
342                     IPackageFragment pack= (IPackageFragment)iJavaElement;
343                     if (! pack.isReadOnly())
344                         result.addAll(analyze(pack, new SubProgressMonitor(pm, 1)));
345                     else
346                         pm.worked(1);
347                 } else
348                     pm.worked(1);
349             }
350             return result;
351         } finally{
352             pm.done();
353         }
354     }
355     
356     /*
357      * returns List of Strings
358      */

359     private List JavaDoc analyze(IJavaProject project, IProgressMonitor pm) throws CoreException {
360         try{
361             IPackageFragment[] packs= project.getPackageFragments();
362             pm.beginTask("", packs.length); //$NON-NLS-1$
363
List JavaDoc result= new ArrayList JavaDoc();
364             for (int i= 0; i < packs.length; i++) {
365                 if (! packs[i].isReadOnly())
366                     result.addAll(analyze(packs[i], new SubProgressMonitor(pm, 1)));
367                 else
368                     pm.worked(1);
369             }
370             return result;
371         } finally{
372             pm.done();
373         }
374     }
375
376     private int countStrings() {
377         int found= 0;
378         if (fElements != null) {
379             for (int i= 0; i < fElements.length; i++)
380                 found+= fElements[i].count;
381         }
382         return found;
383     }
384
385     private NonNLSElement analyze(ICompilationUnit cu) throws CoreException {
386         int count= countNonExternalizedStrings(cu);
387         if (count == 0)
388             return null;
389         else
390             return new NonNLSElement(cu, count);
391     }
392     
393     private int countNonExternalizedStrings(ICompilationUnit cu) throws CoreException {
394         try{
395             NLSLine[] lines= NLSScanner.scan(cu);
396             int result= 0;
397             for (int i= 0; i < lines.length; i++) {
398                 result += countNonExternalizedStrings(lines[i]);
399             }
400             return result;
401         } catch (InvalidInputException e) {
402             throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.ERROR,
403                 Messages.format(ActionMessages.FindStringsToExternalizeAction_error_cannotBeParsed, cu.getElementName()),
404                 e));
405         }
406     }
407
408     private int countNonExternalizedStrings(NLSLine line){
409         int result= 0;
410         NLSElement[] elements= line.getElements();
411         for (int i= 0; i < elements.length; i++){
412             if (! elements[i].hasTag())
413                 result++;
414         }
415         return result;
416     }
417
418     /**
419      * returns <code>List</code> of <code>IPackageFragments</code>, <code>IPackageFragmentRoots</code> or
420      * <code>IJavaProjects</code> (all entries are of the same kind)
421      */

422     private static List JavaDoc getSelectedElementList(IStructuredSelection selection) {
423         if (selection == null)
424             return null;
425             
426         return selection.toList();
427     }
428             
429     //-------private classes --------------
430

431     private static class NonNLSListDialog extends ListDialog {
432         
433         private static final int OPEN_BUTTON_ID= IDialogConstants.CLIENT_ID + 1;
434         
435         private Button fOpenButton;
436         
437         NonNLSListDialog(Shell parent, NonNLSElement[] input, int count) {
438             super(parent);
439             setInput(Arrays.asList(input));
440             setTitle(ActionMessages.ExternalizeStringsAction_dialog_title);
441             setMessage(Messages.format(ActionMessages.FindStringsToExternalizeAction_non_externalized, new Object JavaDoc[] {new Integer JavaDoc(count)} ));
442             setContentProvider(new ArrayContentProvider());
443             setLabelProvider(createLabelProvider());
444         }
445
446         public void create() {
447             setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN);
448             super.create();
449         }
450
451         protected Point getInitialSize() {
452             return getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
453         }
454
455         protected Control createDialogArea(Composite parent) {
456             Composite result= (Composite)super.createDialogArea(parent);
457             getTableViewer().addSelectionChangedListener(new ISelectionChangedListener(){
458                 public void selectionChanged(SelectionChangedEvent event){
459                     if (fOpenButton != null){
460                         fOpenButton.setEnabled(! getTableViewer().getSelection().isEmpty());
461                     }
462                 }
463             });
464             getTableViewer().getTable().addSelectionListener(new SelectionAdapter(){
465                 public void widgetDefaultSelected(SelectionEvent e) {
466                     NonNLSElement element= (NonNLSElement)e.item.getData();
467                     openWizard(element.cu);
468                 }
469             });
470             getTableViewer().getTable().setFocus();
471             applyDialogFont(result);
472             return result;
473         }
474         
475         protected void createButtonsForButtonBar(Composite parent) {
476             fOpenButton= createButton(parent, OPEN_BUTTON_ID, ActionMessages.FindStringsToExternalizeAction_button_label, true);
477             fOpenButton.setEnabled(false);
478             
479             //looks like a 'close' but it a 'cancel'
480
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CLOSE_LABEL, false);
481         }
482
483         protected void buttonPressed(int buttonId) {
484             if (buttonId != OPEN_BUTTON_ID){
485                 super.buttonPressed(buttonId);
486                 return;
487             }
488             ISelection s= getTableViewer().getSelection();
489             if (s instanceof IStructuredSelection){
490                 IStructuredSelection ss= (IStructuredSelection)s;
491                 if (ss.getFirstElement() instanceof NonNLSElement)
492                     openWizard(((NonNLSElement)ss.getFirstElement()).cu);
493             }
494         }
495
496         private void openWizard(ICompilationUnit unit) {
497             try {
498                 if (unit != null && unit.exists()) {
499                     NLSRefactoring refactoring= NLSRefactoring.create(unit);
500                     if (refactoring != null)
501                         new RefactoringStarter().activate(refactoring, new ExternalizeWizard(refactoring), getShell(), ActionMessages.ExternalizeStringsAction_dialog_title, RefactoringSaveHelper.SAVE_NON_JAVA_UPDATES);
502                 }
503             } catch (JavaModelException e) {
504                 ExceptionHandler.handle(e,
505                     ActionMessages.ExternalizeStringsAction_dialog_title,
506                     ActionMessages.FindStringsToExternalizeAction_error_message);
507             }
508         }
509         
510         private static LabelProvider createLabelProvider() {
511             return new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT){
512                 public String JavaDoc getText(Object JavaDoc element) {
513                     NonNLSElement nlsel= (NonNLSElement)element;
514                     String JavaDoc elementName= nlsel.cu.getResource().getFullPath().toString();
515                     return Messages.format(
516                         ActionMessages.FindStringsToExternalizeAction_foundStrings,
517                         new Object JavaDoc[] {new Integer JavaDoc(nlsel.count), elementName} );
518                 }
519                 public Image getImage(Object JavaDoc element) {
520                     return super.getImage(((NonNLSElement)element).cu);
521                 }
522             };
523         }
524         
525         /*
526          * @see org.eclipse.jface.window.Window#configureShell(Shell)
527          */

528         protected void configureShell(Shell newShell) {
529             super.configureShell(newShell);
530             PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IJavaHelpContextIds.NONNLS_DIALOG);
531         }
532
533
534     }
535         
536     private static class NonNLSElement{
537         ICompilationUnit cu;
538         int count;
539         NonNLSElement(ICompilationUnit cu, int count){
540             this.cu= cu;
541             this.count= count;
542         }
543     }
544
545 }
546
Popular Tags