KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > javaeditor > EditorUtility


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
12 package org.eclipse.jdt.internal.ui.javaeditor;
13
14
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Status;
26
27 import org.eclipse.core.resources.IFile;
28 import org.eclipse.core.resources.IMarker;
29 import org.eclipse.core.resources.IProject;
30 import org.eclipse.core.resources.IResource;
31 import org.eclipse.core.resources.IStorage;
32
33 import org.eclipse.swt.SWT;
34
35 import org.eclipse.jface.action.Action;
36 import org.eclipse.jface.action.IAction;
37 import org.eclipse.jface.viewers.ISelectionProvider;
38
39 import org.eclipse.jface.text.IRegion;
40 import org.eclipse.jface.text.TextSelection;
41
42 import org.eclipse.ui.IEditorDescriptor;
43 import org.eclipse.ui.IEditorInput;
44 import org.eclipse.ui.IEditorPart;
45 import org.eclipse.ui.IEditorSite;
46 import org.eclipse.ui.IFileEditorInput;
47 import org.eclipse.ui.IWorkbench;
48 import org.eclipse.ui.IWorkbenchPage;
49 import org.eclipse.ui.IWorkbenchWindow;
50 import org.eclipse.ui.PartInitException;
51 import org.eclipse.ui.PlatformUI;
52 import org.eclipse.ui.actions.WorkspaceModifyOperation;
53 import org.eclipse.ui.part.FileEditorInput;
54 import org.eclipse.ui.part.MultiEditorInput;
55 import org.eclipse.ui.texteditor.IDocumentProvider;
56 import org.eclipse.ui.texteditor.ITextEditor;
57 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
58 import org.eclipse.ui.texteditor.TextEditorAction;
59
60 import org.eclipse.ui.editors.text.TextFileDocumentProvider;
61
62 import org.eclipse.ui.ide.IDE;
63 import org.eclipse.ui.ide.IGotoMarker;
64
65 import org.eclipse.jdt.core.IClassFile;
66 import org.eclipse.jdt.core.ICompilationUnit;
67 import org.eclipse.jdt.core.IJavaElement;
68 import org.eclipse.jdt.core.IJavaProject;
69 import org.eclipse.jdt.core.ILocalVariable;
70 import org.eclipse.jdt.core.IMember;
71 import org.eclipse.jdt.core.ISourceRange;
72 import org.eclipse.jdt.core.ISourceReference;
73 import org.eclipse.jdt.core.ITypeParameter;
74 import org.eclipse.jdt.core.JavaCore;
75 import org.eclipse.jdt.core.JavaModelException;
76
77 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
78 import org.eclipse.jdt.internal.corext.util.Messages;
79
80 import org.eclipse.jdt.ui.JavaUI;
81 import org.eclipse.jdt.ui.PreferenceConstants;
82
83 import org.eclipse.jdt.internal.ui.JavaPlugin;
84
85 /**
86  * A number of routines for working with JavaElements in editors.
87  *
88  * Use 'isOpenInEditor' to test if an element is already open in a editor
89  * Use 'openInEditor' to force opening an element in a editor
90  * With 'getWorkingCopy' you get the working copy (element in the editor) of an element
91  */

