KickJava   Java API By Example, From Geeks To Geeks.

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


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
16 import java.lang.reflect.InvocationTargetException JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.core.runtime.jobs.Job;
28
29 import org.eclipse.core.resources.IFile;
30
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.custom.StackLayout;
33 import org.eclipse.swt.custom.StyledText;
34 import org.eclipse.swt.events.DisposeEvent;
35 import org.eclipse.swt.events.DisposeListener;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.events.SelectionListener;
38 import org.eclipse.swt.graphics.Color;
39 import org.eclipse.swt.graphics.Font;
40 import org.eclipse.swt.layout.FillLayout;
41 import org.eclipse.swt.layout.GridData;
42 import org.eclipse.swt.layout.GridLayout;
43 import org.eclipse.swt.widgets.Button;
44 import org.eclipse.swt.widgets.Composite;
45 import org.eclipse.swt.widgets.Control;
46 import org.eclipse.swt.widgets.Display;
47 import org.eclipse.swt.widgets.Label;
48 import org.eclipse.swt.widgets.Shell;
49
50 import org.eclipse.jface.action.Action;
51 import org.eclipse.jface.action.IAction;
52 import org.eclipse.jface.action.IMenuManager;
53 import org.eclipse.jface.operation.IRunnableWithProgress;
54 import org.eclipse.jface.preference.IPreferenceStore;
55 import org.eclipse.jface.resource.JFaceResources;
56 import org.eclipse.jface.util.IPropertyChangeListener;
57 import org.eclipse.jface.util.PropertyChangeEvent;
58
59 import org.eclipse.jface.text.IWidgetTokenKeeper;
60 import org.eclipse.jface.text.source.ISourceViewer;
61 import org.eclipse.jface.text.source.IVerticalRuler;
62
63 import org.eclipse.ui.IActionBars;
64 import org.eclipse.ui.IEditorInput;
65 import org.eclipse.ui.IFileEditorInput;
66 import org.eclipse.ui.PlatformUI;
67 import org.eclipse.ui.actions.ActionContext;
68 import org.eclipse.ui.actions.ActionGroup;
69 import org.eclipse.ui.texteditor.IDocumentProvider;
70 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
71 import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
72
73 import org.eclipse.jdt.core.ClasspathContainerInitializer;
74 import org.eclipse.jdt.core.IClassFile;
75 import org.eclipse.jdt.core.IClasspathContainer;
76 import org.eclipse.jdt.core.IClasspathEntry;
77 import org.eclipse.jdt.core.IJavaElement;
78 import org.eclipse.jdt.core.IJavaModelStatusConstants;
79 import org.eclipse.jdt.core.IJavaProject;
80 import org.eclipse.jdt.core.IPackageFragmentRoot;
81 import org.eclipse.jdt.core.JavaCore;
82 import org.eclipse.jdt.core.JavaModelException;
83 import org.eclipse.jdt.core.ToolFactory;
84 import org.eclipse.jdt.core.dom.CompilationUnit;
85 import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
86 import org.eclipse.jdt.core.util.ClassFormatException;
87
88 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
89 import org.eclipse.jdt.internal.corext.util.Messages;
90
91 import org.eclipse.jdt.ui.actions.RefactorActionGroup;
92 import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
93
94 import org.eclipse.jdt.internal.ui.JavaPlugin;
95 import org.eclipse.jdt.internal.ui.JavaUIStatus;
96 import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
97 import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
98 import org.eclipse.jdt.internal.ui.wizards.buildpaths.SourceAttachmentBlock;
99
100 /**
101  * Java specific text editor.
102  */

