Bug 500755: [Generic Editor] attach completion to all token contenttypes

As some extension can provide some specific document partitioner, we
need to attach completion dynamically to all supported token
content-types.

Change-Id: Ibfb55c7c254d78b6b6da61916af8b789bb50dfd5
Signed-off-by: Mickael Istria <mistria@redhat.com>
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextEditor.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextEditor.java
index 467be53..bcbf846 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextEditor.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextEditor.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.ui.internal.genericeditor;
 
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.editors.text.TextEditor;
 
 /**
@@ -21,17 +24,25 @@
 public class ExtensionBasedTextEditor extends TextEditor {
 
 	private static final String CONTEXT_ID = "org.eclipse.ui.genericeditor.genericEditorContext"; //$NON-NLS-1$
+	private ExtensionBasedTextViewerConfiguration configuration;
 
 	/**
 	 * 
 	 */
 	public ExtensionBasedTextEditor() {
-		setSourceViewerConfiguration(new ExtensionBasedTextViewerConfiguration(this, getPreferenceStore()));
+		configuration = new ExtensionBasedTextViewerConfiguration(this, getPreferenceStore());
+		setSourceViewerConfiguration(configuration);
 	}
-
+	
 	@Override
 	protected void setKeyBindingScopes(String[] scopes) {
 		super.setKeyBindingScopes(new String[] { CONTEXT_ID });
 	}
 
+	@Override
+	protected void doSetInput(IEditorInput input) throws CoreException {
+		super.doSetInput(input);
+		configuration.watchDocument(getDocumentProvider().getDocument(input));
+	}
+
 }
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java
index d5b84b5..6af35f9 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java
@@ -23,6 +23,7 @@
 import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
 import org.eclipse.jface.text.DefaultInformationControl;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioningListener;
 import org.eclipse.jface.text.IInformationControl;
 import org.eclipse.jface.text.ITextHover;
 import org.eclipse.jface.text.contentassist.ContentAssistant;
@@ -32,7 +33,9 @@
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPropertyListener;
 import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+import org.eclipse.ui.texteditor.ITextEditor;
 
 /**
  * The configuration of the {@link ExtensionBasedTextEditor}. It registers the proxy composite
@@ -41,19 +44,30 @@
  * 
  * @since 1.0
  */
-public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewerConfiguration {
+public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewerConfiguration implements IDocumentPartitioningListener {
 
-	private IEditorPart editor;
+	private ITextEditor editor;
 	private Set<IContentType> contentTypes;
+	private IDocument document;
+	private ContentAssistant contentAssistant;
+	private IContentAssistProcessor contentAssistProcessor;
 
 	/**
 	 * 
 	 * @param editor the editor we're creating.
 	 * @param preferenceStore the preference store.
 	 */
-	public ExtensionBasedTextViewerConfiguration(IEditorPart editor, IPreferenceStore preferenceStore) {
+	public ExtensionBasedTextViewerConfiguration(ITextEditor editor, IPreferenceStore preferenceStore) {
 		super(preferenceStore);
 		this.editor = editor;
+		this.editor.addPropertyListener(new IPropertyListener() {
+			@Override
+			public void propertyChanged(Object source, int propId) {
+				if (propId == IEditorPart.PROP_INPUT) {
+					watchDocument(editor.getDocumentProvider().getDocument(editor.getEditorInput()));
+				}
+			}
+		});
 	}
 
 	private Set<IContentType> getContentTypes() {
@@ -81,20 +95,23 @@
 	@Override
 	public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
 		ContentAssistProcessorRegistry registry= GenericEditorPlugin.getDefault().getContentAssistProcessorRegistry();
-		IContentAssistProcessor processor = new CompositeContentAssistProcessor(registry.getContentAssistProcessors(sourceViewer, getContentTypes()));
-		ContentAssistant res= new ContentAssistant();
-		res.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_BELOW);
-		res.setProposalPopupOrientation(ContentAssistant.PROPOSAL_REMOVE);
-		res.enableColoredLabels(true);
-		res.enableAutoActivation(true);
-		res.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
-		res.setInformationControlCreator(new AbstractReusableInformationControlCreator() {
+		contentAssistProcessor = new CompositeContentAssistProcessor(registry.getContentAssistProcessors(sourceViewer, getContentTypes()));
+		contentAssistant = new ContentAssistant();
+		contentAssistant.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_BELOW);
+		contentAssistant.setProposalPopupOrientation(ContentAssistant.PROPOSAL_REMOVE);
+		contentAssistant.enableColoredLabels(true);
+		contentAssistant.enableAutoActivation(true);
+		contentAssistant.setContentAssistProcessor(contentAssistProcessor, IDocument.DEFAULT_CONTENT_TYPE);
+		if (this.document != null) {
+			associateTokenContentTypes(this.document);
+		}
+		contentAssistant.setInformationControlCreator(new AbstractReusableInformationControlCreator() {
 			@Override
 			protected IInformationControl doCreateInformationControl(Shell parent) {
 				return new DefaultInformationControl(parent);
 			}
 		});
-		return res;
+		return contentAssistant;
 	}
 
 	@Override
@@ -107,4 +124,30 @@
 		return super.getPresentationReconciler(sourceViewer);
 	}
 
+	void watchDocument(IDocument document) {
+		if (this.document == document) {
+			return;
+		}
+		if (this.document != null) {
+			this.document.removeDocumentPartitioningListener(this);
+		}
+		this.document = document;
+		associateTokenContentTypes(document);
+		document.addDocumentPartitioningListener(this);
+	}
+
+	@Override
+	public void documentPartitioningChanged(IDocument document) {
+		associateTokenContentTypes(document);
+	}
+
+	private void associateTokenContentTypes(IDocument document) {
+		if (contentAssistant == null) {
+			return;
+		}
+		for (String legalTokenContentType : document.getLegalContentTypes()) {
+			contentAssistant.setContentAssistProcessor(this.contentAssistProcessor, legalTokenContentType);
+		}
+	}
+
 }