92 public class EditorUtility {
93
94
95     /**
96      * Tests if a CU is currently shown in an editor
97      *
98      * @return the IEditorPart if shown, null if element is not open in an editor
99      */

100     public static IEditorPart isOpenInEditor(Object JavaDoc inputElement) {
101         IEditorInput input= null;
102
103         try {
104             input= getEditorInput(inputElement);
105         } catch (JavaModelException x) {
106             JavaPlugin.log(x.getStatus());
107         }
108
109         if (input != null) {
110             IWorkbenchPage p= JavaPlugin.getActivePage();
111             if (p != null) {
112                 return p.findEditor(input);
113             }
114         }
115
116         return null;
117     }
118
119     /**
120      * Opens a Java editor for an element such as <code>IJavaElement</code>, <code>IFile</code>, or <code>IStorage</code>.
121      * The editor is activated by default.
122      *
123      * @return an open editor or <code>null</code> if an external editor was opened
124      * @throws PartInitException if the editor could not be opened or the input element is not valid
125      */

126     public static IEditorPart openInEditor(Object JavaDoc inputElement) throws JavaModelException, PartInitException {
127         return openInEditor(inputElement, true);
128     }
129
130     /**
131      * Opens the editor currently associated with the given element (IJavaElement, IFile, IStorage...)
132      *
133      * @return an open editor or <code>null</code> if an external editor was opened
134      * @throws PartInitException if the editor could not be opened or the input element is not valid
135      */

136     public static IEditorPart openInEditor(Object JavaDoc inputElement, boolean activate) throws JavaModelException, PartInitException {
137
138         if (inputElement instanceof IFile)
139             return openInEditor((IFile) inputElement, activate);
140
141         /*
142          * Support to navigate inside non-primary working copy.
143          * For now we only support to navigate inside the currently
144          * active editor.
145          *
146          * XXX: once we have FileStoreEditorInput as API,
147          * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=111887
148          * we can fix this code by creating the correct editor input
149          * in getEditorInput(Object)
150          */

151         if (inputElement instanceof IJavaElement) {
152             ICompilationUnit cu= (ICompilationUnit)((IJavaElement)inputElement).getAncestor(IJavaElement.COMPILATION_UNIT);
153             if (cu != null && !JavaModelUtil.isPrimary(cu)) {
154                 IWorkbenchPage page= JavaPlugin.getActivePage();
155                 if (page != null) {
156                     IEditorPart editor= page.getActiveEditor();
157                     if (editor != null) {
158                         IJavaElement editorCU= EditorUtility.getEditorInputJavaElement(editor, false);
159                         if (cu.equals(editorCU)) {
160                             if (activate && page.getActivePart() != editor)
161                                 page.activate(editor);
162                             return editor;
163                         }
164                     }
165                 }
166             }
167         }
168
169         IEditorInput input= getEditorInput(inputElement);
170         if (input == null)
171             throwPartInitException(JavaEditorMessages.EditorUtility_no_editorInput);
172         
173         return openInEditor(input, getEditorID(input), activate);
174     }
175
176     /**
177      * Selects a Java Element in an editor
178      */

179     public static void revealInEditor(IEditorPart part, IJavaElement element) {
180         if (element == null)
181             return;
182
183         if (part instanceof JavaEditor) {
184             ((JavaEditor) part).setSelection(element);
185             return;
186         }
187
188         // Support for non-Java editor
189
try {
190             ISourceRange range= null;
191             if (element instanceof ICompilationUnit)
192                 range= null;
193             else if (element instanceof IClassFile)
194                 range= null;
195             else if (element instanceof ILocalVariable)
196                 range= ((ILocalVariable)element).getNameRange();
197             else if (element instanceof IMember)
198                 range= ((IMember)element).getNameRange();
199             else if (element instanceof ITypeParameter)
200                 range= ((ITypeParameter)element).getNameRange();
201             else if (element instanceof ISourceReference)
202                 range= ((ISourceReference)element).getSourceRange();
203
204             if (range != null)
205                 revealInEditor(part, range.getOffset(), range.getLength());
206         } catch (JavaModelException e) {
207             // don't reveal
208
}
209     }
210
211     /**
212      * Selects and reveals the given region in the given editor part.
213      */

214     public static void revealInEditor(IEditorPart part, IRegion region) {
215         if (part != null && region != null)
216             revealInEditor(part, region.getOffset(), region.getLength());
217     }
218
219     /**
220      * Selects and reveals the given offset and length in the given editor part.
221      */

222     public static void revealInEditor(IEditorPart editor, final int offset, final int length) {
223         if (editor instanceof ITextEditor) {
224             ((ITextEditor)editor).selectAndReveal(offset, length);
225             return;
226         }
227
228         // Support for non-text editor - try IGotoMarker interface
229
if (editor instanceof IGotoMarker) {
230             final IEditorInput input= editor.getEditorInput();
231             if (input instanceof IFileEditorInput) {
232                 final IGotoMarker gotoMarkerTarget= (IGotoMarker)editor;
233                 WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
234                     protected void execute(IProgressMonitor monitor) throws CoreException {
235                         IMarker marker= null;
236                         try {
237                             marker= ((IFileEditorInput)input).getFile().createMarker(IMarker.TEXT);
238                             marker.setAttribute(IMarker.CHAR_START, offset);
239                             marker.setAttribute(IMarker.CHAR_END, offset + length);
240
241                             gotoMarkerTarget.gotoMarker(marker);
242
243                         } finally {
244                             if (marker != null)
245                                 marker.delete();
246                         }
247                     }
248                 };
249
250                 try {
251                     op.run(null);
252                 } catch (InvocationTargetException JavaDoc ex) {
253                     // reveal failed
254
} catch (InterruptedException JavaDoc e) {
255                     Assert.isTrue(false, "this operation can not be canceled"); //$NON-NLS-1$
256
}
257             }
258             return;
259         }
260
261         /*
262          * Workaround: send out a text selection
263          * XXX: Needs to be improved, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=32214
264          */

265         if (editor != null && editor.getEditorSite().getSelectionProvider() != null) {
266             IEditorSite site= editor.getEditorSite();
267             if (site == null)
268                 return;
269
270             ISelectionProvider provider= editor.getEditorSite().getSelectionProvider();
271             if (provider == null)
272                 return;
273
274             provider.setSelection(new TextSelection(offset, length));
275         }
276     }
277
278     private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException {
279         if (file == null)
280             throwPartInitException(JavaEditorMessages.EditorUtility_file_must_not_be_null);
281         
282         IWorkbenchPage p= JavaPlugin.getActivePage();
283         if (p == null)
284             throwPartInitException(JavaEditorMessages.EditorUtility_no_active_WorkbenchPage);
285         
286         IEditorPart editorPart= IDE.openEditor(p, file, activate);
287         initializeHighlightRange(editorPart);
288         return editorPart;
289     }
290
291     private static IEditorPart openInEditor(IEditorInput input, String JavaDoc editorID, boolean activate) throws PartInitException {
292         Assert.isNotNull(input);
293         Assert.isNotNull(editorID);
294
295         IWorkbenchPage p= JavaPlugin.getActivePage();
296         if (p == null)
297             throwPartInitException(JavaEditorMessages.EditorUtility_no_active_WorkbenchPage);
298
299         IEditorPart editorPart= p.openEditor(input, editorID, activate);
300         initializeHighlightRange(editorPart);
301         return editorPart;
302     }
303
304     private static void throwPartInitException(String JavaDoc message) throws PartInitException {
305         IStatus status= new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.OK, message, null);
306         throw new PartInitException(status);
307     }
308
309     private static void initializeHighlightRange(IEditorPart editorPart) {
310         if (editorPart instanceof ITextEditor) {
311             IAction toggleAction= editorPart.getEditorSite().getActionBars().getGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY);
312             boolean enable= toggleAction != null;
313             if (enable && editorPart instanceof JavaEditor)
314                 enable= JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS);
315             else
316                 enable= enable && toggleAction.isEnabled() && toggleAction.isChecked();
317             if (enable) {
318                 if (toggleAction instanceof TextEditorAction) {
319                     // Reset the action
320
((TextEditorAction)toggleAction).setEditor(null);
321                     // Restore the action
322
((TextEditorAction)toggleAction).setEditor((ITextEditor)editorPart);
323                 } else {
324                     // Uncheck
325
toggleAction.run();
326                     // Check
327
toggleAction.run();
328                 }
329             }
330         }
331     }
332
333     private static String JavaDoc getEditorID(IEditorInput input) throws PartInitException {
334         Assert.isNotNull(input);
335         IEditorDescriptor editorDescriptor;
336         if (input instanceof IFileEditorInput)
337             editorDescriptor= IDE.getEditorDescriptor(((IFileEditorInput)input).getFile());
338         else {
339             String JavaDoc name= input.getName();
340             if (name == null)
341                 throwPartInitException(JavaEditorMessages.EditorUtility_could_not_find_editorId);
342             editorDescriptor= IDE.getEditorDescriptor(name);
343         }
344         return editorDescriptor.getId();
345     }
346
347     /**
348      * Returns the given editor's input as Java element.
349      *
350      * @param editor the editor
351      * @param primaryOnly if <code>true</code> only primary working copies will be returned
352      * @return the given editor's input as Java element or <code>null</code> if none
353      * @since 3.2
354      */

