diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-28 15:53:04 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-28 15:53:04 +0000 |
commit | f25c971275702a3a53195b568fe3c91469076c83 (patch) | |
tree | 52764695c638d5905d6116d2bf4d5d4416290ba6 /sonar-core | |
parent | 5cdbf337fef2559593e53dc7b2a2c68d8e1f992f (diff) | |
download | sonarqube-f25c971275702a3a53195b568fe3c91469076c83.tar.gz sonarqube-f25c971275702a3a53195b568fe3c91469076c83.zip |
SONAR-1814 add the method ExtensionProvider.provide() in order to support obfuscated code
Diffstat (limited to 'sonar-core')
-rw-r--r-- | sonar-core/src/main/java/org/sonar/core/plugin/AbstractPluginRepository.java | 49 | ||||
-rw-r--r-- | sonar-core/src/test/java/org/sonar/core/plugin/AbstractPluginRepositoryTest.java | 34 |
2 files changed, 48 insertions, 35 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/plugin/AbstractPluginRepository.java b/sonar-core/src/main/java/org/sonar/core/plugin/AbstractPluginRepository.java index b62bf983045..9a15c9e06ba 100644 --- a/sonar-core/src/main/java/org/sonar/core/plugin/AbstractPluginRepository.java +++ b/sonar-core/src/main/java/org/sonar/core/plugin/AbstractPluginRepository.java @@ -19,16 +19,18 @@ */ package org.sonar.core.plugin; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.Maps; import org.picocontainer.Characteristics; import org.picocontainer.MutablePicoContainer; -import org.picocontainer.injectors.ProviderAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.*; import org.sonar.api.platform.PluginRepository; import java.util.Collection; +import java.util.List; import java.util.Map; /** @@ -38,7 +40,7 @@ public abstract class AbstractPluginRepository implements PluginRepository { private static final Logger LOG = LoggerFactory.getLogger(AbstractPluginRepository.class); - private Map<String, Plugin> pluginByKey = Maps.newHashMap(); + private BiMap<String, Plugin> pluginByKey = HashBiMap.create(); private Map<Object, Plugin> pluginByExtension = Maps.newIdentityHashMap(); protected void registerPlugin(MutablePicoContainer container, Plugin plugin, String pluginKey) { @@ -49,15 +51,30 @@ public abstract class AbstractPluginRepository implements PluginRepository { } } + /** + * Must be executed by implementations when all plugins are registered. + */ + protected void invokeExtensionProviders(MutablePicoContainer container) { + List<ExtensionProvider> providers = container.getComponents(ExtensionProvider.class); + for (ExtensionProvider provider : providers) { + Plugin plugin = getPluginForExtension(provider); + Object obj = provider.provide(); + if (obj instanceof Iterable) { + for (Object elt : (Iterable) obj) { + registerExtension(container, plugin, getPluginKey(plugin), elt); + } + } else { + registerExtension(container, plugin, getPluginKey(plugin), obj); + } + } + } + private void registerExtension(MutablePicoContainer container, Plugin plugin, String pluginKey, Object extension) { if (shouldRegisterExtension(pluginKey, extension)) { LOG.debug("Register the extension: {}", extension); container.as(Characteristics.CACHE).addComponent(getExtensionKey(extension), extension); pluginByExtension.put(extension, plugin); - } - if (isExtensionProvider(extension)) { - LOG.debug("Register the extension provider: {}", extension); - container.as(Characteristics.CACHE).addAdapter(new ExtensionProviderAdapter(extension)); + } } @@ -71,6 +88,10 @@ public abstract class AbstractPluginRepository implements PluginRepository { return pluginByKey.get(key); } + public String getPluginKey(Plugin plugin) { + return pluginByKey.inverse().get(plugin); + } + /** * Returns the list of properties of a plugin */ @@ -102,15 +123,7 @@ public abstract class AbstractPluginRepository implements PluginRepository { } protected static boolean isExtensionProvider(Object extension) { - boolean is = false; - if (isType(extension, ExtensionProvider.class)) { - if (extension instanceof ExtensionProvider) { - is = true; - } else { - LOG.error("The following ExtensionProvider must be registered in Plugin.getExtensions() as an instance but not a class: " + extension); - } - } - return is; + return isType(extension, ExtensionProvider.class); } protected static Object getExtensionKey(Object component) { @@ -119,10 +132,4 @@ public abstract class AbstractPluginRepository implements PluginRepository { } return component.getClass().getCanonicalName() + "-" + component.toString(); } - - public static class ExtensionProviderAdapter extends ProviderAdapter { - public ExtensionProviderAdapter(Object provider) { - super(provider); - } - } } diff --git a/sonar-core/src/test/java/org/sonar/core/plugin/AbstractPluginRepositoryTest.java b/sonar-core/src/test/java/org/sonar/core/plugin/AbstractPluginRepositoryTest.java index 319150c5c95..de2343a07f5 100644 --- a/sonar-core/src/test/java/org/sonar/core/plugin/AbstractPluginRepositoryTest.java +++ b/sonar-core/src/test/java/org/sonar/core/plugin/AbstractPluginRepositoryTest.java @@ -28,6 +28,7 @@ import org.sonar.api.ServerExtension; import org.sonar.api.utils.IocContainer; import java.util.Arrays; +import java.util.Collection; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.notNullValue; @@ -61,9 +62,9 @@ public class AbstractPluginRepositoryTest { } @Test - public void extensionProviderIsAnObjectButNotAClass() { - assertThat(AbstractPluginRepository.isExtensionProvider(BProvider.class), is(false)); - assertThat(AbstractPluginRepository.isExtensionProvider(new BProvider()), is(true)); + public void shouldBeExtensionProvider() { + assertThat(AbstractPluginRepository.isExtensionProvider(BProvider.class), is(true)); + assertThat(AbstractPluginRepository.isExtensionProvider(new BProvider(new A())), is(true)); } @Test @@ -77,20 +78,18 @@ public class AbstractPluginRepositoryTest { }; Plugin plugin = mock(Plugin.class); - BProvider bProvider = new BProvider(); - when(plugin.getExtensions()).thenReturn(Arrays.asList(A.class, bProvider, C.class, D.class)); + when(plugin.getExtensions()).thenReturn(Arrays.asList(A.class, BProvider.class, B.class, C.class, D.class)); repository.registerPlugin(pico, plugin, "foo"); + repository.invokeExtensionProviders(pico); pico.start(); assertThat(pico.getComponent(A.class), is(A.class)); assertThat(pico.getComponent(C.class), is(C.class)); assertThat(pico.getComponent(D.class), is(D.class)); - assertThat(pico.getComponent(C.class).getBees().length, is(2)); - assertThat(pico.getComponent(D.class).getBees().length, is(2)); - assertThat(bProvider.calls, is(1)); // do not create B instances two times (C and D dependencies) - - // Picocontainer question: why components created by providers are not registered in the container ? - //assertThat(pico.getComponents(B.class).size(), is(2)); // created by the ExtensionProvider + assertThat(pico.getComponent(C.class).getBees().length, is(3));// 1 in plugin.getExtensions() + 2 created by BProvider + assertThat(pico.getComponent(D.class).getBees().length, is(3)); + assertThat(pico.getComponent(BProvider.class).calls, is(1)); // do not create B instances two times (C and D dependencies) + assertThat(pico.getComponents(B.class).size(), is(3)); } public static class FakeServerExtension implements ServerExtension { @@ -115,6 +114,7 @@ public class AbstractPluginRepositoryTest { } } + public static class C implements ServerExtension { private B[] bees; @@ -139,12 +139,18 @@ public class AbstractPluginRepositoryTest { } } - public static class BProvider extends ExtensionProvider { + public static class BProvider extends ExtensionProvider implements ServerExtension { private int calls = 0; - public B[] provide(A a) { + private A a; + + public BProvider(A a) { + this.a = a; + } + + public Collection<B> provide() { calls++; - return new B[]{new B(a), new B(a)}; + return Arrays.asList(new B(a), new B(a)); } } |