]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2507 support deprecated directory /extensions/rules/
authorsimonbrandhof <simon.brandhof@gmail.com>
Fri, 10 Jun 2011 12:06:37 +0000 (14:06 +0200)
committersimonbrandhof <simon.brandhof@gmail.com>
Fri, 10 Jun 2011 12:06:37 +0000 (14:06 +0200)
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java
sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/checkstyle-ext.xml [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java
sonar-core/src/main/java/org/sonar/core/plugins/PluginFileExtractor.java
sonar-core/src/main/java/org/sonar/core/plugins/RemotePlugin.java [new file with mode: 0644]
sonar-core/src/test/java/org/sonar/core/plugins/PluginFileExtractorTest.java
sonar-core/src/test/java/org/sonar/core/plugins/RemotePluginTest.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java

index b8ae733084838dbacc4ba3f3ae9c6f2739fed451..946df51833ea220bf8920ec1fb7f5c9f26e6f472 100644 (file)
@@ -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();
-    }
-  }
 }
index 2452983bd11eea3036bd34aa30b28568ba755e67..e8d698d29596269869336417002dc1b556abe1a6 100644 (file)
@@ -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);
index 9fc772f0dd5c3c782b1ab293a44672269bc6aa27..c65cfb61cd53cfc4669220cea19de25ef470298d 100644 (file)
 */
 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()));
@@ -86,31 +89,54 @@ public class BatchPluginRepositoryTest {
     assertThat(repository.getMetadata("checkstyleextensions").getVersion(), Matchers.is("0.1-SNAPSHOT"));
   }
 
+  @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 (file)
index 0000000..75a263d
--- /dev/null
@@ -0,0 +1 @@
+<fake/>
\ No newline at end of file
index 798cd20bf2b72ca8ba3c6831736986ab7319d168..56cb45aa239929edaa4fc3fdc31f7c982bd9101c 100644 (file)
 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;
   }
index e248ffd078e8956c416620795a2bd2090259c786..da200c937bee3607d8951685307b5d01a47e1088 100644 (file)
 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 (file)
index 0000000..bf3477f
--- /dev/null
@@ -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();
+  }
+}
index 4923a470ab9cc23c6a47b9711dfe3ab125ad98ac..1dff51b01192918fcb704e539fb1e0267f336813 100644 (file)
@@ -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 (file)
index 0000000..941c930
--- /dev/null
@@ -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"));
+  }
+}
index 97581b89791cb78ad778c90c4114c90ab6356fe4..b39126da4bb140f5b04969b61d25213fab47020a 100644 (file)
@@ -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();