355     public static IJavaElement getEditorInputJavaElement(IEditorPart editor, boolean primaryOnly) {
356         Assert.isNotNull(editor);
357         IEditorInput editorInput= editor.getEditorInput();
358         if (editorInput == null)
359             return null;
360         
361         IJavaElement je= JavaUI.getEditorInputJavaElement(editorInput);
362         if (je != null || primaryOnly)
363             return je;
364
365         return JavaPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editorInput, false);
366     }
367
368     private static IEditorInput getEditorInput(IJavaElement element) throws JavaModelException {
369         while (element != null) {
370             if (element instanceof ICompilationUnit) {
371                 ICompilationUnit unit= ((ICompilationUnit) element).getPrimary();
372                     IResource resource= unit.getResource();
373                     if (resource instanceof IFile)
374                         return new FileEditorInput((IFile) resource);
375             }
376
377             if (element instanceof IClassFile)
378                 return new InternalClassFileEditorInput((IClassFile) element);
379
380             element= element.getParent();
381         }
382
383         return null;
384     }
385
386     public static IEditorInput getEditorInput(Object JavaDoc input) throws JavaModelException {
387         if (input instanceof IJavaElement)
388             return getEditorInput((IJavaElement) input);
389
390         if (input instanceof IFile)
391             return new FileEditorInput((IFile) input);
392
393         if (JavaModelUtil.isOpenableStorage(input))
394             return new JarEntryEditorInput((IStorage)input);
395
396         return null;
397     }
398
399     /**
400      * If the current active editor edits a java element return it, else
401      * return null
402      */

