]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / infoviews / JavadocView.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2012 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  *     Genady Beryozkin <eclipse@genady.org> - [misc] Display values for constant fields in the Javadoc view - https://bugs.eclipse.org/bugs/show_bug.cgi?id=204914
11  *     Brock Janiczak <brockj@tpg.com.au> - [implementation] Streams not being closed in Javadoc views - https://bugs.eclipse.org/bugs/show_bug.cgi?id=214854
12  *     Benjamin Muskalla <bmuskalla@innoopract.com> - [javadoc view] NPE on enumerations - https://bugs.eclipse.org/bugs/show_bug.cgi?id=223586
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.ui.infoviews;
15
16 import java.io.BufferedReader;
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.Reader;
20 import java.io.StringReader;
21 import java.net.URL;
22
23 import org.osgi.framework.Bundle;
24
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.SWTError;
27 import org.eclipse.swt.browser.Browser;
28 import org.eclipse.swt.browser.OpenWindowListener;
29 import org.eclipse.swt.browser.WindowEvent;
30 import org.eclipse.swt.custom.StyledText;
31 import org.eclipse.swt.events.ControlAdapter;
32 import org.eclipse.swt.events.ControlEvent;
33 import org.eclipse.swt.events.SelectionAdapter;
34 import org.eclipse.swt.events.SelectionEvent;
35 import org.eclipse.swt.graphics.Color;
36 import org.eclipse.swt.graphics.FontData;
37 import org.eclipse.swt.graphics.RGB;
38 import org.eclipse.swt.graphics.Rectangle;
39 import org.eclipse.swt.widgets.Composite;
40 import org.eclipse.swt.widgets.Control;
41 import org.eclipse.swt.widgets.Display;
42
43 import org.eclipse.core.runtime.Assert;
44 import org.eclipse.core.runtime.IProgressMonitor;
45 import org.eclipse.core.runtime.ListenerList;
46 import org.eclipse.core.runtime.NullProgressMonitor;
47 import org.eclipse.core.runtime.OperationCanceledException;
48 import org.eclipse.core.runtime.Platform;
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.action.IToolBarManager;
54 import org.eclipse.jface.action.Separator;
55 import org.eclipse.jface.commands.ActionHandler;
56 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
57 import org.eclipse.jface.internal.text.html.BrowserInput;
58 import org.eclipse.jface.internal.text.html.HTMLPrinter;
59 import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
60 import org.eclipse.jface.preference.IPreferenceStore;
61 import org.eclipse.jface.resource.JFaceResources;
62 import org.eclipse.jface.util.IPropertyChangeListener;
63 import org.eclipse.jface.util.PropertyChangeEvent;
64 import org.eclipse.jface.viewers.ISelection;
65 import org.eclipse.jface.viewers.ISelectionChangedListener;
66 import org.eclipse.jface.viewers.ISelectionProvider;
67 import org.eclipse.jface.viewers.IStructuredSelection;
68 import org.eclipse.jface.viewers.SelectionChangedEvent;
69 import org.eclipse.jface.viewers.StructuredSelection;
70 import org.eclipse.jface.window.Window;
71
72 import org.eclipse.jface.text.BadLocationException;
73 import org.eclipse.jface.text.BadPartitioningException;
74 import org.eclipse.jface.text.Document;
75 import org.eclipse.jface.text.IDocument;
76 import org.eclipse.jface.text.IDocumentExtension3;
77 import org.eclipse.jface.text.ITextSelection;
78 import org.eclipse.jface.text.Region;
79 import org.eclipse.jface.text.TextPresentation;
80 import org.eclipse.jface.text.TextSelection;
81
82 import org.eclipse.ui.IActionBars;
83 import org.eclipse.ui.IEditorPart;
84 import org.eclipse.ui.ISharedImages;
85 import org.eclipse.ui.IWorkbenchCommandConstants;
86 import org.eclipse.ui.IWorkbenchPage;
87 import org.eclipse.ui.IWorkbenchPart;
88 import org.eclipse.ui.IWorkbenchPartSite;
89 import org.eclipse.ui.IWorkbenchSite;
90 import org.eclipse.ui.IWorkbenchWindow;
91 import org.eclipse.ui.PartInitException;
92 import org.eclipse.ui.PlatformUI;
93 import org.eclipse.ui.actions.ActionFactory;
94 import org.eclipse.ui.handlers.IHandlerService;
95
96 import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
97 import org.eclipse.ui.texteditor.IDocumentProvider;
98 import org.eclipse.ui.texteditor.ITextEditor;
99
100 import org.eclipse.jdt.core.IClassFile;
101 import org.eclipse.jdt.core.ICompilationUnit;
102 import org.eclipse.jdt.core.IField;
103 import org.eclipse.jdt.core.IJavaElement;
104 import org.eclipse.jdt.core.IJavaProject;
105 import org.eclipse.jdt.core.ILocalVariable;
106 import org.eclipse.jdt.core.IMember;
107 import org.eclipse.jdt.core.IOpenable;
108 import org.eclipse.jdt.core.IPackageFragmentRoot;
109 import org.eclipse.jdt.core.ISourceRange;
110 import org.eclipse.jdt.core.ITypeRoot;
111 import org.eclipse.jdt.core.JavaCore;
112 import org.eclipse.jdt.core.JavaModelException;
113 import org.eclipse.jdt.core.SourceRange;
114 import org.eclipse.jdt.core.dom.ASTNode;
115 import org.eclipse.jdt.core.dom.ASTParser;
116 import org.eclipse.jdt.core.dom.CompilationUnit;
117 import org.eclipse.jdt.core.dom.Expression;
118 import org.eclipse.jdt.core.dom.IBinding;
119 import org.eclipse.jdt.core.dom.IVariableBinding;
120 import org.eclipse.jdt.core.dom.NodeFinder;
121 import org.eclipse.jdt.core.dom.SimpleName;
122 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
123 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
124
125 import org.eclipse.jdt.internal.corext.javadoc.JavaDocLocations;
126 import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
127 import org.eclipse.jdt.internal.corext.util.JdtFlags;
128 import org.eclipse.jdt.internal.corext.util.Messages;
129
130 import org.eclipse.jdt.ui.IContextMenuConstants;
131 import org.eclipse.jdt.ui.JavaElementLabels;
132 import org.eclipse.jdt.ui.JavaUI;
133 import org.eclipse.jdt.ui.PreferenceConstants;
134 import org.eclipse.jdt.ui.SharedASTProvider;
135 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
136 import org.eclipse.jdt.ui.actions.JdtActionConstants;
137 import org.eclipse.jdt.ui.actions.OpenAttachedJavadocAction;
138 import org.eclipse.jdt.ui.text.IJavaPartitions;
139
140 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
141 import org.eclipse.jdt.internal.ui.JavaPlugin;
142 import org.eclipse.jdt.internal.ui.JavaPluginImages;
143 import org.eclipse.jdt.internal.ui.actions.ActionMessages;
144 import org.eclipse.jdt.internal.ui.actions.SimpleSelectionProvider;
145 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
146 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
147 import org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover;
148 import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2;
149 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
150 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks;
151
152
153 /**
154  * View which shows Javadoc for a given Java element.
155  *
156  * FIXME: As of 3.0 selectAll() and getSelection() is not working
157  *                      see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
158  *
159  * @since 3.0
160  */
161 public class JavadocView extends AbstractInfoView {
162
163         /**
164          * Implementation of a {@link BrowserInput} using
165          * a {@link IJavaElement} as input.
166          *
167          * @since 3.4
168          */
169         private static final class JavaElementBrowserInput extends BrowserInput {
170
171                 private final IJavaElement fInput;
172
173                 public JavaElementBrowserInput(BrowserInput previous, IJavaElement inputElement) {
174                         super(previous);
175                         Assert.isNotNull(inputElement);
176                         fInput= inputElement;
177                 }
178
179                 /* (non-Javadoc)
180                  * @see org.eclipse.jdt.internal.ui.infoviews.JavadocView.IBrowserInput#getInputElement()
181                  */
182                 @Override
183                 public Object getInputElement() {
184                         return fInput;
185                 }
186
187                 /* (non-Javadoc)
188                  * @see org.eclipse.jdt.internal.ui.infoviews.JavadocView.IBrowserInput#getInputName()
189                  */
190                 @Override
191                 public String getInputName() {
192                         return fInput.getElementName();
193                 }
194         }
195
196         /**
197          * Implementation of a {@link BrowserInput} using an
198          * {@link URL} as input.
199          *
200          * @since 3.4
201          */
202         private static class URLBrowserInput extends BrowserInput {
203
204                 private final URL fURL;
205
206                 public URLBrowserInput(BrowserInput previous, URL url) {
207                         super(previous);
208                         Assert.isNotNull(url);
209                         fURL= url;
210                 }
211
212                 /* (non-Javadoc)
213                  * @see org.eclipse.jdt.internal.ui.infoviews.JavadocView.IBrowserInput#getInputElement()
214                  */
215                 @Override
216                 public Object getInputElement() {
217                         return fURL;
218                 }
219
220                 /* (non-Javadoc)
221                  * @see org.eclipse.jdt.internal.ui.infoviews.JavadocView.IBrowserInput#getInputName()
222                  */
223                 @Override
224                 public String getInputName() {
225                         return fURL.toExternalForm();
226                 }
227         }
228
229         /**
230          * Action to go forward in the history.
231          *
232          * @since 3.4
233          */
234         private final class ForthAction extends Action {
235
236                 public ForthAction() {
237                         setText(InfoViewMessages.JavadocView_action_forward_name);
238                         ISharedImages images= PlatformUI.getWorkbench().getSharedImages();
239                         setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));
240                         setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD_DISABLED));
241
242                         update();
243                 }
244
245                 public void update() {
246                         if (fCurrent != null && fCurrent.getNext() != null) {
247                                 BrowserInput element= fCurrent.getNext();
248                                 setToolTipText(Messages.format(InfoViewMessages.JavadocView_action_forward_enabledTooltip, BasicElementLabels.getJavaElementName(element.getInputName())));
249                                 setEnabled(true);
250                         } else {
251                                 setToolTipText(InfoViewMessages.JavadocView_action_forward_disabledTooltip);
252                                 setEnabled(false);
253                         }
254                 }
255
256                 /* (non-Javadoc)
257                  * @see org.eclipse.jface.action.Action#run()
258                  */
259                 @Override
260                 public void run() {
261                         setInput(fCurrent.getNext());
262                 }
263
264         }
265
266         /**
267          * Action to go backwards in the history.
268          *
269          * @since 3.4
270          */
271         private final class BackAction extends Action {
272
273                 public BackAction() {
274                         setText(InfoViewMessages.JavadocView_action_back_name);
275                         ISharedImages images= PlatformUI.getWorkbench().getSharedImages();
276                         setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_BACK));
277                         setDisabledImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED));
278
279                         update();
280                 }
281
282                 private void update() {
283                         if (fCurrent != null && fCurrent.getPrevious() != null) {
284                                 BrowserInput element= fCurrent.getPrevious();
285                                 setToolTipText(Messages.format(InfoViewMessages.JavadocView_action_back_enabledTooltip, BasicElementLabels.getJavaElementName(element.getInputName())));
286                                 setEnabled(true);
287                         } else {
288                                 setToolTipText(InfoViewMessages.JavadocView_action_back_disabledTooltip);
289                                 setEnabled(false);
290                         }
291                 }
292
293                 /* (non-Javadoc)
294                  * @see org.eclipse.jface.action.Action#run()
295                  */
296                 @Override
297                 public void run() {
298                         setInput(fCurrent.getPrevious());
299                 }
300         }
301
302         /**
303          * Action to toggle linking with selection.
304          *
305          * @since 3.4
306          */
307         private class LinkAction extends Action {
308
309                 public LinkAction() {
310                         super(InfoViewMessages.JavadocView_action_toogleLinking_text, SWT.TOGGLE);
311                         setToolTipText(InfoViewMessages.JavadocView_action_toggleLinking_toolTipText);
312                         JavaPluginImages.setLocalImageDescriptors(this, "synced.gif"); //$NON-NLS-1$
313                         setChecked(isLinkingEnabled());
314                 }
315
316                 /* (non-Javadoc)
317                  * @see org.eclipse.jface.action.Action#run()
318                  */
319                 @Override
320                 public void run() {
321                         setLinkingEnabled(!isLinkingEnabled());
322                 }
323         }
324
325         /**
326          * Action to open the selection in an external browser. If the selection is a java element its
327          * corresponding javadoc is shown if possible. If it is an URL the URL's content is shown.
328          * 
329          * The action is disabled if the selection can not be opened.
330          * 
331          * @since 3.6
332          */
333         private static class OpenInBrowserAction extends OpenAttachedJavadocAction {
334
335                 /**
336                  * Create a new ShowExternalJavadocAction
337                  * 
338                  * @param site the site
339                  */
340                 public OpenInBrowserAction(IWorkbenchSite site) {
341                         super(site);
342                 }
343
344                 /* (non-Javadoc)
345                  * Method declared on SelectionDispatchAction.
346                  */
347                 @Override
348                 public void selectionChanged(IStructuredSelection structuredSelection) {
349                         super.selectionChanged(structuredSelection);
350                         Object element= structuredSelection.getFirstElement();
351                         if (element instanceof URL) {
352                                 setText(InfoViewMessages.OpenInBrowserAction_url_label);
353                                 setToolTipText(InfoViewMessages.OpenInBrowserAction_url_toolTip);
354                         } else {
355                                 setText(ActionMessages.OpenAttachedJavadocAction_label);
356                                 setToolTipText(ActionMessages.OpenAttachedJavadocAction_tooltip);
357                         }
358                 }
359
360                 /* (non-Javadoc)
361                  * Method declared on SelectionDispatchAction.
362                  */
363                 @Override
364                 public void run(IStructuredSelection selection) {
365                         if (!canEnableFor(selection))
366                                 return;
367
368                         Object element= selection.getFirstElement();
369                         if (element instanceof IJavaElement)
370                                 super.run(selection);
371                         else
372                                 open((URL)element);
373
374                 }
375
376                 /*
377                  * @see org.eclipse.jdt.ui.actions.OpenAttachedJavadocAction#canEnableFor(org.eclipse.jface.viewers.IStructuredSelection)
378                  */
379                 @Override
380                 protected boolean canEnableFor(IStructuredSelection selection) {
381                         if (selection.size() != 1)
382                                 return false;
383
384                         Object element= selection.getFirstElement();
385                         return element instanceof URL || super.canEnableFor(selection);
386                 }
387
388                 public void generated_5908484398134673766(JavadocView javadocview) {
389                         setSpecialSelectionProvider(javadocview.fInputSelectionProvider);
390                         setImageDescriptor(JavaPluginImages.DESC_ELCL_OPEN_BROWSER);
391                         setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_OPEN_BROWSER);
392                         setActionDefinitionId(IJavaEditorActionDefinitionIds.OPEN_ATTACHED_JAVADOC);
393                         javadocview.fInputSelectionProvider.addSelectionChangedListener(this);
394                 }
395
396         }
397
398
399         /**
400          * Preference key for the preference whether to show a dialog
401          * when the SWT Browser widget is not available.
402          * @since 3.0
403          */
404         private static final String DO_NOT_WARN_PREFERENCE_KEY= "JavadocView.error.doNotWarn"; //$NON-NLS-1$
405
406         // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=73558
407         private static final boolean WARNING_DIALOG_ENABLED= false;
408
409         /** Flags used to render a label in the text widget. */
410         private static final long LABEL_FLAGS=  JavaElementLabels.ALL_FULLY_QUALIFIED
411                 | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.M_PARAMETER_ANNOTATIONS | JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_EXCEPTIONS
412                 | JavaElementLabels.F_PRE_TYPE_SIGNATURE | JavaElementLabels.T_TYPE_PARAMETERS;
413
414
415         /** The HTML widget. */
416         private Browser fBrowser;
417         /** The text widget. */
418         private StyledText fText;
419         /** The information presenter. */
420         private HTMLTextPresenter fPresenter;
421         /** The text presentation. */
422         private final TextPresentation fPresentation= new TextPresentation();
423         /** The select all action */
424         private SelectAllAction fSelectAllAction;
425         /** The style sheet (css) */
426         private static String fgStyleSheet;
427         /**
428          * <code>true</code> once the style sheet has been loaded.
429          * @since 3.3
430          */
431         private static boolean fgStyleSheetLoaded= false;
432
433         /** The Browser widget */
434         private boolean fIsUsingBrowserWidget;
435
436         private RGB fBackgroundColorRGB;
437         /**
438          * The font listener.
439          * @since 3.3
440          */
441         private IPropertyChangeListener fFontListener;
442
443         /**
444          * Holds original Javadoc input string.
445          * @since 3.4
446          */
447         private String fOriginalInput;
448
449         /**
450          * The current input element if any
451          * @since 3.4
452          */
453         private BrowserInput fCurrent;
454
455         /**
456          * Action to go back in the link history.
457          * @since 3.4
458          */
459         private BackAction fBackAction;
460
461         /**
462          * Action to go forth in the link history.
463          * @since 3.4
464          */
465         private ForthAction fForthAction;
466
467         /**
468          * Action to enable and disable link with selection.
469          * @since 3.4
470          */
471         private LinkAction fToggleLinkAction;
472
473         /**
474          * Action to open the attached Javadoc.
475          * 
476          * @since 3.4
477          */
478         private OpenInBrowserAction fOpenBrowserAction;
479
480         /**
481          * A selection provider providing the current
482          * Java element input of this view as selection.
483          * @since 3.4
484          */
485         private ISelectionProvider fInputSelectionProvider;
486
487         /**
488          * The Javadoc view's select all action.
489          */
490         private class SelectAllAction extends Action {
491
492                 /** The control. */
493                 private final Control fControl;
494                 /** The selection provider. */
495                 private final SelectionProvider fSelectionProvider;
496
497                 /**
498                  * Creates the action.
499                  *
500                  * @param control the widget
501                  * @param selectionProvider the selection provider
502                  */
503                 public SelectAllAction(Control control, SelectionProvider selectionProvider) {
504                         super("selectAll"); //$NON-NLS-1$
505
506                         Assert.isNotNull(control);
507                         Assert.isNotNull(selectionProvider);
508                         fControl= control;
509                         fSelectionProvider= selectionProvider;
510
511                         // FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
512                         setEnabled(!fIsUsingBrowserWidget);
513
514                         setText(InfoViewMessages.SelectAllAction_label);
515                         setToolTipText(InfoViewMessages.SelectAllAction_tooltip);
516                         setDescription(InfoViewMessages.SelectAllAction_description);
517
518                         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAbstractTextEditorHelpContextIds.SELECT_ALL_ACTION);
519                 }
520
521                 /**
522                  * Selects all in the view.
523                  */
524                 @Override
525                 public void run() {
526                         if (fControl instanceof StyledText)
527                         ((StyledText)fControl).selectAll();
528                         else {
529                                 // FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
530 //                              ((Browser)fControl).selectAll();
531                                 if (fSelectionProvider != null)
532                                         fSelectionProvider.fireSelectionChanged();
533                         }
534                 }
535         }
536
537         /**
538          * The Javadoc view's selection provider.
539          */
540         private static class SelectionProvider implements ISelectionProvider {
541
542                 /** The selection changed listeners. */
543                 private final ListenerList fListeners= new ListenerList(ListenerList.IDENTITY);
544                 /** The widget. */
545                 private final Control fControl;
546
547                 /**
548                  * Creates a new selection provider.
549                  *
550                  * @param control       the widget
551                  */
552                 public SelectionProvider(Control control) {
553                     Assert.isNotNull(control);
554                         fControl= control;
555                         if (fControl instanceof StyledText) {
556                             ((StyledText)fControl).addSelectionListener(new SelectionAdapter() {
557                                         @Override
558                                         public void widgetSelected(SelectionEvent e) {
559                                             fireSelectionChanged();
560                                         }
561                             });
562                         } else {
563                                 // FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
564 //                              ((Browser)fControl).addSelectionListener(new SelectionAdapter() {
565 //                                      public void widgetSelected(SelectionEvent e) {
566 //                                              fireSelectionChanged();
567 //                                      }
568 //                              });
569                         }
570                 }
571
572                 /**
573                  * Sends a selection changed event to all listeners.
574                  */
575                 public void fireSelectionChanged() {
576                         ISelection selection= getSelection();
577                         SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
578                         Object[] selectionChangedListeners= fListeners.getListeners();
579                         for (int i= 0; i < selectionChangedListeners.length; i++)
580                                 ((ISelectionChangedListener)selectionChangedListeners[i]).selectionChanged(event);
581                 }
582
583                 /*
584                  * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
585                  */
586                 public void addSelectionChangedListener(ISelectionChangedListener listener) {
587                         fListeners.add(listener);
588                 }
589
590                 /*
591                  * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
592                  */
593                 public ISelection getSelection() {
594                         if (fControl instanceof StyledText) {
595                                 IDocument document= new Document(((StyledText)fControl).getSelectionText());
596                                 return new TextSelection(document, 0, document.getLength());
597                         } else {
598                                 // FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
599                                 return StructuredSelection.EMPTY;
600                         }
601                 }
602
603                 /*
604                  * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
605                  */
606                 public void removeSelectionChangedListener(ISelectionChangedListener listener) {
607                         fListeners.remove(listener);
608                 }
609
610                 /*
611                  * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
612                  */
613                 public void setSelection(ISelection selection) {
614                         // not supported
615                 }
616         }
617
618         /*
619          * @see AbstractInfoView#internalCreatePartControl(Composite)
620          */
621         @Override
622         protected void internalCreatePartControl(Composite parent) {
623                 try {
624                         fBrowser= new Browser(parent, SWT.NONE);
625                         fBrowser.setJavascriptEnabled(false);
626                         fIsUsingBrowserWidget= true;
627                         addLinkListener(fBrowser);
628                         fBrowser.addOpenWindowListener(new OpenWindowListener() {
629                                 public void open(WindowEvent event) {
630                                         event.required= true; // Cancel opening of new windows
631                                 }
632                         });
633
634                 } catch (SWTError er) {
635
636                         /* The Browser widget throws an SWTError if it fails to
637                          * instantiate properly. Application code should catch
638                          * this SWTError and disable any feature requiring the
639                          * Browser widget.
640                          * Platform requirements for the SWT Browser widget are available
641                          * from the SWT FAQ web site.
642                          */
643
644                         IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
645                         boolean doNotWarn= store.getBoolean(DO_NOT_WARN_PREFERENCE_KEY);
646                         if (WARNING_DIALOG_ENABLED) {
647                                 if (!doNotWarn) {
648                                         String title= InfoViewMessages.JavadocView_error_noBrowser_title;
649                                         String message= InfoViewMessages.JavadocView_error_noBrowser_message;
650                                         String toggleMessage= InfoViewMessages.JavadocView_error_noBrowser_doNotWarn;
651                                         MessageDialogWithToggle dialog= MessageDialogWithToggle.openError(parent.getShell(), title, message, toggleMessage, false, null, null);
652                                         if (dialog.getReturnCode() == Window.OK)
653                                                 store.setValue(DO_NOT_WARN_PREFERENCE_KEY, dialog.getToggleState());
654                                 }
655                         }
656
657                         fIsUsingBrowserWidget= false;
658                 }
659
660                 if (!fIsUsingBrowserWidget) {
661                         fText= new StyledText(parent, SWT.V_SCROLL | SWT.H_SCROLL);
662                         fText.setEditable(false);
663                         fPresenter= new HTMLTextPresenter(false);
664
665                         fText.addControlListener(new ControlAdapter() {
666                                 /*
667                                  * @see org.eclipse.swt.events.ControlAdapter#controlResized(org.eclipse.swt.events.ControlEvent)
668                                  */
669                                 @Override
670                                 public void controlResized(ControlEvent e) {
671                                         doSetInput(fOriginalInput);
672                                 }
673                         });
674                 }
675
676                 initStyleSheet();
677                 listenForFontChanges();
678                 getViewSite().setSelectionProvider(new SelectionProvider(getControl()));
679         }
680
681         /**
682          * Registers a listener for the Java editor font.
683          *
684          * @since 3.3
685          */
686         private void listenForFontChanges() {
687                 fFontListener= new IPropertyChangeListener() {
688                         public void propertyChange(PropertyChangeEvent event) {
689                                 if (PreferenceConstants.APPEARANCE_JAVADOC_FONT.equals(event.getProperty())) {
690                                         fgStyleSheetLoaded= false;
691                                         // trigger reloading, but make sure other listeners have already run, so that
692                                         // the style sheet gets reloaded only once.
693                                         final Display display= getSite().getPage().getWorkbenchWindow().getWorkbench().getDisplay();
694                                         if (!display.isDisposed()) {
695                                                 display.asyncExec(new Runnable() {
696                                                         public void run() {
697                                                                 if (!display.isDisposed()) {
698                                                                         initStyleSheet();
699                                                                         refresh();
700                                                                 }
701                                                         }
702                                                 });
703                                         }
704                                 }
705                         }
706                 };
707                 JFaceResources.getFontRegistry().addListener(fFontListener);
708         }
709
710         private static void initStyleSheet() {
711                 if (fgStyleSheetLoaded)
712                         return;
713                 fgStyleSheetLoaded= true;
714                 fgStyleSheet= loadStyleSheet();
715         }
716
717         private static String loadStyleSheet() {
718                 Bundle bundle= Platform.getBundle(JavaPlugin.getPluginId());
719                 URL styleSheetURL= bundle.getEntry("/JavadocViewStyleSheet.css"); //$NON-NLS-1$
720                 if (styleSheetURL == null)
721                         return null;
722
723                 BufferedReader reader= null;
724                 try {
725                         reader= new BufferedReader(new InputStreamReader(styleSheetURL.openStream()));
726                         StringBuffer buffer= new StringBuffer(1500);
727                         String line= reader.readLine();
728                         while (line != null) {
729                                 buffer.append(line);
730                                 buffer.append('\n');
731                                 line= reader.readLine();
732                         }
733
734                         FontData fontData= JFaceResources.getFontRegistry().getFontData(PreferenceConstants.APPEARANCE_JAVADOC_FONT)[0];
735                         return HTMLPrinter.convertTopLevelFont(buffer.toString(), fontData);
736                 } catch (IOException ex) {
737                         JavaPlugin.log(ex);
738                         return null;
739                 } finally {
740                         try {
741                                 if (reader != null)
742                                         reader.close();
743                         } catch (IOException e) {
744                         }
745                 }
746         }
747
748         /*
749          * @see AbstractInfoView#createActions()
750          */
751         @Override
752         protected void createActions() {
753                 super.createActions();
754                 fSelectAllAction= new SelectAllAction(getControl(), (SelectionProvider) getSelectionProvider());
755
756                 fBackAction= new BackAction();
757                 fBackAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_BACK);
758                 fForthAction= new ForthAction();
759                 fForthAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_FORWARD);
760
761                 fToggleLinkAction= new LinkAction();
762                 fToggleLinkAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR);
763
764                 fInputSelectionProvider= new SimpleSelectionProvider();
765                 fOpenBrowserAction= new OpenInBrowserAction(getSite());
766                 fOpenBrowserAction.generated_5908484398134673766(this);
767
768                 IJavaElement input= getInput();
769                 StructuredSelection selection;
770                 if (input != null) {
771                         selection= new StructuredSelection(input);
772                 } else {
773                         selection= new StructuredSelection();
774                 }
775                 fInputSelectionProvider.setSelection(selection);
776         }
777
778         /* (non-Javadoc)
779          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#fillActionBars(org.eclipse.ui.IActionBars)
780          * @since 3.4
781          */
782         @Override
783         protected void fillActionBars(final IActionBars actionBars) {
784                 super.fillActionBars(actionBars);
785
786                 actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(), fBackAction);
787                 actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(), fForthAction);
788
789                 fInputSelectionProvider.addSelectionChangedListener(new ISelectionChangedListener() {
790                         public void selectionChanged(SelectionChangedEvent event) {
791                                 actionBars.setGlobalActionHandler(JdtActionConstants.OPEN_ATTACHED_JAVA_DOC, fOpenBrowserAction);
792                         }
793                 });
794
795                 IHandlerService handlerService= (IHandlerService) getSite().getService(IHandlerService.class);
796                 handlerService.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, new ActionHandler(fToggleLinkAction));
797         }
798
799         /* (non-Javadoc)
800          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#fillToolBar(org.eclipse.jface.action.IToolBarManager)
801          * @since 3.4
802          */
803         @Override
804         protected void fillToolBar(IToolBarManager tbm) {
805                 tbm.add(fBackAction);
806                 tbm.add(fForthAction);
807                 tbm.add(new Separator());
808
809                 tbm.add(fToggleLinkAction);
810                 super.fillToolBar(tbm);
811                 tbm.add(fOpenBrowserAction);
812         }
813
814         /* (non-Javadoc)
815          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
816          * @since 3.4
817          */
818         @Override
819         public void menuAboutToShow(IMenuManager menu) {
820                 super.menuAboutToShow(menu);
821
822                 menu.appendToGroup(IContextMenuConstants.GROUP_GOTO, fBackAction);
823                 menu.appendToGroup(IContextMenuConstants.GROUP_GOTO, fForthAction);
824
825                 menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, fOpenBrowserAction);
826         }
827
828         /*
829          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getSelectAllAction()
830          * @since 3.0
831          */
832         @Override
833         protected IAction getSelectAllAction() {
834                 // FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
835                 if (fIsUsingBrowserWidget)
836                         return null;
837
838                 return fSelectAllAction;
839         }
840
841         /*
842          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getCopyToClipboardAction()
843          * @since 3.0
844          */
845         @Override
846         protected IAction getCopyToClipboardAction() {
847                 // FIXME: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63022
848                 if (fIsUsingBrowserWidget)
849                         return null;
850
851                 return super.getCopyToClipboardAction();
852         }
853
854         /*
855          * @see AbstractInfoView#setForeground(Color)
856          */
857         @Override
858         protected void setForeground(Color color) {
859                 getControl().setForeground(color);
860         }
861
862         /*
863          * @see AbstractInfoView#setBackground(Color)
864          */
865         @Override
866         protected void setBackground(Color color) {
867                 getControl().setBackground(color);
868                 fBackgroundColorRGB= color.getRGB();
869                 refresh();
870         }
871
872         /**
873          * Refreshes the view.
874          *
875          * @since 3.3
876          */
877         private void refresh() {
878                 IJavaElement input= getInput();
879                 if (input == null) {
880                         StringBuffer buffer= new StringBuffer(""); //$NON-NLS-1$
881                         HTMLPrinter.insertPageProlog(buffer, 0, null, fBackgroundColorRGB, fgStyleSheet);
882                         doSetInput(buffer.toString());
883                 } else {
884                         doSetInput(computeInput(input));
885                 }
886         }
887
888         /*
889          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getBackgroundColorKey()
890          * @since 3.2
891          */
892         @Override
893         protected String getBackgroundColorKey() {
894                 return "org.eclipse.jdt.ui.JavadocView.backgroundColor";                 //$NON-NLS-1$
895         }
896
897         /*
898          * @see AbstractInfoView#internalDispose()
899          */
900         @Override
901         protected void internalDispose() {
902                 fText= null;
903                 fBrowser= null;
904                 if (fFontListener != null) {
905                         JFaceResources.getFontRegistry().removeListener(fFontListener);
906                         fFontListener= null;
907                 }
908
909                 if (fOpenBrowserAction != null) {
910                         fInputSelectionProvider.removeSelectionChangedListener(fOpenBrowserAction);
911                         fOpenBrowserAction= null;
912                 }
913         }
914
915         /*
916          * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
917          */
918         @Override
919         public void setFocus() {
920                 getControl().setFocus();
921         }
922
923         /*
924          * @see AbstractInfoView#computeInput(Object)
925          */
926         @Override
927         protected Object computeInput(Object input) {
928                 if (getControl() == null || ! (input instanceof IJavaElement))
929                         return getInputForNull();
930
931                 IWorkbenchPart part= null;
932                 IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
933                 if (window != null) {
934                         IWorkbenchPage page= window.getActivePage();
935                         if (page != null) {
936                                 part= page.getActivePart();
937                         }
938                 }
939
940                 ISelection selection= null;
941                 if (part != null) {
942                         IWorkbenchPartSite site= part.getSite();
943                         if (site != null) {
944                                 ISelectionProvider provider= site.getSelectionProvider();
945                                 if (provider != null) {
946                                         selection= provider.getSelection();
947                                 }
948                         }
949                 }
950
951                 return computeInput(part, selection, (IJavaElement) input, new NullProgressMonitor());
952         }
953
954         /* (non-Javadoc)
955          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#computeInput(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.jdt.core.IJavaElement, org.eclipse.core.runtime.IProgressMonitor)
956          * @since 3.4
957          */
958         @Override
959         protected Object computeInput(IWorkbenchPart part, ISelection selection, IJavaElement input, IProgressMonitor monitor) {
960                 if (getControl() == null || input == null)
961                         return getInputForNull();
962
963                 String javadocHtml;
964
965                 switch (input.getElementType()) {
966                         case IJavaElement.COMPILATION_UNIT:
967                                 try {
968                                         javadocHtml= getJavadocHtml(((ICompilationUnit) input).getTypes(), part, selection, monitor);
969                                 } catch (JavaModelException ex) {
970                                         javadocHtml= null;
971                                 }
972                                 break;
973                         case IJavaElement.CLASS_FILE:
974                                 javadocHtml= getJavadocHtml(new IJavaElement[] { ((IClassFile) input).getType() }, part, selection, monitor);
975                                 break;
976                         default:
977                                 javadocHtml= getJavadocHtml(new IJavaElement[] { input }, part, selection, monitor);
978                 }
979
980                 if (javadocHtml == null)
981                         return ""; //$NON-NLS-1$
982
983                 return javadocHtml;
984         }
985
986         /*
987          * @see AbstractInfoView#computeDescription(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.jdt.core.IJavaElement, org.eclipse.core.runtime.IProgressMonitor)
988          * @since 3.4
989          */
990         @Override
991         protected String computeDescription(IWorkbenchPart part, ISelection selection, IJavaElement inputElement, IProgressMonitor monitor) {
992                 return ""; //$NON-NLS-1$
993         }
994
995         /**
996          * Set input to the given input.
997          *
998          * @param input the input for the view
999          * @since 3.4
1000          */
1001         public void setInput(BrowserInput input) {
1002                 fCurrent= input;
1003
1004                 Object inputElement= input.getInputElement();
1005                 if (inputElement instanceof IJavaElement) {
1006                         setInput((IJavaElement) inputElement);
1007                 } else if (inputElement instanceof URL) {
1008                         fBrowser.setUrl(((URL) inputElement).toExternalForm());
1009
1010                         if (fInputSelectionProvider != null)
1011                                 fInputSelectionProvider.setSelection(new StructuredSelection(inputElement));
1012                 }
1013
1014                 fForthAction.update();
1015                 fBackAction.update();
1016         }
1017
1018         /**
1019          * {@inheritDoc}
1020          * 
1021          * @param input a String containing the HTML to be showin in the view
1022          */
1023         @Override
1024         protected void doSetInput(Object input) {
1025                 String javadocHtml= (String)input;
1026                 fOriginalInput= javadocHtml;
1027
1028                 if (fInputSelectionProvider != null) {
1029                         IJavaElement inputElement= getInput();
1030                         StructuredSelection selection= inputElement == null ? StructuredSelection.EMPTY : new StructuredSelection(inputElement);
1031                         fInputSelectionProvider.setSelection(selection);
1032                 }
1033
1034                 if (fIsUsingBrowserWidget) {
1035                         if (javadocHtml != null && javadocHtml.length() > 0) {
1036                                 boolean RTL= (getSite().getShell().getStyle() & SWT.RIGHT_TO_LEFT) != 0;
1037                                 if (RTL) {
1038                                         StringBuffer buffer= new StringBuffer(javadocHtml);
1039                                         HTMLPrinter.insertStyles(buffer, new String[] { "direction:rtl" } ); //$NON-NLS-1$
1040                                         javadocHtml= buffer.toString();
1041                                 }
1042                         }
1043                         fBrowser.setText(javadocHtml);
1044                 } else {
1045                         fPresentation.clear();
1046                         Rectangle size=  fText.getClientArea();
1047
1048                         try {
1049                                 javadocHtml= fPresenter.updatePresentation(fText, javadocHtml, fPresentation, size.width, size.height);
1050                         } catch (IllegalArgumentException ex) {
1051                                 // the javadoc might no longer be valid
1052                                 return;
1053                         }
1054                         fText.setText(javadocHtml);
1055                         TextPresentation.applyTextPresentation(fPresentation, fText);
1056                 }
1057         }
1058
1059         /**
1060          * Returns the Javadoc in HTML format.
1061          *
1062          * @param result the Java elements for which to get the Javadoc
1063          * @param activePart the active part if any
1064          * @param selection the selection of the active site if any
1065          * @param monitor a monitor to report progress to
1066          * @return a string with the Javadoc in HTML format.
1067          */
1068         private String getJavadocHtml(IJavaElement[] result, IWorkbenchPart activePart, ISelection selection, IProgressMonitor monitor) {
1069                 StringBuffer buffer= new StringBuffer();
1070                 int nResults= result.length;
1071
1072                 if (nResults == 0)
1073                         return null;
1074
1075                 String base= null;
1076                 if (nResults > 1) {
1077
1078                         for (int i= 0; i < result.length; i++) {
1079                                 HTMLPrinter.startBulletList(buffer);
1080                                 IJavaElement curr= result[i];
1081                                 if (curr instanceof IMember || curr.getElementType() == IJavaElement.LOCAL_VARIABLE)
1082                                         HTMLPrinter.addBullet(buffer, getInfoText(curr, null, false));
1083                                 HTMLPrinter.endBulletList(buffer);
1084                         }
1085
1086                 } else {
1087
1088                         IJavaElement curr= result[0];
1089                         if (curr instanceof IMember) {
1090                                 final IMember member= (IMember)curr;
1091
1092                                 String constantValue= null;
1093                                 if (member instanceof IField) {
1094                                         constantValue= computeFieldConstant(activePart, selection, (IField) member, monitor);
1095                                         if (constantValue != null)
1096                                                 constantValue= HTMLPrinter.convertToHTMLContentWithWhitespace(constantValue);
1097                                 }
1098
1099                                 HTMLPrinter.addSmallHeader(buffer, getInfoText(member, constantValue, true));
1100
1101                                 try {
1102                                         ISourceRange nameRange= ((IMember)curr).getNameRange();
1103                                         if (SourceRange.isAvailable(nameRange)) {
1104                                                 ITypeRoot typeRoot= ((IMember)curr).getTypeRoot();
1105                                                 Region hoverRegion= new Region(nameRange.getOffset(), nameRange.getLength());
1106                                                 buffer.append("<br>"); //$NON-NLS-1$
1107                                                 JavadocHover.addAnnotations(buffer, curr, typeRoot, hoverRegion);
1108                                         }
1109                                 } catch (JavaModelException e) {
1110                                         // no annotations this time...
1111                                 }
1112                                 
1113                                 Reader reader;
1114                                 try {
1115                                         String content= JavadocContentAccess2.getHTMLContent(member, true);
1116                                         reader= content == null ? null : new StringReader(content);
1117
1118                                         // Provide hint why there's no Javadoc
1119                                         if (reader == null && member.isBinary()) {
1120                                                 boolean hasAttachedJavadoc= JavaDocLocations.getJavadocBaseLocation(member) != null;
1121                                                 IPackageFragmentRoot root= (IPackageFragmentRoot)member.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
1122                                                 boolean hasAttachedSource= root != null && root.getSourceAttachmentPath() != null;
1123                                                 IOpenable openable= member.getOpenable();
1124                                                 boolean hasSource= openable.getBuffer() != null;
1125
1126                                                 if (!hasAttachedSource && !hasAttachedJavadoc)
1127                                                         reader= new StringReader(InfoViewMessages.JavadocView_noAttachments);
1128                                                 else if (!hasAttachedJavadoc && !hasSource)
1129                                                         reader= new StringReader(InfoViewMessages.JavadocView_noAttachedJavadoc);
1130                                                 else if (!hasAttachedSource)
1131                                                         reader= new StringReader(InfoViewMessages.JavadocView_noAttachedSource);
1132                                                 else if (!hasSource)
1133                                                         reader= new StringReader(InfoViewMessages.JavadocView_noInformation);
1134
1135                                         } else {
1136                                                 base= JavaDocLocations.getBaseURL(member);
1137                                         }
1138
1139                                 } catch (JavaModelException ex) {
1140                                         reader= new StringReader(InfoViewMessages.JavadocView_error_gettingJavadoc);
1141                                         JavaPlugin.log(ex.getStatus());
1142                                 }
1143                                 if (reader != null) {
1144                                         HTMLPrinter.addParagraph(buffer, reader);
1145                                 }
1146
1147                         } else if (curr.getElementType() == IJavaElement.LOCAL_VARIABLE || curr.getElementType() == IJavaElement.TYPE_PARAMETER) {
1148                                 HTMLPrinter.addSmallHeader(buffer, getInfoText(curr, null, true));
1149                                 if (curr instanceof ILocalVariable) {
1150                                         ISourceRange nameRange= ((ILocalVariable) curr).getNameRange();
1151                                         ITypeRoot typeRoot= ((ILocalVariable) curr).getTypeRoot();
1152                                         Region hoverRegion= new Region(nameRange.getOffset(), nameRange.getLength());
1153                                         buffer.append("<br>"); //$NON-NLS-1$
1154                                         JavadocHover.addAnnotations(buffer, curr, typeRoot, hoverRegion);
1155                                 }
1156                         }
1157                 }
1158
1159                 HTMLPrinter.insertPageProlog(buffer, 0, null, fBackgroundColorRGB, fgStyleSheet);
1160                 if (base != null) {
1161                         int endHeadIdx= buffer.indexOf("</head>"); //$NON-NLS-1$
1162                         buffer.insert(endHeadIdx, "\n<base href='" + base + "'>\n"); //$NON-NLS-1$ //$NON-NLS-2$
1163                 }
1164                 HTMLPrinter.addPageEpilog(buffer);
1165                 return buffer.toString();
1166         }
1167
1168         private String getInputForNull() {
1169                 StringBuffer buffer= new StringBuffer();
1170                 HTMLPrinter.insertPageProlog(buffer, 0, null, fBackgroundColorRGB, fgStyleSheet);
1171                 HTMLPrinter.addPageEpilog(buffer);
1172                 return buffer.toString();
1173         }
1174
1175         /**
1176          * Gets the label for the given member.
1177          *
1178          * @param member the Java member
1179          * @param constantValue the constant value if any
1180          * @param allowImage true if the java element image should be shown
1181          * @return a string containing the member's label
1182          */
1183         private String getInfoText(IJavaElement member, String constantValue, boolean allowImage) {
1184                 StringBuffer label= new StringBuffer(JavaElementLinks.getElementLabel(member, LABEL_FLAGS));
1185                 if (member.getElementType() == IJavaElement.FIELD && constantValue != null) {
1186                         label.append(constantValue);
1187                 }
1188
1189                 String imageName= null;
1190                 if (allowImage) {
1191                         URL imageUrl= JavaPlugin.getDefault().getImagesOnFSRegistry().getImageURL(member);
1192                         if (imageUrl != null) {
1193                                 imageName= imageUrl.toExternalForm();
1194                         }
1195                 }
1196
1197                 StringBuffer buf= new StringBuffer();
1198                 JavadocHover.addImageAndLabel(buf, member, imageName, 16, 16, label.toString(), 20, 2);
1199                 return buf.toString();
1200         }
1201
1202         /*
1203          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#isIgnoringNewInput(org.eclipse.jdt.core.IJavaElement, org.eclipse.jface.viewers.ISelection)
1204          * @since 3.2
1205          */
1206         @Override
1207         protected boolean isIgnoringNewInput(IJavaElement je, IWorkbenchPart part, ISelection selection) {
1208                 if (fCurrent != null && fCurrent.getInputElement() instanceof URL)
1209                         return false;
1210
1211                 if (super.isIgnoringNewInput(je, part, selection)
1212                                 && part instanceof ITextEditor
1213                                 && selection instanceof ITextSelection) {
1214
1215                         ITextEditor editor= (ITextEditor)part;
1216                         IDocumentProvider docProvider= editor.getDocumentProvider();
1217                         if (docProvider == null)
1218                                 return false;
1219
1220                         IDocument document= docProvider.getDocument(editor.getEditorInput());
1221                         if (!(document instanceof IDocumentExtension3))
1222                                 return false;
1223
1224                         try {
1225                                 int offset= ((ITextSelection)selection).getOffset();
1226                                 String partition= ((IDocumentExtension3)document).getContentType(IJavaPartitions.JAVA_PARTITIONING, offset, false);
1227                                 return  partition != IJavaPartitions.JAVA_DOC;
1228                         } catch (BadPartitioningException ex) {
1229                                 return false;
1230                         } catch (BadLocationException ex) {
1231                                 return false;
1232                         }
1233
1234                 }
1235                 return false;
1236         }
1237
1238         /*
1239          * @see AbstractInfoView#findSelectedJavaElement(IWorkbenchPart)
1240          */
1241         @Override
1242         protected IJavaElement findSelectedJavaElement(IWorkbenchPart part, ISelection selection) {
1243                 IJavaElement element;
1244                 try {
1245                         element= super.findSelectedJavaElement(part, selection);
1246
1247                         if (element == null && part instanceof JavaEditor && selection instanceof ITextSelection) {
1248
1249                                 JavaEditor editor= (JavaEditor)part;
1250                                 return editor.generated_685633402562717764(part, selection);
1251                         } else
1252                                 return element;
1253                 } catch (JavaModelException e) {
1254                         return null;
1255                 } catch (BadLocationException e) {
1256                         return null;
1257                 }
1258         }
1259
1260         /*
1261          * @see AbstractInfoView#getControl()
1262          */
1263         @Override
1264         protected Control getControl() {
1265                 if (fIsUsingBrowserWidget)
1266                         return fBrowser;
1267                 else
1268                         return fText;
1269         }
1270
1271         /*
1272          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getHelpContextId()
1273          * @since 3.1
1274          */
1275         @Override
1276         protected String getHelpContextId() {
1277                 return IJavaHelpContextIds.JAVADOC_VIEW;
1278         }
1279
1280         /**
1281          * Compute the textual representation of a 'static' 'final' field's constant initializer value.
1282          *
1283          * @param activePart the part that triggered the computation, or <code>null</code>
1284          * @param selection the selection that references the field, or <code>null</code>
1285          * @param resolvedField the filed whose constant value will be computed
1286          * @param monitor the progress monitor
1287          *
1288          * @return the textual representation of the constant, or <code>null</code> if the
1289          *   field is not a constant field, the initializer value could not be computed, or
1290          *   the progress monitor was cancelled
1291          * @since 3.4
1292          */
1293         private String computeFieldConstant(IWorkbenchPart activePart, ISelection selection, IField resolvedField, IProgressMonitor monitor) {
1294
1295                 if (!isStaticFinal(resolvedField))
1296                         return null;
1297
1298                 Object constantValue;
1299                 IJavaProject preferenceProject;
1300
1301                 if (selection instanceof ITextSelection && activePart instanceof JavaEditor) {
1302                         IEditorPart editor= (IEditorPart) activePart;
1303                         ITypeRoot activeType= JavaUI.getEditorInputTypeRoot(editor.getEditorInput());
1304                         preferenceProject= activeType.getJavaProject();
1305                         constantValue= getConstantValueFromActiveEditor(activeType, resolvedField, (ITextSelection) selection, monitor);
1306                         if (constantValue == null) // fall back - e.g. when selection is inside Javadoc of the element
1307                                 constantValue= computeFieldConstantFromTypeAST(resolvedField, monitor);
1308                 } else {
1309                         constantValue= computeFieldConstantFromTypeAST(resolvedField, monitor);
1310                         preferenceProject= resolvedField.getJavaProject();
1311                 }
1312
1313                 if (constantValue != null)
1314                         return getFormattedAssignmentOperator(preferenceProject) + formatCompilerConstantValue(constantValue);
1315
1316                 return null;
1317         }
1318
1319         /**
1320          * Retrieve a constant initializer value of a field by (AST) parsing field's type.
1321          *
1322          * @param constantField the constant field
1323          * @param monitor the progress monitor
1324          * @return the constant value of the field, or <code>null</code> if it could not be computed
1325          *   (or if the progress was cancelled).
1326          * @since 3.4
1327          */
1328         private Object computeFieldConstantFromTypeAST(IField constantField, IProgressMonitor monitor) {
1329                 if (monitor.isCanceled())
1330                         return null;
1331
1332                 CompilationUnit ast= SharedASTProvider.getAST(constantField.getTypeRoot(), SharedASTProvider.WAIT_NO, monitor);
1333                 if (ast != null) {
1334                         try {
1335                                 if (constantField.isEnumConstant())
1336                                         return null;
1337
1338                                 VariableDeclarationFragment fieldDecl= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(constantField, ast);
1339                                 if (fieldDecl == null)
1340                                         return null;
1341                                 Expression initializer= fieldDecl.getInitializer();
1342                                 if (initializer == null)
1343                                         return null;
1344                                 return initializer.resolveConstantExpressionValue();
1345                         } catch (JavaModelException e) {
1346                                 // ignore the exception and try the next method
1347                         }
1348                 }
1349
1350                 if (monitor.isCanceled())
1351                         return null;
1352
1353                 ASTParser p= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
1354                 p.setProject(constantField.getJavaProject());
1355                 IBinding[] createBindings;
1356                 try {
1357                         createBindings= p.createBindings(new IJavaElement[] { constantField }, monitor);
1358                 } catch (OperationCanceledException e) {
1359                         return null;
1360                 }
1361
1362                 IVariableBinding variableBinding= (IVariableBinding) createBindings[0];
1363                 if (variableBinding != null)
1364                         return variableBinding.getConstantValue();
1365
1366                 return null;
1367         }
1368
1369         /**
1370          * Tells whether the given member is static final.
1371          * <p>
1372          * XXX: Copied from {@link JavadocHover}.
1373          * </p>
1374          * @param member the member to test
1375          * @return <code>true</code> if static final
1376          * @since 3.4
1377          */
1378         private static boolean isStaticFinal(IJavaElement member) {
1379                 if (member.getElementType() != IJavaElement.FIELD)
1380                         return false;
1381
1382                 IField field= (IField)member;
1383                 try {
1384                         return JdtFlags.isFinal(field) && JdtFlags.isStatic(field);
1385                 } catch (JavaModelException e) {
1386                         JavaPlugin.log(e);
1387                         return false;
1388                 }
1389         }
1390
1391         /**
1392          * Returns the constant value for a field that is referenced by the currently active type.
1393          * This method does may not run in the main UI thread.
1394          * <p>
1395          * XXX: This method was part of the JavadocHover#getConstantValue(IField field, IRegion hoverRegion)
1396          *              method (lines 299-314).
1397          * </p>
1398          * @param activeType the type that is currently active
1399          * @param field the field that is being referenced (usually not declared in <code>activeType</code>)
1400          * @param selection the region in <code>activeType</code> that contains the field reference
1401          * @param monitor a progress monitor
1402          *
1403          * @return the constant value for the given field or <code>null</code> if none
1404          * @since 3.4
1405          */
1406         private static Object getConstantValueFromActiveEditor(ITypeRoot activeType, IField field, ITextSelection selection, IProgressMonitor monitor) {
1407                 Object constantValue= null;
1408
1409                 CompilationUnit unit= SharedASTProvider.getAST(activeType, SharedASTProvider.WAIT_ACTIVE_ONLY, monitor);
1410                 if (unit == null)
1411                         return null;
1412
1413                 ASTNode node= NodeFinder.perform(unit, selection.getOffset(), selection.getLength());
1414                 if (node != null && node.getNodeType() == ASTNode.SIMPLE_NAME) {
1415                         IBinding binding= ((SimpleName)node).resolveBinding();
1416                         if (binding != null && binding.getKind() == IBinding.VARIABLE) {
1417                                 IVariableBinding variableBinding= (IVariableBinding)binding;
1418                                 if (field.equals(variableBinding.getJavaElement())) {
1419                                         constantValue= variableBinding.getConstantValue();
1420                                 }
1421                         }
1422                 }
1423                 return constantValue;
1424         }
1425
1426         /**
1427          * Returns the string representation of the given constant value.
1428          * <p>
1429          * XXX: In {@link JavadocHover} this method was part of JavadocHover#getConstantValue lines 318-361.
1430          * </p>
1431          * @param constantValue the constant value
1432          * @return the string representation of the given constant value.
1433          * @since 3.4
1434          */
1435         private static String formatCompilerConstantValue(Object constantValue) {
1436                 if (constantValue instanceof String) {
1437                         StringBuffer result= new StringBuffer();
1438                         result.append('"');
1439                         String stringConstant= (String)constantValue;
1440                         if (stringConstant.length() > 80) {
1441                                 result.append(stringConstant.substring(0, 80));
1442                                 result.append(JavaElementLabels.ELLIPSIS_STRING);
1443                         } else {
1444                                 result.append(stringConstant);
1445                         }
1446                         result.append('"');
1447                         return result.toString();
1448
1449                 } else if (constantValue instanceof Character) {
1450                         String constantResult= '\'' + constantValue.toString() + '\'';
1451
1452                         char charValue= ((Character) constantValue).charValue();
1453                         String hexString= Integer.toHexString(charValue);
1454                         StringBuffer hexResult= new StringBuffer("\\u"); //$NON-NLS-1$
1455                         for (int i= hexString.length(); i < 4; i++) {
1456                                 hexResult.append('0');
1457                         }
1458                         hexResult.append(hexString);
1459                         return formatWithHexValue(constantResult, hexResult.toString());
1460
1461                 } else if (constantValue instanceof Byte) {
1462                         int byteValue= ((Byte) constantValue).intValue() & 0xFF;
1463                         return formatWithHexValue(constantValue, "0x" + Integer.toHexString(byteValue)); //$NON-NLS-1$
1464
1465                 } else if (constantValue instanceof Short) {
1466                         int shortValue= ((Short) constantValue).shortValue() & 0xFFFF;
1467                         return formatWithHexValue(constantValue, "0x" + Integer.toHexString(shortValue)); //$NON-NLS-1$
1468
1469                 } else if (constantValue instanceof Integer) {
1470                         int intValue= ((Integer) constantValue).intValue();
1471                         return formatWithHexValue(constantValue, "0x" + Integer.toHexString(intValue)); //$NON-NLS-1$
1472
1473                 } else if (constantValue instanceof Long) {
1474                         long longValue= ((Long) constantValue).longValue();
1475                         return formatWithHexValue(constantValue, "0x" + Long.toHexString(longValue)); //$NON-NLS-1$
1476
1477                 } else {
1478                         return constantValue.toString();
1479                 }
1480         }
1481
1482         /**
1483          * Creates and returns a formatted message for the given
1484          * constant with its hex value.
1485          * <p>
1486          * XXX: Copied from {@link JavadocHover}.
1487          * </p>
1488          *
1489          * @param constantValue the constant value
1490          * @param hexValue the hex value
1491          * @return a formatted string with constant and hex values
1492          * @since 3.4
1493          */
1494         private static String formatWithHexValue(Object constantValue, String hexValue) {
1495                 return Messages.format(InfoViewMessages.JavadocView_constantValue_hexValue, new String[] { constantValue.toString(), hexValue });
1496         }
1497
1498         /**
1499          * Returns the assignment operator string with the project's formatting applied to it.
1500          * <p>
1501          * XXX: This method was extracted from JavadocHover#getInfoText method.
1502          * </p>
1503          * @param javaProject the Java project whose formatting options will be used.
1504          * @return the formatted assignment operator string.
1505          * @since 3.4
1506          */
1507         private static String getFormattedAssignmentOperator(IJavaProject javaProject) {
1508                 StringBuffer buffer= new StringBuffer();
1509                 if (JavaCore.INSERT.equals(javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, true)))
1510                         buffer.append(' ');
1511                 buffer.append('=');
1512                 if (JavaCore.INSERT.equals(javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR, true)))
1513                         buffer.append(' ');
1514                 return buffer.toString();
1515         }
1516
1517         /**
1518          * see also org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.addLinkListener(BrowserInformationControl)
1519          *
1520          * Add link listener to the given browser
1521          * @param browser the browser to add a listener to
1522          * @since 3.4
1523          */
1524         private void addLinkListener(Browser browser) {
1525                 browser.addLocationListener(JavaElementLinks.createLocationListener(new JavaElementLinks.ILinkHandler() {
1526
1527                         /* (non-Javadoc)
1528                          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleDeclarationLink(org.eclipse.jdt.core.IJavaElement)
1529                          */
1530                         public void handleDeclarationLink(IJavaElement target) {
1531                                 try {
1532                                         JavaUI.openInEditor(target);
1533                                 } catch (PartInitException e) {
1534                                         JavaPlugin.log(e);
1535                                 } catch (JavaModelException e) {
1536                                         JavaPlugin.log(e);
1537                                 }
1538                         }
1539
1540                         /* (non-Javadoc)
1541                          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleExternalLink(java.net.URL, org.eclipse.swt.widgets.Display)
1542                          */
1543                         public boolean handleExternalLink(final URL url, Display display) {
1544                                 if (fCurrent == null || (fCurrent.getInputElement() instanceof URL && !url.toExternalForm().equals(((URL) fCurrent.getInputElement()).toExternalForm()))) {
1545                                         fCurrent= new URLBrowserInput(fCurrent, url);
1546
1547                                         if (fBackAction != null) {
1548                                                 fBackAction.update();
1549                                                 fForthAction.update();
1550                                         }
1551
1552                                         if (fInputSelectionProvider != null)
1553                                                 fInputSelectionProvider.setSelection(new StructuredSelection(url));
1554                                 }
1555
1556                                 return false;
1557                         }
1558
1559                         /* (non-Javadoc)
1560                          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleInlineJavadocLink(org.eclipse.jdt.core.IJavaElement)
1561                          */
1562                         public void handleInlineJavadocLink(IJavaElement target) {
1563                                 JavaElementBrowserInput newInput= new JavaElementBrowserInput(fCurrent, target);
1564                                 JavadocView.this.setInput(newInput);
1565                         }
1566
1567                         /* (non-Javadoc)
1568                          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleJavadocViewLink(org.eclipse.jdt.core.IJavaElement)
1569                          */
1570                         public void handleJavadocViewLink(IJavaElement target) {
1571                                 handleInlineJavadocLink(target);
1572                         }
1573
1574                         /* (non-Javadoc)
1575                          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleTextSet()
1576                          */
1577                         public void handleTextSet() {
1578                                 IJavaElement input= getInput();
1579                                 if (input == null)
1580                                         return;
1581
1582                                 if (fCurrent == null || !fCurrent.getInputElement().equals(input)) {
1583                                         fCurrent= new JavaElementBrowserInput(null, input);
1584
1585                                         if (fBackAction != null) {
1586                                                 fBackAction.update();
1587                                                 fForthAction.update();
1588                                         }
1589                                 }
1590                         }
1591                 }));
1592         }
1593
1594 }