From d39d594496d4a7e566c02c700bb2ac77c2444311 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 13 May 2014 10:26:07 +0200 Subject: [PATCH] SONAR-5287 SONAR-5293 Create Java WS client for "/api/sources/show" and "/api/sources/scm" --- sonar-ws-client/pom.xml | 5 ++ .../java/org/sonar/wsclient/source/Scm.java | 37 +++++++++ .../org/sonar/wsclient/source/Source.java | 32 ++++++++ .../sonar/wsclient/source/SourceClient.java | 37 +++++++++ .../wsclient/source/internal/DefaultScm.java | 56 ++++++++++++++ .../source/internal/DefaultSource.java | 44 +++++++++++ .../source/internal/DefaultSourceClient.java | 77 +++++++++++++++++++ .../wsclient/unmarshallers/JsonUtils.java | 15 ++-- .../internal/DefaultSourceClientTest.java | 72 +++++++++++++++++ .../DefaultSourceClientTest/return_scm.json | 7 ++ .../DefaultSourceClientTest/show_source.json | 10 +++ 11 files changed, 387 insertions(+), 5 deletions(-) create mode 100644 sonar-ws-client/src/main/java/org/sonar/wsclient/source/Scm.java create mode 100644 sonar-ws-client/src/main/java/org/sonar/wsclient/source/Source.java create mode 100644 sonar-ws-client/src/main/java/org/sonar/wsclient/source/SourceClient.java create mode 100644 sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultScm.java create mode 100644 sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSource.java create mode 100644 sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSourceClient.java create mode 100644 sonar-ws-client/src/test/java/org/sonar/wsclient/source/internal/DefaultSourceClientTest.java create mode 100644 sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/return_scm.json create mode 100644 sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/show_source.json diff --git a/sonar-ws-client/pom.xml b/sonar-ws-client/pom.xml index 1a9a8ad3ff4..1a1206dd6f0 100644 --- a/sonar-ws-client/pom.xml +++ b/sonar-ws-client/pom.xml @@ -95,6 +95,11 @@ fest-assert test + + com.google.guava + guava + test + diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/Scm.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/Scm.java new file mode 100644 index 00000000000..cf420820659 --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/Scm.java @@ -0,0 +1,37 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source; + +import javax.annotation.CheckForNull; + +import java.util.Date; + +public interface Scm { + + long index(); + + @CheckForNull + String author(); + + @CheckForNull + Date date(); + +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/Source.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/Source.java new file mode 100644 index 00000000000..f1d1cf7b032 --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/Source.java @@ -0,0 +1,32 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source; + +/** + * @since 4.4 + */ +public interface Source { + + long index(); + + String line(); + +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/SourceClient.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/SourceClient.java new file mode 100644 index 00000000000..36b65251bd4 --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/SourceClient.java @@ -0,0 +1,37 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source; + +import javax.annotation.Nullable; + +import java.util.List; + +/** + * Display sources information + * @since 4.4 + */ +public interface SourceClient { + + List show(String key, @Nullable String from, @Nullable String to); + + List scm(String key, @Nullable String from, @Nullable String to, @Nullable Boolean groupCommits); + +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultScm.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultScm.java new file mode 100644 index 00000000000..b563f5ec39a --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultScm.java @@ -0,0 +1,56 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source.internal; + +import org.sonar.wsclient.source.Scm; +import org.sonar.wsclient.unmarshallers.JsonUtils; + +import javax.annotation.CheckForNull; + +import java.util.Date; +import java.util.List; + +public class DefaultScm implements Scm { + + private final List json; + + public DefaultScm(List json) { + this.json = json; + } + + @Override + public long index() { + return (Long) json.get(0); + } + + @Override + @CheckForNull + public String author() { + return (String) json.get(1); + } + + @Override + @CheckForNull + public Date date() { + return JsonUtils.parseDate((String) json.get(2)); + } + +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSource.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSource.java new file mode 100644 index 00000000000..8794a5f8bff --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSource.java @@ -0,0 +1,44 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source.internal; + +import org.sonar.wsclient.source.Source; + +import java.util.List; + +public class DefaultSource implements Source { + + private final List json; + + public DefaultSource(List json) { + this.json = json; + } + + @Override + public long index() { + return (Long) json.get(0); + } + + @Override + public String line() { + return (String) json.get(1); + } +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSourceClient.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSourceClient.java new file mode 100644 index 00000000000..d5e0acffe26 --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/source/internal/DefaultSourceClient.java @@ -0,0 +1,77 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source.internal; + +import org.json.simple.JSONValue; +import org.sonar.wsclient.internal.EncodingUtils; +import org.sonar.wsclient.internal.HttpRequestFactory; +import org.sonar.wsclient.source.Scm; +import org.sonar.wsclient.source.Source; +import org.sonar.wsclient.source.SourceClient; + +import javax.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class DefaultSourceClient implements SourceClient { + + private final HttpRequestFactory requestFactory; + + public DefaultSourceClient(HttpRequestFactory requestFactory) { + this.requestFactory = requestFactory; + } + + @Override + public List show(String key, @Nullable String from, @Nullable String to) { + Map params = EncodingUtils.toMap("key", key, "from", from, "to", to); + String json = requestFactory.get("/api/sources/show", params); + + List sources = new ArrayList(); + Map jRoot = (Map) JSONValue.parse(json); + List jsonSources = (List) jRoot.get("sources"); + if (jsonSources != null) { + for (List jSource : jsonSources) { + sources.add(new DefaultSource(jSource)); + } + } + return sources; + } + + @Override + public List scm(String key, @Nullable String from, @Nullable String to, @Nullable Boolean groupCommits) { + Map params = EncodingUtils.toMap("key", key, "from", from, "to", to); + params.put("group_commits", groupCommits); + String json = requestFactory.get("/api/sources/scm", params); + + List result = new ArrayList(); + Map jRoot = (Map) JSONValue.parse(json); + List jsonResult = (List) jRoot.get("scm"); + if (jsonResult != null) { + for (List line : jsonResult) { + result.add(new DefaultScm(line)); + } + } + return result; + } + +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/JsonUtils.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/JsonUtils.java index cd24c301dcf..6843ec8c9b3 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/JsonUtils.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/JsonUtils.java @@ -22,6 +22,7 @@ package org.sonar.wsclient.unmarshallers; import org.json.simple.JSONArray; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -94,24 +95,28 @@ public final class JsonUtils { @CheckForNull public static Date getDateTime(Map obj, String field) { - return parseDate(obj, field, "yyyy-MM-dd'T'HH:mm:ssZ"); + return parseDate(getString(obj, field), "yyyy-MM-dd'T'HH:mm:ssZ"); } @CheckForNull public static Date getDate(Map obj, String field) { - return parseDate(obj, field, "yyyy-MM-dd"); + return parseDate(getString(obj, field)); } @CheckForNull - private static Date parseDate(Map obj, String field, String format) { - String value = getString(obj, field); + public static Date parseDate(@Nullable String value) { + return parseDate(value, "yyyy-MM-dd"); + } + + @CheckForNull + private static Date parseDate(@Nullable String value, String format) { if (value != null) { try { SimpleDateFormat dateFormat = new SimpleDateFormat(format); return dateFormat.parse(value); } catch (ParseException e) { - throw new IllegalArgumentException("Fail to parse date property '" + field + "': " + format, e); + throw new IllegalArgumentException("Fail to parse date '" + value + "': " + format, e); } } return null; diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/source/internal/DefaultSourceClientTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/source/internal/DefaultSourceClientTest.java new file mode 100644 index 00000000000..4abb642671c --- /dev/null +++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/source/internal/DefaultSourceClientTest.java @@ -0,0 +1,72 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.wsclient.source.internal; + +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.wsclient.MockHttpServerInterceptor; +import org.sonar.wsclient.internal.HttpRequestFactory; +import org.sonar.wsclient.source.Scm; +import org.sonar.wsclient.source.Source; +import org.sonar.wsclient.source.SourceClient; + +import java.io.IOException; +import java.util.List; + +import static org.fest.assertions.Assertions.assertThat; + +public class DefaultSourceClientTest { + + @Rule + public MockHttpServerInterceptor httpServer = new MockHttpServerInterceptor(); + + @Test + public void show_source() throws IOException { + HttpRequestFactory requestFactory = new HttpRequestFactory(httpServer.url()); + httpServer.stubResponseBody(Resources.toString(Resources.getResource(this.getClass(), "DefaultSourceClientTest/show_source.json"), Charsets.UTF_8)); + + SourceClient client = new DefaultSourceClient(requestFactory); + List sources = client.show("MyFile", "20", "25"); + + assertThat(httpServer.requestedPath()).isEqualTo("/api/sources/show?key=MyFile&from=20&to=25"); + assertThat(sources).hasSize(6); + assertThat(sources.get(0).index()).isEqualTo(20); + assertThat(sources.get(0).line()).isEqualTo("package org.sonar.check;"); + } + + @Test + public void return_scm() throws IOException { + HttpRequestFactory requestFactory = new HttpRequestFactory(httpServer.url()); + httpServer.stubResponseBody(Resources.toString(Resources.getResource(this.getClass(), "DefaultSourceClientTest/return_scm.json"), Charsets.UTF_8)); + + SourceClient client = new DefaultSourceClient(requestFactory); + List result = client.scm("MyFile", "1", "3", true); + + assertThat(httpServer.requestedPath()).isEqualTo("/api/sources/scm?key=MyFile&from=1&to=3&group_commits=true"); + assertThat(result).hasSize(3); + assertThat(result.get(0).index()).isEqualTo(1); + assertThat(result.get(0).author()).isEqualTo("julien"); + assertThat(result.get(0).date().getTime()).isEqualTo(1363129200000L); + } + +} diff --git a/sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/return_scm.json b/sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/return_scm.json new file mode 100644 index 00000000000..513f3e4a17f --- /dev/null +++ b/sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/return_scm.json @@ -0,0 +1,7 @@ +{ + "scm": [ + [1, "julien", "2013-03-13"], + [2, "julien", "2013-03-14"], + [3, "simon", "2014-01-01"] + ] +} diff --git a/sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/show_source.json b/sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/show_source.json new file mode 100644 index 00000000000..74ef52f4510 --- /dev/null +++ b/sonar-ws-client/src/test/resources/org/sonar/wsclient/source/internal/DefaultSourceClientTest/show_source.json @@ -0,0 +1,10 @@ +{ + "sources": [ + [20, "package org.sonar.check;"], + [21, ""], + [22, "public enum Priority {"], + [23, " /**"], + [24, " * WARNING : DO NOT CHANGE THE ENUMERATION ORDER"], + [25, " * the enum ordinal is used for db persistence"] + ] +} -- 2.39.5