103 public class ClassFileEditor extends JavaEditor implements ClassFileDocumentProvider.InputChangeListener {
104
105
106     /**
107      * A form to attach source to a class file.
108      */

109     private class SourceAttachmentForm implements IPropertyChangeListener {
110
111         private final IClassFile fFile;
112         private Composite fComposite;
113         private Color fBackgroundColor;
114         private Color fForegroundColor;
115         private Color fSeparatorColor;
116         private List JavaDoc fBannerLabels= new ArrayList JavaDoc();
117         private List JavaDoc fHeaderLabels= new ArrayList JavaDoc();
118         private Font fFont;
119
120         /**
121          * Creates a source attachment form for a class file.
122          *
123          * @param file the class file
124          */

125         public SourceAttachmentForm(IClassFile file) {
126             fFile= file;
127         }
128
129         /**
130          * Returns the package fragment root of this file.
131          *
132          * @param file the class file
133          * @return the package fragment root of the given class file
134          */

135         private IPackageFragmentRoot getPackageFragmentRoot(IClassFile file) {
136
137             IJavaElement element= file.getParent();
138             while (element != null && element.getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT)
139                 element= element.getParent();
140
141             return (IPackageFragmentRoot) element;
142         }
143
144         /**
145          * Creates the control of the source attachment form.
146          *
147          * @param parent the parent composite
148          * @return the creates source attachment form
149          */

150         public Control createControl(Composite parent) {
151
152             Display display= parent.getDisplay();
153             fBackgroundColor= display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
154             fForegroundColor= display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
155             fSeparatorColor= new Color(display, 152, 170, 203);
156
157             JFaceResources.getFontRegistry().addListener(this);
158
159             fComposite= createComposite(parent);
160             fComposite.setLayout(new GridLayout());
161             fComposite.addDisposeListener(new DisposeListener() {
162                 public void widgetDisposed(DisposeEvent e) {
163                     JFaceResources.getFontRegistry().removeListener(SourceAttachmentForm.this);
164                     fComposite= null;
165                     fSeparatorColor.dispose();
166                     fSeparatorColor= null;
167                     fBannerLabels.clear();
168                     fHeaderLabels.clear();
169                     if (fFont != null) {
170                         fFont.dispose();
171                         fFont= null;
172                     }
173                 }
174             });
175
176             createTitleLabel(fComposite, JavaEditorMessages.SourceAttachmentForm_title);
177             createLabel(fComposite, null);
178             createLabel(fComposite, null);
179
180             createHeadingLabel(fComposite, JavaEditorMessages.SourceAttachmentForm_heading);
181
182             Composite separator= createCompositeSeparator(fComposite);
183             GridData data= new GridData(GridData.FILL_HORIZONTAL);
184             data.heightHint= 2;
185             separator.setLayoutData(data);
186
187             try {
188                 IPackageFragmentRoot root= getPackageFragmentRoot(fFile);
189                 if (root != null) {
190                     createSourceAttachmentControls(fComposite, root);
191                 }
192             } catch (JavaModelException e) {
193                 String JavaDoc title= JavaEditorMessages.SourceAttachmentForm_error_title;
194                 String JavaDoc message= JavaEditorMessages.SourceAttachmentForm_error_message;
195                 ExceptionHandler.handle(e, fComposite.getShell(), title, message);
196             }
197
198             separator= createCompositeSeparator(fComposite);
199             data= new GridData(GridData.FILL_HORIZONTAL);
200             data.heightHint= 2;
201             separator.setLayoutData(data);
202
203             fNoSourceTextWidget= createCodeView(fComposite);
204             data= new GridData(GridData.FILL_BOTH);
205             fNoSourceTextWidget.setLayoutData(data);
206             
207             updateCodeView(fNoSourceTextWidget, fFile);
208             
209             return fComposite;
210         }
211
212         private void createSourceAttachmentControls(Composite composite, IPackageFragmentRoot root) throws JavaModelException {
213             IClasspathEntry entry;
214             try {
215                 entry= root.getRawClasspathEntry();
216             } catch (JavaModelException ex) {
217                 if (ex.isDoesNotExist())
218                     entry= null;
219                 else
220                     throw ex;
221             }
222             IPath containerPath= null;
223
224             if (entry == null || root.getKind() != IPackageFragmentRoot.K_BINARY) {
225                 createLabel(composite, Messages.format(JavaEditorMessages.SourceAttachmentForm_message_noSource, fFile.getElementName()));
226                 return;
227             }
228
229             IJavaProject jproject= root.getJavaProject();
230             if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
231                 containerPath= entry.getPath();
232                 ClasspathContainerInitializer initializer= JavaCore.getClasspathContainerInitializer(containerPath.segment(0));
233                 IClasspathContainer container= JavaCore.getClasspathContainer(containerPath, jproject);
234                 if (initializer == null || container == null) {
235                     createLabel(composite, Messages.format(JavaEditorMessages.ClassFileEditor_SourceAttachmentForm_cannotconfigure, containerPath.toString()));
236                     return;
237                 }
238                 String JavaDoc containerName= container.getDescription();
239                 IStatus status= initializer.getSourceAttachmentStatus(containerPath, jproject);
240                 if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_NOT_SUPPORTED) {
241                     createLabel(composite, Messages.format(JavaEditorMessages.ClassFileEditor_SourceAttachmentForm_notsupported, containerName));
242                     return;
243                 }
244                 if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_READ_ONLY) {
245                     createLabel(composite, Messages.format(JavaEditorMessages.ClassFileEditor_SourceAttachmentForm_readonly, containerName));
246                     return;
247                 }
248                 entry= JavaModelUtil.findEntryInContainer(container, root.getPath());
249                 Assert.isNotNull(entry);
250             }
251
252
253             Button button;
254
255             IPath path= entry.getSourceAttachmentPath();
256             if (path == null || path.isEmpty()) {
257                 createLabel(composite, Messages.format(JavaEditorMessages.SourceAttachmentForm_message_noSourceAttachment, root.getElementName()));
258                 createLabel(composite, JavaEditorMessages.SourceAttachmentForm_message_pressButtonToAttach);
259                 createLabel(composite, null);
260
261                 button= createButton(composite, JavaEditorMessages.SourceAttachmentForm_button_attachSource);
262
263             } else {
264                 createLabel(composite, Messages.format(JavaEditorMessages.SourceAttachmentForm_message_noSourceInAttachment, fFile.getElementName()));
265                 createLabel(composite, JavaEditorMessages.SourceAttachmentForm_message_pressButtonToChange);
266                 createLabel(composite, null);
267
268                 button= createButton(composite, JavaEditorMessages.SourceAttachmentForm_button_changeAttachedSource);
269             }
270
271             button.addSelectionListener(getButtonListener(entry, containerPath, jproject));
272         }
273
274         private SelectionListener getButtonListener(final IClasspathEntry entry, final IPath containerPath, final IJavaProject jproject) {
275             return new SelectionListener() {
276                 public void widgetSelected(SelectionEvent event) {
277                     Shell shell= getSite().getShell();
278                     try {
279                         IClasspathEntry result= BuildPathDialogAccess.configureSourceAttachment(shell, entry);
280                         if (result != null) {
281                             applySourceAttachment(shell, result, jproject, containerPath);
282                             verifyInput(getEditorInput());
283                         }
284                     } catch (CoreException e) {
285                         String JavaDoc title= JavaEditorMessages.SourceAttachmentForm_error_title;
286                         String JavaDoc message= JavaEditorMessages.SourceAttachmentForm_error_message;
287                         ExceptionHandler.handle(e, shell, title, message);
288                     }
289                 }
290
291                 public void widgetDefaultSelected(SelectionEvent e) {}
292             };
293         }
294
295         protected void applySourceAttachment(Shell shell, IClasspathEntry newEntry, IJavaProject project, IPath containerPath) {
296             try {
297                 IRunnableWithProgress runnable= SourceAttachmentBlock.getRunnable(shell, newEntry, project, containerPath);
298                 PlatformUI.getWorkbench().getProgressService().run(true, true, runnable);
299
300             } catch (InvocationTargetException JavaDoc e) {
301                 String JavaDoc title= JavaEditorMessages.SourceAttachmentForm_attach_error_title;
302                 String JavaDoc message= JavaEditorMessages.SourceAttachmentForm_attach_error_message;
303                 ExceptionHandler.handle(e, shell, title, message);
304
305             } catch (InterruptedException JavaDoc e) {
306                 // cancelled
307
}
308         }
309
310         /*
311          * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
312          */

