import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.IocContainer;
import org.sonar.api.utils.ServerHttpClient;
+import org.sonar.batch.bootstrap.BatchPluginRepository;
+import org.sonar.batch.bootstrap.BootstrapClassLoader;
+import org.sonar.batch.bootstrap.ExtensionDownloader;
+import org.sonar.batch.bootstrap.TempDirectories;
import org.sonar.batch.index.*;
import org.sonar.core.components.CacheMetricFinder;
import org.sonar.core.components.CacheRuleFinder;
try {
container = buildPicoContainer();
container.start();
- analyzeProjects(container);
+ analyzeModules(container);
} finally {
if (container != null) {
}
}
- private void analyzeProjects(MutablePicoContainer container) {
+ private void analyzeModules(MutablePicoContainer container) {
// a child container is built to ensure database connector is up
MutablePicoContainer batchContainer = container.makeChildContainer();
- batchContainer.as(Characteristics.CACHE).addComponent(ServerMetadata.class);
batchContainer.as(Characteristics.CACHE).addComponent(ProjectTree.class);
batchContainer.as(Characteristics.CACHE).addComponent(DefaultResourceCreationLock.class);
batchContainer.as(Characteristics.CACHE).addComponent(DefaultIndex.class);
batchContainer.as(Characteristics.CACHE).addComponent(BatchPluginRepository.class);
batchContainer.as(Characteristics.CACHE).addComponent(Plugins.class);
batchContainer.as(Characteristics.CACHE).addComponent(ServerHttpClient.class);
- batchContainer.as(Characteristics.CACHE).addComponent(HttpDownloader.class);
batchContainer.as(Characteristics.CACHE).addComponent(MeasuresDao.class);
batchContainer.as(Characteristics.CACHE).addComponent(CacheRuleFinder.class);
batchContainer.as(Characteristics.CACHE).addComponent(CacheMetricFinder.class);
ProjectTree projectTree = batchContainer.getComponent(ProjectTree.class);
DefaultIndex index = batchContainer.getComponent(DefaultIndex.class);
- analyzeProject(batchContainer, index, projectTree.getRootProject());
+ analyzeModule(batchContainer, index, projectTree.getRootProject());
// batchContainer is stopped by its parent
}
MutablePicoContainer container = IocContainer.buildPicoContainer();
register(container, configuration);
- URLClassLoader fullClassloader = RemoteClassLoader.createForJdbcDriver(configuration).getClassLoader();
+ register(container, ServerMetadata.class);// registered here because used by BootstrapClassLoader
+ register(container, TempDirectories.class);// registered here because used by BootstrapClassLoader
+ register(container, HttpDownloader.class);// registered here because used by BootstrapClassLoader
+ register(container, ExtensionDownloader.class);// registered here because used by BootstrapClassLoader
+ register(container, BootstrapClassLoader.class);
+
+ URLClassLoader bootstrapClassLoader = container.getComponent(BootstrapClassLoader.class).getClassLoader();
// set as the current context classloader for hibernate, else it does not find the JDBC driver.
- Thread.currentThread().setContextClassLoader(fullClassloader);
+ Thread.currentThread().setContextClassLoader(bootstrapClassLoader);
- register(container, new DriverDatabaseConnector(configuration, fullClassloader));
+ register(container, new DriverDatabaseConnector(configuration, bootstrapClassLoader));
register(container, ThreadLocalDatabaseSessionFactory.class);
container.as(Characteristics.CACHE).addAdapter(new DatabaseSessionProvider());
for (Object component : components) {
container.as(Characteristics.CACHE).addComponent(component);
}
- private void analyzeProject(MutablePicoContainer container, DefaultIndex index, Project project) {
+ private void analyzeModule(MutablePicoContainer container, DefaultIndex index, Project project) {
for (Project module : project.getModules()) {
- analyzeProject(container, index, module);
+ analyzeModule(container, index, module);
}
LOG.info("------------- Analyzing {}", project.getName());
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2009 SonarSource SA
- * 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.batch;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.picocontainer.MutablePicoContainer;
-import org.picocontainer.PicoContainer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.Plugin;
-import org.sonar.api.batch.AbstractCoverageExtension;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.SonarException;
-import org.sonar.core.classloaders.ClassLoadersCollection;
-import org.sonar.core.plugin.AbstractPluginRepository;
-import org.sonar.core.plugin.JpaPlugin;
-import org.sonar.core.plugin.JpaPluginDao;
-import org.sonar.core.plugin.JpaPluginFile;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-public class BatchPluginRepository extends AbstractPluginRepository {
-
- private static final Logger LOG = LoggerFactory.getLogger(BatchPluginRepository.class);
-
- private String baseUrl;
- private JpaPluginDao dao;
-
- private ClassLoadersCollection classLoaders;
-
- public BatchPluginRepository(JpaPluginDao dao, ServerMetadata server) {
- this.dao = dao;
- this.baseUrl = server.getURL() + "/deploy/plugins/";
- }
-
- /**
- * for unit tests only
- */
- BatchPluginRepository() {
-
- }
-
- public void start() {
- classLoaders = new ClassLoadersCollection(Thread.currentThread().getContextClassLoader());
- for (JpaPlugin pluginMetadata : dao.getPlugins()) {
- String key = pluginMetadata.getKey();
- List<URL> urls = Lists.newArrayList();
- for (JpaPluginFile pluginFile : pluginMetadata.getFiles()) {
- try {
- URL url = new URL(baseUrl + pluginFile.getPath());
- urls.add(url);
- } catch (MalformedURLException e) {
- throw new SonarException("Can not build the classloader of the plugin " + pluginFile.getPluginKey(), e);
- }
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("Classloader of plugin " + key + ":");
- for (URL url : urls) {
- LOG.debug(" -> " + url);
- }
- }
- classLoaders.createClassLoader(key, urls, pluginMetadata.isUseChildFirstClassLoader() == Boolean.TRUE);
- }
- classLoaders.done();
- }
-
- public void registerPlugins(MutablePicoContainer pico) {
- for (JpaPlugin pluginMetadata : dao.getPlugins()) {
- try {
- Class claz = classLoaders.get(pluginMetadata.getKey()).loadClass(pluginMetadata.getPluginClass());
- Plugin plugin = (Plugin) claz.newInstance();
- registerPlugin(pico, plugin, pluginMetadata.getKey());
-
- } catch (Exception e) {
- throw new SonarException("Fail to load extensions from plugin " + pluginMetadata.getKey(), e);
- }
- }
- invokeExtensionProviders(pico);
- }
-
- @Override
- protected boolean shouldRegisterExtension(PicoContainer container, String pluginKey, Object extension) {
- boolean ok = isType(extension, BatchExtension.class);
- if (ok && isType(extension, AbstractCoverageExtension.class)) {
- ok = shouldRegisterCoverageExtension(pluginKey, container.getComponent(Project.class), container.getComponent(Configuration.class));
- if ( !ok) {
- LOG.debug("The following extension is ignored: " + extension + ". See the parameter " + AbstractCoverageExtension.PARAM_PLUGIN);
- }
- }
- return ok;
- }
-
- boolean shouldRegisterCoverageExtension(String pluginKey, Project project, Configuration conf) {
- boolean ok = true;
- if (StringUtils.equals(project.getLanguageKey(), Java.KEY)) {
- String[] selectedPluginKeys = conf.getStringArray(AbstractCoverageExtension.PARAM_PLUGIN);
- if (ArrayUtils.isEmpty(selectedPluginKeys)) {
- selectedPluginKeys = new String[] { AbstractCoverageExtension.DEFAULT_PLUGIN };
- }
- ok = ArrayUtils.contains(selectedPluginKeys, pluginKey);
- }
- return ok;
- }
-}
import org.sonar.api.rules.DefaultRulesManager;
import org.sonar.api.utils.IocContainer;
import org.sonar.api.utils.SonarException;
+import org.sonar.batch.bootstrap.BatchPluginRepository;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.DefaultResourcePersister;
import org.sonar.batch.phases.Phases;
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2009 SonarSource SA
- * 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.batch;
-
-import org.apache.commons.configuration.Configuration;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Collection;
-
-/**
- * Create classloader from remote URLs.
- *
- * IMPORTANT : it generates URLClassLoaders, which use the parent first delegation mode. It finds classes in the parent classloader THEN
- * in the plugin classloader.
- * Using a child-first delegation mode can avoid some conflicts with API dependencies (xml-api, antlr). It's
- * not possible for now, but it would be simple to implement by replacing the URLClassLoader by
- * the class ChildFirstClassLoader (see http://articles.qos.ch/classloader.html)
- */
-public class RemoteClassLoader {
-
- private URLClassLoader classLoader;
-
- public RemoteClassLoader(URL[] urls, ClassLoader parent) {
- ClassLoader parentClassLoader = (parent==null ? RemoteClassLoader.class.getClassLoader() : parent);
- classLoader = URLClassLoader.newInstance(urls, parentClassLoader);
- }
-
- public RemoteClassLoader(URL[] urls) {
- this(urls, null);
- }
-
- public RemoteClassLoader(Collection<URL> urls, ClassLoader parent) {
- this(urls.toArray(new URL[urls.size()]), parent);
- }
-
- public URLClassLoader getClassLoader() {
- return classLoader;
- }
-
- public static RemoteClassLoader createForJdbcDriver(Configuration conf) {
- String baseUrl = ServerMetadata.getURL(conf);
- String url = baseUrl + "/deploy/jdbc-driver.jar";
- try {
- return new RemoteClassLoader(new URL[]{new URL(url)});
-
- } catch (MalformedURLException e) {
- throw new RuntimeException("Fail to download the JDBC driver from server: " + url, e);
- }
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.PicoContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.Plugin;
+import org.sonar.api.batch.AbstractCoverageExtension;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.SonarException;
+import org.sonar.core.classloaders.ClassLoadersCollection;
+import org.sonar.core.plugin.AbstractPluginRepository;
+import org.sonar.core.plugin.JpaPlugin;
+import org.sonar.core.plugin.JpaPluginDao;
+import org.sonar.core.plugin.JpaPluginFile;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+public class BatchPluginRepository extends AbstractPluginRepository {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BatchPluginRepository.class);
+
+ private JpaPluginDao dao;
+
+ private ClassLoadersCollection classLoaders;
+ private ExtensionDownloader extensionDownloader;
+
+ public BatchPluginRepository(JpaPluginDao dao, ExtensionDownloader extensionDownloader) {
+ this.dao = dao;
+ this.extensionDownloader = extensionDownloader;
+ }
+
+ /**
+ * for unit tests only
+ */
+ BatchPluginRepository() {
+
+ }
+
+ public void start() {
+ classLoaders = new ClassLoadersCollection(Thread.currentThread().getContextClassLoader());
+ for (JpaPlugin pluginMetadata : dao.getPlugins()) {
+ String key = pluginMetadata.getKey();
+ List<URL> urls = Lists.newArrayList();
+ for (JpaPluginFile pluginFile : pluginMetadata.getFiles()) {
+ File file = extensionDownloader.downloadExtension(pluginFile);
+ try {
+ urls.add(file.toURI().toURL());
+
+ } catch (MalformedURLException e) {
+ throw new SonarException("Can not get the URL of: " + file, e);
+ }
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Classloader of plugin " + key + ":");
+ for (URL url : urls) {
+ LOG.debug(" -> " + url);
+ }
+ }
+ classLoaders.createClassLoader(key, urls, pluginMetadata.isUseChildFirstClassLoader() == Boolean.TRUE);
+ }
+ classLoaders.done();
+ }
+
+ public void registerPlugins(MutablePicoContainer pico) {
+ for (JpaPlugin pluginMetadata : dao.getPlugins()) {
+ try {
+ Class claz = classLoaders.get(pluginMetadata.getKey()).loadClass(pluginMetadata.getPluginClass());
+ Plugin plugin = (Plugin) claz.newInstance();
+ registerPlugin(pico, plugin, pluginMetadata.getKey());
+
+ } catch (Exception e) {
+ throw new SonarException("Fail to load extensions from plugin " + pluginMetadata.getKey(), e);
+ }
+ }
+ invokeExtensionProviders(pico);
+ }
+
+ @Override
+ protected boolean shouldRegisterExtension(PicoContainer container, String pluginKey, Object extension) {
+ boolean ok = isType(extension, BatchExtension.class);
+ if (ok && isType(extension, AbstractCoverageExtension.class)) {
+ ok = shouldRegisterCoverageExtension(pluginKey, container.getComponent(Project.class), container.getComponent(Configuration.class));
+ if ( !ok) {
+ LOG.debug("The following extension is ignored: " + extension + ". See the parameter " + AbstractCoverageExtension.PARAM_PLUGIN);
+ }
+ }
+ return ok;
+ }
+
+ boolean shouldRegisterCoverageExtension(String pluginKey, Project project, Configuration conf) {
+ boolean ok = true;
+ if (StringUtils.equals(project.getLanguageKey(), Java.KEY)) {
+ String[] selectedPluginKeys = conf.getStringArray(AbstractCoverageExtension.PARAM_PLUGIN);
+ if (ArrayUtils.isEmpty(selectedPluginKeys)) {
+ selectedPluginKeys = new String[] { AbstractCoverageExtension.DEFAULT_PLUGIN };
+ }
+ ok = ArrayUtils.contains(selectedPluginKeys, pluginKey);
+ }
+ return ok;
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * ClassLoader extended with the JDBC Driver hosted on the server-side.
+ */
+public class BootstrapClassLoader {
+
+ private URLClassLoader classLoader;
+
+ public BootstrapClassLoader(ExtensionDownloader extensionDownloader) {
+ this(extensionDownloader.downloadJdbcDriver());
+ }
+
+ BootstrapClassLoader(File jdbcDriver) {
+ try {
+ ClassLoader parentClassLoader = BootstrapClassLoader.class.getClassLoader();
+ classLoader = URLClassLoader.newInstance(new URL[]{jdbcDriver.toURI().toURL()}, parentClassLoader);
+
+ } catch (MalformedURLException e) {
+ throw new SonarException("Fail to get URL of : " + jdbcDriver.getAbsolutePath(), e);
+ }
+ }
+
+ public URLClassLoader getClassLoader() {
+ return classLoader;
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.HttpDownloader;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.ServerMetadata;
+import org.sonar.core.plugin.JpaPluginFile;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public final class ExtensionDownloader {
+
+ private HttpDownloader httpDownloader;
+ private TempDirectories workingDirectories;
+ private String baseUrl;
+
+ public ExtensionDownloader(HttpDownloader httpDownloader, TempDirectories workingDirectories, ServerMetadata server) {
+ this.httpDownloader = httpDownloader;
+ this.workingDirectories = workingDirectories;
+ this.baseUrl = server.getURL();
+ }
+
+ public File downloadJdbcDriver() {
+ String url = baseUrl + "/deploy/jdbc-driver.jar";
+ try {
+ File jdbcDriver = new File(workingDirectories.getRoot(), "jdbc-driver.jar");
+ LoggerFactory.getLogger(getClass()).debug("Download JDBC Driver from " + url + " to " + jdbcDriver.getAbsolutePath());
+ httpDownloader.download(new URI(url), jdbcDriver);
+ return jdbcDriver;
+
+ } catch (URISyntaxException e) {
+ throw new SonarException("Fail to download the JDBC driver from : " + url, e);
+ }
+ }
+
+ public File downloadExtension(JpaPluginFile extension) {
+ File targetFile = new File(workingDirectories.getDir(extension.getPluginKey()), extension.getFilename());
+ String url = baseUrl + "/deploy/plugins/" + extension.getPluginKey() + "/" + extension.getFilename();
+ LoggerFactory.getLogger(getClass()).debug("Download " + url + " to " + targetFile.getAbsolutePath());
+ try {
+ httpDownloader.download(new URI(url), targetFile);
+ return targetFile;
+
+ } catch (URISyntaxException e) {
+ throw new SonarException("Can not download extension: " + url, e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.TempFileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+public final class TempDirectories {
+
+ private File rootDir;
+ private Map<String, File> directoriesByKey = Maps.newHashMap();
+
+ public TempDirectories() throws IOException {
+ this.rootDir = TempFileUtils.createTempDirectory("sonar-batch");
+ LoggerFactory.getLogger(getClass()).debug("Temporary directory: " + rootDir.getAbsolutePath());
+ }
+
+ public File getRoot() {
+ return rootDir;
+ }
+
+ /**
+ * Get or create a working directory
+ */
+ public File getDir(String key) {
+ if (StringUtils.isBlank(key)) {
+ return rootDir;
+ }
+
+ File dir = directoriesByKey.get(key);
+ if (dir == null) {
+ dir = new File(rootDir, key);
+ try {
+ FileUtils.forceMkdir(dir);
+ directoriesByKey.put(key, dir);
+
+ } catch (IOException e) {
+ throw new SonarException("Can not create the temp directory: " + dir, e);
+ }
+ }
+ return dir;
+ }
+
+ public File getFile(String directoryKey, String filename) {
+ File dir = getDir(directoryKey);
+ return new File(dir, filename);
+ }
+
+ /**
+ * This method is executed by picocontainer during shutdown.
+ */
+ public void stop() {
+ directoriesByKey.clear();
+ LoggerFactory.getLogger(getClass()).debug("Delete temporary directory: " + rootDir.getAbsolutePath());
+ FileUtils.deleteQuietly(rootDir);
+ }
+}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2009 SonarSource SA
- * 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.batch;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.junit.Test;
-import org.picocontainer.MutablePicoContainer;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.ServerExtension;
-import org.sonar.api.batch.AbstractCoverageExtension;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.IocContainer;
-
-public class BatchPluginRepositoryTest {
-
- @Test
- public void shouldRegisterBatchExtension() {
- MutablePicoContainer pico = IocContainer.buildPicoContainer();
- pico.addComponent(new PropertiesConfiguration());
- BatchPluginRepository repository = new BatchPluginRepository();
-
- // check classes
- assertThat(repository.shouldRegisterExtension(pico, "foo", FakeBatchExtension.class), is(true));
- assertThat(repository.shouldRegisterExtension(pico, "foo", FakeServerExtension.class), is(false));
- assertThat(repository.shouldRegisterExtension(pico, "foo", String.class), is(false));
-
- // check objects
- assertThat(repository.shouldRegisterExtension(pico, "foo", new FakeBatchExtension()), is(true));
- assertThat(repository.shouldRegisterExtension(pico, "foo", new FakeServerExtension()), is(false));
- assertThat(repository.shouldRegisterExtension(pico, "foo", "bar"), is(false));
- }
-
- @Test
- public void shouldRegisterOnlyCoberturaExtensionByDefault() {
- BatchPluginRepository repository = new BatchPluginRepository();
- PropertiesConfiguration conf = new PropertiesConfiguration();
- assertThat(repository.shouldRegisterCoverageExtension("cobertura", newJavaProject(), conf), is(true));
- assertThat(repository.shouldRegisterCoverageExtension("clover", newJavaProject(), conf), is(false));
- }
-
- @Test
- public void shouldRegisterCustomCoverageExtension() {
- Configuration conf = new PropertiesConfiguration();
- conf.setProperty(AbstractCoverageExtension.PARAM_PLUGIN, "clover,phpunit");
- BatchPluginRepository repository = new BatchPluginRepository();
- assertThat(repository.shouldRegisterCoverageExtension("cobertura", newJavaProject(), conf), is(false));
- assertThat(repository.shouldRegisterCoverageExtension("clover", newJavaProject(), conf), is(true));
- assertThat(repository.shouldRegisterCoverageExtension("phpunit", newJavaProject(), conf), is(true));
- assertThat(repository.shouldRegisterCoverageExtension("other", newJavaProject(), conf), is(false));
- }
-
- @Test
- public void shouldNotCheckCoverageExtensionsOnNonJavaProjects() {
- Configuration conf = new PropertiesConfiguration();
- conf.setProperty(AbstractCoverageExtension.PARAM_PLUGIN, "cobertura");
- BatchPluginRepository repository = new BatchPluginRepository();
-
- assertThat(repository.shouldRegisterCoverageExtension("groovy", newGroovyProject(), conf), is(true));
- assertThat(repository.shouldRegisterCoverageExtension("groovy", newJavaProject(), conf), is(false));
- }
-
- private static Project newJavaProject() {
- return new Project("foo").setLanguageKey(Java.KEY);
- }
-
- private static Project newGroovyProject() {
- return new Project("foo").setLanguageKey("grvy");
- }
-
- public static class FakeBatchExtension implements BatchExtension {
-
- }
-
- public static class FakeServerExtension implements ServerExtension {
-
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2009 SonarSource SA
- * 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.batch;
-
-import org.junit.Test;
-
-import java.net.URL;
-import java.util.Arrays;
-
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-
-public class RemoteClassLoaderTest {
-
- @Test
- public void testClassLoader() {
- /* foo.jar has just one file /foo/foo.txt */
- assertNull(getClass().getClassLoader().getResource("foo/foo.txt"));
-
- URL url = getClass().getResource("/org/sonar/batch/RemoteClassLoaderTest/foo.jar");
- RemoteClassLoader classloader = new RemoteClassLoader(Arrays.asList(url), null);
- assertNotNull(classloader.getClassLoader());
- assertNotNull(classloader.getClassLoader().getResource("foo/foo.txt"));
-
- }
-}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.junit.Test;
+import org.picocontainer.MutablePicoContainer;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.batch.AbstractCoverageExtension;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.IocContainer;
+import org.sonar.batch.bootstrap.BatchPluginRepository;
+
+public class BatchPluginRepositoryTest {
+
+ @Test
+ public void shouldRegisterBatchExtension() {
+ MutablePicoContainer pico = IocContainer.buildPicoContainer();
+ pico.addComponent(new PropertiesConfiguration());
+ BatchPluginRepository repository = new BatchPluginRepository();
+
+ // check classes
+ assertThat(repository.shouldRegisterExtension(pico, "foo", FakeBatchExtension.class), is(true));
+ assertThat(repository.shouldRegisterExtension(pico, "foo", FakeServerExtension.class), is(false));
+ assertThat(repository.shouldRegisterExtension(pico, "foo", String.class), is(false));
+
+ // check objects
+ assertThat(repository.shouldRegisterExtension(pico, "foo", new FakeBatchExtension()), is(true));
+ assertThat(repository.shouldRegisterExtension(pico, "foo", new FakeServerExtension()), is(false));
+ assertThat(repository.shouldRegisterExtension(pico, "foo", "bar"), is(false));
+ }
+
+ @Test
+ public void shouldRegisterOnlyCoberturaExtensionByDefault() {
+ BatchPluginRepository repository = new BatchPluginRepository();
+ PropertiesConfiguration conf = new PropertiesConfiguration();
+ assertThat(repository.shouldRegisterCoverageExtension("cobertura", newJavaProject(), conf), is(true));
+ assertThat(repository.shouldRegisterCoverageExtension("clover", newJavaProject(), conf), is(false));
+ }
+
+ @Test
+ public void shouldRegisterCustomCoverageExtension() {
+ Configuration conf = new PropertiesConfiguration();
+ conf.setProperty(AbstractCoverageExtension.PARAM_PLUGIN, "clover,phpunit");
+ BatchPluginRepository repository = new BatchPluginRepository();
+ assertThat(repository.shouldRegisterCoverageExtension("cobertura", newJavaProject(), conf), is(false));
+ assertThat(repository.shouldRegisterCoverageExtension("clover", newJavaProject(), conf), is(true));
+ assertThat(repository.shouldRegisterCoverageExtension("phpunit", newJavaProject(), conf), is(true));
+ assertThat(repository.shouldRegisterCoverageExtension("other", newJavaProject(), conf), is(false));
+ }
+
+ @Test
+ public void shouldNotCheckCoverageExtensionsOnNonJavaProjects() {
+ Configuration conf = new PropertiesConfiguration();
+ conf.setProperty(AbstractCoverageExtension.PARAM_PLUGIN, "cobertura");
+ BatchPluginRepository repository = new BatchPluginRepository();
+
+ assertThat(repository.shouldRegisterCoverageExtension("groovy", newGroovyProject(), conf), is(true));
+ assertThat(repository.shouldRegisterCoverageExtension("groovy", newJavaProject(), conf), is(false));
+ }
+
+ private static Project newJavaProject() {
+ return new Project("foo").setLanguageKey(Java.KEY);
+ }
+
+ private static Project newGroovyProject() {
+ return new Project("foo").setLanguageKey("grvy");
+ }
+
+ public static class FakeBatchExtension implements BatchExtension {
+
+ }
+
+ public static class FakeServerExtension implements ServerExtension {
+
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+public class BootstrapClassLoaderTest {
+
+ @Test
+ public void testClassLoader() throws URISyntaxException {
+ /* foo.jar has just one file /foo/foo.txt */
+ assertNull(getClass().getClassLoader().getResource("foo/foo.txt"));
+
+ URL url = getClass().getResource("/org/sonar/batch/bootstrap/BootstrapClassLoaderTest/foo.jar");
+ BootstrapClassLoader classloader = new BootstrapClassLoader(new File(url.toURI()));
+ assertNotNull(classloader.getClassLoader());
+ assertNotNull(classloader.getClassLoader().getResource("foo/foo.txt"));
+
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import org.junit.Test;
+import org.sonar.api.utils.HttpDownloader;
+import org.sonar.batch.ServerMetadata;
+import org.sonar.core.plugin.JpaPlugin;
+import org.sonar.core.plugin.JpaPluginFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.*;
+
+public class ExtensionDownloaderTest {
+
+ @Test
+ public void shouldDownloadJdbcDriver() throws IOException, URISyntaxException {
+ ServerMetadata server = mock(ServerMetadata.class);
+ when(server.getURL()).thenReturn("http://sonar:8000");
+
+ HttpDownloader httpDownloader = mock(HttpDownloader.class);
+ TempDirectories workingDirectories = new TempDirectories();
+
+ ExtensionDownloader downloader = new ExtensionDownloader(httpDownloader, workingDirectories, server);
+ File jdbcDriver = downloader.downloadJdbcDriver();
+
+ assertNotNull(jdbcDriver);
+ verify(httpDownloader).download(new URI("http://sonar:8000/deploy/jdbc-driver.jar"), jdbcDriver);
+ }
+
+ @Test
+ public void shouldDownloadExtension() throws IOException, URISyntaxException {
+ ServerMetadata server = mock(ServerMetadata.class);
+ when(server.getURL()).thenReturn("http://sonar:8000");
+
+ HttpDownloader httpDownloader = mock(HttpDownloader.class);
+ TempDirectories workingDirectories = new TempDirectories();
+
+ ExtensionDownloader downloader = new ExtensionDownloader(httpDownloader, workingDirectories, server);
+ JpaPluginFile extension = new JpaPluginFile(new JpaPlugin("findbugs"), "bcel.jar");
+ File bcel = downloader.downloadExtension(extension);
+
+ assertNotNull(bcel);
+ verify(httpDownloader).download(new URI("http://sonar:8000/deploy/plugins/findbugs/bcel.jar"), bcel);
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * 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.batch.bootstrap;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+public class TempDirectoriesTest {
+
+ private TempDirectories tempDirectories;
+
+ @Before
+ public void before() throws IOException {
+ tempDirectories = new TempDirectories();
+ }
+
+ @After
+ public void after() throws IOException {
+ if (tempDirectories != null) {
+ tempDirectories.stop();
+ }
+ }
+
+ @Test
+ public void shouldCreateRoot() throws IOException {
+ assertNotNull(tempDirectories.getRoot());
+ assertThat(tempDirectories.getRoot().exists(), is(true));
+ assertThat(tempDirectories.getRoot().isDirectory(), is(true));
+ }
+
+ @Test
+ public void shouldCreateDirectory() throws IOException {
+ File findbugsDir = tempDirectories.getDir("findbugs");
+ assertNotNull(findbugsDir);
+ assertThat(findbugsDir.exists(), is(true));
+ assertThat(findbugsDir.getParentFile(), is(tempDirectories.getRoot()));
+ assertThat(findbugsDir.getName(), is("findbugs"));
+ }
+
+ @Test
+ public void shouldStopAndDeleteDirectory() throws IOException {
+ File root = tempDirectories.getRoot();
+ File findbugsDir = tempDirectories.getDir("findbugs");
+ assertThat(findbugsDir.exists(), is(true));
+
+ tempDirectories.stop();
+
+ assertThat(root.exists(), is(false));
+ assertThat(findbugsDir.exists(), is(false));
+ }
+
+ @Test
+ public void shouldCreateDirectoryWhenGettingFile() {
+ File file = tempDirectories.getFile("findbugs", "bcel.jar");
+ assertNotNull(file);
+ assertThat(file.getParentFile().getName(), is("findbugs"));
+ }
+}