403     public static IJavaElement getActiveEditorJavaInput() {
404         IWorkbenchPage page= JavaPlugin.getActivePage();
405         if (page != null) {
406             IEditorPart part= page.getActiveEditor();
407             if (part != null) {
408                 IEditorInput editorInput= part.getEditorInput();
409                 if (editorInput != null) {
410                     return JavaUI.getEditorInputJavaElement(editorInput);
411                 }
412             }
413         }
414         return null;
415     }
416
417     /**
418      * Maps the localized modifier name to a code in the same
419      * manner as #findModifier.
420      *
421      * @param modifierName the modifier name
422      * @return the SWT modifier bit, or <code>0</code> if no match was found
423      * @since 2.1.1
424      */

425     public static int findLocalizedModifier(String JavaDoc modifierName) {
426         if (modifierName == null)
427             return 0;
428
429         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
430             return SWT.CTRL;
431         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
432             return SWT.SHIFT;
433         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
434             return SWT.ALT;
435         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
436             return SWT.COMMAND;
437
438         return 0;
439     }
440
441     /**
442      * Returns the modifier string for the given SWT modifier
443      * modifier bits.
444      *
445      * @param stateMask the SWT modifier bits
446      * @return the modifier string
447      * @since 2.1.1
448      */

449     public static String JavaDoc getModifierString(int stateMask) {
450         String JavaDoc modifierString= ""; //$NON-NLS-1$
451
if ((stateMask & SWT.CTRL) == SWT.CTRL)
452             modifierString= appendModifierString(modifierString, SWT.CTRL);
453         if ((stateMask & SWT.ALT) == SWT.ALT)
454             modifierString= appendModifierString(modifierString, SWT.ALT);
455         if ((stateMask & SWT.SHIFT) == SWT.SHIFT)
456             modifierString= appendModifierString(modifierString, SWT.SHIFT);
457         if ((stateMask & SWT.COMMAND) == SWT.COMMAND)
458             modifierString= appendModifierString(modifierString, SWT.COMMAND);
459
460         return modifierString;
461     }
462
463     /**
464      * Appends to modifier string of the given SWT modifier bit
465      * to the given modifierString.
466      *
467      * @param modifierString the modifier string
468      * @param modifier an int with SWT modifier bit
469      * @return the concatenated modifier string
470      * @since 2.1.1
471      */

472     private static String JavaDoc appendModifierString(String JavaDoc modifierString, int modifier) {
473         if (modifierString == null)
474             modifierString= ""; //$NON-NLS-1$
475
String JavaDoc newModifierString= Action.findModifierString(modifier);
476         if (modifierString.length() == 0)
477             return newModifierString;
478         return Messages.format(JavaEditorMessages.EditorUtility_concatModifierStrings, new String JavaDoc[] {modifierString, newModifierString});
479     }
480
481     /**
482      * Returns the Java project for a given editor input or <code>null</code> if no corresponding
483      * Java project exists.
484      *
485      * @param input the editor input
486      * @return the corresponding Java project
487      *
488      * @since 3.0
489      */

490     public static IJavaProject getJavaProject(IEditorInput input) {
491         IJavaProject jProject= null;
492         if (input instanceof IFileEditorInput) {
493             IProject project= ((IFileEditorInput)input).getFile().getProject();
494             if (project != null) {
495                 jProject= JavaCore.create(project);
496                 if (!jProject.exists())
497                     jProject= null;
498             }
499         } else if (input instanceof IClassFileEditorInput) {
500             jProject= ((IClassFileEditorInput)input).getClassFile().getJavaProject();
501         }
502         return jProject;
503     }
504     
505     /**
506      * Returns an array of all editors that have an unsaved content. If the identical content is
507      * presented in more than one editor, only one of those editor parts is part of the result.
508      *
509      * @return an array of all dirty editor parts.
510      * @since 3.2
511      * @deprecated TODO: remove for 3.4
512      */

513     public static IEditorPart[] getDirtyEditors() {
514         return getDirtyEditors(false);
515     }
516     
517     /**
518      * Returns an array of all editors that have an unsaved content. If the identical content is
519      * presented in more than one editor, only one of those editor parts is part of the result.
520      * @param skipNonResourceEditors if <code>true</code>, editors whose inputs do not adapt to {@link IResource}
521      * are not saved
522      *
523      * @return an array of dirty editor parts
524      * @since 3.4
525      */