313         public void propertyChange(PropertyChangeEvent event) {
314
315             for (Iterator JavaDoc iterator = fBannerLabels.iterator(); iterator.hasNext();) {
316                 Label label = (Label) iterator.next();
317                 label.setFont(JFaceResources.getBannerFont());
318             }
319
320             for (Iterator JavaDoc iterator = fHeaderLabels.iterator(); iterator.hasNext();) {
321                 Label label = (Label) iterator.next();
322                 label.setFont(JFaceResources.getHeaderFont());
323             }
324
325             fComposite.layout(true);
326             fComposite.redraw();
327         }
328
329         // --- copied from org.eclipse.update.ui.forms.internal.FormWidgetFactory
330

331         private Composite createComposite(Composite parent) {
332             Composite composite = new Composite(parent, SWT.NONE);
333             composite.setBackground(fBackgroundColor);
334             // composite.addMouseListener(new MouseAdapter() {
335
// public void mousePressed(MouseEvent e) {
336
// ((Control) e.widget).setFocus();
337
// }
338
// });
339
return composite;
340         }
341
342         private Composite createCompositeSeparator(Composite parent) {
343             Composite composite = new Composite(parent, SWT.NONE);
344             composite.setBackground(fSeparatorColor);
345             return composite;
346         }
347
348         private StyledText createCodeView(Composite parent) {
349             int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION;
350             StyledText styledText= new StyledText(parent, styles);
351             styledText.setBackground(fBackgroundColor);
352             styledText.setForeground(fForegroundColor);
353             styledText.setEditable(false);
354             return styledText;
355         }
356
357         private Label createLabel(Composite parent, String JavaDoc text) {
358             Label label= new Label(parent, SWT.WRAP);
359             if (text != null)
360                 label.setText(text);
361             label.setBackground(fBackgroundColor);
362             label.setForeground(fForegroundColor);
363             GridData gd= new GridData(SWT.FILL, SWT.FILL, true, false);
364             label.setLayoutData(gd);
365             return label;
366         }
367
368         private Label createTitleLabel(Composite parent, String JavaDoc text) {
369             Label label = new Label(parent, SWT.NONE);
370             if (text != null)
371                 label.setText(text);
372             label.setBackground(fBackgroundColor);
373             label.setForeground(fForegroundColor);
374             label.setFont(JFaceResources.getHeaderFont());
375             fHeaderLabels.add(label);
376             return label;
377         }
378
379         private Label createHeadingLabel(Composite parent, String JavaDoc text) {
380             Label label = new Label(parent, SWT.NONE);
381             if (text != null)
382                 label.setText(text);
383             label.setBackground(fBackgroundColor);
384             label.setForeground(fForegroundColor);
385             label.setFont(JFaceResources.getBannerFont());
386             fBannerLabels.add(label);
387             return label;
388         }
389
390         private Button createButton(Composite parent, String JavaDoc text) {
391             Button button = new Button(parent, SWT.FLAT);
392             button.setBackground(fBackgroundColor);
393             button.setForeground(fForegroundColor);
394             if (text != null)
395                 button.setText(text);
396             return button;
397         }
398
399         private void updateCodeView(StyledText styledText, IClassFile classFile) {
400             String JavaDoc content= null;
401             ClassFileBytesDisassembler disassembler= ToolFactory.createDefaultClassFileBytesDisassembler();
402             try {
403                 content= disassembler.disassemble(classFile.getBytes(), "\n", ClassFileBytesDisassembler.DETAILED); //$NON-NLS-1$
404
} catch (JavaModelException ex) {
405                 JavaPlugin.log(ex.getStatus());
406             } catch (ClassFormatException ex) {
407                 JavaPlugin.log(ex);
408             }
409             styledText.setText(content == null ? "" : content); //$NON-NLS-1$
410
}
411     }
412
413     /**
414      * Updater that takes care of minimizing changes of the editor input.
415      */

