diff options
10 files changed, 274 insertions, 103 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java index b8ae7330848..946df51833e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java @@ -29,6 +29,7 @@ import org.sonar.api.BatchComponent; import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.SonarException; import org.sonar.batch.ServerMetadata; +import org.sonar.core.plugins.RemotePlugin; import java.io.File; import java.net.URI; @@ -62,28 +63,36 @@ public class ArtifactDownloader implements BatchComponent { } } - public File downloadPlugin(RemotePluginLocation remote) { - File targetFile = new File(workingDirectories.getDir("plugins/" + remote.getPluginKey()), remote.getFilename()); - String url = baseUrl + "/deploy/plugins/" + remote.getRemotePath(); + public List<File> downloadPlugin(RemotePlugin remote) { try { - FileUtils.forceMkdir(targetFile.getParentFile()); - LOG.info("Download plugin to " + targetFile); - httpDownloader.download(new URI(url), targetFile); - return targetFile; + File targetDir = workingDirectories.getDir("plugins/" + remote.getKey()); + FileUtils.forceMkdir(targetDir); + LOG.info("Downloading plugin " + remote.getKey() + " into " + targetDir); + + List<File> files = Lists.newArrayList(); + for (String filename : remote.getFilenames()) { + String url = baseUrl + "/deploy/plugins/" + remote.getKey() + "/" + filename; + File toFile = new File(targetDir, filename); + httpDownloader.download(new URI(url), toFile); + files.add(toFile); + } + + + return files; } catch (Exception e) { - throw new SonarException("Fail to download extension: " + url, e); + throw new SonarException("Fail to download plugin: " + remote.getKey(), e); } } - public List<RemotePluginLocation> downloadPluginIndex() { + public List<RemotePlugin> downloadPluginIndex() { String url = baseUrl + "/deploy/plugins/index.txt"; try { String indexContent = httpDownloader.downloadPlainText(new URI(url), "UTF-8"); String[] rows = StringUtils.split(indexContent, CharUtils.LF); - List<RemotePluginLocation> remoteLocations = Lists.newArrayList(); + List<RemotePlugin> remoteLocations = Lists.newArrayList(); for (String row : rows) { - remoteLocations.add(RemotePluginLocation.createFromRow(row)); + remoteLocations.add(RemotePlugin.unmarshal(row)); } return remoteLocations; @@ -92,57 +101,4 @@ public class ArtifactDownloader implements BatchComponent { } } - public static final class RemotePluginLocation { - private String pluginKey; - private String remotePath; - private boolean core; - - private RemotePluginLocation(String pluginKey, String remotePath, boolean core) { - this.pluginKey = pluginKey; - this.remotePath = remotePath; - this.core = core; - } - - static RemotePluginLocation create(String key) { - return new RemotePluginLocation(key, null, false); - } - - static RemotePluginLocation createFromRow(String row) { - String[] fields = StringUtils.split(row, ","); - return new RemotePluginLocation(fields[0], fields[1], Boolean.parseBoolean(fields[2])); - } - - public String getPluginKey() { - return pluginKey; - } - - public String getRemotePath() { - return remotePath; - } - - public String getFilename() { - return StringUtils.substringAfterLast(remotePath, "/"); - } - - public boolean isCore() { - return core; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RemotePluginLocation that = (RemotePluginLocation) o; - return pluginKey.equals(that.pluginKey); - } - - @Override - public int hashCode() { - return pluginKey.hashCode(); - } - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java index 2452983bd11..e8d698d2959 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java @@ -34,6 +34,7 @@ import org.sonar.api.platform.PluginMetadata; import org.sonar.api.platform.PluginRepository; import org.sonar.core.plugins.PluginClassloaders; import org.sonar.core.plugins.PluginFileExtractor; +import org.sonar.core.plugins.RemotePlugin; import java.io.File; import java.util.*; @@ -66,13 +67,14 @@ public class BatchPluginRepository implements PluginRepository { doStart(artifactDownloader.downloadPluginIndex()); } - void doStart(List<ArtifactDownloader.RemotePluginLocation> remoteLocations) { + void doStart(List<RemotePlugin> remotePlugins) { PluginFileExtractor extractor = new PluginFileExtractor(); metadataByKey = Maps.newHashMap(); - for (ArtifactDownloader.RemotePluginLocation remoteLocation : remoteLocations) { - if (isAccepted(remoteLocation.getPluginKey())) { - File pluginFile = artifactDownloader.downloadPlugin(remoteLocation); - PluginMetadata metadata = extractor.installInSameLocation(pluginFile, remoteLocation.isCore()); + for (RemotePlugin remote : remotePlugins) { + if (isAccepted(remote.getKey())) { + List<File> pluginFiles = artifactDownloader.downloadPlugin(remote); + List<File> extensionFiles = pluginFiles.subList(1, pluginFiles.size()); + PluginMetadata metadata = extractor.installInSameLocation(pluginFiles.get(0), remote.isCore(), extensionFiles); if (StringUtils.isBlank(metadata.getBasePlugin()) || isAccepted(metadata.getBasePlugin())) { // TODO log when excluding plugin metadataByKey.put(metadata.getKey(), metadata); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java index 9fc772f0dd5..c65cfb61cd5 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java @@ -19,21 +19,23 @@ */ package org.sonar.batch.bootstrap; +import com.google.common.collect.Lists; import org.apache.commons.configuration.PropertiesConfiguration; import org.codehaus.plexus.util.FileUtils; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Test; import org.sonar.api.CoreProperties; +import org.sonar.core.plugins.RemotePlugin; import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.List; import static org.hamcrest.Matchers.not; import static org.hamcrest.core.IsNull.nullValue; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -50,33 +52,34 @@ public class BatchPluginRepositoryTest { @Test public void shouldLoadPlugin() throws IOException { - ArtifactDownloader.RemotePluginLocation checkstyleLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyle"); + RemotePlugin checkstyle = new RemotePlugin("checkstyle", true); ArtifactDownloader downloader = mock(ArtifactDownloader.class); - when(downloader.downloadPlugin(eq(checkstyleLocation))).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar")); + when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar")); repository = new BatchPluginRepository(downloader, new PropertiesConfiguration()); - repository.doStart(Arrays.asList(checkstyleLocation)); + repository.doStart(Arrays.asList(checkstyle)); assertThat(repository.getPlugins().size(), Matchers.is(1)); assertThat(repository.getPlugin("checkstyle"), not(nullValue())); assertThat(repository.getMetadata().size(), Matchers.is(1)); assertThat(repository.getMetadata("checkstyle").getName(), Matchers.is("Checkstyle")); + assertThat(repository.getMetadata("checkstyle").getDeployedFiles().size(), Matchers.is(4)); // plugin + 3 dependencies } @Test public void shouldLoadPluginExtension() throws IOException { - ArtifactDownloader.RemotePluginLocation checkstyleLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyle"); - ArtifactDownloader.RemotePluginLocation checkstyleExtLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyleextensions"); + RemotePlugin checkstyle = new RemotePlugin("checkstyle", true); + RemotePlugin checkstyleExt = new RemotePlugin("checkstyleextensions", false); ArtifactDownloader downloader = mock(ArtifactDownloader.class); - when(downloader.downloadPlugin(eq(checkstyleLocation))).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar")); - when(downloader.downloadPlugin(eq(checkstyleExtLocation))).thenReturn(copyFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar")); + when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar")); + when(downloader.downloadPlugin(checkstyleExt)).thenReturn(copyFiles("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar")); repository = new BatchPluginRepository(downloader, new PropertiesConfiguration()); - repository.doStart(Arrays.asList(checkstyleLocation, checkstyleExtLocation)); + repository.doStart(Arrays.asList(checkstyle, checkstyleExt)); assertThat(repository.getPlugins().size(), Matchers.is(2)); assertThat(repository.getPlugin("checkstyle"), not(nullValue())); @@ -87,30 +90,53 @@ public class BatchPluginRepositoryTest { } @Test + public void shouldLoadPluginDeprecatedExtensions() throws IOException { + RemotePlugin checkstyle = new RemotePlugin("checkstyle", true) + .addFilename("checkstyle-ext.xml"); + + ArtifactDownloader downloader = mock(ArtifactDownloader.class); + when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar", "checkstyle-ext.xml")); + + repository = new BatchPluginRepository(downloader, new PropertiesConfiguration()); + + repository.doStart(Arrays.asList(checkstyle)); + + assertThat(repository.getPlugins().size(), Matchers.is(1)); + assertThat(repository.getPlugin("checkstyle"), not(nullValue())); + assertThat(repository.getMetadata().size(), Matchers.is(1)); + assertThat(repository.getMetadata("checkstyle").getName(), Matchers.is("Checkstyle")); + assertThat(repository.getMetadata("checkstyle").getDeployedFiles().size(), Matchers.is(5)); // plugin + 3 dependencies + 1 deprecated extension + } + + @Test public void shouldExcludePluginAndItsExtensions() throws IOException { - ArtifactDownloader.RemotePluginLocation checkstyleLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyle"); - ArtifactDownloader.RemotePluginLocation checkstyleExtLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyleextensions"); + RemotePlugin checkstyle = new RemotePlugin("checkstyle", true); + RemotePlugin checkstyleExt = new RemotePlugin("checkstyleextensions", false); ArtifactDownloader downloader = mock(ArtifactDownloader.class); - when(downloader.downloadPlugin(eq(checkstyleLocation))).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar")); - when(downloader.downloadPlugin(eq(checkstyleExtLocation))).thenReturn(copyFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar")); + when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFiles("sonar-checkstyle-plugin-2.8.jar")); + when(downloader.downloadPlugin(checkstyleExt)).thenReturn(copyFiles("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar")); PropertiesConfiguration conf = new PropertiesConfiguration(); conf.setProperty(CoreProperties.EXCLUDE_PLUGINS, "checkstyle"); repository = new BatchPluginRepository(downloader, conf); - repository.doStart(Arrays.asList(checkstyleLocation, checkstyleExtLocation)); + repository.doStart(Arrays.asList(checkstyle, checkstyleExt)); assertThat(repository.getPlugins().size(), Matchers.is(0)); assertThat(repository.getMetadata().size(), Matchers.is(0)); } - private File copyFile(String filename) throws IOException { - File file = FileUtils.toFile(getClass().getResource("/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/" + filename)); - File tempDir = new File("target/test-tmp/BatchPluginRepositoryTest"); - FileUtils.forceMkdir(tempDir); - FileUtils.copyFileToDirectory(file, tempDir); - return new File(tempDir, filename); + private List<File> copyFiles(String... filenames) throws IOException { + List files = Lists.newArrayList(); + for (String filename : filenames) { + File file = FileUtils.toFile(getClass().getResource("/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/" + filename)); + File tempDir = new File("target/test-tmp/BatchPluginRepositoryTest"); + FileUtils.forceMkdir(tempDir); + FileUtils.copyFileToDirectory(file, tempDir); + files.add(new File(tempDir, filename)); + } + return files; } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/checkstyle-ext.xml b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/checkstyle-ext.xml new file mode 100644 index 00000000000..75a263db3c3 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/checkstyle-ext.xml @@ -0,0 +1 @@ +<fake/>
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java b/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java index 798cd20bf2b..56cb45aa239 100644 --- a/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java +++ b/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java @@ -20,14 +20,12 @@ package org.sonar.core.plugins; import com.google.common.collect.Lists; -import org.apache.commons.collections.ComparatorUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.sonar.api.platform.PluginMetadata; import java.io.File; -import java.util.ArrayList; import java.util.List; public final class DefaultPluginMetadata implements PluginMetadata, Comparable<PluginMetadata> { @@ -82,6 +80,11 @@ public final class DefaultPluginMetadata implements PluginMetadata, Comparable<P return this; } + public DefaultPluginMetadata setDeprecatedExtensions(List<File> files) { + this.deprecatedExtensions = (files==null ? Lists.<File>newArrayList() : files); + return this; + } + public String[] getPathsToInternalDeps() { return pathsToInternalDeps; } diff --git a/sonar-core/src/main/java/org/sonar/core/plugins/PluginFileExtractor.java b/sonar-core/src/main/java/org/sonar/core/plugins/PluginFileExtractor.java index e248ffd078e..da200c937be 100644 --- a/sonar-core/src/main/java/org/sonar/core/plugins/PluginFileExtractor.java +++ b/sonar-core/src/main/java/org/sonar/core/plugins/PluginFileExtractor.java @@ -20,28 +20,28 @@ package org.sonar.core.plugins; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; import org.sonar.api.Plugin; import org.sonar.api.utils.SonarException; import org.sonar.api.utils.ZipUtils; import org.sonar.updatecenter.common.PluginKeyUtils; import org.sonar.updatecenter.common.PluginManifest; -import javax.swing.plaf.metal.MetalTabbedPaneUI; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; +import java.util.List; import java.util.zip.ZipEntry; public class PluginFileExtractor { - public DefaultPluginMetadata installInSameLocation(File pluginFile, boolean isCore) { - return install(pluginFile, isCore, null); + public DefaultPluginMetadata installInSameLocation(File pluginFile, boolean isCore, List<File> deprecatedExtensions) { + return install(pluginFile, isCore, deprecatedExtensions, null); } - public DefaultPluginMetadata install(File pluginFile, boolean isCore, File toDir) { + public DefaultPluginMetadata install(File pluginFile, boolean isCore, List<File> deprecatedExtensions, File toDir) { DefaultPluginMetadata metadata = extractMetadata(pluginFile, isCore); + metadata.setDeprecatedExtensions(deprecatedExtensions); return install(metadata, toDir); } @@ -78,7 +78,9 @@ public class PluginFileExtractor { for (File extension : metadata.getDeprecatedExtensions()) { File toFile = new File(pluginBasedir, extension.getName()); - FileUtils.copyFile(extension, toFile); + if (!toFile.equals(extension)) { + FileUtils.copyFile(extension, toFile); + } metadata.addDeployedFile(toFile); } @@ -123,7 +125,7 @@ public class PluginFileExtractor { // copy file in a temp directory because Windows+Oracle JVM Classloader lock the JAR file File tempFile = File.createTempFile(pluginFile.getName(), null); FileUtils.copyFile(pluginFile, tempFile); - + URLClassLoader pluginClassLoader = URLClassLoader.newInstance(new URL[]{tempFile.toURI().toURL()}, getClass().getClassLoader()); Plugin pluginInstance = (Plugin) pluginClassLoader.loadClass(mainClass).newInstance(); metadata.setKey(PluginKeyUtils.sanitize(pluginInstance.getKey())); diff --git a/sonar-core/src/main/java/org/sonar/core/plugins/RemotePlugin.java b/sonar-core/src/main/java/org/sonar/core/plugins/RemotePlugin.java new file mode 100644 index 00000000000..bf3477f2663 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/plugins/RemotePlugin.java @@ -0,0 +1,106 @@ +/* + * 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.core.plugins; + +import com.google.common.collect.Lists; +import org.apache.commons.lang.StringUtils; + +import java.io.File; +import java.util.List; + +public class RemotePlugin { + private String pluginKey; + private List<String> filenames = Lists.newArrayList(); + private boolean core; + + public RemotePlugin(String pluginKey, boolean core) { + this.pluginKey = pluginKey; + this.core = core; + } + + public static RemotePlugin create(DefaultPluginMetadata metadata) { + RemotePlugin result = new RemotePlugin(metadata.getKey(), metadata.isCore()); + result.addFilename(metadata.getFile().getName()); + for (File file : metadata.getDeprecatedExtensions()) { + result.addFilename(file.getName()); + } + return result; + } + + public static RemotePlugin unmarshal(String row) { + String[] fields = StringUtils.split(row, ","); + RemotePlugin result = new RemotePlugin(fields[0], Boolean.parseBoolean(fields[1])); + if (fields.length > 2) { + for (int index = 2; index < fields.length; index++) { + result.addFilename(fields[index]); + } + } + return result; + } + + public String marshal() { + StringBuilder sb = new StringBuilder(); + sb.append(pluginKey).append(","); + sb.append(String.valueOf(core)); + for (String filename : filenames) { + sb.append(",").append(filename); + } + return sb.toString(); + } + + public String getKey() { + return pluginKey; + } + + + public boolean isCore() { + return core; + } + + public RemotePlugin addFilename(String s) { + filenames.add(s); + return this; + } + + public List<String> getFilenames() { + return filenames; + } + + public String getPluginFilename() { + return (filenames.size()>0 ? filenames.get(0) : null); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RemotePlugin that = (RemotePlugin) o; + return pluginKey.equals(that.pluginKey); + } + + @Override + public int hashCode() { + return pluginKey.hashCode(); + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/plugins/PluginFileExtractorTest.java b/sonar-core/src/test/java/org/sonar/core/plugins/PluginFileExtractorTest.java index 4923a470ab9..1dff51b0119 100644 --- a/sonar-core/src/test/java/org/sonar/core/plugins/PluginFileExtractorTest.java +++ b/sonar-core/src/test/java/org/sonar/core/plugins/PluginFileExtractorTest.java @@ -64,7 +64,7 @@ public class PluginFileExtractorTest { FileUtils.forceMkdir(toDir); FileUtils.cleanDirectory(toDir); - DefaultPluginMetadata metadata = extractor.install(getFile("sonar-checkstyle-plugin-2.8.jar"), true, toDir); + DefaultPluginMetadata metadata = extractor.install(getFile("sonar-checkstyle-plugin-2.8.jar"), true, null, toDir); assertThat(metadata.getKey(), is("checkstyle")); assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar").exists(), is(true)); @@ -77,7 +77,7 @@ public class PluginFileExtractorTest { FileUtils.forceMkdir(toDir); FileUtils.cleanDirectory(toDir); - extractor.install(getFile("sonar-checkstyle-plugin-2.8.jar"), true, toDir); + extractor.install(getFile("sonar-checkstyle-plugin-2.8.jar"), true, null, toDir); assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar").exists(), is(true)); assertThat(new File(toDir, "META-INF/MANIFEST.MF").exists(), is(false)); diff --git a/sonar-core/src/test/java/org/sonar/core/plugins/RemotePluginTest.java b/sonar-core/src/test/java/org/sonar/core/plugins/RemotePluginTest.java new file mode 100644 index 00000000000..941c9301791 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/plugins/RemotePluginTest.java @@ -0,0 +1,75 @@ +/* + * 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.core.plugins; + +import org.junit.Test; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.matchers.JUnitMatchers.hasItems; + +public class RemotePluginTest { + @Test + public void shouldEqual() { + RemotePlugin clirr1 = new RemotePlugin("clirr", false); + RemotePlugin clirr2 = new RemotePlugin("clirr", false); + RemotePlugin checkstyle = new RemotePlugin("checkstyle", true); + assertThat(clirr1.equals(clirr2), is(true)); + assertThat(clirr1.equals(clirr1), is(true)); + assertThat(clirr1.equals(checkstyle), is(false)); + } + + @Test + public void shouldMarshal() { + RemotePlugin clirr = new RemotePlugin("clirr", false).addFilename("clirr-1.1.jar"); + String text = clirr.marshal(); + assertThat(text, is("clirr,false,clirr-1.1.jar")); + } + + @Test + public void shouldMarshalDeprecatedExtensions() { + RemotePlugin checkstyle = new RemotePlugin("checkstyle", true); + checkstyle.addFilename("checkstyle-2.8.jar"); + checkstyle.addFilename("ext.xml"); + checkstyle.addFilename("ext.jar"); + + String text = checkstyle.marshal(); + assertThat(text, is("checkstyle,true,checkstyle-2.8.jar,ext.xml,ext.jar")); + } + + @Test + public void shouldUnmarshal() { + RemotePlugin clirr = RemotePlugin.unmarshal("clirr,false,clirr-1.1.jar"); + assertThat(clirr.getKey(), is("clirr")); + assertThat(clirr.isCore(), is(false)); + assertThat(clirr.getFilenames().size(), is(1)); + assertThat(clirr.getFilenames().get(0), is("clirr-1.1.jar")); + + } + + @Test + public void shouldUnmarshalDeprecatedExtensions() { + RemotePlugin checkstyle = RemotePlugin.unmarshal("checkstyle,true,checkstyle-2.8.jar,ext.xml,ext.jar"); + assertThat(checkstyle.getKey(), is("checkstyle")); + assertThat(checkstyle.isCore(), is(true)); + assertThat(checkstyle.getFilenames().size(), is(3)); + assertThat(checkstyle.getFilenames(), hasItems("checkstyle-2.8.jar", "ext.xml", "ext.jar")); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java index 97581b89791..b39126da4bb 100644 --- a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java +++ b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java @@ -34,6 +34,7 @@ import org.sonar.api.utils.SonarException; 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; @@ -154,9 +155,8 @@ public final class PluginDeployer implements ServerComponent { FileWriter writer = new FileWriter(indexFile, false); try { for (PluginMetadata metadata : pluginByKeys.values()) { - writer.append(metadata.getKey()).append(","); - writer.append(metadata.getKey()).append("/").append(metadata.getFile().getName()).append(","); - writer.append(String.valueOf(metadata.isCore())).append(CharUtils.LF); + writer.append(RemotePlugin.create((DefaultPluginMetadata)metadata).marshal()); + writer.append(CharUtils.LF); } writer.flush(); |