526     public static IEditorPart[] getDirtyEditors(boolean skipNonResourceEditors) {
527         Set JavaDoc inputs= new HashSet JavaDoc();
528         List JavaDoc result= new ArrayList JavaDoc(0);
529         IWorkbench workbench= PlatformUI.getWorkbench();
530         IWorkbenchWindow[] windows= workbench.getWorkbenchWindows();
531         for (int i= 0; i < windows.length; i++) {
532             IWorkbenchPage[] pages= windows[i].getPages();
533             for (int x= 0; x < pages.length; x++) {
534                 IEditorPart[] editors= pages[x].getDirtyEditors();
535                 for (int z= 0; z < editors.length; z++) {
536                     IEditorPart ep= editors[z];
537                     IEditorInput input= ep.getEditorInput();
538                     if (inputs.add(input)) {
539                         if (!skipNonResourceEditors || isResourceEditorInput(input)) {
540                             result.add(ep);
541                         }
542                     }
543                 }
544             }
545         }
546         return (IEditorPart[])result.toArray(new IEditorPart[result.size()]);
547     }
548     
549     private static boolean isResourceEditorInput(IEditorInput input) {
550         if (input instanceof MultiEditorInput) {
551             IEditorInput[] inputs= ((MultiEditorInput) input).getInput();
552             for (int i= 0; i < inputs.length; i++) {
553                 if (inputs[i].getAdapter(IResource.class) != null) {
554                     return true;
555                 }
556             }
557         } else if (input.getAdapter(IResource.class) != null) {
558             return true;
559         }
560         return false;
561     }
562     
563     
564     /**
565      * Returns the editors to save before performing global Java-related
566      * operations.
567      *
568      * @param saveUnknownEditors <code>true</code> iff editors with unknown buffer management should also be saved
569      * @return the editors to save
570      * @since 3.3
571      */

572     public static IEditorPart[] getDirtyEditorsToSave(boolean saveUnknownEditors) {
573         Set JavaDoc inputs= new HashSet JavaDoc();
574         List JavaDoc result= new ArrayList JavaDoc(0);
575         IWorkbench workbench= PlatformUI.getWorkbench();
576         IWorkbenchWindow[] windows= workbench.getWorkbenchWindows();
577         for (int i= 0; i < windows.length; i++) {
578             IWorkbenchPage[] pages= windows[i].getPages();
579             for (int x= 0; x < pages.length; x++) {
580                 IEditorPart[] editors= pages[x].getDirtyEditors();
581                 for (int z= 0; z < editors.length; z++) {
582                     IEditorPart ep= editors[z];
583                     IEditorInput input= ep.getEditorInput();
584                     if (!mustSaveDirtyEditor(ep, input, saveUnknownEditors))
585                         continue;
586                     
587                     if (inputs.add(input))
588                         result.add(ep);
589                 }
590             }
591         }
592         return (IEditorPart[])result.toArray(new IEditorPart[result.size()]);
593     }
594
595     /**
596      * @since 3.3
597      */

598     private static boolean mustSaveDirtyEditor(IEditorPart ep, IEditorInput input, boolean saveUnknownEditors) {
599         /*
600          * Goal: save all editors that could interfere with refactoring operations.
601          *
602          * Always save all editors for compilation units that are not working copies.
603          * (Leaving them dirty would cause problems, since the file buffer could have been
604          * modified but the Java model is not reconciled.)
605          *
606          * If <code>saveUnknownEditors</code> is <code>true</code>, save all editors
607          * whose implementation is probably not based on file buffers.
608          */

609         IResource resource= (IResource) input.getAdapter(IResource.class);
610         if (resource == null)
611             return saveUnknownEditors;
612
613         IJavaElement javaElement= JavaCore.create(resource);
614         if (javaElement instanceof ICompilationUnit) {
615             ICompilationUnit cu= (ICompilationUnit) javaElement;
616             if (!cu.isWorkingCopy()) {
617                 return true;
618             }
619         }
620         
621         if (! (ep instanceof ITextEditor))
622             return saveUnknownEditors;
623         
624         ITextEditor textEditor= (ITextEditor) ep;
625         IDocumentProvider documentProvider= textEditor.getDocumentProvider();
626         if (! (documentProvider instanceof TextFileDocumentProvider))
627             return saveUnknownEditors;
628         
629         return false;
630     }
631
632 }
633
Popular Tags