416     private class InputUpdater implements Runnable JavaDoc {
417
418         /** Has the runnable already been posted? */
419         private boolean fPosted= false;
420         /** Editor input */
421         private IClassFileEditorInput fClassFileEditorInput;
422
423
424         public InputUpdater() {
425         }
426
427         /*
428          * @see Runnable#run()
429          */

430         public void run() {
431
432             IClassFileEditorInput input;
433             synchronized (this) {
434                 input= fClassFileEditorInput;
435             }
436
437             try {
438
439                 if (getSourceViewer() != null)
440                     setInput(input);
441
442             } finally {
443                 synchronized (this) {
444                     fPosted= false;
445                 }
446             }
447         }
448
449         /**
450          * Posts this runnable into the event queue if not already there.
451          *
452          * @param input the input to be set when executed
453          */

454         public void post(IClassFileEditorInput input) {
455
456             synchronized(this) {
457                 if (fPosted) {
458                     if (input != null && input.equals(fClassFileEditorInput))
459                         fClassFileEditorInput= input;
460                     return;
461                 }
462             }
463
464             if (input != null && input.equals(getEditorInput())) {
465                 ISourceViewer viewer= getSourceViewer();
466                 if (viewer != null) {
467                     StyledText textWidget= viewer.getTextWidget();
468                     if (textWidget != null && !textWidget.isDisposed()) {
469                         synchronized (this) {
470                             fPosted= true;
471                             fClassFileEditorInput= input;
472                         }
473                         textWidget.getDisplay().asyncExec(this);
474                     }
475                 }
476             }
477         }
478     }
479
480
481     private StackLayout fStackLayout;
482     private Composite fParent;
483
484     private Composite fViewerComposite;
485     private Control fSourceAttachmentForm;
486
487     private CompositeActionGroup fContextMenuGroup;
488
489     private InputUpdater fInputUpdater= new InputUpdater();
490     
491     /**
492      * The copy action used when there's attached source.
493      * @since 3.3
494      */

