aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/sonar-update-center/sonar-update-center-server
diff options
context:
space:
mode:
authorsimonbrandhof <simon.brandhof@gmail.com>2010-09-06 14:08:06 +0000
committersimonbrandhof <simon.brandhof@gmail.com>2010-09-06 14:08:06 +0000
commitaeadc1f9129274949daaa57738c7c4550bdfbc7b (patch)
tree08dadf5ef7474fc41d1d48f74648f1ba8b55f34d /subprojects/sonar-update-center/sonar-update-center-server
downloadsonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.tar.gz
sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.zip
SONAR-236 remove deprecated code from checkstyle plugin + display default value of rule parameters in Q profile console
Diffstat (limited to 'subprojects/sonar-update-center/sonar-update-center-server')
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/pom.xml134
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/History.java56
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Plugin.java206
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Sonar.java58
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateCenter.java318
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateInfo.java42
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Versioned.java27
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Configuration.java94
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/HttpDownloader.java102
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/MetadataFile.java72
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Server.java83
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/log4j.properties6
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugin-info-widget-template.html46
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugins.txt38
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/style.css29
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/HistoryTest.java53
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/PluginTest.java60
-rw-r--r--subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/SonarTest.java41
18 files changed, 1465 insertions, 0 deletions
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/pom.xml b/subprojects/sonar-update-center/sonar-update-center-server/pom.xml
new file mode 100644
index 00000000000..ad5f9faa4aa
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/pom.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-update-center</artifactId>
+ <version>0.3-SNAPSHOT</version>
+ </parent>
+ <artifactId>sonar-update-center-server</artifactId>
+ <name>Sonar :: Update Center :: Server</name>
+
+ <properties>
+ <maven.version>3.0-beta-1</maven.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-update-center-common</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.thoughtworks.xstream</groupId>
+ <artifactId>xstream</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>xpp3</groupId>
+ <artifactId>xpp3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.5.6</version>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>0.9.15</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http</artifactId>
+ <version>1.0-beta-5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.googlecode.json-simple</groupId>
+ <artifactId>json-simple</artifactId>
+ <version>1.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>args4j</groupId>
+ <artifactId>args4j</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+
+
+ <!-- experimental -->
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.0.1</version>
+ </dependency>
+
+
+ <!-- unit tests -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <configuration>
+ <mainClass>org.sonar.updatecenter.deprecated.UpdateCenter</mainClass>
+ <arguments>
+ <argument>-d</argument>
+ <argument>${project.basedir}/target/site</argument>
+ </arguments>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>wagon-maven-plugin</artifactId>
+ <configuration>
+ <serverId>sonar-plugins</serverId>
+ <fromDir>${project.basedir}/target/site</fromDir>
+ <includes>**</includes>
+ <url>dav:https://dav.codehaus.org/dist/sonar-plugins/update-center</url>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/History.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/History.java
new file mode 100644
index 00000000000..f9b4de9e11d
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/History.java
@@ -0,0 +1,56 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Information about release history, discovered from Maven repository.
+ *
+ * @author Evgeny Mandrikov
+ */
+public class History<M extends Versioned> {
+
+ private TreeMap<ArtifactVersion, M> artifacts = new TreeMap<ArtifactVersion, M>();
+
+ public History() {
+ }
+
+ public Set<ArtifactVersion> getAllVersions() {
+ return artifacts.keySet();
+ }
+
+ /**
+ * @return latest version of plugin
+ */
+ public M latest() {
+ if (artifacts.size() == 0) {
+ return null;
+ }
+ return artifacts.get(artifacts.lastKey());
+ }
+
+ public void addArtifact(ArtifactVersion version, M artifact) {
+ artifacts.put(version, artifact);
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Plugin.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Plugin.java
new file mode 100644
index 00000000000..7dbf87a5374
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Plugin.java
@@ -0,0 +1,206 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.apache.maven.model.Developer;
+import org.json.simple.JSONObject;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+/**
+ * Information about Sonar Plugin.
+ *
+ * @author Evgeny Mandrikov
+ */
+public class Plugin implements Versioned {
+ private String key;
+ private String name;
+ private String description;
+ private String version;
+ private String downloadUrl;
+ private String requiredSonarVersion;
+ private String homepage;
+ private long timestamp;
+
+ private String pluginClass;
+ private String issueTracker;
+ private String sources;
+ private String license;
+
+ private List<Developer> developers;
+
+ public Plugin(String pluginKey) {
+ this.key = pluginKey;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * @return version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getReleaseDate() {
+ return (new SimpleDateFormat("d MMM yyyy")).format(new Date(timestamp));
+ }
+
+ private void setDate(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * @return URL for downloading
+ */
+ public String getDownloadUrl() {
+ return downloadUrl;
+ }
+
+ public void setDownloadUrl(String downloadUrl) {
+ this.downloadUrl = downloadUrl;
+ }
+
+ /**
+ * @return minimal Sonar version to run this plugin
+ */
+ public String getRequiredSonarVersion() {
+ // TODO Sonar-Version from MANIFEST.MF
+ return requiredSonarVersion;
+ }
+
+ public void setRequiredSonarVersion(String sonarVersion) {
+ this.requiredSonarVersion = sonarVersion;
+ }
+
+ /**
+ * @return homepage
+ */
+ public String getHomepage() {
+ // TODO Plugin-Homepage from MANIFEST.MF
+ return homepage;
+ }
+
+ public void setHomepage(String homepage) {
+ this.homepage = homepage;
+ }
+
+ public String getIssueTracker() {
+ return issueTracker;
+ }
+
+ public void setIssueTracker(String url) {
+ this.issueTracker = url;
+ }
+
+ public String getSources() {
+ return sources;
+ }
+
+ public void setSources(String sources) {
+ this.sources = sources;
+ }
+
+ public String getLicense() {
+ return license;
+ }
+
+ public void setLicense(String license) {
+ this.license = license;
+ }
+
+ public List<Developer> getDevelopers() {
+ return developers;
+ }
+
+ public void setDevelopers(List<Developer> developers) {
+ this.developers = developers;
+ }
+
+ public JSONObject toJsonObject() {
+ JSONObject obj = new JSONObject();
+ obj.put("id", getKey());
+ obj.put("name", getName());
+ obj.put("version", getVersion());
+ obj.put("sonarVersion", getRequiredSonarVersion());
+ if (getDownloadUrl() != null) {
+ obj.put("downloadUrl", getDownloadUrl());
+ }
+ if (getHomepage() != null) {
+ obj.put("homepage", getHomepage());
+ }
+ return obj;
+ }
+
+ public static Plugin extractMetadata(File file) throws IOException {
+ JarFile jar = new JarFile(file);
+ ZipEntry entry = jar.getEntry("META-INF/MANIFEST.MF");
+ long timestamp = entry.getTime();
+ Manifest manifest = jar.getManifest();
+ jar.close();
+
+ Attributes attributes = manifest.getMainAttributes();
+ String pluginKey = attributes.getValue("Plugin-Key");
+ Plugin plugin = new Plugin(pluginKey);
+ plugin.setName(attributes.getValue("Plugin-Name"));
+ plugin.setVersion(attributes.getValue("Plugin-Version"));
+ plugin.setRequiredSonarVersion(attributes.getValue("Sonar-Version"));
+ plugin.setHomepage(attributes.getValue("Plugin-Homepage"));
+ plugin.setDate(timestamp);
+ return plugin;
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Sonar.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Sonar.java
new file mode 100644
index 00000000000..cb652459af1
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Sonar.java
@@ -0,0 +1,58 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.json.simple.JSONObject;
+
+/**
+ * Information about Sonar.
+ *
+ * @author Evgeny Mandrikov
+ */
+public class Sonar implements Versioned {
+
+ private final String version;
+
+ public Sonar(String version) {
+ this.version = version;
+ }
+
+ /**
+ * @return Sonar version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * @return URL for downloading
+ */
+ public String getDownloadUrl() {
+ return "http://dist.sonar.codehaus.org/sonar-" + getVersion() + ".zip";
+ }
+
+ public JSONObject toJsonObject() {
+ JSONObject obj = new JSONObject();
+ obj.put("version", getVersion());
+ obj.put("downloadUrl", getDownloadUrl());
+ return obj;
+ }
+
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateCenter.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateCenter.java
new file mode 100644
index 00000000000..7e95d397679
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateCenter.java
@@ -0,0 +1,318 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Developer;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
+import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.Option;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class UpdateCenter {
+ // FIXME value set only for debug purposes
+ @Option(name = "-d")
+ public File outputDirectory = new File("/tmp/site");
+
+ private static final String ARTIFACT_JAR_TYPE = "jar";
+ private static final String ARTIFACT_POM_TYPE = "pom";
+
+ private List<ArtifactRepository> remoteRepositories;
+ private ArtifactRepository localRepository;
+
+ private ArtifactFactory artifactFactory;
+ private ArtifactResolver artifactResolver;
+ private ArtifactMetadataSource metadataSource;
+ private MavenProjectBuilder mavenProjectBuilder;
+
+ private void run() throws Exception {
+ // Init plexus
+ ClassWorld classWorld = new ClassWorld("plexus.core", UpdateCenter.class.getClassLoader());
+ ContainerConfiguration configuration = new DefaultContainerConfiguration().setClassWorld(classWorld);
+ PlexusContainer plexus = new DefaultPlexusContainer(configuration);
+ // Init components
+ artifactFactory = plexus.lookup(ArtifactFactory.class);
+ artifactResolver = plexus.lookup(ArtifactResolver.class);
+ metadataSource = plexus.lookup(ArtifactMetadataSource.class);
+ mavenProjectBuilder = plexus.lookup(MavenProjectBuilder.class);
+ ArtifactRepositoryFactory artifactRepositoryFactory = plexus.lookup(ArtifactRepositoryFactory.class);
+ // Init repositories
+ ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy(
+ true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN
+ );
+ remoteRepositories = Collections.singletonList( // TODO add SonarSource repository with commercial plugins
+ artifactRepositoryFactory.createArtifactRepository(
+ "codehaus",
+ "http://repository.codehaus.org/",
+ new DefaultRepositoryLayout(),
+ policy,
+ policy
+ )
+ );
+ File localRepo = new File(new File(System.getProperty("user.home")), ".m2/repository");
+ localRepository = artifactRepositoryFactory.createArtifactRepository(
+ "local",
+ localRepo.toURI().toURL().toExternalForm(),
+ new DefaultRepositoryLayout(),
+ policy,
+ policy
+ );
+ // Do work
+ JSONObject obj = new JSONObject();
+
+ obj.put("version", "1"); // We can bump this version, when we make incompatible changes
+ obj.put("plugins", resolvePlugins());
+ obj.put("sonar", resolveSonar());
+
+ if (outputDirectory != null) {
+ FileUtils.writeStringToFile(new File(outputDirectory, "update-center.json"), obj.toJSONString());
+ }
+ }
+
+ private JSONArray resolvePlugins() throws Exception {
+ List<String> plugins = FileUtils.readLines(FileUtils.toFile(getClass().getResource("/plugins.txt")));
+
+ String pluginInfoWidgetTemplate = FileUtils.readFileToString(
+ FileUtils.toFile(getClass().getResource("/plugin-info-widget-template.html"))
+ );
+ if (outputDirectory != null) {
+ FileUtils.copyURLToFile(getClass().getResource("/style.css"), new File(outputDirectory, "plugins/style.css"));
+ }
+
+ JSONArray json = new JSONArray();
+ for (String plugin : plugins) {
+ if (plugin.startsWith("#")) {
+ // Skip comments
+ continue;
+ }
+ History<Plugin> history = resolvePluginHistory(plugin);
+ if (history.latest() == null) {
+ System.out.println("WTF? " + plugin);
+ continue;
+ }
+ json.add(history.latest().toJsonObject());
+
+ Plugin latest = history.latest();
+
+ if (outputDirectory != null) {
+ String pluginInfoWidget = StringUtils.replaceEach(
+ pluginInfoWidgetTemplate,
+ new String[]{"%name%", "%version%", "%date%", "%downloadUrl%", "%sonarVersion%", "%issueTracker%", "%sources%", "%license%", "%developers%"},
+ new String[]{
+ latest.getName(),
+ latest.getVersion(),
+ latest.getReleaseDate(),
+ latest.getDownloadUrl(),
+ latest.getRequiredSonarVersion(),
+ formatLink(latest.getIssueTracker()),
+ formatLink(latest.getSources()),
+ latest.getLicense() == null ? "Unknown" : latest.getLicense(),
+ formatDevelopers(latest.getDevelopers())
+ }
+ );
+ FileUtils.writeStringToFile(new File(outputDirectory, "plugins/" + latest.getKey() + ".html"), pluginInfoWidget);
+ }
+
+ // TODO use logger
+ System.out.println(latest.getName() + " : " + history.getAllVersions() + ", latest " + latest.getVersion());
+ }
+
+ return json;
+ }
+
+ private String formatDevelopers(List<Developer> developers) {
+ if (developers == null) {
+ return "Unknown";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < developers.size(); i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(developers.get(i).getName());
+ }
+ return sb.toString();
+ }
+
+ private String formatLink(String url) {
+ return StringUtils.isBlank(url) ? "Unknown" : "<a href=\"" + url + "\" target=\"_top\">" + url + "</a>";
+ }
+
+ private JSONObject resolveSonar() throws Exception {
+ Artifact artifact = artifactFactory.createArtifact(
+ "org.codehaus.sonar",
+ "sonar-plugin-api",
+ Artifact.LATEST_VERSION,
+ Artifact.SCOPE_COMPILE,
+ ARTIFACT_JAR_TYPE
+ );
+
+ List<ArtifactVersion> versions = filterSnapshots(
+ metadataSource.retrieveAvailableVersions(artifact, localRepository, remoteRepositories)
+ );
+ History<Sonar> history = new History<Sonar>();
+ for (ArtifactVersion version : versions) {
+ history.addArtifact(version, new Sonar(version.toString()));
+ }
+
+ return history.latest().toJsonObject();
+ }
+
+ private String getDownloadUrl(String groupId, String artifactId, String version) {
+ // FIXME dirty hack
+ return "http://repository.codehaus.org/"
+ + StringUtils.replace(groupId, ".", "/") + "/"
+ + artifactId + "/"
+ + version + "/"
+ + artifactId + "-" + version + "." + ARTIFACT_JAR_TYPE;
+ }
+
+ private History<Plugin> resolvePluginHistory(String id) throws Exception {
+ String groupId = StringUtils.substringBefore(id, ":");
+ String artifactId = StringUtils.substringAfter(id, ":");
+
+ Artifact artifact = artifactFactory.createArtifact(
+ groupId, artifactId, Artifact.LATEST_VERSION, Artifact.SCOPE_COMPILE, ARTIFACT_JAR_TYPE
+ );
+
+ List<ArtifactVersion> versions = filterSnapshots(
+ metadataSource.retrieveAvailableVersions(artifact, localRepository, remoteRepositories)
+ );
+
+ History<Plugin> history = new History<Plugin>();
+ for (ArtifactVersion version : versions) {
+ Plugin plugin = org.sonar.updatecenter.deprecated.Plugin.extractMetadata(resolve(artifact.getGroupId(), artifact.getArtifactId(), version.toString()));
+ history.addArtifact(version, plugin);
+
+ MavenProject project = mavenProjectBuilder.buildFromRepository(
+ artifactFactory.createArtifact(groupId, artifactId, version.toString(), Artifact.SCOPE_COMPILE, ARTIFACT_POM_TYPE),
+ remoteRepositories,
+ localRepository
+ );
+
+ if (plugin.getVersion() == null) {
+ // Legacy plugin - set default values
+ plugin.setKey(project.getArtifactId());
+ plugin.setName(project.getName());
+ plugin.setVersion(project.getVersion());
+
+ String sonarVersion = "1.10"; // TODO Is it minimal version for all extension points ?
+ for (Dependency dependency : project.getDependencies()) {
+ if ("sonar-plugin-api".equals(dependency.getArtifactId())) { // TODO dirty hack
+ sonarVersion = dependency.getVersion();
+ }
+ }
+
+ plugin.setRequiredSonarVersion(sonarVersion);
+ plugin.setHomepage(project.getUrl());
+ }
+ plugin.setDownloadUrl(getDownloadUrl(groupId, artifactId, plugin.getVersion()));
+ // There is no equivalent for following properties in MANIFEST.MF
+ if (project.getIssueManagement() != null) {
+ plugin.setIssueTracker(project.getIssueManagement().getUrl());
+ } else {
+ System.out.println("Unknown Issue Management for " + plugin.getKey() + ":" + plugin.getVersion());
+ }
+ if (project.getScm() != null) {
+ String scmUrl = project.getScm().getUrl();
+ if (StringUtils.startsWith(scmUrl, "scm:")) {
+ scmUrl = StringUtils.substringAfter(StringUtils.substringAfter(scmUrl, ":"), ":");
+ }
+ plugin.setSources(scmUrl);
+ } else {
+ System.out.println("Unknown SCM for " + plugin.getKey() + ":" + plugin.getVersion());
+ }
+ if (project.getLicenses() != null && project.getLicenses().size() > 0) {
+ plugin.setLicense(project.getLicenses().get(0).getName());
+ } else {
+ System.out.println("Unknown License for " + plugin.getKey() + ":" + plugin.getVersion());
+ }
+ if (project.getDevelopers().size() > 0) {
+ plugin.setDevelopers(project.getDevelopers());
+ } else {
+ System.out.println("Unknown Developers for " + plugin.getKey() + ":" + plugin.getVersion());
+ }
+ }
+ return history;
+ }
+
+ private List<ArtifactVersion> filterSnapshots(List<ArtifactVersion> versions) {
+ List<ArtifactVersion> result = new ArrayList<ArtifactVersion>();
+ for (ArtifactVersion version : versions) {
+ // Ignore snapshots
+ if (!"SNAPSHOT".equalsIgnoreCase(version.getQualifier())) {
+ result.add(version);
+ }
+ }
+ return result;
+ }
+
+ private File resolve(String groupId, String artifactId, String version) throws Exception {
+ return resolve(groupId, artifactId, version, ARTIFACT_JAR_TYPE);
+ }
+
+ private File resolve(String groupId, String artifactId, String version, String type) throws Exception {
+ Artifact artifact = artifactFactory.createArtifact(groupId, artifactId, version, Artifact.SCOPE_COMPILE, type);
+ ArtifactResolutionRequest request = new ArtifactResolutionRequest()
+ .setArtifact(artifact)
+ .setResolveTransitively(false)
+ .setLocalRepository(localRepository)
+ .setRemoteRepositories(remoteRepositories);
+ artifactResolver.resolve(request);
+ return artifact.getFile();
+ }
+
+ public static void main(String[] args) throws Exception {
+ UpdateCenter updateCenter = new UpdateCenter();
+ CmdLineParser p = new CmdLineParser(updateCenter);
+ p.parseArgument(args);
+
+ updateCenter.run();
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateInfo.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateInfo.java
new file mode 100644
index 00000000000..bf65ee8a861
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/UpdateInfo.java
@@ -0,0 +1,42 @@
+package org.sonar.updatecenter.deprecated;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamImplicit;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Information about updates.
+ *
+ * @author Evgeny Mandrikov
+ */
+@XStreamAlias("updateInfo")
+public class UpdateInfo {
+
+ public Sonar sonar;
+
+ @XStreamImplicit(itemFieldName = "plugin")
+ public List<Plugin> plugins;
+
+ public UpdateInfo(Sonar sonar, List<Plugin> plugins) {
+ this.sonar = sonar;
+ this.plugins = plugins;
+ }
+
+ public static void main(String[] args) {
+ XStream xstream = new XStream();
+ xstream.autodetectAnnotations(true);
+
+ Plugin plugin = new Plugin("sonar-test-plugin");
+ plugin.setVersion("0.1");
+ plugin.setName("Sonar Test Plugin");
+ plugin.setDescription("Test");
+ plugin.setHomepage("http://homepage");
+ plugin.setDownloadUrl("http://download");
+ plugin.setRequiredSonarVersion("2.0");
+
+ System.out.println(xstream.toXML(new UpdateInfo(new Sonar("2.0"), Arrays.asList(plugin))));
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Versioned.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Versioned.java
new file mode 100644
index 00000000000..fc50234c990
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/deprecated/Versioned.java
@@ -0,0 +1,27 @@
+/*
+ * 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.updatecenter.deprecated;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public interface Versioned {
+ String getVersion();
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Configuration.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Configuration.java
new file mode 100644
index 00000000000..165b7883562
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Configuration.java
@@ -0,0 +1,94 @@
+/*
+ * 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.updatecenter.server;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+public class Configuration {
+
+ public static final String WORKING_DIR = "workingDir";
+ public static final String OUTPUT_FILE = "outputFile";
+ public static final String SOURCE_PATH = "path";
+ public static final String SOURCE_LOGIN = "login";
+ public static final String SOURCE_PASSWORD = "password";
+
+ private static Logger LOG = LoggerFactory.getLogger(Configuration.class);
+ private Properties props;
+ private File workingDir = null;
+
+ public Configuration(Properties props) {
+ this.props = props;
+ }
+
+ public void log() {
+ LOG.info("-------------------------------");
+ LOG.info(WORKING_DIR + ": " + getWorkingDir().getPath());
+ LOG.info(OUTPUT_FILE + ": " + getOutputFile().getPath());
+ LOG.info(SOURCE_PATH + ": " + getSourcePath());
+ LOG.info(SOURCE_LOGIN + ": " + getSourceLogin());
+ LOG.info(SOURCE_PASSWORD + ": " + getSourcePassword());
+ LOG.info("-------------------------------");
+ }
+
+ public File getWorkingDir() {
+ if (workingDir == null) {
+ String path = props.getProperty(WORKING_DIR);
+ if (StringUtils.isBlank(path)) {
+ workingDir = new File(System.getProperty("user.home"), ".sonar-update-center");
+ } else {
+ workingDir = new File(path);
+ }
+ try {
+ FileUtils.forceMkdir(workingDir);
+
+ } catch (IOException e) {
+ throw new RuntimeException("Fail to create the working directory: " + workingDir.getAbsolutePath(), e);
+ }
+ }
+ return workingDir;
+ }
+
+ public File getOutputFile() {
+ String path = props.getProperty(OUTPUT_FILE);
+ if (StringUtils.isNotBlank(path)) {
+ return new File(path);
+ }
+ return new File(getWorkingDir(), "generated-sonar-updates.properties");
+ }
+
+ public String getSourcePath() {
+ return props.getProperty(SOURCE_PATH);
+ }
+
+ public String getSourceLogin() {
+ return props.getProperty(SOURCE_LOGIN);
+ }
+
+ public String getSourcePassword() {
+ return props.getProperty(SOURCE_PASSWORD);
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/HttpDownloader.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/HttpDownloader.java
new file mode 100644
index 00000000000..44aad96b860
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/HttpDownloader.java
@@ -0,0 +1,102 @@
+/*
+ * 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.updatecenter.server;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class HttpDownloader {
+ private static Logger LOG = LoggerFactory.getLogger(HttpDownloader.class);
+
+ private File outputDir;
+
+ public HttpDownloader(File outputDir) {
+ this.outputDir = outputDir;
+ }
+
+ public File download(String url, boolean force) throws IOException, URISyntaxException {
+ return download(url, force, null, null);
+ }
+ public File download(String url, boolean force, String login, String password) throws IOException, URISyntaxException {
+ FileUtils.forceMkdir(outputDir);
+
+ String filename = StringUtils.substringAfterLast(url, "/");
+ File output = new File(outputDir, filename);
+ if (force || !output.exists() || output.length() <= 0) {
+ downloadFile(new URI(url), output, login, password);
+ } else {
+ LOG.info("Already downloaded: " + url);
+ }
+ return output;
+ }
+
+ File downloadFile(URI fileURI, File toFile, String login, String password) {
+ LOG.error("Download " + fileURI + " in " + toFile);
+ DefaultHttpClient client = new DefaultHttpClient();
+ try {
+ if (StringUtils.isNotBlank(login)) {
+ client.getCredentialsProvider().setCredentials(
+ new AuthScope(fileURI.getHost(), fileURI.getPort()),
+ new UsernamePasswordCredentials(login, password));
+ }
+ HttpGet httpget = new HttpGet(fileURI);
+ byte[] data = client.execute(httpget, new ByteResponseHandler());
+ if (data != null) {
+ FileUtils.writeByteArrayToFile(toFile, data);
+ }
+
+ } catch (Exception e) {
+ LOG.error("Fail to download " + fileURI + " to " + toFile, e);
+ FileUtils.deleteQuietly(toFile);
+
+ } finally {
+ client.getConnectionManager().shutdown();
+ }
+ return toFile;
+ }
+
+ static class ByteResponseHandler implements ResponseHandler<byte[]> {
+ public byte[] handleResponse(HttpResponse response) throws IOException {
+ HttpEntity entity = response.getEntity();
+ if (response.getStatusLine().getStatusCode()!=200) {
+ throw new RuntimeException("Unvalid HTTP response: " + response.getStatusLine());
+ }
+ if (entity != null) {
+ return EntityUtils.toByteArray(entity);
+ }
+ return null;
+ }
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/MetadataFile.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/MetadataFile.java
new file mode 100644
index 00000000000..a0207021726
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/MetadataFile.java
@@ -0,0 +1,72 @@
+/*
+ * 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.updatecenter.server;
+
+import org.sonar.updatecenter.common.UpdateCenter;
+import org.sonar.updatecenter.common.UpdateCenterDeserializer;
+
+import java.io.File;
+import java.io.IOException;
+
+public final class MetadataFile {
+
+ private Configuration conf;
+ private HttpDownloader downloader;
+
+ public MetadataFile(Configuration conf, HttpDownloader downloader) {
+ this.conf = conf;
+ this.downloader = downloader;
+ }
+
+ public File getFile() {
+ try {
+ File file;
+ if (isRemote()) {
+ file = downloader.download(conf.getSourcePath(), true, conf.getSourceLogin(), conf.getSourcePassword());
+ } else {
+ file = new File(conf.getSourcePath());
+ }
+ if (!file.exists()) {
+ throw new RuntimeException("The metadata file does not exist: " + file.getPath());
+ }
+ return file;
+
+ } catch (RuntimeException e) {
+ throw e;
+
+ } catch (Exception e) {
+ throw new RuntimeException("Can not open the metadata file: " + conf.getSourcePath(), e);
+ }
+ }
+
+ public UpdateCenter getUpdateCenter() {
+ File file = getFile();
+ try {
+ return UpdateCenterDeserializer.fromProperties(file);
+
+ } catch (IOException e) {
+ throw new RuntimeException("Can not read properties from: " + file.getPath(), e);
+ }
+ }
+
+ private boolean isRemote() {
+ return conf.getSourcePath().startsWith("http");
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Server.java b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Server.java
new file mode 100644
index 00000000000..4288ba2e8a1
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/java/org/sonar/updatecenter/server/Server.java
@@ -0,0 +1,83 @@
+/*
+ * 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.updatecenter.server;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.updatecenter.common.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+public final class Server {
+ private static Logger LOG = LoggerFactory.getLogger(Server.class);
+
+ public void start() throws IOException, URISyntaxException {
+ Configuration conf = new Configuration(System.getProperties());
+ conf.log();
+ HttpDownloader downloader = new HttpDownloader(conf.getWorkingDir());
+ UpdateCenter center = buildFromPartialMetadata(conf, downloader);
+ downloadReleases(downloader, center);
+ generateMetadata(conf, center);
+ }
+
+ private UpdateCenter buildFromPartialMetadata(Configuration conf, HttpDownloader downloader) {
+ return new MetadataFile(conf, downloader).getUpdateCenter();
+ }
+
+ private void downloadReleases(HttpDownloader downloader, UpdateCenter center) throws IOException, URISyntaxException {
+ for (Plugin plugin : center.getPlugins()) {
+ LOG.info("Load plugin: " + plugin.getKey());
+
+ File masterJar = null;
+ for (Release release : plugin.getReleases()) {
+ if (StringUtils.isNotBlank(release.getDownloadUrl())) {
+ File jar = downloader.download(release.getDownloadUrl(), false);
+ if (jar!= null && jar.exists()) {
+ masterJar = jar;
+ } else {
+ release.setDownloadUrl(null);
+ LOG.warn("Ignored because of wrong downloadUrl: plugin " + plugin.getKey() + ", version " + release.getVersion());
+ }
+
+ } else {
+ LOG.warn("Ignored because of missing downloadUrl: plugin " + plugin.getKey() + ", version " + release.getVersion());
+ }
+ }
+
+ // the last release is the master version for loading metadata included in manifest
+ if (masterJar != null) {
+ plugin.merge(new PluginManifest(masterJar));
+ }
+ }
+ }
+
+ private void generateMetadata(Configuration conf, UpdateCenter center) {
+ LOG.info("Generate output: " + conf.getOutputFile());
+ UpdateCenterSerializer.toProperties(center, conf.getOutputFile());
+ }
+
+ public static void main(String[] args) throws IOException, URISyntaxException {
+ new Server().start();
+ }
+
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/log4j.properties b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/log4j.properties
new file mode 100644
index 00000000000..be19b35722a
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/log4j.properties
@@ -0,0 +1,6 @@
+log4j.rootCategory=INFO, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+
+log4j.appender.stdout.layout.ConversionPattern=[%d{HH:mm:ss}] %p [%c] - %m%n
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugin-info-widget-template.html b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugin-info-widget-template.html
new file mode 100644
index 00000000000..2abbbb8f41a
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugin-info-widget-template.html
@@ -0,0 +1,46 @@
+<html>
+<head>
+ <title>%name%</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="generator" content="Sonar Update Center" />
+ <style type="text/css">
+ @import url("style.css");
+ </style>
+</head>
+<body>
+<a href="%downloadUrl%" class="button">Download</a>
+<table cellpadding="0" cellspacing="0">
+ <tr>
+ <td><strong>Name</strong></td>
+ <td>%name%</td>
+ </tr>
+ <tr>
+ <td><strong>Latest version</strong></td>
+ <td><strong>%version%</strong> ( %date% )</td>
+ </tr>
+ <tr>
+ <td><strong>Requires Sonar version</strong></td>
+ <td>
+ <strong>%sonarVersion%</strong> or higher
+ ( check <a href="http://docs.codehaus.org/display/SONAR/Plugin+version+matrix" target="_top">version compatibility</a> )
+ </td>
+ </tr>
+ <tr>
+ <td><strong>License</strong></td>
+ <td>%license%</td>
+ </tr>
+ <tr>
+ <td><strong>Developers</strong></td>
+ <td>%developers%</td>
+ </tr>
+ <tr>
+ <td><strong>Issue tracker</strong></td>
+ <td>%issueTracker%</td>
+ </tr>
+ <tr>
+ <td><strong>Sources</strong></td>
+ <td>%sources%</td>
+ </tr>
+</table>
+</body>
+</html>
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugins.txt b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugins.txt
new file mode 100644
index 00000000000..222e5a4b0cb
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/plugins.txt
@@ -0,0 +1,38 @@
+#
+# Open-source plugins
+#
+org.codehaus.sonar-plugins:sonar-artifact-size-plugin
+org.codehaus.sonar-plugins:sonar-build-breaker-plugin
+org.codehaus.sonar-plugins:sonar-build-stability-plugin
+org.codehaus.sonar-plugins:sonar-clirr-plugin
+org.codehaus.sonar-plugins:sonar-crowd-plugin
+org.codehaus.sonar-plugins:sonar-emma-plugin
+org.codehaus.sonar-plugins:sonar-flex-plugin
+org.codehaus.sonar-plugins:sonar-greenpepper-plugin
+org.codehaus.sonar-plugins:sonar-jacoco-plugin
+org.codehaus.sonar-plugins:sonar-jira-plugin
+org.codehaus.sonar-plugins:sonar-ldap-plugin
+org.codehaus.sonar-plugins:sonar-motion-chart-plugin
+org.codehaus.sonar-plugins:sonar-piwik-plugin
+org.codehaus.sonar-plugins:sonar-plugin-taglist
+org.codehaus.sonar-plugins:sonar-quality-index-plugin
+org.codehaus.sonar-plugins:sonar-radiator-plugin
+org.codehaus.sonar-plugins:sonar-rulesmeter-plugin
+org.codehaus.sonar-plugins:sonar-security-rules-plugin
+org.codehaus.sonar-plugins:sonar-sigmm-plugin
+org.codehaus.sonar-plugins:sonar-sonarj-plugin
+org.codehaus.sonar-plugins:sonar-taglist-plugin
+org.codehaus.sonar-plugins:sonar-technicaldebt-plugin
+org.codehaus.sonar-plugins:sonar-timeline-plugin
+org.codehaus.sonar-plugins:sonar-total-quality-plugin
+org.codehaus.sonar-plugins:sonar-trac-plugin
+org.codehaus.sonar-plugins:sonar-twitter-plugin
+org.codehaus.sonar-plugins.scm-activity:sonar-scm-activity-plugin
+org.codehaus.sonar-plugins:sonar-groovy-plugin
+org.codehaus.sonar-plugins:sonar-web-plugin
+#
+# Incorrect artifactId
+#
+#org.codehaus.sonar-plugins:pdf-report
+#org.codehaus.sonar-plugins:technical-debt
+#org.codehaus.sonar-plugins:emma
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/style.css b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/style.css
new file mode 100644
index 00000000000..a3215e49890
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/main/resources/style.css
@@ -0,0 +1,29 @@
+body {
+ font-family: Verdana,arial,sans-serif;
+ font-size: 9pt;
+}
+a {
+ color: #036;
+}
+table {
+ border-collapse: collapse;
+ width: 100%;
+}
+table td {
+ border: 1px #CCC solid;
+ padding: 3px;
+ font-size: 9pt;
+}
+th {
+ text-align: left;
+}
+.button {
+ background: #3C78B5;
+ text-align: center;
+ border-radius: 3px;
+ display: block;
+ padding: 5px;
+ cursor: pointer;
+ margin: 5px;
+ color: white;
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/HistoryTest.java b/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/HistoryTest.java
new file mode 100644
index 00000000000..f0563ee42f1
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/HistoryTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class HistoryTest {
+ @Test
+ public void testLatest() {
+ History<Plugin> history = new History<Plugin>();
+
+ history.addArtifact(new DefaultArtifactVersion("0.1"), newPlugin("0.1"));
+ assertEquals(1, history.getAllVersions().size());
+ assertEquals("0.1", history.latest().getVersion());
+
+ history.addArtifact(new DefaultArtifactVersion("1.0"), newPlugin("1.0"));
+ assertEquals(2, history.getAllVersions().size());
+ assertEquals("1.0", history.latest().getVersion());
+
+ history.addArtifact(new DefaultArtifactVersion("0.2"), newPlugin("0.2"));
+ assertEquals(3, history.getAllVersions().size());
+ assertEquals("1.0", history.latest().getVersion());
+ }
+
+ private Plugin newPlugin(String version) {
+ Plugin plugin = new Plugin(version);
+ plugin.setVersion(version);
+ return plugin;
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/PluginTest.java b/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/PluginTest.java
new file mode 100644
index 00000000000..95914a870e3
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/PluginTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class PluginTest {
+ @Test
+ public void testToJsonObject() {
+ /*
+ Plugin plugin = new Plugin("org.sonar.plugins.test.Test");
+ plugin.setVersion("0.1");
+ plugin.setName("Sonar Test Plugin");
+ plugin.setRequiredSonarVersion("2.0");
+ assertEquals(
+ "{\"sonarVersion\":\"2.0\"" +
+ ",\"id\":\"org.sonar.plugins.test.Test\"" +
+ ",\"name\":\"Sonar Test Plugin\"" +
+ ",\"version\":\"0.1\"" +
+ "}",
+ plugin.toJsonObject().toJSONString()
+ );
+
+ plugin.setDownloadUrl("http://download");
+ plugin.setHomepage("http://homepage");
+ assertEquals(
+ "{\"sonarVersion\":\"2.0\"" +
+ ",\"id\":\"org.sonar.plugins.test.Test\"" +
+ ",\"name\":\"Sonar Test Plugin\"" +
+ ",\"downloadUrl\":\"http:\\/\\/download\"" +
+ ",\"homepage\":\"http:\\/\\/homepage\"" +
+ ",\"version\":\"0.1\"" +
+ "}",
+ plugin.toJsonObject().toJSONString()
+ );
+ */
+ }
+}
diff --git a/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/SonarTest.java b/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/SonarTest.java
new file mode 100644
index 00000000000..efcae7fe7f8
--- /dev/null
+++ b/subprojects/sonar-update-center/sonar-update-center-server/src/test/java/org/sonar/updatecenter/deprecated/SonarTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.updatecenter.deprecated;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class SonarTest {
+ @Test
+ public void testToJsonObject() throws Exception {
+ /*
+ assertEquals(
+ "{\"downloadUrl\":\"http:\\/\\/dist.sonar.codehaus.org\\/sonar-2.0.zip\"" +
+ ",\"version\":\"2.0\"" +
+ "}",
+ new Sonar("2.0").toJsonObject().toJSONString()
+ );
+ */
+ }
+}