aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch-bootstrapper
diff options
context:
space:
mode:
authorEvgeny Mandrikov <mandrikov@gmail.com>2011-01-19 02:20:45 +0300
committerEvgeny Mandrikov <mandrikov@gmail.com>2011-01-24 01:14:07 +0300
commit6b5035087075113699015583fd4d76b75bf36894 (patch)
tree97a3a3ef3be082d68db071405f7aab50d4963a19 /sonar-batch-bootstrapper
parenta1fca497333231931a3df3e3973918ade12ab6bc (diff)
downloadsonarqube-6b5035087075113699015583fd4d76b75bf36894.tar.gz
sonarqube-6b5035087075113699015583fd4d76b75bf36894.zip
SONAR-2106: New Java library to bootstrap project analysis
* Add BatchResourcesServlet to allow downloading libraries from server * Create in memory POM for non-maven environments * Provide fake MavenPluginExecutor for non-maven environments * Add new module sonar-batch-maven-compat with shaded maven-project
Diffstat (limited to 'sonar-batch-bootstrapper')
-rw-r--r--sonar-batch-bootstrapper/pom.xml27
-rw-r--r--sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BatchDownloader.java134
-rw-r--r--sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BootstrapperIOUtils.java79
-rw-r--r--sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/package-info.java24
-rw-r--r--sonar-batch-bootstrapper/src/test/java/org/sonar/batch/bootstrapper/BatchDownloaderTest.java54
5 files changed, 318 insertions, 0 deletions
diff --git a/sonar-batch-bootstrapper/pom.xml b/sonar-batch-bootstrapper/pom.xml
new file mode 100644
index 00000000000..75a7498f456
--- /dev/null
+++ b/sonar-batch-bootstrapper/pom.xml
@@ -0,0 +1,27 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar</artifactId>
+ <version>2.6-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>sonar-batch-bootstrapper</artifactId>
+ <name>Sonar :: Batch Bootstrapper</name>
+ <description>Provides API to bootstrap Sonar Batch.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BatchDownloader.java b/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BatchDownloader.java
new file mode 100644
index 00000000000..b5eba165324
--- /dev/null
+++ b/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BatchDownloader.java
@@ -0,0 +1,134 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.batch.bootstrapper;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BatchDownloader {
+
+ private static final String VERSION_PATH = "/api/server/version";
+ private static final String BATCH_PATH = "/batch/";
+
+ public static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
+ public static final int READ_TIMEOUT_MILLISECONDS = 60000;
+
+ private String serverUrl;
+ private String serverVersion;
+
+ public BatchDownloader(String serverUrl) {
+ if (serverUrl.endsWith("/")) {
+ this.serverUrl = serverUrl.substring(0, serverUrl.length() - 1);
+ } else {
+ this.serverUrl = serverUrl;
+ }
+ }
+
+ /**
+ * @return server url
+ */
+ public String getServerUrl() {
+ return serverUrl;
+ }
+
+ /**
+ * @return server version
+ */
+ public String getServerVersion() {
+ if (serverVersion == null) {
+ try {
+ serverVersion = remoteContent(VERSION_PATH);
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+ return serverVersion;
+ }
+
+ /**
+ * @return list of downloaded files
+ */
+ public List<File> downloadBatchFiles(File toDir) {
+ try {
+ List<File> files = new ArrayList<File>();
+
+ String libs = remoteContent(BATCH_PATH);
+
+ for (String lib : libs.split(",")) {
+ File file = new File(toDir, lib);
+ remoteContentToFile(BATCH_PATH + lib, file);
+ files.add(file);
+ }
+
+ return files;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void remoteContentToFile(String path, File toFile) {
+ InputStream input = null;
+ FileOutputStream output = null;
+ String fullUrl = serverUrl + path;
+ try {
+ HttpURLConnection connection = newHttpConnection(new URL(fullUrl));
+ output = new FileOutputStream(toFile, false);
+ input = connection.getInputStream();
+ BootstrapperIOUtils.copyLarge(input, output);
+ } catch (Exception e) {
+ BootstrapperIOUtils.closeQuietly(output);
+ BootstrapperIOUtils.deleteFileQuietly(toFile);
+ throw new RuntimeException("Fail to download the file: " + fullUrl);
+ } finally {
+ BootstrapperIOUtils.closeQuietly(input);
+ BootstrapperIOUtils.closeQuietly(output);
+ }
+ }
+
+ String remoteContent(String path) throws IOException {
+ String fullUrl = serverUrl + path;
+ HttpURLConnection conn = newHttpConnection(new URL(fullUrl));
+ Reader reader = new InputStreamReader((InputStream) conn.getContent());
+ try {
+ int statusCode = conn.getResponseCode();
+ if (statusCode != HttpURLConnection.HTTP_OK) {
+ throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
+ }
+ return BootstrapperIOUtils.toString(reader);
+ } finally {
+ BootstrapperIOUtils.closeQuietly(reader);
+ conn.disconnect();
+ }
+ }
+
+ static HttpURLConnection newHttpConnection(URL url) throws IOException {
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setConnectTimeout(CONNECT_TIMEOUT_MILLISECONDS);
+ connection.setReadTimeout(READ_TIMEOUT_MILLISECONDS);
+ connection.setInstanceFollowRedirects(true);
+ connection.setRequestMethod("GET");
+ // TODO connection.setRequestProperty("User-Agent", userAgent);
+ return connection;
+ }
+
+}
diff --git a/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BootstrapperIOUtils.java b/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BootstrapperIOUtils.java
new file mode 100644
index 00000000000..c764ac50105
--- /dev/null
+++ b/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/BootstrapperIOUtils.java
@@ -0,0 +1,79 @@
+package org.sonar.batch.bootstrapper;
+
+import java.io.*;
+
+final class BootstrapperIOUtils {
+
+ private BootstrapperIOUtils() {
+ }
+
+ /**
+ * The default buffer size to use.
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+
+ /**
+ * Unconditionally close a <code>Closeable</code>.
+ */
+ public static void closeQuietly(Closeable closeable) {
+ try {
+ if (closeable != null) {
+ closeable.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Get the contents of a <code>Reader</code> as a String.
+ */
+ public static String toString(Reader input) throws IOException {
+ StringWriter sw = new StringWriter();
+ copyLarge(input, sw);
+ return sw.toString();
+ }
+
+ /**
+ * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
+ */
+ public static long copyLarge(InputStream input, OutputStream output) throws IOException {
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ long count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ /**
+ * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
+ */
+ public static long copyLarge(Reader input, Writer output) throws IOException {
+ char[] buffer = new char[DEFAULT_BUFFER_SIZE];
+ long count = 0;
+ int n = 0;
+ while (-1 != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ /**
+ * Deletes a file (not a directory).
+ */
+ public static boolean deleteFileQuietly(File file) {
+ if (file == null) {
+ return false;
+ }
+ try {
+ return file.delete();
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+}
diff --git a/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/package-info.java b/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/package-info.java
new file mode 100644
index 00000000000..7c23a7aa9ec
--- /dev/null
+++ b/sonar-batch-bootstrapper/src/main/java/org/sonar/batch/bootstrapper/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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
+ */
+
+/**
+ * Provides API to bootstrap Sonar Batch.
+ */
+package org.sonar.batch.bootstrapper; \ No newline at end of file
diff --git a/sonar-batch-bootstrapper/src/test/java/org/sonar/batch/bootstrapper/BatchDownloaderTest.java b/sonar-batch-bootstrapper/src/test/java/org/sonar/batch/bootstrapper/BatchDownloaderTest.java
new file mode 100644
index 00000000000..1822a53f014
--- /dev/null
+++ b/sonar-batch-bootstrapper/src/test/java/org/sonar/batch/bootstrapper/BatchDownloaderTest.java
@@ -0,0 +1,54 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.batch.bootstrapper;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class BatchDownloaderTest {
+
+ @Test
+ public void shouldRemoveLastUrlSlash() {
+ BatchDownloader bootstrapper = new BatchDownloader("http://test/");
+ assertThat(bootstrapper.getServerUrl(), is("http://test"));
+ }
+
+ @Test(expected = Exception.class)
+ public void shouldFailIfCanNotConnectServer() {
+ BatchDownloader bootstrapper = new BatchDownloader("http://unknown.foo");
+ bootstrapper.getServerVersion();
+ }
+
+ @Test
+ public void shouldReturnValidVersion() {
+ BatchDownloader bootstrapper = new BatchDownloader("http://test") {
+ @Override
+ String remoteContent(String path) throws IOException {
+ return "2.6";
+ }
+ };
+ assertThat(bootstrapper.getServerVersion(), is("2.6"));
+ }
+
+}