Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2017-08-08 14:33:41 +0000
committerMickael Istria2017-08-08 23:00:38 +0000
commit1ba9040176a1bdaf3c47df85728ae4ab5b0d2a93 (patch)
treef15d6c6e94d1f07e3c163a9e8c94321f6ad75ce8
parent896e9624a30afb9e3f75daa648707b808d26ae0b (diff)
downloadeclipse.platform.text-1ba9040176a1bdaf3c47df85728ae4ab5b0d2a93.tar.gz
eclipse.platform.text-1ba9040176a1bdaf3c47df85728ae4ab5b0d2a93.tar.xz
eclipse.platform.text-1ba9040176a1bdaf3c47df85728ae4ab5b0d2a93.zip
Bug 520685 - [Generic Editor] Sort ext. by most specialized content-typeI20170809-2000
Factorize extensions and registry polling (can be continued). This allows most registries to return first the extension that applies to the most specialized content-types. Change-Id: Icfd5d0c2e72cd579e9fe8c034420d88c628f39a6 Signed-off-by: Mickael Istria <mistria@redhat.com>
-rw-r--r--org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/NaturesAndProjectsContentAssistProcessor.java5
-rw-r--r--org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/TagAutoEditStrategy.java4
-rw-r--r--org.eclipse.ui.genericeditor.tests/plugin.xml29
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AutoEditTest.java3
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategySecond.java2
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategyThird.java2
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerBlue.java38
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerGreen.java42
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerRed.java (renamed from org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconciler.java)4
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/AutoEditStrategyRegistry.java49
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentAssistProcessorRegistry.java51
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeSpecializationComparator.java39
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericContentTypeRelatedExtension.java47
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/PresentationReconcilerRegistry.java45
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java46
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java35
16 files changed, 243 insertions, 198 deletions
diff --git a/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/NaturesAndProjectsContentAssistProcessor.java b/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/NaturesAndProjectsContentAssistProcessor.java
index 1f8fd98bb90..c78d9cc5158 100644
--- a/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/NaturesAndProjectsContentAssistProcessor.java
+++ b/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/NaturesAndProjectsContentAssistProcessor.java
@@ -14,7 +14,6 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNatureDescriptor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
-
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
@@ -24,6 +23,10 @@ import org.eclipse.jface.text.contentassist.IContextInformationValidator;
public class NaturesAndProjectsContentAssistProcessor implements IContentAssistProcessor {
+ public NaturesAndProjectsContentAssistProcessor() {
+ // TODO Auto-generated constructor stub
+ }
+
@Override
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
String text = viewer.getDocument().get();
diff --git a/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/TagAutoEditStrategy.java b/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/TagAutoEditStrategy.java
index c997bae69d6..a8c689e9ed8 100644
--- a/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/TagAutoEditStrategy.java
+++ b/org.eclipse.ui.genericeditor.examples/src/org/eclipse/ui/genericeditor/examples/dotproject/TagAutoEditStrategy.java
@@ -18,6 +18,10 @@ import org.eclipse.jface.text.IRegion;
public class TagAutoEditStrategy implements IAutoEditStrategy {
+ public TagAutoEditStrategy() {
+ // TODO Auto-generated constructor stub
+ }
+
@Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
if (!">".equals(command.text)) { //$NON-NLS-1$
diff --git a/org.eclipse.ui.genericeditor.tests/plugin.xml b/org.eclipse.ui.genericeditor.tests/plugin.xml
index a6b4124536f..4d02c03dfc1 100644
--- a/org.eclipse.ui.genericeditor.tests/plugin.xml
+++ b/org.eclipse.ui.genericeditor.tests/plugin.xml
@@ -36,14 +36,22 @@
class="org.eclipse.ui.genericeditor.tests.contributions.TheReconciler"
contentType="org.eclipse.ui.genericeditor.tests.content-type">
</reconciler>
- </extension>
- <extension
+ </extension>
+ <extension
point="org.eclipse.ui.genericeditor.presentationReconcilers">
<presentationReconciler
- class="org.eclipse.ui.genericeditor.tests.contributions.ThePresentationReconciler"
- contentType="org.eclipse.ui.genericeditor.tests.content-type">
+ class="org.eclipse.ui.genericeditor.tests.contributions.ThePresentationReconcilerBlue"
+ contentType="org.eclipse.core.runtime.text">
+ </presentationReconciler>
+ <presentationReconciler
+ class="org.eclipse.ui.genericeditor.tests.contributions.ThePresentationReconcilerRed"
+ contentType="org.eclipse.ui.genericeditor.tests.specialized-content-type">
+ </presentationReconciler>
+ <presentationReconciler
+ class="org.eclipse.ui.genericeditor.tests.contributions.ThePresentationReconcilerGreen"
+ contentType="org.eclipse.ui.genericeditor.tests.content-type">
</presentationReconciler>
- </extension>
+ </extension>
<extension
point="org.eclipse.ui.ide.markerResolution">
<markerResolutionGenerator
@@ -60,6 +68,13 @@
name="Generic Editor Test content-type"
priority="normal">
</content-type>
+ <content-type
+ base-type="org.eclipse.ui.genericeditor.tests.content-type"
+ file-names="foo.txt"
+ id="org.eclipse.ui.genericeditor.tests.specialized-content-type"
+ name="Specialized Generic Editor content-type"
+ priority="normal">
+ </content-type>
</extension>
<extension
point="org.eclipse.ui.genericeditor.autoEditStrategies">
@@ -69,11 +84,11 @@
</autoEditStrategy>
<autoEditStrategy
class="org.eclipse.ui.genericeditor.tests.contributions.TheAutoEditStrategySecond"
- contentType="org.eclipse.core.runtime.text">
+ contentType="org.eclipse.ui.genericeditor.tests.content-type">
</autoEditStrategy>
<autoEditStrategy
class="org.eclipse.ui.genericeditor.tests.contributions.TheAutoEditStrategyThird"
- contentType="org.eclipse.core.runtime.text">
+ contentType="org.eclipse.ui.genericeditor.tests.specialized-content-type">
</autoEditStrategy>
</extension>
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AutoEditTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AutoEditTest.java
index 8a30f57a70d..1aa3a3e5146 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AutoEditTest.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/AutoEditTest.java
@@ -25,7 +25,8 @@ public class AutoEditTest extends AbstratGenericEditorTest {
IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput());
StyledText control= (StyledText) editor.getAdapter(Control.class);
control.setText("");
- Assert.assertEquals("AutoAddedFirst! AutoAddedSecond! AutoAddedThird!", document.get());
+ // order of auto-edits from most specialized to least specialized
+ Assert.assertEquals("AutoAddedThird!AutoAddedSecond!AutoAddedFirst!", document.get());
}
}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategySecond.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategySecond.java
index 37e2587d8ed..92c0ec64b10 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategySecond.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategySecond.java
@@ -18,7 +18,7 @@ public class TheAutoEditStrategySecond implements IAutoEditStrategy {
@Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
- command.text = command.text + " AutoAddedSecond!";
+ command.text = command.text + "AutoAddedSecond!";
}
}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategyThird.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategyThird.java
index c7882aaf446..5c4ef8c8d3e 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategyThird.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/TheAutoEditStrategyThird.java
@@ -18,7 +18,7 @@ public class TheAutoEditStrategyThird implements IAutoEditStrategy {
@Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
- command.text = command.text + " AutoAddedThird!";
+ command.text = command.text + "AutoAddedThird!";
}
}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerBlue.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerBlue.java
new file mode 100644
index 00000000000..44ce5c58b31
--- /dev/null
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerBlue.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Red Hat Inc. and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sopot Cela (Red Hat Inc.)
+ *******************************************************************************/
+package org.eclipse.ui.genericeditor.tests.contributions;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+
+public class ThePresentationReconcilerBlue extends PresentationReconciler {
+
+ public ThePresentationReconcilerBlue() {
+ RuleBasedScanner scanner= new RuleBasedScanner();
+ IRule[] rules = new IRule[1];
+ rules[0]= new SingleLineRule("'", "'", new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 0, 255))))); //$NON-NLS-1$ //$NON-NLS-2$
+ scanner.setRules(rules);
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(scanner);
+ this.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ this.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerGreen.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerGreen.java
new file mode 100644
index 00000000000..2c6d8c41b54
--- /dev/null
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerGreen.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2016-2017 Red Hat Inc. and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Sopot Cela (Red Hat Inc.)
+ *******************************************************************************/
+package org.eclipse.ui.genericeditor.tests.contributions;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * This presentation reconciler is associated to a more "basic" content-type so it
+ * shouldn't be used.
+ */
+public class ThePresentationReconcilerGreen extends PresentationReconciler {
+
+ public ThePresentationReconcilerGreen() {
+ RuleBasedScanner scanner= new RuleBasedScanner();
+ IRule[] rules = new IRule[1];
+ rules[0]= new SingleLineRule("'", "'", new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 255, 0))))); //$NON-NLS-1$ //$NON-NLS-2$
+ scanner.setRules(rules);
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(scanner);
+ this.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ this.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconciler.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerRed.java
index c2ee68a7417..abfd5cb0e1a 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconciler.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/ThePresentationReconcilerRed.java
@@ -23,9 +23,9 @@ import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
-public class ThePresentationReconciler extends PresentationReconciler {
+public class ThePresentationReconcilerRed extends PresentationReconciler {
- public ThePresentationReconciler() {
+ public ThePresentationReconcilerRed() {
RuleBasedScanner scanner= new RuleBasedScanner();
IRule[] rules = new IRule[1];
rules[0]= new SingleLineRule("'", "'", new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(255, 0, 0))))); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/AutoEditStrategyRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/AutoEditStrategyRegistry.java
index 349f455d7ba..425415a953b 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/AutoEditStrategyRegistry.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/AutoEditStrategyRegistry.java
@@ -10,14 +10,13 @@
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
@@ -39,36 +38,9 @@ public class AutoEditStrategyRegistry {
private static final String EXTENSION_POINT_ID = GenericEditorPlugin.BUNDLE_ID + ".autoEditStrategies"; //$NON-NLS-1$
- private Map<IConfigurationElement, AutoEditStrategyExtension> extensions = new LinkedHashMap<>();
+ private Map<IConfigurationElement, GenericContentTypeRelatedExtension<IAutoEditStrategy>> extensions = new LinkedHashMap<>();
private boolean outOfSync = true;
- static class AutoEditStrategyExtension {
- private static final String CONTENT_TYPE_ATTRIBUTE = "contentType"; //$NON-NLS-1$
- private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
-
- private IConfigurationElement extension;
- private IContentType targetContentType;
-
- public AutoEditStrategyExtension(IConfigurationElement extension) throws Exception {
- this.extension = extension;
- this.targetContentType = Platform.getContentTypeManager()
- .getContentType(extension.getAttribute(CONTENT_TYPE_ATTRIBUTE));
- }
-
- public IAutoEditStrategy createStrategy() {
- try {
- return (IAutoEditStrategy) extension.createExecutableExtension(CLASS_ATTRIBUTE);
- } catch (CoreException e) {
- GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, e.getMessage(), e));
- return null;
- }
- }
-
- IConfigurationElement getConfigurationElement() {
- return this.extension;
- }
- }
-
/**
* Creates the registry and binds it to the extension point.
*/
@@ -96,16 +68,11 @@ public class AutoEditStrategyRegistry {
if (this.outOfSync) {
sync();
}
- List<IAutoEditStrategy> res = new ArrayList<>();
- for (AutoEditStrategyExtension ext : this.extensions.values()) {
- if (contentTypes.contains(ext.targetContentType)) {
- IAutoEditStrategy strategy = ext.createStrategy();
- if (strategy != null) {
- res.add(strategy);
- }
- }
- }
- return res;
+ return this.extensions.values().stream()
+ .filter(ext -> contentTypes.contains(ext.targetContentType))
+ .sorted(new ContentTypeSpecializationComparator<IAutoEditStrategy>())
+ .map(GenericContentTypeRelatedExtension<IAutoEditStrategy>::createDelegate)
+ .collect(Collectors.toList());
}
private void sync() {
@@ -115,7 +82,7 @@ public class AutoEditStrategyRegistry {
toRemoveExtensions.remove(extension);
if (!this.extensions.containsKey(extension)) {
try {
- this.extensions.put(extension, new AutoEditStrategyExtension(extension));
+ this.extensions.put(extension, new GenericContentTypeRelatedExtension<IAutoEditStrategy>(extension));
} catch (Exception ex) {
GenericEditorPlugin.getDefault().getLog()
.log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, ex.getMessage(), ex));
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentAssistProcessorRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentAssistProcessorRegistry.java
index 0da557bfef7..187de272595 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentAssistProcessorRegistry.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentAssistProcessorRegistry.java
@@ -10,15 +10,14 @@
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.eclipse.core.filebuffers.FileBuffers;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IRegistryChangeEvent;
@@ -127,39 +126,7 @@ public class ContentAssistProcessorRegistry {
}
}
- /**
- * This class wraps and proxies an {@link IContentAssistProcessor} provided through extensions
- * and loads it lazily when it can contribute to the editor, then delegates all operations to
- * actual processor.
- * When the contribution cannot contribute to the editor, this wrapper will return neutral values
- * that don't affect editor behavior.
- */
- private static class ContentAssistProcessorExtension {
- private static final String CONTENT_TYPE_ATTRIBUTE = "contentType"; //$NON-NLS-1$
- private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
-
- private IConfigurationElement extension;
- private IContentType targetContentType;
-
- private ContentAssistProcessorExtension(IConfigurationElement element) throws Exception {
- this.extension = element;
- this.targetContentType = Platform.getContentTypeManager().getContentType(element.getAttribute(CONTENT_TYPE_ATTRIBUTE));
- }
-
- public ContentAssistProcessorDelegate createDelegate() {
- try {
- IContentAssistProcessor delegate = (IContentAssistProcessor) extension.createExecutableExtension(CLASS_ATTRIBUTE);
- if (delegate != null) {
- return new ContentAssistProcessorDelegate(delegate, targetContentType);
- }
- } catch (CoreException e) {
- GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, e.getMessage(), e));
- }
- return null;
- }
- }
-
- private Map<IConfigurationElement, ContentAssistProcessorExtension> extensions = new HashMap<>();
+ private Map<IConfigurationElement, GenericContentTypeRelatedExtension<IContentAssistProcessor>> extensions = new HashMap<>();
private boolean outOfSync = true;
/**
@@ -185,13 +152,11 @@ public class ContentAssistProcessorRegistry {
if (this.outOfSync) {
sync();
}
- List<IContentAssistProcessor> res = new ArrayList<>();
- for (ContentAssistProcessorExtension ext : this.extensions.values()) {
- if (contentTypes.contains(ext.targetContentType)) {
- res.add(ext.createDelegate());
- }
- }
- return res;
+ return this.extensions.values().stream()
+ .filter(ext -> contentTypes.contains(ext.targetContentType))
+ .sorted(new ContentTypeSpecializationComparator<IContentAssistProcessor>())
+ .map(GenericContentTypeRelatedExtension<IContentAssistProcessor>::createDelegate)
+ .collect(Collectors.toList());
}
private void sync() {
@@ -200,7 +165,7 @@ public class ContentAssistProcessorRegistry {
toRemoveExtensions.remove(extension);
if (!this.extensions.containsKey(extension)) {
try {
- this.extensions.put(extension, new ContentAssistProcessorExtension(extension));
+ this.extensions.put(extension, new GenericContentTypeRelatedExtension<IContentAssistProcessor>(extension));
} catch (Exception ex) {
GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, ex.getMessage(), ex));
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeSpecializationComparator.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeSpecializationComparator.java
new file mode 100644
index 00000000000..2a2d329434c
--- /dev/null
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeSpecializationComparator.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Red Hat Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * - Mickael Istria (Red Hat Inc.)
+ *******************************************************************************/
+package org.eclipse.ui.internal.genericeditor;
+
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.content.IContentType;
+
+/**
+ * Compares extension so that the ones with the most "specialized" content-types are returned first.
+ *
+ * @param <T>
+ */
+public class ContentTypeSpecializationComparator<T> implements Comparator<GenericContentTypeRelatedExtension<T>> {
+
+ @Override
+ public int compare(GenericContentTypeRelatedExtension<T> o1, GenericContentTypeRelatedExtension<T> o2) {
+ return depth(o2.targetContentType) - depth(o1.targetContentType);
+ }
+
+ private static int depth(IContentType targetContentType) {
+ int res = 0;
+ IContentType current = targetContentType;
+ while (current != null) {
+ res++;
+ current = current.getBaseType();
+ }
+ return res;
+ }
+
+}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericContentTypeRelatedExtension.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericContentTypeRelatedExtension.java
new file mode 100644
index 00000000000..da7dc2be16c
--- /dev/null
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericContentTypeRelatedExtension.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Red Hat Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * - Mickael Istria (Red Hat Inc.)
+ *******************************************************************************/
+package org.eclipse.ui.internal.genericeditor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.content.IContentType;
+
+/**
+ * This class wraps and proxies an instance of T provided through extensions
+ * and loads it lazily when it can contribute to the editor, then delegates all operations to
+ * actual instance.
+ *
+ * @param <T> the actual type to proxy, typically the one defined on the extension point.
+ */
+public class GenericContentTypeRelatedExtension<T> {
+ private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
+ private static final String CONTENT_TYPE_ATTRIBUTE = "contentType"; //$NON-NLS-1$
+
+ public final IConfigurationElement extension;
+ public final IContentType targetContentType;
+
+ public GenericContentTypeRelatedExtension(IConfigurationElement element) throws Exception {
+ this.extension = element;
+ this.targetContentType = Platform.getContentTypeManager().getContentType(element.getAttribute(CONTENT_TYPE_ATTRIBUTE));
+ }
+
+ public T createDelegate() {
+ try {
+ return (T) extension.createExecutableExtension(CLASS_ATTRIBUTE);
+ } catch (CoreException e) {
+ GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, e.getMessage(), e));
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/PresentationReconcilerRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/PresentationReconcilerRegistry.java
index b1692332f9b..6826e4ead20 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/PresentationReconcilerRegistry.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/PresentationReconcilerRegistry.java
@@ -10,14 +10,13 @@
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
@@ -38,33 +37,7 @@ public class PresentationReconcilerRegistry {
private static final String EXTENSION_POINT_ID = GenericEditorPlugin.BUNDLE_ID + ".presentationReconcilers"; //$NON-NLS-1$
- /**
- * This class wraps and proxies an {@link IPresentationReconcilier} provided through extensions
- * and loads it lazily when it can contribute to the editor, then delegates all operations to
- * actual reconcilier.
- */
- private static class PresentationReconcilerExtension {
- private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
- private static final String CONTENT_TYPE_ATTRIBUTE = "contentType"; //$NON-NLS-1$
-
- private IConfigurationElement extension;
- private IContentType targetContentType;
-
- private PresentationReconcilerExtension(IConfigurationElement element) throws Exception {
- this.extension = element;
- this.targetContentType = Platform.getContentTypeManager().getContentType(element.getAttribute(CONTENT_TYPE_ATTRIBUTE));
- }
-
- public IPresentationReconciler createDelegate() {
- try {
- return (IPresentationReconciler) extension.createExecutableExtension(CLASS_ATTRIBUTE);
- } catch (CoreException e) {
- GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, e.getMessage(), e));
- }
- return null;
- }
- }
- private Map<IConfigurationElement, PresentationReconcilerExtension> extensions = new HashMap<>();
+ private Map<IConfigurationElement, GenericContentTypeRelatedExtension<IPresentationReconciler>> extensions = new HashMap<>();
private boolean outOfSync = true;
/**
@@ -90,13 +63,11 @@ public class PresentationReconcilerRegistry {
if (this.outOfSync) {
sync();
}
- List<IPresentationReconciler> res = new ArrayList<>();
- for (PresentationReconcilerExtension ext : this.extensions.values()) {
- if (contentTypes.contains(ext.targetContentType)) {
- res.add(ext.createDelegate());
- }
- }
- return res;
+ return this.extensions.values().stream()
+ .filter(ext -> contentTypes.contains(ext.targetContentType))
+ .sorted(new ContentTypeSpecializationComparator<IPresentationReconciler>())
+ .map(GenericContentTypeRelatedExtension<IPresentationReconciler>::createDelegate)
+ .collect(Collectors.toList());
}
private void sync() {
@@ -105,7 +76,7 @@ public class PresentationReconcilerRegistry {
toRemoveExtensions.remove(extension);
if (!this.extensions.containsKey(extension)) {
try {
- this.extensions.put(extension, new PresentationReconcilerExtension(extension));
+ this.extensions.put(extension, new GenericContentTypeRelatedExtension<IPresentationReconciler>(extension));
} catch (Exception ex) {
GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, ex.getMessage(), ex));
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java
index c942335a0dc..28d1f39f751 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ReconcilerRegistry.java
@@ -10,14 +10,13 @@
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
@@ -38,34 +37,7 @@ public class ReconcilerRegistry {
private static final String EXTENSION_POINT_ID = GenericEditorPlugin.BUNDLE_ID + ".reconcilers"; //$NON-NLS-1$
- /**
- * This class wraps and proxies an {@link IReconciler} provided through extensions
- * and loads it lazily when it can contribute to the editor, then delegates all operations to
- * actual reconcilier.
- */
- private static class ReconcilerExtension {
- private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
- private static final String CONTENT_TYPE_ATTRIBUTE = "contentType"; //$NON-NLS-1$
-
- private IConfigurationElement extension;
- private IContentType targetContentType;
-
- private ReconcilerExtension(IConfigurationElement element) throws Exception {
- this.extension = element;
- this.targetContentType = Platform.getContentTypeManager().getContentType(element.getAttribute(CONTENT_TYPE_ATTRIBUTE));
- }
-
- public IReconciler createDelegate() {
- try {
- return (IReconciler) extension.createExecutableExtension(CLASS_ATTRIBUTE);
- } catch (CoreException e) {
- GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, e.getMessage(), e));
- }
- return null;
- }
-
- }
- private Map<IConfigurationElement, ReconcilerExtension> extensions = new HashMap<>();
+ private Map<IConfigurationElement, GenericContentTypeRelatedExtension<IReconciler>> extensions = new HashMap<>();
private boolean outOfSync = true;
/**
@@ -91,13 +63,11 @@ public class ReconcilerRegistry {
if (this.outOfSync) {
sync();
}
- List<IReconciler> res = new ArrayList<>();
- for (ReconcilerExtension ext : this.extensions.values()) {
- if (contentTypes.contains(ext.targetContentType)) {
- res.add(ext.createDelegate());
- }
- }
- return res;
+ return this.extensions.values().stream()
+ .filter(ext -> contentTypes.contains(ext.targetContentType))
+ .sorted(new ContentTypeSpecializationComparator<IReconciler>())
+ .map(GenericContentTypeRelatedExtension<IReconciler>::createDelegate)
+ .collect(Collectors.toList());
}
private void sync() {
@@ -106,7 +76,7 @@ public class ReconcilerRegistry {
toRemoveExtensions.remove(extension);
if (!this.extensions.containsKey(extension)) {
try {
- this.extensions.put(extension, new ReconcilerExtension(extension));
+ this.extensions.put(extension, new GenericContentTypeRelatedExtension<IReconciler>(extension));
} catch (Exception ex) {
GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, ex.getMessage(), ex));
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java
index 0e572876762..374c066eccc 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 Red Hat Inc. and others.
+ * Copyright (c) 2016-2017 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -21,7 +20,6 @@ import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
@@ -47,36 +45,22 @@ public final class TextHoverRegistry {
private SortedSet<TextHoverExtension> extensions;
private boolean outOfSync = true;
- static class TextHoverExtension {
- private static final String CONTENT_TYPE_ATTRIBUTE = "contentType"; //$NON-NLS-1$
- private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
+ static class TextHoverExtension extends GenericContentTypeRelatedExtension<ITextHover> {
private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
private static final String IS_BEFORE_ATTRIBUTE = "isBefore"; //$NON-NLS-1$
private static final String IS_AFTER_ATTRIBUTE = "isAfter"; //$NON-NLS-1$
- private IConfigurationElement extension;
- private IContentType targetContentType;
private String id;
private String isBefore;
private String isAfter;
public TextHoverExtension(IConfigurationElement extension) throws Exception {
- this.extension = extension;
- this.targetContentType = Platform.getContentTypeManager().getContentType(extension.getAttribute(CONTENT_TYPE_ATTRIBUTE));
+ super(extension);
this.id = extension.getAttribute(ID_ATTRIBUTE);
this.isBefore = extension.getAttribute(IS_BEFORE_ATTRIBUTE);
this.isAfter = extension.getAttribute(IS_AFTER_ATTRIBUTE);
}
- public ITextHover createDelegate() {
- try {
- return (ITextHover) extension.createExecutableExtension(CLASS_ATTRIBUTE);
- } catch (CoreException e) {
- GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GenericEditorPlugin.BUNDLE_ID, e.getMessage(), e));
- }
- return null;
- }
-
public String getId() {
if (this.id != null) {
return this.id;
@@ -110,14 +94,13 @@ public final class TextHoverRegistry {
if (this.outOfSync) {
sync();
}
- List<TextHoverExtension> hoversToConsider = new ArrayList<>();
- for (TextHoverExtension ext : this.extensions) {
- if (contentTypes.contains(ext.targetContentType)) {
- hoversToConsider.add(ext);
- }
- }
+ List<ITextHover> hoversToConsider = this.extensions.stream()
+ .filter(ext -> contentTypes.contains(ext.targetContentType))
+ // don't sort in the stream as the initial structure is already sorted by isAfter/isBefore
+ .map(GenericContentTypeRelatedExtension<ITextHover>::createDelegate)
+ .collect(Collectors.toList());
if (!hoversToConsider.isEmpty()) {
- return new CompositeTextHover(hoversToConsider.stream().map(TextHoverExtension::createDelegate).collect(Collectors.toList()));
+ return new CompositeTextHover(hoversToConsider);
}
return null;
}

Back to the top