This commit is contained in:
Alexey Kudravtsev
2018-10-11 15:37:15 +03:00
parent c7d20f05cd
commit bd7146ba54
7 changed files with 43 additions and 45 deletions
@@ -47,13 +47,6 @@ public class ExtensionComponentAdapter implements LoadingOrder.Orderable, Assign
myOrder = order;
}
public ExtensionComponentAdapter(@NotNull String implementationClassName,
@Nullable Element extensionElement,
PicoContainer container,
PluginDescriptor pluginDescriptor) {
this(implementationClassName, container, pluginDescriptor, null, LoadingOrder.ANY, extensionElement);
}
@Override
public Object getComponentKey() {
return this;
@@ -66,21 +59,22 @@ public class ExtensionComponentAdapter implements LoadingOrder.Orderable, Assign
@Override
public Object getComponentInstance(final PicoContainer container) throws PicoException, ProcessCanceledException {
if (myComponentInstance == null) {
Object instance = myComponentInstance;
if (instance == null) {
try {
Class impl = loadImplementationClass();
Object componentInstance = new CachingConstructorInjectionComponentAdapter(getComponentKey(), impl, null, true).getComponentInstance(container);
instance = new CachingConstructorInjectionComponentAdapter(getComponentKey(), impl, null, true).getComponentInstance(container);
if (myExtensionElement != null) {
try {
XmlSerializer.deserializeInto(componentInstance, myExtensionElement);
XmlSerializer.deserializeInto(instance, myExtensionElement);
}
catch (Exception e) {
throw new PicoInitializationException(e);
}
}
myComponentInstance = componentInstance;
myComponentInstance = instance;
}
catch (ProcessCanceledException e) {
throw e;
@@ -90,13 +84,13 @@ public class ExtensionComponentAdapter implements LoadingOrder.Orderable, Assign
throw new PicoPluginExtensionInitializationException(t.getMessage(), t, pluginId);
}
if (myComponentInstance instanceof PluginAware) {
PluginAware pluginAware = (PluginAware)myComponentInstance;
if (instance instanceof PluginAware) {
PluginAware pluginAware = (PluginAware)instance;
pluginAware.setPluginDescriptor(myPluginDescriptor);
}
}
return myComponentInstance;
return instance;
}
@Override
@@ -162,8 +156,8 @@ public class ExtensionComponentAdapter implements LoadingOrder.Orderable, Assign
return myNotificationSent;
}
void setNotificationSent(boolean notificationSent) {
myNotificationSent = notificationSent;
void setNotificationSent() {
myNotificationSent = true;
}
@Override
@@ -10,6 +10,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.OpenTHashSet;
import com.intellij.util.containers.StringInterner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -152,7 +153,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
}
notifyListenersOnAdd(extension, adapter.getPluginDescriptor());
adapter.setNotificationSent(true);
adapter.setNotificationSent();
}
}
}
@@ -199,9 +200,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
//noinspection unchecked
return (T[])Array.newInstance(getExtensionClass(), 0);
}
else {
return myExtensionsCacheAsArray.clone();
}
return myExtensionsCacheAsArray.clone();
}
@NotNull
@@ -243,6 +242,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
myExtensionAdapters = new LinkedHashSet<>(adapters);
Set<ExtensionComponentAdapter> loaded = ContainerUtil.newHashOrEmptySet(myLoadedAdapters);
OpenTHashSet<T> duplicates = new OpenTHashSet<>(adapters.size());
myLoadedAdapters = Collections.emptyList();
boolean errorHappened = false;
@@ -254,11 +254,12 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
errorHappened = true;
LOG.error("null extension in: " + adapter + ";\ngetExtensionClass(): " + getExtensionClass() + ";\n" );
}
if (i > 0 && extension == result[i - 1]) {
if (!duplicates.add(extension)) {
errorHappened = true;
T duplicate = duplicates.get(extension);
LOG.error("Duplicate extension found: " + extension + "; " +
" Adapter: " + adapter + ";\n" +
" Prev adapter: " + adapters.get(i-1) + ";\n" +
" Prev extension: " + duplicate + ";\n" +
" Adapter: " + adapter + ";\n" +
" getExtensionClass(): " + getExtensionClass() + ";\n" +
" result:" + Arrays.asList(result));
}
@@ -268,6 +269,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
continue;
}
result[i] = extension;
registerExtension(extension, adapter, myLoadedAdapters.size(), !loaded.contains(adapter));
}
catch (ProcessCanceledException e) {
@@ -331,7 +333,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
}
@Override
public void unregisterExtension(@NotNull Class<? extends T> extensionClass) {
public synchronized void unregisterExtension(@NotNull Class<? extends T> extensionClass) {
for (ExtensionComponentAdapter adapter : ContainerUtil.concat(myExtensionAdapters, myLoadedAdapters)) {
if (adapter.getAssignableToClassName().equals(extensionClass.getCanonicalName())) {
unregisterExtensionAdapter(adapter);
@@ -479,6 +481,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
return extensionClass;
}
@Override
public String toString() {
return getName();
}
@@ -528,7 +531,7 @@ public final class ExtensionPointImpl<T> implements ExtensionPoint<T> {
private final LoadingOrder myLoadingOrder;
private ObjectComponentAdapter(@NotNull Object extension, @NotNull LoadingOrder loadingOrder) {
super(extension.getClass().getName(), null, null, null);
super(extension.getClass().getName(), null, null, null, LoadingOrder.ANY, null);
myExtension = extension;
myLoadingOrder = loadingOrder;
}
@@ -144,10 +144,6 @@ public class ExtensionsAreaImpl implements ExtensionsArea {
registerExtensionPoint(epName, className, pluginDescriptor, kind);
}
public void registerExtension(@NotNull final String pluginName, @NotNull final Element extensionElement) {
registerExtension(new DefaultPluginDescriptor(PluginId.getId(pluginName)), extensionElement, null);
}
@Override
public void registerExtension(@NotNull final PluginDescriptor pluginDescriptor, @NotNull final Element extensionElement, String extensionNs) {
String epName = extractEPName(extensionElement, extensionNs);
@@ -33,7 +33,7 @@ public class ExtensionComponentAdapterTest {
Element element = JDOMUtil.load("<bean implementation=\"123\"/>");
DefaultPicoContainer container = new DefaultPicoContainer();
DefaultPluginDescriptor descriptor = new DefaultPluginDescriptor("test");
new ExtensionComponentAdapter(name, element, container, descriptor).getComponentInstance(container);
new ExtensionComponentAdapter(name, container, descriptor, null, LoadingOrder.ANY, element).getComponentInstance(container);
}
@NotNull
@@ -262,7 +262,7 @@ public class ExtensionPointImplTest {
private boolean myFire;
MyShootingComponentAdapter(@NotNull String implementationClass) {
super(implementationClass, null, new DefaultPicoContainer(), new DefaultPluginDescriptor("test"));
super(implementationClass, new DefaultPicoContainer(), new DefaultPluginDescriptor("test"), null, LoadingOrder.ANY, null);
}
public void setFire(boolean fire) {
@@ -110,7 +110,7 @@ public class ExtensionsComplexTest {
private static void initExtensions(@NonNls String data, AreaInstance instance) throws IOException, JDOMException {
final Element element = JDOMUtil.load(data);
for (final Element child : element.getChildren()) {
((ExtensionsAreaImpl)Extensions.getArea(instance)).registerExtension(element.getNamespaceURI(), child);
ExtensionsImplTest.registerExtension(((ExtensionsAreaImpl)Extensions.getArea(instance)), element.getNamespaceURI(), child);
}
}
@@ -3,6 +3,7 @@ package com.intellij.openapi.extensions.impl;
import com.intellij.openapi.extensions.*;
import com.intellij.openapi.util.JDOMUtil;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
@@ -156,11 +157,11 @@ public class ExtensionsImplTest {
public void testExtensionsNamespaces() throws IOException, JDOMException {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
extensionsArea.registerExtensionPoint("plugin.ep1", TestExtensionClassOne.class.getName(), ExtensionPoint.Kind.BEAN_CLASS);
extensionsArea.registerExtension("plugin", JDOMUtil.load(
registerExtension(extensionsArea, "plugin", JDOMUtil.load(
"<plugin:ep1 xmlns:plugin=\"plugin\" order=\"LAST\"><text>3</text></plugin:ep1>"));
extensionsArea.registerExtension("plugin", JDOMUtil.load(
registerExtension(extensionsArea, "plugin", JDOMUtil.load(
"<ep1 xmlns=\"plugin\" order=\"FIRST\"><text>1</text></ep1>"));
extensionsArea.registerExtension("plugin", JDOMUtil.load(
registerExtension(extensionsArea, "plugin", JDOMUtil.load(
"<extension point=\"plugin.ep1\"><text>2</text></extension>"));
ExtensionPoint extensionPoint = extensionsArea.getExtensionPoint("plugin.ep1");
TestExtensionClassOne[] extensions = (TestExtensionClassOne[]) extensionPoint.getExtensions();
@@ -174,11 +175,11 @@ public class ExtensionsImplTest {
public void testExtensionsWithOrdering() throws IOException, JDOMException {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
extensionsArea.registerExtensionPoint("ep1", TestExtensionClassOne.class.getName(), ExtensionPoint.Kind.BEAN_CLASS);
extensionsArea.registerExtension("", JDOMUtil.load(
registerExtension(extensionsArea, "", JDOMUtil.load(
"<extension point=\"ep1\" order=\"LAST\"><text>3</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load(
registerExtension(extensionsArea, "", JDOMUtil.load(
"<extension point=\"ep1\" order=\"FIRST\"><text>1</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load(
registerExtension(extensionsArea, "", JDOMUtil.load(
"<extension point=\"ep1\"><text>2</text></extension>"));
ExtensionPoint extensionPoint = extensionsArea.getExtensionPoint("ep1");
TestExtensionClassOne[] extensions = (TestExtensionClassOne[]) extensionPoint.getExtensions();
@@ -192,9 +193,9 @@ public class ExtensionsImplTest {
public void testExtensionsWithOrderingUpdate() throws IOException, JDOMException {
ExtensionsAreaImpl extensionsArea = new ExtensionsAreaImpl(new DefaultPicoContainer());
extensionsArea.registerExtensionPoint("ep1", TestExtensionClassOne.class.getName(), ExtensionPoint.Kind.BEAN_CLASS);
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" id=\"_7\" order=\"LAST\"><text>7</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" id=\"fst\" order=\"FIRST\"><text>1</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" id=\"id\"><text>3</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" id=\"_7\" order=\"LAST\"><text>7</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" id=\"fst\" order=\"FIRST\"><text>1</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" id=\"id\"><text>3</text></extension>"));
ExtensionPoint<TestExtensionClassOne> extensionPoint = extensionsArea.getExtensionPoint("ep1");
TestExtensionClassOne[] extensions = extensionPoint.getExtensions();
assertEquals(3, extensions.length);
@@ -204,10 +205,10 @@ public class ExtensionsImplTest {
TestExtensionClassOne extension = new TestExtensionClassOne("xxx");
extensionPoint.registerExtension(extension);
extensionPoint.unregisterExtension(extension);
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" order=\"BEFORE id\"><text>2</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" order=\"AFTER id\"><text>4</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" order=\"last, after _7\"><text>8</text></extension>"));
extensionsArea.registerExtension("", JDOMUtil.load("<extension point=\"ep1\" order=\"after:id, before _7, after fst\"><text>5</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" order=\"BEFORE id\"><text>2</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" order=\"AFTER id\"><text>4</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" order=\"last, after _7\"><text>8</text></extension>"));
registerExtension(extensionsArea, "", JDOMUtil.load("<extension point=\"ep1\" order=\"after:id, before _7, after fst\"><text>5</text></extension>"));
extensionPoint.registerExtension(new TestExtensionClassOne("6"));
extensions = extensionPoint.getExtensions();
assertEquals(8, extensions.length);
@@ -221,6 +222,10 @@ public class ExtensionsImplTest {
assertEquals("8", extensions[7].getText());
}
public static void registerExtension(ExtensionsAreaImpl area, @NotNull final String pluginName, @NotNull final Element extensionElement) {
area.registerExtension(new DefaultPluginDescriptor(PluginId.getId(pluginName)), extensionElement, null);
}
public interface MyInterface1 extends Runnable {
}