495     private IAction fSourceCopyAction;
496     /**
497      * The Select All action used when there's attached source.
498      * @since 3.3
499      */

500     private IAction fSelectAllAction;
501
502     /**
503      * StyledText widget used to show the disassembled code.
504      * if there's no source.
505      *
506      * @since 3.3
507      */

508     private StyledText fNoSourceTextWidget;
509
510     
511     /**
512      * Default constructor.
513      */

514     public ClassFileEditor() {
515         super();
516         setDocumentProvider(JavaPlugin.getDefault().getClassFileDocumentProvider());
517         setEditorContextMenuId("#ClassFileEditorContext"); //$NON-NLS-1$
518
setRulerContextMenuId("#ClassFileRulerContext"); //$NON-NLS-1$
519
setOutlinerContextMenuId("#ClassFileOutlinerContext"); //$NON-NLS-1$
520
// don't set help contextId, we install our own help context
521
}
522
523     /*
524      * @see AbstractTextEditor#createActions()
525      */

526     protected void createActions() {
527         super.createActions();
528
529         setAction(ITextEditorActionConstants.SAVE, null);
530         setAction(ITextEditorActionConstants.REVERT_TO_SAVED, null);
531
532         fSourceCopyAction= getAction(ITextEditorActionConstants.COPY);
533         fSelectAllAction= getAction(ITextEditorActionConstants.SELECT_ALL);
534
535         final ActionGroup group= new RefactorActionGroup(this, ITextEditorActionConstants.GROUP_EDIT, true);
536         fActionGroups.addGroup(group);
537         fContextMenuGroup= new CompositeActionGroup(new ActionGroup[] {group});
538
539         /*
540          * 1GF82PL: ITPJUI:ALL - Need to be able to add bookmark to class file
541          *
542          * // replace default action with class file specific ones
543          *
544          * setAction(ITextEditorActionConstants.BOOKMARK, new AddClassFileMarkerAction("AddBookmark.", this, IMarker.BOOKMARK, true)); //$NON-NLS-1$
545          * setAction(ITextEditorActionConstants.ADD_TASK, new AddClassFileMarkerAction("AddTask.", this, IMarker.TASK, false)); //$NON-NLS-1$
546          * setAction(ITextEditorActionConstants.RULER_MANAGE_BOOKMARKS, new ClassFileMarkerRulerAction("ManageBookmarks.", getVerticalRuler(), this, IMarker.BOOKMARK, true)); //$NON-NLS-1$
547          * setAction(ITextEditorActionConstants.RULER_MANAGE_TASKS, new ClassFileMarkerRulerAction("ManageTasks.", getVerticalRuler(), this, IMarker.TASK, true)); //$NON-NLS-1$
548          */

549     }
550
551     /*
552      * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager)
553      */

