import java.io.File;
import java.util.List;
-public final class DefaultPluginMetadata implements PluginMetadata, Comparable<PluginMetadata> {
+public class DefaultPluginMetadata implements PluginMetadata, Comparable<PluginMetadata> {
private File file;
private List<File> deployedFiles = Lists.newArrayList();
private List<File> deprecatedExtensions = Lists.newArrayList();
import org.sonar.api.BatchComponent;
import org.sonar.api.Plugin;
import org.sonar.api.Property;
-import org.sonar.api.ServerComponent;
import java.util.Collection;
-public interface PluginRepository extends BatchComponent, ServerComponent {
+public interface PluginRepository extends BatchComponent {
Collection<Plugin> getPlugins();
Plugin getPlugin(String key);
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.platform;
+
+import org.sonar.api.ServerComponent;
+
+/**
+ * @since 2.11
+ */
+public interface ServerPluginRepository extends PluginRepository, ServerComponent {
+
+ /**
+ * Disabled plugins are not loaded by batch, but they are still installed :
+ * <ul>
+ * <li>Plugin properties are available in General Settings</li>
+ * <li>Plugin is marked as installed in Update Center</li>
+ * </ul>
+ */
+ void disable(String pluginKey);
+
+ /**
+ * @param plugingKey can not be null
+ */
+ boolean isDisabled(String plugingKey);
+
+}
return new File(getHomeDir(), "extensions/rules");
}
- public File getPluginsIndex() {
+ public File getPluginIndex() {
return new File(getDeployDir(), "plugins/index.txt");
}
private void startCoreComponents() {
coreContainer = rootContainer.makeChildContainer();
coreContainer.as(Characteristics.CACHE).addComponent(PluginDeployer.class);
- coreContainer.as(Characteristics.CACHE).addComponent(ServerPluginRepository.class);
+ coreContainer.as(Characteristics.CACHE).addComponent(DefaultServerPluginRepository.class);
coreContainer.as(Characteristics.CACHE).addComponent(DefaultServerFileSystem.class);
coreContainer.as(Characteristics.CACHE).addComponent(ThreadLocalDatabaseSessionFactory.class);
coreContainer.as(Characteristics.CACHE).addComponent(HttpDownloader.class);
private void startServiceComponents() {
servicesContainer = coreContainer.makeChildContainer();
- ServerPluginRepository pluginRepository = servicesContainer.getComponent(ServerPluginRepository.class);
+ DefaultServerPluginRepository pluginRepository = servicesContainer.getComponent(DefaultServerPluginRepository.class);
pluginRepository.registerExtensions(servicesContainer);
servicesContainer.as(Characteristics.CACHE).addComponent(ServerImpl.class);
startupContainer.as(Characteristics.CACHE).addComponent(ServerMetadataPersister.class);
startupContainer.as(Characteristics.CACHE).addComponent(RegisterQualityModels.class);
startupContainer.as(Characteristics.CACHE).addComponent(DeleteDeprecatedMeasures.class);
+ startupContainer.as(Characteristics.CACHE).addComponent(GeneratePluginIndex.class);
startupContainer.start();
startupContainer.getComponent(ServerLifecycleNotifier.class).notifyStart();
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.plugins;
+
+import com.google.common.collect.Sets;
+import org.picocontainer.Characteristics;
+import org.picocontainer.MutablePicoContainer;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.*;
+import org.sonar.api.platform.PluginMetadata;
+import org.sonar.api.platform.ServerPluginRepository;
+import org.sonar.core.plugins.PluginClassloaders;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @since 2.2
+ */
+public class DefaultServerPluginRepository implements ServerPluginRepository {
+
+ private PluginClassloaders classloaders;
+ private PluginDeployer deployer;
+ private Map<String, Plugin> pluginsByKey;
+ private Set<String> disabledPlugins = Sets.newHashSet();
+
+ public DefaultServerPluginRepository(PluginDeployer deployer) {
+ this.classloaders = new PluginClassloaders(getClass().getClassLoader());
+ this.deployer = deployer;
+ }
+
+ public void start() {
+ pluginsByKey = classloaders.init(deployer.getMetadata());
+ }
+
+ public void stop() {
+ if (classloaders != null) {
+ classloaders.clean();
+ classloaders = null;
+ }
+ }
+
+ public void disable(String pluginKey) {
+ disabledPlugins.add(pluginKey);
+ for (PluginMetadata metadata : getMetadata()) {
+ if (pluginKey.equals(metadata.getBasePlugin())) {
+ disable(metadata.getKey());
+ }
+ }
+ }
+
+ public boolean isDisabled(String pluginKey) {
+ return disabledPlugins.contains(pluginKey);
+ }
+
+ public Collection<Plugin> getPlugins() {
+ return pluginsByKey.values();
+ }
+
+ public Plugin getPlugin(String key) {
+ return pluginsByKey.get(key);
+ }
+
+ public ClassLoader getClassloader(String pluginKey) {
+ return classloaders.get(pluginKey);
+ }
+
+ public Class getClass(String pluginKey, String classname) {
+ Class clazz = null;
+ ClassLoader classloader = getClassloader(pluginKey);
+ if (classloader != null) {
+ try {
+ clazz = classloader.loadClass(classname);
+
+ } catch (ClassNotFoundException e) {
+ LoggerFactory.getLogger(getClass()).warn("Class not found in plugin " + pluginKey + ": " + classname, e);
+ }
+ }
+ return clazz;
+ }
+
+
+ public Property[] getProperties(Plugin plugin) {
+ if (plugin != null) {
+ Class<? extends Plugin> classInstance = plugin.getClass();
+ if (classInstance.isAnnotationPresent(Properties.class)) {
+ return classInstance.getAnnotation(Properties.class).value();
+ }
+ }
+ return new Property[0];
+ }
+
+ public Collection<PluginMetadata> getMetadata() {
+ return deployer.getMetadata();
+ }
+
+ public PluginMetadata getMetadata(String pluginKey) {
+ return deployer.getMetadata(pluginKey);
+ }
+
+ public void registerExtensions(MutablePicoContainer container) {
+ registerExtensions(container, getPlugins());
+ }
+
+ void registerExtensions(MutablePicoContainer container, Collection<Plugin> plugins) {
+ for (Plugin plugin : plugins) {
+ container.as(Characteristics.CACHE).addComponent(plugin);
+ for (Object extension : plugin.getExtensions()) {
+ installExtension(container, extension);
+ }
+ }
+ installExtensionProviders(container);
+ }
+
+ void installExtensionProviders(MutablePicoContainer container) {
+ List<ExtensionProvider> providers = container.getComponents(ExtensionProvider.class);
+ for (ExtensionProvider provider : providers) {
+ Object obj = provider.provide();
+ if (obj instanceof Iterable) {
+ for (Object extension : (Iterable) obj) {
+ installExtension(container, extension);
+ }
+ } else {
+ installExtension(container, obj);
+ }
+ }
+ }
+
+ void installExtension(MutablePicoContainer container, Object extension) {
+ if (isType(extension, ServerExtension.class)) {
+ container.as(Characteristics.CACHE).addComponent(getExtensionKey(extension), extension);
+ }
+ }
+
+ static boolean isType(Object extension, Class<? extends Extension> extensionClass) {
+ Class clazz = (extension instanceof Class ? (Class) extension : extension.getClass());
+ return extensionClass.isAssignableFrom(clazz);
+ }
+
+ static Object getExtensionKey(Object component) {
+ if (component instanceof Class) {
+ return component;
+ }
+ return component.getClass().getCanonicalName() + "-" + component.toString();
+ }
+}
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.CharUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.core.plugins.DefaultPluginMetadata;
import org.sonar.core.plugins.PluginFileExtractor;
-import org.sonar.core.plugins.RemotePlugin;
import org.sonar.server.platform.DefaultServerFileSystem;
import org.sonar.server.platform.ServerStartException;
import java.io.File;
-import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
deployPlugins();
- generateIndexFile();
profiler.stop();
}
}
}
-
- private void generateIndexFile() throws IOException {
- File indexFile = fileSystem.getPluginsIndex();
- FileUtils.forceMkdir(indexFile.getParentFile());
- FileWriter writer = new FileWriter(indexFile, false);
- try {
- for (PluginMetadata metadata : pluginByKeys.values()) {
- writer.append(RemotePlugin.create((DefaultPluginMetadata)metadata).marshal());
- writer.append(CharUtils.LF);
- }
- writer.flush();
-
- } finally {
- IOUtils.closeQuietly(writer);
- }
- }
-
-
public void uninstall(String pluginKey) {
PluginMetadata metadata = pluginByKeys.get(pluginKey);
if (metadata != null && !metadata.isCore()) {
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.server.plugins;
-
-import org.picocontainer.Characteristics;
-import org.picocontainer.MutablePicoContainer;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.*;
-import org.sonar.api.platform.PluginMetadata;
-import org.sonar.api.platform.PluginRepository;
-import org.sonar.core.plugins.PluginClassloaders;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @since 2.2
- */
-public class ServerPluginRepository implements PluginRepository {
-
- private PluginClassloaders classloaders;
- private PluginDeployer deployer;
- private Map<String, Plugin> pluginsByKey;
-
- public ServerPluginRepository(PluginDeployer deployer) {
- this.classloaders = new PluginClassloaders(getClass().getClassLoader());
- this.deployer = deployer;
- }
-
- public void start() {
- pluginsByKey = classloaders.init(deployer.getMetadata());
- }
-
- public void stop() {
- if (classloaders != null) {
- classloaders.clean();
- classloaders = null;
- }
- }
-
- public Collection<Plugin> getPlugins() {
- return pluginsByKey.values();
- }
-
- public Plugin getPlugin(String key) {
- return pluginsByKey.get(key);
- }
-
- public ClassLoader getClassloader(String pluginKey) {
- return classloaders.get(pluginKey);
- }
-
- public Class getClass(String pluginKey, String classname) {
- Class clazz = null;
- ClassLoader classloader = getClassloader(pluginKey);
- if (classloader != null) {
- try {
- clazz = classloader.loadClass(classname);
-
- } catch (ClassNotFoundException e) {
- LoggerFactory.getLogger(getClass()).warn("Class not found in plugin " + pluginKey + ": " + classname, e);
- }
- }
- return clazz;
- }
-
-
- public Property[] getProperties(Plugin plugin) {
- if (plugin != null) {
- Class<? extends Plugin> classInstance = plugin.getClass();
- if (classInstance.isAnnotationPresent(Properties.class)) {
- return classInstance.getAnnotation(Properties.class).value();
- }
- }
- return new Property[0];
- }
-
- public Collection<PluginMetadata> getMetadata() {
- return deployer.getMetadata();
- }
-
- public PluginMetadata getMetadata(String pluginKey) {
- return deployer.getMetadata(pluginKey);
- }
-
- public void registerExtensions(MutablePicoContainer container) {
- registerExtensions(container, getPlugins());
- }
-
- void registerExtensions(MutablePicoContainer container, Collection<Plugin> plugins) {
- for (Plugin plugin : plugins) {
- container.as(Characteristics.CACHE).addComponent(plugin);
- for (Object extension : plugin.getExtensions()) {
- installExtension(container, extension);
- }
- }
- installExtensionProviders(container);
- }
-
- void installExtensionProviders(MutablePicoContainer container) {
- List<ExtensionProvider> providers = container.getComponents(ExtensionProvider.class);
- for (ExtensionProvider provider : providers) {
- Object obj = provider.provide();
- if (obj instanceof Iterable) {
- for (Object extension : (Iterable) obj) {
- installExtension(container, extension);
- }
- } else {
- installExtension(container, obj);
- }
- }
- }
-
- void installExtension(MutablePicoContainer container, Object extension) {
- if (isType(extension, ServerExtension.class)) {
- container.as(Characteristics.CACHE).addComponent(getExtensionKey(extension), extension);
- }
- }
-
- static boolean isType(Object extension, Class<? extends Extension> extensionClass) {
- Class clazz = (extension instanceof Class ? (Class) extension : extension.getClass());
- return extensionClass.isAssignableFrom(clazz);
- }
-
- static Object getExtensionKey(Object component) {
- if (component instanceof Class) {
- return component;
- }
- return component.getClass().getCanonicalName() + "-" + component.toString();
- }
-}
String pluginKey = getPluginKey(request);
String resource = getResourcePath(request);
- ServerPluginRepository pluginRepository = Platform.getInstance().getContainer().getComponent(ServerPluginRepository.class);
+ DefaultServerPluginRepository pluginRepository = Platform.getInstance().getContainer().getComponent(DefaultServerPluginRepository.class);
ClassLoader classLoader = pluginRepository.getClassloader(pluginKey);
if (classLoader == null) {
LOG.error("Plugin not found: " + pluginKey);
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.startup;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.CharUtils;
+import org.sonar.api.platform.PluginMetadata;
+import org.sonar.core.plugins.DefaultPluginMetadata;
+import org.sonar.core.plugins.RemotePlugin;
+import org.sonar.server.platform.DefaultServerFileSystem;
+import org.sonar.server.plugins.DefaultServerPluginRepository;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * @since 2.11
+ */
+public final class GeneratePluginIndex {
+
+ private DefaultServerFileSystem fileSystem;
+ private DefaultServerPluginRepository repository;
+
+ public GeneratePluginIndex(DefaultServerFileSystem fileSystem, DefaultServerPluginRepository repository) {
+ this.fileSystem = fileSystem;
+ this.repository = repository;
+ }
+
+ public void start() throws IOException {
+ writeIndex(fileSystem.getPluginIndex());
+ }
+
+ void writeIndex(File indexFile) throws IOException {
+ FileUtils.forceMkdir(indexFile.getParentFile());
+ FileWriter writer = new FileWriter(indexFile, false);
+ try {
+ for (PluginMetadata metadata : repository.getMetadata()) {
+ if (!repository.isDisabled(metadata.getKey())) {
+ writer.append(RemotePlugin.create((DefaultPluginMetadata) metadata).marshal());
+ writer.append(CharUtils.LF);
+ }
+ }
+ writer.flush();
+
+ } finally {
+ IOUtils.closeQuietly(writer);
+ }
+ }
+}
public Object getComponentByClassname(String pluginKey, String className) {
Object component = null;
PicoContainer container = getContainer();
- Class componentClass = container.getComponent(ServerPluginRepository.class).getClass(pluginKey, className);
+ Class componentClass = container.getComponent(DefaultServerPluginRepository.class).getClass(pluginKey, className);
if (componentClass != null) {
component = container.getComponent(componentClass);
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.plugins;
+
+import org.apache.commons.io.FileUtils;
+import org.hamcrest.core.Is;
+import org.junit.After;
+import org.junit.Test;
+import org.picocontainer.containers.TransientPicoContainer;
+import org.sonar.api.*;
+import org.sonar.api.platform.PluginMetadata;
+import org.sonar.core.plugins.DefaultPluginMetadata;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import static junit.framework.Assert.assertFalse;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class DefaultServerPluginRepositoryTest {
+
+ private DefaultServerPluginRepository repository;
+
+ @After
+ public void stop() {
+ if (repository != null) {
+ repository.stop();
+ }
+ }
+
+ @Test
+ public void testStart() {
+ PluginDeployer deployer = mock(PluginDeployer.class);
+ File pluginFile = FileUtils.toFile(getClass().getResource("/org/sonar/server/plugins/DefaultServerPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar"));
+ PluginMetadata plugin = DefaultPluginMetadata.create(pluginFile)
+ .setKey("artifactsize")
+ .setMainClass("org.sonar.plugins.artifactsize.ArtifactSizePlugin")
+ .addDeployedFile(pluginFile);
+ when(deployer.getMetadata()).thenReturn(Arrays.asList(plugin));
+
+ repository = new DefaultServerPluginRepository(deployer);
+ repository.start();
+
+ assertThat(repository.getPlugins().size(), Is.is(1));
+ assertThat(repository.getPlugin("artifactsize"), not(nullValue()));
+ assertThat(repository.getClassloader("artifactsize"), not(nullValue()));
+ assertThat(repository.getClass("artifactsize", "org.sonar.plugins.artifactsize.ArtifactSizeMetrics"), not(nullValue()));
+ assertThat(repository.getClass("artifactsize", "org.Unknown"), nullValue());
+ assertThat(repository.getClass("other", "org.sonar.plugins.artifactsize.ArtifactSizeMetrics"), nullValue());
+ }
+
+ @Test
+ public void shouldRegisterServerExtensions() {
+ DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class));
+
+ TransientPicoContainer container = new TransientPicoContainer();
+ repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeBatchExtension.class, FakeServerExtension.class))));
+
+ assertThat(container.getComponents(Extension.class).size(), is(1));
+ assertThat(container.getComponents(FakeServerExtension.class).size(), is(1));
+ assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0));
+ }
+
+ @Test
+ public void shouldInvokeServerExtensionProviderss() {
+ DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class));
+
+ TransientPicoContainer container = new TransientPicoContainer();
+ repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeExtensionProvider.class))));
+
+ assertThat(container.getComponents(Extension.class).size(), is(2));// provider + FakeServerExtension
+ assertThat(container.getComponents(FakeServerExtension.class).size(), is(1));
+ assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0));
+ }
+
+ @Test
+ public void shouldDisablePlugin() {
+ DefaultServerPluginRepository repository = new DefaultServerPluginRepository(mock(PluginDeployer.class));
+ repository.disable("checkstyle");
+
+ assertTrue(repository.isDisabled("checkstyle"));
+ assertFalse(repository.isDisabled("sqale"));
+ }
+
+ @Test
+ public void shouldDisableDependentPlugins() {
+ PluginDeployer deployer = mock(PluginDeployer.class);
+ List<PluginMetadata> metadata = Arrays.asList(
+ newMetadata("checkstyle", null),
+ newMetadata("checkstyle-extensions", "checkstyle"),
+ newMetadata("sqale", null)
+ );
+ when(deployer.getMetadata()).thenReturn(metadata);
+ DefaultServerPluginRepository repository = new DefaultServerPluginRepository(deployer);
+
+ repository.disable("checkstyle");
+
+ assertTrue(repository.isDisabled("checkstyle"));
+ assertTrue(repository.isDisabled("checkstyle-extensions"));
+ assertFalse(repository.isDisabled("sqale"));
+ }
+
+ @Test
+ public void shouldNotDisableBasePlugin() {
+ PluginDeployer deployer = mock(PluginDeployer.class);
+ List<PluginMetadata> metadata = Arrays.asList(
+ newMetadata("checkstyle", null),
+ newMetadata("checkstyle-extensions", "checkstyle"),
+ newMetadata("sqale", null)
+ );
+ when(deployer.getMetadata()).thenReturn(metadata);
+ DefaultServerPluginRepository repository = new DefaultServerPluginRepository(deployer);
+
+ repository.disable("checkstyle-extensions");
+
+ assertFalse(repository.isDisabled("checkstyle"));
+ assertTrue(repository.isDisabled("checkstyle-extensions"));
+ }
+
+ private PluginMetadata newMetadata(String pluginKey, String basePluginKey) {
+ PluginMetadata plugin = mock(PluginMetadata.class);
+ when(plugin.getKey()).thenReturn(pluginKey);
+ when(plugin.getBasePlugin()).thenReturn(basePluginKey);
+ return plugin;
+ }
+
+ public static class FakePlugin extends SonarPlugin {
+ private List<Class> extensions;
+
+ public FakePlugin(List<Class> extensions) {
+ this.extensions = extensions;
+ }
+
+ public List getExtensions() {
+ return extensions;
+ }
+ }
+
+ public static class FakeBatchExtension implements BatchExtension {
+
+ }
+
+ public static class FakeServerExtension implements ServerExtension {
+
+ }
+
+ public static class FakeExtensionProvider extends ExtensionProvider implements ServerExtension {
+
+ @Override
+ public Object provide() {
+ return Arrays.asList(FakeBatchExtension.class, FakeServerExtension.class);
+ }
+ }
+}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.server.plugins;
-
-import org.apache.commons.io.FileUtils;
-import org.hamcrest.core.Is;
-import org.junit.After;
-import org.junit.Test;
-import org.picocontainer.containers.TransientPicoContainer;
-import org.sonar.api.*;
-import org.sonar.api.platform.PluginMetadata;
-import org.sonar.core.plugins.DefaultPluginMetadata;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.core.IsNot.not;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ServerPluginRepositoryTest {
-
- private ServerPluginRepository repository;
-
- @After
- public void stop() {
- if (repository != null) {
- repository.stop();
- }
- }
-
- @Test
- public void testStart() {
- PluginDeployer deployer = mock(PluginDeployer.class);
- File pluginFile = FileUtils.toFile(getClass().getResource("/org/sonar/server/plugins/ServerPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar"));
- PluginMetadata plugin = DefaultPluginMetadata.create(pluginFile)
- .setKey("artifactsize")
- .setMainClass("org.sonar.plugins.artifactsize.ArtifactSizePlugin")
- .addDeployedFile(pluginFile);
- when(deployer.getMetadata()).thenReturn(Arrays.asList(plugin));
-
- repository = new ServerPluginRepository(deployer);
- repository.start();
-
- assertThat(repository.getPlugins().size(), Is.is(1));
- assertThat(repository.getPlugin("artifactsize"), not(nullValue()));
- assertThat(repository.getClassloader("artifactsize"), not(nullValue()));
- assertThat(repository.getClass("artifactsize", "org.sonar.plugins.artifactsize.ArtifactSizeMetrics"), not(nullValue()));
- assertThat(repository.getClass("artifactsize", "org.Unknown"), nullValue());
- assertThat(repository.getClass("other", "org.sonar.plugins.artifactsize.ArtifactSizeMetrics"), nullValue());
- }
-
- @Test
- public void shouldRegisterServerExtensions() {
- ServerPluginRepository repository = new ServerPluginRepository(mock(PluginDeployer.class));
-
- TransientPicoContainer container = new TransientPicoContainer();
- repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeBatchExtension.class, FakeServerExtension.class))));
-
- assertThat(container.getComponents(Extension.class).size(), is(1));
- assertThat(container.getComponents(FakeServerExtension.class).size(), is(1));
- assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0));
- }
-
- @Test
- public void shouldInvokeServerExtensionProviderss() {
- ServerPluginRepository repository = new ServerPluginRepository(mock(PluginDeployer.class));
-
- TransientPicoContainer container = new TransientPicoContainer();
- repository.registerExtensions(container, Arrays.<Plugin>asList(new FakePlugin(Arrays.<Class>asList(FakeExtensionProvider.class))));
-
- assertThat(container.getComponents(Extension.class).size(), is(2));// provider + FakeServerExtension
- assertThat(container.getComponents(FakeServerExtension.class).size(), is(1));
- assertThat(container.getComponents(FakeBatchExtension.class).size(), is(0));
- }
-
- public static class FakePlugin extends SonarPlugin {
- private List<Class> extensions;
-
- public FakePlugin(List<Class> extensions) {
- this.extensions = extensions;
- }
-
- public List getExtensions() {
- return extensions;
- }
- }
-
- public static class FakeBatchExtension implements BatchExtension {
-
- }
-
- public static class FakeServerExtension implements ServerExtension {
-
- }
-
- public static class FakeExtensionProvider extends ExtensionProvider implements ServerExtension {
-
- @Override
- public Object provide() {
- return Arrays.asList(FakeBatchExtension.class, FakeServerExtension.class);
- }
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.startup;
+
+import org.apache.commons.io.FileUtils;
+import org.hamcrest.core.Is;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.platform.PluginMetadata;
+import org.sonar.core.plugins.DefaultPluginMetadata;
+import org.sonar.server.platform.DefaultServerFileSystem;
+import org.sonar.server.plugins.DefaultServerPluginRepository;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.containsString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class GeneratePluginIndexTest {
+
+ private DefaultServerFileSystem fileSystem;
+ private File index;
+
+ @Before
+ public void createIndexFile() {
+ fileSystem = mock(DefaultServerFileSystem.class);
+ index = new File("target/test-tmp/GeneratePluginIndexTest/plugins.txt");
+ when(fileSystem.getPluginIndex()).thenReturn(index);
+ }
+
+ @Test
+ public void shouldWriteIndex() throws IOException {
+ DefaultServerPluginRepository repository = mock(DefaultServerPluginRepository.class);
+ PluginMetadata sqale = newMetadata("sqale");
+ PluginMetadata checkstyle = newMetadata("checkstyle");
+ when(repository.getMetadata()).thenReturn(Arrays.asList(sqale, checkstyle));
+
+ new GeneratePluginIndex(fileSystem, repository).start();
+
+ List<String> lines = FileUtils.readLines(index);
+ assertThat(lines.size(), Is.is(2));
+ assertThat(lines.get(0), containsString("sqale"));
+ assertThat(lines.get(1), containsString("checkstyle"));
+ }
+
+ @Test
+ public void shouldSkipDisabledPlugin() throws IOException {
+ DefaultServerPluginRepository repository = mock(DefaultServerPluginRepository.class);
+ PluginMetadata sqale = newMetadata("sqale");
+ PluginMetadata checkstyle = newMetadata("checkstyle");
+ when(repository.getMetadata()).thenReturn(Arrays.asList(sqale, checkstyle));
+ when(repository.isDisabled("checkstyle")).thenReturn(true);
+
+ new GeneratePluginIndex(fileSystem, repository).start();
+
+ List<String> lines = FileUtils.readLines(index);
+ assertThat(lines.size(), Is.is(1));
+ assertThat(lines.get(0), containsString("sqale"));
+ }
+
+ private PluginMetadata newMetadata(String pluginKey) {
+ PluginMetadata plugin = mock(DefaultPluginMetadata.class);
+ when(plugin.getKey()).thenReturn(pluginKey);
+ when(plugin.getFile()).thenReturn(new File(pluginKey + ".jar"));
+ return plugin;
+ }
+}