]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / ui / text / JavaSourceViewerConfiguration.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  *     Tom Eicher (Avaloq Evolution AG) - block selection mode
11  *******************************************************************************/
12 package org.eclipse.jdt.ui.text;
13
14 import java.util.Arrays;
15 import java.util.Map;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.widgets.Shell;
19
20 import org.eclipse.core.runtime.Assert;
21 import org.eclipse.core.runtime.IAdaptable;
22
23 import org.eclipse.jface.dialogs.IDialogSettings;
24 import org.eclipse.jface.preference.IPreferenceStore;
25 import org.eclipse.jface.util.PropertyChangeEvent;
26
27 import org.eclipse.jface.text.AbstractInformationControlManager;
28 import org.eclipse.jface.text.DefaultInformationControl;
29 import org.eclipse.jface.text.IAutoEditStrategy;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.jface.text.IInformationControl;
32 import org.eclipse.jface.text.IInformationControlCreator;
33 import org.eclipse.jface.text.ITextDoubleClickStrategy;
34 import org.eclipse.jface.text.ITextHover;
35 import org.eclipse.jface.text.ITextViewerExtension2;
36 import org.eclipse.jface.text.contentassist.ContentAssistant;
37 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
38 import org.eclipse.jface.text.contentassist.IContentAssistant;
39 import org.eclipse.jface.text.formatter.IContentFormatter;
40 import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
41 import org.eclipse.jface.text.information.IInformationPresenter;
42 import org.eclipse.jface.text.information.IInformationProvider;
43 import org.eclipse.jface.text.information.InformationPresenter;
44 import org.eclipse.jface.text.presentation.IPresentationReconciler;
45 import org.eclipse.jface.text.presentation.PresentationReconciler;
46 import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
47 import org.eclipse.jface.text.reconciler.IReconciler;
48 import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
49 import org.eclipse.jface.text.rules.RuleBasedScanner;
50 import org.eclipse.jface.text.source.Annotation;
51 import org.eclipse.jface.text.source.IAnnotationHover;
52 import org.eclipse.jface.text.source.ISourceViewer;
53
54 import org.eclipse.ui.IEditorInput;
55
56 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
57 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
58 import org.eclipse.ui.texteditor.IDocumentProvider;
59 import org.eclipse.ui.texteditor.ITextEditor;
60
61 import org.eclipse.ui.editors.text.EditorsUI;
62 import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
63
64 import org.eclipse.jdt.core.IJavaElement;
65 import org.eclipse.jdt.core.IJavaProject;
66 import org.eclipse.jdt.core.JavaCore;
67 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
68
69 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
70
71 import org.eclipse.jdt.ui.JavaUI;
72 import org.eclipse.jdt.ui.PreferenceConstants;
73 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
74
75 import org.eclipse.jdt.internal.ui.JavaPlugin;
76 import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
77 import org.eclipse.jdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider;
78 import org.eclipse.jdt.internal.ui.text.AbstractJavaScanner;
79 import org.eclipse.jdt.internal.ui.text.ContentAssistPreference;
80 import org.eclipse.jdt.internal.ui.text.HTMLAnnotationHover;
81 import org.eclipse.jdt.internal.ui.text.JavaCommentScanner;
82 import org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy;
83 import org.eclipse.jdt.internal.ui.text.JavaElementProvider;
84 import org.eclipse.jdt.internal.ui.text.JavaOutlineInformationControl;
85 import org.eclipse.jdt.internal.ui.text.JavaPresentationReconciler;
86 import org.eclipse.jdt.internal.ui.text.JavaReconciler;
87 import org.eclipse.jdt.internal.ui.text.PreferencesAdapter;
88 import org.eclipse.jdt.internal.ui.text.SingleTokenJavaScanner;
89 import org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionAssistant;
90 import org.eclipse.jdt.internal.ui.text.java.ContentAssistProcessor;
91 import org.eclipse.jdt.internal.ui.text.java.JavaAutoIndentStrategy;
92 import org.eclipse.jdt.internal.ui.text.java.JavaCodeScanner;
93 import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProcessor;
94 import org.eclipse.jdt.internal.ui.text.java.JavaDoubleClickSelector;
95 import org.eclipse.jdt.internal.ui.text.java.JavaFormattingStrategy;
96 import org.eclipse.jdt.internal.ui.text.java.JavaStringAutoIndentStrategy;
97 import org.eclipse.jdt.internal.ui.text.java.JavadocDoubleClickStrategy;
98 import org.eclipse.jdt.internal.ui.text.java.PartitionDoubleClickSelector;
99 import org.eclipse.jdt.internal.ui.text.java.SmartSemicolonAutoEditStrategy;
100 import org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
101 import org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy;
102 import org.eclipse.jdt.internal.ui.text.java.hover.JavaInformationProvider;
103 import org.eclipse.jdt.internal.ui.text.javadoc.JavaDocAutoIndentStrategy;
104 import org.eclipse.jdt.internal.ui.text.javadoc.JavaDocScanner;
105 import org.eclipse.jdt.internal.ui.text.javadoc.JavadocCompletionProcessor;
106 import org.eclipse.jdt.internal.ui.typehierarchy.HierarchyInformationControl;
107
108
109 /**
110  * Configuration for a source viewer which shows Java code.
111  * <p>
112  * This class may be instantiated; it is not intended to be subclassed.
113  * </p>
114  *
115  * @noextend This class is not intended to be subclassed by clients.
116  */
117 public class JavaSourceViewerConfiguration extends TextSourceViewerConfiguration {
118
119         /**
120          * Preference key used to look up display tab width.
121          *
122          * @since 2.0
123          * @deprecated As of 3.0, replaced by {@link AbstractDecoratedTextEditorPreferenceConstants#EDITOR_TAB_WIDTH}
124          */
125         public final static String PREFERENCE_TAB_WIDTH= PreferenceConstants.EDITOR_TAB_WIDTH;
126
127         /**
128          * Preference key for inserting spaces rather than tabs.
129          *
130          * @since 2.0
131          * @deprecated as of 3.1 use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_CHAR}
132          */
133         public final static String SPACES_FOR_TABS= PreferenceConstants.EDITOR_SPACES_FOR_TABS;
134
135
136         private JavaTextTools fJavaTextTools;
137         private ITextEditor fTextEditor;
138         /**
139          * The document partitioning.
140          * @since 3.0
141          */
142         private String fDocumentPartitioning;
143         /**
144          * The Java source code scanner.
145          * @since 3.0
146          */
147         private AbstractJavaScanner fCodeScanner;
148         /**
149          * The Java multi-line comment scanner.
150          * @since 3.0
151          */
152         private AbstractJavaScanner fMultilineCommentScanner;
153         /**
154          * The Java single-line comment scanner.
155          * @since 3.0
156          */
157         private AbstractJavaScanner fSinglelineCommentScanner;
158         /**
159          * The Java string scanner.
160          * @since 3.0
161          */
162         private AbstractJavaScanner fStringScanner;
163         /**
164          * The Javadoc scanner.
165          * @since 3.0
166          */
167         private AbstractJavaScanner fJavaDocScanner;
168         /**
169          * The color manager.
170          * @since 3.0
171          */
172         private IColorManager fColorManager;
173         /**
174          * The double click strategy.
175          * @since 3.1
176          */
177         private JavaDoubleClickSelector fJavaDoubleClickSelector;
178
179
180         /**
181          * Creates a new Java source viewer configuration for viewers in the given editor
182          * using the given preference store, the color manager and the specified document partitioning.
183          * <p>
184          * Creates a Java source viewer configuration in the new setup without text tools. Clients are
185          * allowed to call {@link JavaSourceViewerConfiguration#handlePropertyChangeEvent(PropertyChangeEvent)}
186          * and disallowed to call {@link JavaSourceViewerConfiguration#getPreferenceStore()} on the resulting
187          * Java source viewer configuration.
188          * </p>
189          *
190          * @param colorManager the color manager
191          * @param preferenceStore the preference store, can be read-only
192          * @param editor the editor in which the configured viewer(s) will reside, or <code>null</code> if none
193          * @param partitioning the document partitioning for this configuration, or <code>null</code> for the default partitioning
194          * @since 3.0
195          */
196         public JavaSourceViewerConfiguration(IColorManager colorManager, IPreferenceStore preferenceStore, ITextEditor editor, String partitioning) {
197                 super(preferenceStore);
198                 fColorManager= colorManager;
199                 fTextEditor= editor;
200                 fDocumentPartitioning= partitioning;
201                 initializeScanners();
202         }
203
204         /**
205          * Creates a new Java source viewer configuration for viewers in the given editor
206          * using the given Java tools.
207          *
208          * @param tools the Java text tools to be used
209          * @param editor the editor in which the configured viewer(s) will reside, or <code>null</code> if none
210          * @see JavaTextTools
211          * @deprecated As of 3.0, replaced by {@link JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager, IPreferenceStore, ITextEditor, String)}
212          */
213         public JavaSourceViewerConfiguration(JavaTextTools tools, ITextEditor editor) {
214                 super(createPreferenceStore(tools));
215                 fJavaTextTools= tools;
216                 fColorManager= tools.getColorManager();
217                 fCodeScanner= (AbstractJavaScanner) fJavaTextTools.getCodeScanner();
218                 fMultilineCommentScanner= (AbstractJavaScanner) fJavaTextTools.getMultilineCommentScanner();
219                 fSinglelineCommentScanner= (AbstractJavaScanner) fJavaTextTools.getSinglelineCommentScanner();
220                 fStringScanner= (AbstractJavaScanner) fJavaTextTools.getStringScanner();
221                 fJavaDocScanner= (AbstractJavaScanner) fJavaTextTools.getJavaDocScanner();
222                 fTextEditor= editor;
223         }
224
225         /**
226          * Returns the Java source code scanner for this configuration.
227          *
228          * @return the Java source code scanner
229          */
230         protected RuleBasedScanner getCodeScanner() {
231                 return fCodeScanner;
232         }
233
234         /**
235          * Returns the Java multi-line comment scanner for this configuration.
236          *
237          * @return the Java multi-line comment scanner
238          * @since 2.0
239          */
240         protected RuleBasedScanner getMultilineCommentScanner() {
241                 return fMultilineCommentScanner;
242         }
243
244         /**
245          * Returns the Java single-line comment scanner for this configuration.
246          *
247          * @return the Java single-line comment scanner
248          * @since 2.0
249          */
250         protected RuleBasedScanner getSinglelineCommentScanner() {
251                 return fSinglelineCommentScanner;
252         }
253
254         /**
255          * Returns the Java string scanner for this configuration.
256          *
257          * @return the Java string scanner
258          * @since 2.0
259          */
260         protected RuleBasedScanner getStringScanner() {
261                 return fStringScanner;
262         }
263
264         /**
265          * Returns the JavaDoc scanner for this configuration.
266          *
267          * @return the JavaDoc scanner
268          */
269         protected RuleBasedScanner getJavaDocScanner() {
270                 return fJavaDocScanner;
271         }
272
273         /**
274          * Returns the color manager for this configuration.
275          *
276          * @return the color manager
277          */
278         protected IColorManager getColorManager() {
279                 return fColorManager;
280         }
281
282         /**
283          * Returns the editor in which the configured viewer(s) will reside.
284          *
285          * @return the enclosing editor
286          */
287         protected ITextEditor getEditor() {
288                 return fTextEditor;
289         }
290
291         /**
292          * Returns the preference store used by this configuration to initialize
293          * the individual bits and pieces.
294          * <p>
295          * Clients are not allowed to call this method if the new setup without
296          * text tools is in use.</p>
297          *
298          * @return the preference store used to initialize this configuration
299          * @see JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager, IPreferenceStore, ITextEditor, String)
300          * @since 2.0
301          * @deprecated As of 3.0
302          */
303         protected IPreferenceStore getPreferenceStore() {
304                 Assert.isTrue(!isNewSetup());
305                 return fJavaTextTools.getPreferenceStore();
306         }
307
308         /**
309          * @return <code>true</code> iff the new setup without text tools is in use.
310          *
311          * @since 3.0
312          */
313         private boolean isNewSetup() {
314                 return fJavaTextTools == null;
315         }
316
317         /**
318          * Creates and returns a preference store which combines the preference
319          * stores from the text tools and which is read-only.
320          *
321          * @param javaTextTools the Java text tools
322          * @return the combined read-only preference store
323          * @since 3.0
324          */
325         private static final IPreferenceStore createPreferenceStore(JavaTextTools javaTextTools) {
326                 Assert.isNotNull(javaTextTools);
327                 IPreferenceStore generalTextStore= EditorsUI.getPreferenceStore();
328                 if (javaTextTools.getCorePreferenceStore() == null)
329                         return new ChainedPreferenceStore(new IPreferenceStore[] { javaTextTools.getPreferenceStore(), generalTextStore});
330
331                 return new ChainedPreferenceStore(new IPreferenceStore[] { javaTextTools.getPreferenceStore(), new PreferencesAdapter(javaTextTools.getCorePreferenceStore()), generalTextStore });
332         }
333
334         /**
335          * Initializes the scanners.
336          *
337          * @since 3.0
338          */
339         private void initializeScanners() {
340                 Assert.isTrue(isNewSetup());
341                 fCodeScanner= new JavaCodeScanner(getColorManager(), fPreferenceStore);
342                 fMultilineCommentScanner= new JavaCommentScanner(getColorManager(), fPreferenceStore, IJavaColorConstants.JAVA_MULTI_LINE_COMMENT);
343                 fSinglelineCommentScanner= new JavaCommentScanner(getColorManager(), fPreferenceStore, IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT);
344                 fStringScanner= new SingleTokenJavaScanner(getColorManager(), fPreferenceStore, IJavaColorConstants.JAVA_STRING);
345                 fJavaDocScanner= new JavaDocScanner(getColorManager(), fPreferenceStore);
346         }
347
348         /*
349          * @see SourceViewerConfiguration#getPresentationReconciler(ISourceViewer)
350          */
351         @Override
352         public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
353
354                 PresentationReconciler reconciler= new JavaPresentationReconciler();
355                 reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
356
357                 DefaultDamagerRepairer dr= new DefaultDamagerRepairer(getCodeScanner());
358                 reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
359                 reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
360
361                 dr= new DefaultDamagerRepairer(getJavaDocScanner());
362                 reconciler.setDamager(dr, IJavaPartitions.JAVA_DOC);
363                 reconciler.setRepairer(dr, IJavaPartitions.JAVA_DOC);
364
365                 dr= new DefaultDamagerRepairer(getMultilineCommentScanner());
366                 reconciler.setDamager(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
367                 reconciler.setRepairer(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
368
369                 dr= new DefaultDamagerRepairer(getSinglelineCommentScanner());
370                 reconciler.setDamager(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
371                 reconciler.setRepairer(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
372
373                 dr= new DefaultDamagerRepairer(getStringScanner());
374                 reconciler.setDamager(dr, IJavaPartitions.JAVA_STRING);
375                 reconciler.setRepairer(dr, IJavaPartitions.JAVA_STRING);
376
377                 dr= new DefaultDamagerRepairer(getStringScanner());
378                 reconciler.setDamager(dr, IJavaPartitions.JAVA_CHARACTER);
379                 reconciler.setRepairer(dr, IJavaPartitions.JAVA_CHARACTER);
380
381
382                 return reconciler;
383         }
384
385         /*
386          * @see SourceViewerConfiguration#getContentAssistant(ISourceViewer)
387          */
388         @Override
389         public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
390
391                 if (getEditor() != null) {
392
393                         ContentAssistant assistant= new ContentAssistant();
394                         assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
395
396                         assistant.setRestoreCompletionProposalSize(getSettings("completion_proposal_size")); //$NON-NLS-1$
397
398                         IContentAssistProcessor javaProcessor= new JavaCompletionProcessor(getEditor(), assistant, IDocument.DEFAULT_CONTENT_TYPE);
399                         assistant.setContentAssistProcessor(javaProcessor, IDocument.DEFAULT_CONTENT_TYPE);
400
401                         ContentAssistProcessor singleLineProcessor= new JavaCompletionProcessor(getEditor(), assistant, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
402                         assistant.setContentAssistProcessor(singleLineProcessor, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
403
404                         ContentAssistProcessor stringProcessor= new JavaCompletionProcessor(getEditor(), assistant, IJavaPartitions.JAVA_STRING);
405                         assistant.setContentAssistProcessor(stringProcessor, IJavaPartitions.JAVA_STRING);
406
407                         ContentAssistProcessor multiLineProcessor= new JavaCompletionProcessor(getEditor(), assistant, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
408                         assistant.setContentAssistProcessor(multiLineProcessor, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
409
410                         ContentAssistProcessor javadocProcessor= new JavadocCompletionProcessor(getEditor(), assistant);
411                         assistant.setContentAssistProcessor(javadocProcessor, IJavaPartitions.JAVA_DOC);
412
413                         ContentAssistPreference.configure(assistant, fPreferenceStore);
414
415                         assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
416                         assistant.setInformationControlCreator(new IInformationControlCreator() {
417                                 public IInformationControl createInformationControl(Shell parent) {
418                                         return new DefaultInformationControl(parent, JavaPlugin.getAdditionalInfoAffordanceString());
419                                 }
420                         });
421
422                         return assistant;
423                 }
424
425                 return null;
426         }
427
428         /*
429          * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getQuickAssistAssistant(org.eclipse.jface.text.source.ISourceViewer)
430          * @since 3.2
431          */
432         @Override
433         public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
434                 if (getEditor() != null) {
435                         JavaCorrectionAssistant assistant= new JavaCorrectionAssistant(getEditor());
436                         assistant.setRestoreCompletionProposalSize(getSettings("quick_assist_proposal_size")); //$NON-NLS-1$
437                         return assistant;
438                 }
439                 return null;
440         }
441
442         /*
443          * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
444          */
445         @Override
446         public IReconciler getReconciler(ISourceViewer sourceViewer) {
447
448                 final ITextEditor editor= getEditor();
449                 if (editor != null && editor.isEditable()) {
450
451                         JavaCompositeReconcilingStrategy strategy= new JavaCompositeReconcilingStrategy(sourceViewer, editor, getConfiguredDocumentPartitioning(sourceViewer));
452                         JavaReconciler reconciler= new JavaReconciler(editor, strategy, false);
453                         reconciler.setIsAllowedToModifyDocument(false);
454                         reconciler.setDelay(500);
455
456                         return reconciler;
457                 }
458                 return null;
459         }
460
461         /*
462          * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
463          */
464         @Override
465         public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
466                 String partitioning= getConfiguredDocumentPartitioning(sourceViewer);
467                 if (IJavaPartitions.JAVA_DOC.equals(contentType) || IJavaPartitions.JAVA_MULTI_LINE_COMMENT.equals(contentType))
468                         return new IAutoEditStrategy[] { new JavaDocAutoIndentStrategy(partitioning) };
469                 else if (IJavaPartitions.JAVA_STRING.equals(contentType))
470                         return new IAutoEditStrategy[] { new SmartSemicolonAutoEditStrategy(partitioning), new JavaStringAutoIndentStrategy(partitioning) };
471                 else if (IJavaPartitions.JAVA_CHARACTER.equals(contentType) || IDocument.DEFAULT_CONTENT_TYPE.equals(contentType))
472                         return new IAutoEditStrategy[] { new SmartSemicolonAutoEditStrategy(partitioning), new JavaAutoIndentStrategy(partitioning, getProject(), sourceViewer) };
473                 else
474                         return new IAutoEditStrategy[] { new JavaAutoIndentStrategy(partitioning, getProject(), sourceViewer) };
475         }
476
477         /*
478          * @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer, String)
479          */
480         @Override
481         public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
482                 if (IJavaPartitions.JAVA_DOC.equals(contentType))
483                         return new JavadocDoubleClickStrategy(getConfiguredDocumentPartitioning(sourceViewer));
484                 if (IJavaPartitions.JAVA_SINGLE_LINE_COMMENT.equals(contentType))
485                         return new PartitionDoubleClickSelector(getConfiguredDocumentPartitioning(sourceViewer), 0, 0);
486                 if (IJavaPartitions.JAVA_MULTI_LINE_COMMENT.equals(contentType))
487                         return new PartitionDoubleClickSelector(getConfiguredDocumentPartitioning(sourceViewer), 0, 0);
488                 else if (IJavaPartitions.JAVA_STRING.equals(contentType) || IJavaPartitions.JAVA_CHARACTER.equals(contentType))
489                         return new PartitionDoubleClickSelector(getConfiguredDocumentPartitioning(sourceViewer), 1, 1);
490                 if (fJavaDoubleClickSelector == null) {
491                         fJavaDoubleClickSelector= new JavaDoubleClickSelector();
492                         fJavaDoubleClickSelector.setSourceVersion(fPreferenceStore.getString(JavaCore.COMPILER_SOURCE));
493                 }
494                 return fJavaDoubleClickSelector;
495         }
496
497         /*
498          * @see SourceViewerConfiguration#getDefaultPrefixes(ISourceViewer, String)
499          * @since 2.0
500          */
501         @Override
502         public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) {
503                 return new String[] { "//", "" }; //$NON-NLS-1$ //$NON-NLS-2$
504         }
505
506         /*
507          * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
508          */
509         @Override
510         public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
511                 IJavaProject project= getProject();
512                 final int tabWidth= CodeFormatterUtil.getTabWidth(project);
513                 final int indentWidth= CodeFormatterUtil.getIndentWidth(project);
514                 boolean allowTabs= tabWidth <= indentWidth;
515
516                 String indentMode;
517                 if (project == null)
518                         indentMode= JavaCore.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
519                 else
520                         indentMode= project.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, true);
521
522                 boolean useSpaces= JavaCore.SPACE.equals(indentMode) || DefaultCodeFormatterConstants.MIXED.equals(indentMode);
523
524                 Assert.isLegal(allowTabs || useSpaces);
525
526                 if (!allowTabs) {
527                         char[] spaces= new char[indentWidth];
528                         Arrays.fill(spaces, ' ');
529                         return new String[] { new String(spaces), "" }; //$NON-NLS-1$
530                 } else if  (!useSpaces)
531                         return getIndentPrefixesForTab(tabWidth);
532                 else
533                         return getIndentPrefixesForSpaces(tabWidth);
534         }
535
536         /**
537          * Computes and returns the indent prefixes for space indentation
538          * and the given <code>tabWidth</code>.
539          *
540          * @param tabWidth the display tab width
541          * @return the indent prefixes
542          * @see #getIndentPrefixes(ISourceViewer, String)
543          * @since 3.3
544          */
545         private String[] getIndentPrefixesForSpaces(int tabWidth) {
546                 String[] indentPrefixes= new String[tabWidth + 2];
547                 indentPrefixes[0]= getStringWithSpaces(tabWidth);
548
549                 for (int i= 0; i < tabWidth; i++) {
550                         String spaces= getStringWithSpaces(i);
551                         if (i < tabWidth)
552                                 indentPrefixes[i+1]= spaces + '\t';
553                         else
554                                 indentPrefixes[i+1]= new String(spaces);
555                 }
556
557                 indentPrefixes[tabWidth + 1]= ""; //$NON-NLS-1$
558
559                 return indentPrefixes;
560         }
561
562         /**
563          * Creates and returns a String with <code>count</code> spaces.
564          *
565          * @param count the space count
566          * @return the string with the spaces
567          * @since 3.3
568          */
569         private String getStringWithSpaces(int count) {
570                 char[] spaceChars= new char[count];
571                 Arrays.fill(spaceChars, ' ');
572                 return new String(spaceChars);
573         }
574
575         private IJavaProject getProject() {
576                 ITextEditor editor= getEditor();
577                 if (editor == null)
578                         return null;
579
580                 IJavaElement element= null;
581                 IEditorInput input= editor.getEditorInput();
582                 IDocumentProvider provider= editor.getDocumentProvider();
583                 if (provider instanceof ICompilationUnitDocumentProvider) {
584                         ICompilationUnitDocumentProvider cudp= (ICompilationUnitDocumentProvider) provider;
585                         element= cudp.getWorkingCopy(input);
586                 } else if (input instanceof IClassFileEditorInput) {
587                         IClassFileEditorInput cfei= (IClassFileEditorInput) input;
588                         element= cfei.getClassFile();
589                 }
590
591                 if (element == null)
592                         return null;
593
594                 return element.getJavaProject();
595         }
596
597         /*
598          * @see SourceViewerConfiguration#getTabWidth(ISourceViewer)
599          */
600         @Override
601         public int getTabWidth(ISourceViewer sourceViewer) {
602                 return CodeFormatterUtil.getTabWidth(getProject());
603         }
604
605         /*
606          * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
607          */
608         @Override
609         public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
610                 return new HTMLAnnotationHover(false) {
611                         @Override
612                         protected boolean isIncluded(Annotation annotation) {
613                                 return isShowInVerticalRuler(annotation);
614                         }
615                 };
616         }
617
618         /*
619          * @see SourceViewerConfiguration#getOverviewRulerAnnotationHover(ISourceViewer)
620          * @since 3.0
621          */
622         @Override
623         public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
624                 return new HTMLAnnotationHover(true) {
625                         @Override
626                         protected boolean isIncluded(Annotation annotation) {
627                                 return isShowInOverviewRuler(annotation);
628                         }
629                 };
630         }
631
632         /*
633          * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String)
634          * @since 2.1
635          */
636         @Override
637         public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) {
638                 JavaEditorTextHoverDescriptor[] hoverDescs= JavaPlugin.getDefault().getJavaEditorTextHoverDescriptors();
639                 int stateMasks[]= new int[hoverDescs.length];
640                 int stateMasksLength= 0;
641                 for (int i= 0; i < hoverDescs.length; i++) {
642                         if (hoverDescs[i].isEnabled()) {
643                                 int j= 0;
644                                 int stateMask= hoverDescs[i].getStateMask();
645                                 while (j < stateMasksLength) {
646                                         if (stateMasks[j] == stateMask)
647                                                 break;
648                                         j++;
649                                 }
650                                 if (j == stateMasksLength)
651                                         stateMasks[stateMasksLength++]= stateMask;
652                         }
653                 }
654                 if (stateMasksLength == hoverDescs.length)
655                         return stateMasks;
656
657                 int[] shortenedStateMasks= new int[stateMasksLength];
658                 System.arraycopy(stateMasks, 0, shortenedStateMasks, 0, stateMasksLength);
659                 return shortenedStateMasks;
660         }
661
662         /*
663          * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int)
664          * @since 2.1
665          */
666         @Override
667         public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
668                 JavaEditorTextHoverDescriptor[] hoverDescs= JavaPlugin.getDefault().getJavaEditorTextHoverDescriptors();
669                 int i= 0;
670                 while (i < hoverDescs.length) {
671                         if (hoverDescs[i].isEnabled() &&  hoverDescs[i].getStateMask() == stateMask)
672                                 return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor());
673                         i++;
674                 }
675
676                 return null;
677         }
678
679         /*
680          * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
681          */
682         @Override
683         public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
684                 return getTextHover(sourceViewer, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
685         }
686
687         /*
688          * @see SourceViewerConfiguration#getConfiguredContentTypes(ISourceViewer)
689          */
690         @Override
691         public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
692                 return new String[] {
693                         IDocument.DEFAULT_CONTENT_TYPE,
694                         IJavaPartitions.JAVA_DOC,
695                         IJavaPartitions.JAVA_MULTI_LINE_COMMENT,
696                         IJavaPartitions.JAVA_SINGLE_LINE_COMMENT,
697                         IJavaPartitions.JAVA_STRING,
698                         IJavaPartitions.JAVA_CHARACTER
699                 };
700         }
701
702         /*
703          * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer)
704          * @since 3.0
705          */
706         @Override
707         public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
708                 if (fDocumentPartitioning != null)
709                         return fDocumentPartitioning;
710                 return super.getConfiguredDocumentPartitioning(sourceViewer);
711         }
712
713         /*
714          * @see SourceViewerConfiguration#getContentFormatter(ISourceViewer)
715          */
716         @Override
717         public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
718                 final MultiPassContentFormatter formatter= new MultiPassContentFormatter(getConfiguredDocumentPartitioning(sourceViewer), IDocument.DEFAULT_CONTENT_TYPE);
719                 formatter.setMasterStrategy(new JavaFormattingStrategy());
720                 return formatter;
721         }
722
723         /*
724          * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer)
725          * @since 2.0
726          */
727         @Override
728         public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
729                 return new IInformationControlCreator() {
730                         public IInformationControl createInformationControl(Shell parent) {
731                                 return new DefaultInformationControl(parent, false);
732                         }
733                 };
734         }
735
736         /**
737          * Returns the information presenter control creator. The creator is a factory creating the
738          * presenter controls for the given source viewer. This implementation always returns a creator
739          * for <code>DefaultInformationControl</code> instances.
740          *
741          * @param sourceViewer the source viewer to be configured by this configuration
742          * @return an information control creator
743          * @since 2.1
744          */
745         private IInformationControlCreator getInformationPresenterControlCreator(ISourceViewer sourceViewer) {
746                 return new IInformationControlCreator() {
747                         public IInformationControl createInformationControl(Shell parent) {
748                                 return new DefaultInformationControl(parent, true);
749                         }
750                 };
751         }
752
753         /**
754          * Returns the outline presenter control creator. The creator is a factory creating outline
755          * presenter controls for the given source viewer. This implementation always returns a creator
756          * for <code>JavaOutlineInformationControl</code> instances.
757          *
758          * @param sourceViewer the source viewer to be configured by this configuration
759          * @param commandId the ID of the command that opens this control
760          * @return an information control creator
761          * @since 2.1
762          */
763         private IInformationControlCreator getOutlinePresenterControlCreator(ISourceViewer sourceViewer, final String commandId) {
764                 return new IInformationControlCreator() {
765                         public IInformationControl createInformationControl(Shell parent) {
766                                 int shellStyle= SWT.RESIZE;
767                                 int treeStyle= SWT.V_SCROLL | SWT.H_SCROLL;
768                                 return new JavaOutlineInformationControl(parent, shellStyle, treeStyle, commandId);
769                         }
770                 };
771         }
772
773         private IInformationControlCreator getHierarchyPresenterControlCreator() {
774                 return new IInformationControlCreator() {
775                         public IInformationControl createInformationControl(Shell parent) {
776                                 int shellStyle= SWT.RESIZE;
777                                 int treeStyle= SWT.V_SCROLL | SWT.H_SCROLL;
778                                 return new HierarchyInformationControl(parent, shellStyle, treeStyle);
779                         }
780                 };
781         }
782
783         /*
784          * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
785          * @since 2.0
786          */
787         @Override
788         public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
789                 InformationPresenter presenter= new InformationPresenter(getInformationPresenterControlCreator(sourceViewer));
790                 presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
791
792                 // Register information provider
793                 IInformationProvider provider= new JavaInformationProvider(getEditor());
794                 String[] contentTypes= getConfiguredContentTypes(sourceViewer);
795                 for (int i= 0; i < contentTypes.length; i++)
796                         presenter.setInformationProvider(provider, contentTypes[i]);
797
798                 // sizes: see org.eclipse.jface.text.TextViewer.TEXT_HOVER_*_CHARS
799                 presenter.setSizeConstraints(100, 12, false, true);
800                 return presenter;
801         }
802
803         /**
804          * Returns the outline presenter which will determine and shown
805          * information requested for the current cursor position.
806          *
807          * @param sourceViewer the source viewer to be configured by this configuration
808          * @param doCodeResolve a boolean which specifies whether code resolve should be used to compute the Java element
809          * @return an information presenter
810          * @since 2.1
811          */
812         public IInformationPresenter getOutlinePresenter(ISourceViewer sourceViewer, boolean doCodeResolve) {
813                 InformationPresenter presenter;
814                 if (doCodeResolve)
815                         presenter= new InformationPresenter(getOutlinePresenterControlCreator(sourceViewer, IJavaEditorActionDefinitionIds.OPEN_STRUCTURE));
816                 else
817                         presenter= new InformationPresenter(getOutlinePresenterControlCreator(sourceViewer, IJavaEditorActionDefinitionIds.SHOW_OUTLINE));
818                 presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
819                 presenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL);
820                 IInformationProvider provider= new JavaElementProvider(getEditor(), doCodeResolve);
821                 presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
822                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
823                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
824                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
825                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_STRING);
826                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_CHARACTER);
827                 presenter.setSizeConstraints(50, 20, true, false);
828                 return presenter;
829         }
830
831         /**
832          * Returns the settings for the given section.
833          *
834          * @param sectionName the section name
835          * @return the settings
836          * @since 3.0
837          */
838         private IDialogSettings getSettings(String sectionName) {
839                 IDialogSettings settings= JavaPlugin.getDefault().getDialogSettings().getSection(sectionName);
840                 if (settings == null)
841                         settings= JavaPlugin.getDefault().getDialogSettings().addNewSection(sectionName);
842
843                 return settings;
844         }
845
846         /**
847          * Returns the hierarchy presenter which will determine and shown type hierarchy
848          * information requested for the current cursor position.
849          *
850          * @param sourceViewer the source viewer to be configured by this configuration
851          * @param doCodeResolve a boolean which specifies whether code resolve should be used to compute the Java element
852          * @return an information presenter
853          * @since 3.0
854          */
855         public IInformationPresenter getHierarchyPresenter(ISourceViewer sourceViewer, boolean doCodeResolve) {
856
857                 // Do not create hierarchy presenter if there's no CU.
858                 if (getEditor() != null && getEditor().getEditorInput() != null && JavaUI.getEditorInputJavaElement(getEditor().getEditorInput()) == null)
859                         return null;
860
861                 InformationPresenter presenter= new InformationPresenter(getHierarchyPresenterControlCreator());
862                 presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
863                 presenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL);
864                 IInformationProvider provider= new JavaElementProvider(getEditor(), doCodeResolve);
865                 presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
866                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
867                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
868                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
869                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_STRING);
870                 presenter.setInformationProvider(provider, IJavaPartitions.JAVA_CHARACTER);
871                 presenter.setSizeConstraints(50, 20, true, false);
872                 return presenter;
873         }
874
875         /**
876          * Determines whether the preference change encoded by the given event
877          * changes the behavior of one of its contained components.
878          *
879          * @param event the event to be investigated
880          * @return <code>true</code> if event causes a behavioral change
881          * @since 3.0
882          */
883         public boolean affectsTextPresentation(PropertyChangeEvent event) {
884                 return  fCodeScanner.affectsBehavior(event)
885                         || fMultilineCommentScanner.affectsBehavior(event)
886                         || fSinglelineCommentScanner.affectsBehavior(event)
887                         || fStringScanner.affectsBehavior(event)
888                         || fJavaDocScanner.affectsBehavior(event);
889         }
890
891         /**
892          * Adapts the behavior of the contained components to the change
893          * encoded in the given event.
894          * <p>
895          * Clients are not allowed to call this method if the old setup with
896          * text tools is in use.
897          * </p>
898          *
899          * @param event the event to which to adapt
900          * @see JavaSourceViewerConfiguration#JavaSourceViewerConfiguration(IColorManager, IPreferenceStore, ITextEditor, String)
901          * @since 3.0
902          */
903         public void handlePropertyChangeEvent(PropertyChangeEvent event) {
904                 Assert.isTrue(isNewSetup());
905                 if (fCodeScanner.affectsBehavior(event))
906                         fCodeScanner.adaptToPreferenceChange(event);
907                 if (fMultilineCommentScanner.affectsBehavior(event))
908                         fMultilineCommentScanner.adaptToPreferenceChange(event);
909                 if (fSinglelineCommentScanner.affectsBehavior(event))
910                         fSinglelineCommentScanner.adaptToPreferenceChange(event);
911                 if (fStringScanner.affectsBehavior(event))
912                         fStringScanner.adaptToPreferenceChange(event);
913                 if (fJavaDocScanner.affectsBehavior(event))
914                         fJavaDocScanner.adaptToPreferenceChange(event);
915                 if (fJavaDoubleClickSelector != null && JavaCore.COMPILER_SOURCE.equals(event.getProperty()))
916                         if (event.getNewValue() instanceof String)
917                                 fJavaDoubleClickSelector.setSourceVersion((String) event.getNewValue());
918         }
919
920         /*
921          * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkDetectorTargets(org.eclipse.jface.text.source.ISourceViewer)
922          * @since 3.3
923          */
924         @Override
925         protected Map<String, IAdaptable> getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
926                 Map<String, IAdaptable> targets= super.getHyperlinkDetectorTargets(sourceViewer);
927                 targets.put("org.eclipse.jdt.ui.javaCode", fTextEditor); //$NON-NLS-1$
928                 return targets;
929         }
930
931 }