554     public void editorContextMenuAboutToShow(IMenuManager menu) {
555         super.editorContextMenuAboutToShow(menu);
556
557         ActionContext context= new ActionContext(getSelectionProvider().getSelection());
558         fContextMenuGroup.setContext(context);
559         fContextMenuGroup.fillContextMenu(menu);
560         fContextMenuGroup.setContext(null);
561     }
562
563     /*
564      * @see JavaEditor#getElementAt(int)
565      */

566     protected IJavaElement getElementAt(int offset) {
567         if (getEditorInput() instanceof IClassFileEditorInput) {
568             try {
569                 IClassFileEditorInput input= (IClassFileEditorInput) getEditorInput();
570                 return input.getClassFile().getElementAt(offset);
571             } catch (JavaModelException x) {
572             }
573         }
574         return null;
575     }
576
577     /*
578      * @see JavaEditor#getCorrespondingElement(IJavaElement)
579      */

580     protected IJavaElement getCorrespondingElement(IJavaElement element) {
581         if (getEditorInput() instanceof IClassFileEditorInput) {
582             IClassFileEditorInput input= (IClassFileEditorInput) getEditorInput();
583             IJavaElement parent= element.getAncestor(IJavaElement.CLASS_FILE);
584             if (input.getClassFile().equals(parent))
585                 return element;
586         }
587         return null;
588     }
589
590     /*
591      * 1GEPKT5: ITPJUI:Linux - Source in editor for external classes is editable
592      * Removed methods isSaveOnClosedNeeded and isDirty.
593      * Added method isEditable.
594      */

595     /*
596      * @see org.eclipse.ui.texteditor.AbstractTextEditor#isEditable()
597      */

598     public boolean isEditable() {
599         return false;
600     }
601
602     /*
603      * @see org.eclipse.ui.texteditor.AbstractTextEditor#isEditorInputReadOnly()
604      * @since 3.2
605      */

606     public boolean isEditorInputReadOnly() {
607         return true;
608     }
609
610     /**
611      * Translates the given editor input into an <code>ExternalClassFileEditorInput</code>
612      * if it is a file editor input representing an external class file.
613      *
614      * @param input the editor input to be transformed if necessary
615      * @return the transformed editor input
616      */

617     protected IEditorInput transformEditorInput(IEditorInput input) {
618
619         if (input instanceof IFileEditorInput) {
620             IFile file= ((IFileEditorInput) input).getFile();
621             IClassFileEditorInput classFileInput= new ExternalClassFileEditorInput(file);
622             if (classFileInput.getClassFile() != null)
623                 input= classFileInput;
624         }
625
626         return input;
627     }
628
629     /*
630      * @see AbstractTextEditor#doSetInput(IEditorInput)
631      */

632     protected void doSetInput(IEditorInput input) throws CoreException {
633         uninstallOccurrencesFinder();
634
635         input= transformEditorInput(input);
636         if (!(input instanceof IClassFileEditorInput))
637             throw new CoreException(JavaUIStatus.createError(
638                     IJavaModelStatusConstants.INVALID_RESOURCE_TYPE,
639                     JavaEditorMessages.ClassFileEditor_error_invalid_input_message,
640                     null));
641
642         JavaModelException e= probeInputForSource(input);
643         if (e != null) {
644             IClassFileEditorInput classFileEditorInput= (IClassFileEditorInput) input;
645             IClassFile file= classFileEditorInput.getClassFile();
646             IJavaProject javaProject= file.getJavaProject();
647             if (!javaProject.exists() || !javaProject.isOnClasspath(file)) {
648                 throw new CoreException(JavaUIStatus.createError(
649                         IJavaModelStatusConstants.INVALID_RESOURCE,
650                         JavaEditorMessages.ClassFileEditor_error_classfile_not_on_classpath,
651                         null));
652             } else {
653                 throw e;
654             }
655         }
656
657         IDocumentProvider documentProvider= getDocumentProvider();
658         if (documentProvider instanceof ClassFileDocumentProvider)
659             ((ClassFileDocumentProvider) documentProvider).removeInputChangeListener(this);
660
661         super.doSetInput(input);
662
663         documentProvider= getDocumentProvider();
664         if (documentProvider instanceof ClassFileDocumentProvider)
665             ((ClassFileDocumentProvider) documentProvider).addInputChangeListener(this);
666
667         verifyInput(getEditorInput());
668         
669         final IJavaElement inputElement= getInputJavaElement();
670
671         Job job= new Job(JavaEditorMessages.OverrideIndicatorManager_intallJob) {
672             /*
673              * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
674              * @since 3.0
675              */

676             protected IStatus run(IProgressMonitor monitor) {
677                 CompilationUnit ast= JavaPlugin.getDefault().getASTProvider().getAST(inputElement, ASTProvider.WAIT_YES, null);
678                 if (fOverrideIndicatorManager != null)
679                     fOverrideIndicatorManager.reconciled(ast, true, monitor);
680                 if (fSemanticManager != null) {
681                     SemanticHighlightingReconciler reconciler= fSemanticManager.getReconciler();
682                     if (reconciler != null)
683                         reconciler.reconciled(ast, false, monitor);
684                 }
685                 if (isMarkingOccurrences())
686                     installOccurrencesFinder(false);
687                 return Status.OK_STATUS;
688             }
689         };
690         job.setPriority(Job.DECORATE);
691         job.setSystem(true);
692         job.schedule();
693         
694     }
695
696     /*
697      * @see IWorkbenchPart#createPartControl(Composite)
698      */

699     public void createPartControl(Composite parent) {
700
701         fParent= new Composite(parent, SWT.NONE);
702         fStackLayout= new StackLayout();
703         fParent.setLayout(fStackLayout);
704
705         fViewerComposite= new Composite(fParent, SWT.NONE);
706         fViewerComposite.setLayout(new FillLayout());
707
708         super.createPartControl(fViewerComposite);
709
710         fStackLayout.topControl= fViewerComposite;
711         fParent.layout();
712
713         try {
714             verifyInput(getEditorInput());
715         } catch (CoreException e) {
716             String JavaDoc title= JavaEditorMessages.ClassFileEditor_error_title;
717             String JavaDoc message= JavaEditorMessages.ClassFileEditor_error_message;
718             ExceptionHandler.handle(e, fParent.getShell(), title, message);
719         }
720     }
721
722     private JavaModelException probeInputForSource(IEditorInput input) {
723         if (input == null)
724             return null;
725
726         IClassFileEditorInput classFileEditorInput= (IClassFileEditorInput) input;
727         IClassFile file= classFileEditorInput.getClassFile();
728
729         try {
730             file.getSourceRange();
731         } catch (JavaModelException e) {
732             return e;
733         }
734
735         return null;
736     }
737
738     /**
739      * Checks if the class file input has no source attached. If so, a source attachment form is shown.
740      *
741      * @param input the editor input
742      * @throws JavaModelException if an exception occurs while accessing its corresponding resource
743      */

744     private void verifyInput(IEditorInput input) throws JavaModelException {
745
746         if (fParent == null || input == null)
747             return;
748
749         IClassFileEditorInput classFileEditorInput= (IClassFileEditorInput) input;
750         IClassFile file= classFileEditorInput.getClassFile();
751         
752         IAction copyQualifiedName= getAction(IJavaEditorActionConstants.COPY_QUALIFIED_NAME);
753         
754         boolean wasUsingSourceCopyAction= fSourceCopyAction == getAction(ITextEditorActionConstants.COPY);
755
756         // show source attachment form if no source found
757
if (file.getSourceRange() == null) {
758
759             // dispose old source attachment form
760
if (fSourceAttachmentForm != null)
761                 fSourceAttachmentForm.dispose();
762
763             SourceAttachmentForm form= new SourceAttachmentForm(file);
764             fSourceAttachmentForm= form.createControl(fParent);
765
766             fStackLayout.topControl= fSourceAttachmentForm;
767             fParent.layout();
768
769             if (fNoSourceTextWidget != null) {
770                 // Copy action for the no attached source case
771
final IAction copyAction= new Action() {
772                     public void run() {
773                         fNoSourceTextWidget.copy();
774                     }
775                 };
776                 copyAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
777                 setAction(ITextEditorActionConstants.COPY, copyAction);
778                 copyAction.setEnabled(fNoSourceTextWidget.getSelectionText().length() > 0);
779                 fNoSourceTextWidget.addSelectionListener(new SelectionListener() {
780                     public void widgetSelected(SelectionEvent e) {
781                         copyAction.setEnabled(fNoSourceTextWidget.getSelectionText().length() > 0);
782                     }
783                     public void widgetDefaultSelected(SelectionEvent e) {
784                     }
785                 });
786                 
787                 // Select All action for the no attached source case
788
final IAction selectAllAction= new Action() {
789                     public void run() {
790                         fNoSourceTextWidget.selectAll();
791                         copyAction.setEnabled(true);
792                     }
793                 };
794                 selectAllAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL);
795                 setAction(ITextEditorActionConstants.SELECT_ALL, selectAllAction);
796                 copyAction.setEnabled(fNoSourceTextWidget.getSelectionText().length() > 0);
797                 copyQualifiedName.setEnabled(false);
798                 
799                 
800             }
801
802         } else { // show source viewer
803

804             if (fSourceAttachmentForm != null) {
805                 fSourceAttachmentForm.dispose();
806                 fSourceAttachmentForm= null;
807
808                 fStackLayout.topControl= fViewerComposite;
809                 fParent.layout();
810             }
811
812             setAction(ITextEditorActionConstants.COPY, fSourceCopyAction);
813             setAction(ITextEditorActionConstants.SELECT_ALL, fSelectAllAction);
814             copyQualifiedName.setEnabled(true);
815
816         }
817         
818         IAction currentCopyAction= getAction(ITextEditorActionConstants.COPY);
819         boolean isUsingSourceCopyAction= fSourceCopyAction == currentCopyAction;
820         if (wasUsingSourceCopyAction != isUsingSourceCopyAction) {
821             IActionBars actionBars= getEditorSite().getActionBars();
822             
823             if (isUsingSourceCopyAction) {
824                 createNavigationActions();
825             } else {
826                 for (int i= 0; i < ACTION_MAP.length; i++) {
827                     IdMapEntry entry= ACTION_MAP[i];
828                     actionBars.setGlobalActionHandler(entry.getActionId(), null);
829                     setAction(entry.getActionId(), null);
830                 }
831             }
832             
833             actionBars.setGlobalActionHandler(ITextEditorActionConstants.COPY, currentCopyAction);
834             actionBars.setGlobalActionHandler(ITextEditorActionConstants.SELECT_ALL, getAction(ITextEditorActionConstants.SELECT_ALL));
835             actionBars.updateActionBars();
836         }
837         
838     }
839
840     /*
841      * @see ClassFileDocumentProvider.InputChangeListener#inputChanged(IClassFileEditorInput)
842      */

843     public void inputChanged(IClassFileEditorInput input) {
844         fInputUpdater.post(input);
845     }
846
847     /*
848      * @see JavaEditor#createJavaSourceViewer(Composite, IVerticalRuler, int)
849      */

850     protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles, IPreferenceStore store) {
851         return new JavaSourceViewer(parent, ruler, null, false, styles, store) {
852
853             public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
854                 if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed())
855                     return false;
856                 return super.requestWidgetToken(requester);
857             }
858
859             public boolean requestWidgetToken(IWidgetTokenKeeper requester, int priority) {
860                 if (PlatformUI.getWorkbench().getHelpSystem().isContextHelpDisplayed())
861                     return false;
862                 return super.requestWidgetToken(requester, priority);
863             }
864         };
865     }
866
867     /*
868      * @see org.eclipse.ui.IWorkbenchPart#dispose()
869      */

870     public void dispose() {
871         // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18510
872
IDocumentProvider documentProvider= getDocumentProvider();
873         if (documentProvider instanceof ClassFileDocumentProvider)
874             ((ClassFileDocumentProvider) documentProvider).removeInputChangeListener(this);
875         super.dispose();
876     }
877
878     /*
879      * @see org.eclipse.ui.IWorkbenchPart#setFocus()
880      */

881     public void setFocus() {
882         super.setFocus();
883
884         if (fSourceAttachmentForm != null && !fSourceAttachmentForm.isDisposed())
885             fSourceAttachmentForm.setFocus();
886     }
887
888 }
889
Popular Tags