]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6017 Add WS to list supported languages
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 20 Jan 2015 10:52:13 +0000 (11:52 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 20 Jan 2015 14:57:49 +0000 (15:57 +0100)
server/sonar-server/src/main/java/org/sonar/server/language/ws/LanguageWs.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/language/ws/ListAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/language/ws/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
server/sonar-server/src/main/resources/org/sonar/server/language/ws/example-list.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/language/ws/LanguageWsTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_filtered_key.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_filtered_name.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_limited.json [new file with mode: 0644]

diff --git a/server/sonar-server/src/main/java/org/sonar/server/language/ws/LanguageWs.java b/server/sonar-server/src/main/java/org/sonar/server/language/ws/LanguageWs.java
new file mode 100644 (file)
index 0000000..cc903c6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.server.language.ws;
+
+import org.sonar.api.server.ws.WebService;
+
+/**
+ * @since 5.1
+ */
+public class LanguageWs implements WebService {
+
+  private final ListAction list;
+
+  public LanguageWs(ListAction list) {
+    this.list = list;
+  }
+
+  @Override
+  public void define(Context context) {
+    NewController languages = context.createController("api/languages")
+      .setDescription("Programming languages")
+      .setSince("5.1");
+
+    list.define(languages);
+
+    languages.done();
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/language/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/language/ws/ListAction.java
new file mode 100644 (file)
index 0000000..fcd4326
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.server.language.ws;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.io.Resources;
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.WebService.NewAction;
+import org.sonar.api.utils.text.JsonWriter;
+
+import javax.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.regex.Pattern;
+
+/**
+ * @since 5.1
+ */
+public class ListAction implements RequestHandler {
+
+  private static final String MATCH_ALL = ".*";
+  private final Languages languages;
+
+  public ListAction(Languages languages) {
+    this.languages = languages;
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    String query = request.param("q");
+    int pageSize = request.mandatoryParamAsInt("ps");
+
+    JsonWriter json = response.newJsonWriter().beginObject().name("languages").beginArray();
+    for (Language language : listMatchingLanguages(query, pageSize)) {
+      json.beginObject().prop("key", language.getKey()).prop("name", language.getName()).endObject();
+    }
+    json.endArray().endObject().close();
+  }
+
+  private Collection<Language> listMatchingLanguages(@Nullable String query, int pageSize) {
+    Pattern pattern = Pattern.compile(query == null ? MATCH_ALL : MATCH_ALL + query + MATCH_ALL, Pattern.CASE_INSENSITIVE);
+
+    SortedMap<String, Language> languagesByName = Maps.newTreeMap();
+    for (Language lang : languages.all()) {
+      if (pattern.matcher(lang.getKey()).matches() || pattern.matcher(lang.getName()).matches()) {
+        languagesByName.put(lang.getName(), lang);
+      }
+    }
+    List<Language> result = Lists.newArrayList(languagesByName.values());
+    if (pageSize > 0 && pageSize < result.size()) {
+      result = result.subList(0, pageSize);
+    }
+    return result;
+  }
+
+  void define(WebService.NewController controller) {
+    NewAction action = controller.createAction("list")
+      .setDescription("List supported programming languages")
+      .setHandler(this)
+      .setResponseExample(Resources.getResource(getClass(), "example-list.json"));
+
+    action.createParam("q")
+      .setDescription("A pattern to match language keys/names against")
+      .setExampleValue("java");
+    action.createParam("ps")
+      .setDescription("The size of the list to return, 0 for all languages")
+      .setExampleValue("25")
+      .setDefaultValue("0");
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/language/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/language/ws/package-info.java
new file mode 100644 (file)
index 0000000..1f5a480
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.server.language.ws;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index 57fbf498be74e4a48248d29af89abf04dc159b69..5d21aaefe5d363c938abc3cc9ccc84d73994422a 100644 (file)
@@ -46,7 +46,6 @@ import org.sonar.core.config.Logback;
 import org.sonar.core.i18n.DefaultI18n;
 import org.sonar.core.i18n.RuleI18nManager;
 import org.sonar.core.issue.IssueFilterSerializer;
-import org.sonar.server.issue.notification.IssueNotifications;
 import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.workflow.FunctionExecutor;
 import org.sonar.core.issue.workflow.IssueWorkflow;
@@ -168,6 +167,7 @@ import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.issue.index.IssueNormalizer;
 import org.sonar.server.issue.notification.ChangesOnMyIssueNotificationDispatcher;
 import org.sonar.server.issue.notification.IssueChangesEmailTemplate;
+import org.sonar.server.issue.notification.IssueNotifications;
 import org.sonar.server.issue.notification.NewFalsePositiveNotificationDispatcher;
 import org.sonar.server.issue.notification.NewIssuesEmailTemplate;
 import org.sonar.server.issue.notification.NewIssuesNotificationDispatcher;
@@ -176,6 +176,8 @@ import org.sonar.server.issue.ws.IssueActionsWriter;
 import org.sonar.server.issue.ws.IssueShowAction;
 import org.sonar.server.issue.ws.IssuesWs;
 import org.sonar.server.issue.ws.SetTagsAction;
+import org.sonar.server.language.ws.LanguageWs;
+import org.sonar.server.language.ws.ListAction;
 import org.sonar.server.measure.MeasureFilterEngine;
 import org.sonar.server.measure.MeasureFilterExecutor;
 import org.sonar.server.measure.MeasureFilterFactory;
@@ -482,7 +484,6 @@ class ServerComponents {
   void startLevel4Components(ComponentContainer pico) {
     pico.addSingleton(PluginDownloader.class);
     pico.addSingleton(ChartFactory.class);
-    pico.addSingleton(Languages.class);
     pico.addSingleton(Views.class);
     pico.addSingleton(ResourceTypes.class);
     pico.addSingleton(SettingsChangeNotifier.class);
@@ -559,6 +560,11 @@ class ServerComponents {
     pico.addSingleton(ActiveRuleCompleter.class);
     pico.addSingleton(AppAction.class);
 
+    // languages
+    pico.addSingleton(Languages.class);
+    pico.addSingleton(LanguageWs.class);
+    pico.addSingleton(ListAction.class);
+
     // activity
     pico.addSingleton(ActivitiesWebService.class);
     pico.addSingleton(org.sonar.server.activity.ws.SearchAction.class);
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/language/ws/example-list.json b/server/sonar-server/src/main/resources/org/sonar/server/language/ws/example-list.json
new file mode 100644 (file)
index 0000000..0ead938
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  "languages": [
+    {"key": "c", "name": "C"},
+    {"key": "cpp", "name": "C++"},
+    {"key": "java", "name": "Java"},
+    {"key": "js", "name": "JavaScript"},
+    {"key": "python", "name": "Python"}
+  ]
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/language/ws/LanguageWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/language/ws/LanguageWsTest.java
new file mode 100644 (file)
index 0000000..e2de7c2
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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.server.language.ws;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.resources.AbstractLanguage;
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.server.ws.WebService.Action;
+import org.sonar.api.server.ws.WebService.Controller;
+import org.sonar.server.ws.WsTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LanguageWsTest {
+
+  private static final String CONTROLLER_LANGUAGES = "api/languages";
+  private static final String ACTION_LIST = "list";
+
+  @Mock
+  private Languages languages;
+
+  WsTester tester;
+
+  @Before
+  public void setUp() {
+    Mockito.when(languages.all()).thenReturn(new Language[] {
+      new Ook(),
+      new LolCode(),
+      new Whitespace(),
+      new ArnoldC()
+    });
+    tester = new WsTester(new LanguageWs(new ListAction(languages)));
+  }
+
+  @Test
+  public void should_be_well_defined() throws Exception {
+    Controller controller = tester.controller(CONTROLLER_LANGUAGES);
+    assertThat(controller).isNotNull();
+    assertThat(controller.description()).isNotEmpty();
+    assertThat(controller.isInternal()).isFalse();
+    assertThat(controller.path()).isEqualTo(CONTROLLER_LANGUAGES);
+    assertThat(controller.since()).isEqualTo("5.1");
+    assertThat(controller.actions()).hasSize(1);
+
+    Action list = controller.action(ACTION_LIST);
+    assertThat(list).isNotNull();
+    assertThat(list.description()).isNotEmpty();
+    assertThat(list.handler()).isInstanceOf(ListAction.class);
+    assertThat(list.isInternal()).isFalse();
+    assertThat(list.isPost()).isFalse();
+    assertThat(list.responseExampleAsString()).isNotEmpty();
+    assertThat(list.params()).hasSize(2);
+  }
+
+  @Test
+  public void should_list_languages() throws Exception {
+    tester.newGetRequest(CONTROLLER_LANGUAGES, ACTION_LIST).execute().assertJson(this.getClass(), "list.json");
+
+    tester.newGetRequest(CONTROLLER_LANGUAGES, ACTION_LIST)
+      .setParam("ps", "2")
+      .execute().assertJson(this.getClass(), "list_limited.json");
+    tester.newGetRequest(CONTROLLER_LANGUAGES, ACTION_LIST)
+      .setParam("ps", "4")
+      .execute().assertJson(this.getClass(), "list.json");
+    tester.newGetRequest(CONTROLLER_LANGUAGES, ACTION_LIST)
+      .setParam("ps", "10")
+      .execute().assertJson(this.getClass(), "list.json");
+
+    tester.newGetRequest(CONTROLLER_LANGUAGES, ACTION_LIST)
+      .setParam("q", "ws")
+      .execute().assertJson(this.getClass(), "list_filtered_key.json");
+    tester.newGetRequest(CONTROLLER_LANGUAGES, ACTION_LIST)
+      .setParam("q", "o")
+      .execute().assertJson(this.getClass(), "list_filtered_name.json");
+  }
+
+  static abstract class TestLanguage extends AbstractLanguage {
+    public TestLanguage(String key, String language) {
+      super(key, language);
+    }
+
+    @Override
+    public String[] getFileSuffixes() {
+      return new String[0];
+    }
+  }
+
+  static class Ook extends TestLanguage {
+    public Ook() {
+      super("ook", "Ook!");
+    }
+  }
+
+  static class LolCode extends TestLanguage {
+    public LolCode() {
+      super("lol", "LOLCODE");
+    }
+  }
+
+  static class Whitespace extends TestLanguage {
+    public Whitespace() {
+      super("ws", "Whitespace");
+    }
+  }
+
+  static class ArnoldC extends TestLanguage {
+    public ArnoldC() {
+      super("ac", "ArnoldC");
+    }
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list.json b/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list.json
new file mode 100644 (file)
index 0000000..32190c0
--- /dev/null
@@ -0,0 +1,8 @@
+{
+  "languages": [
+    {"key": "ac", "name": "ArnoldC"},
+    {"key": "lol", "name": "LOLCODE"},
+    {"key": "ook", "name": "Ook!"},
+    {"key": "ws", "name": "Whitespace"}
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_filtered_key.json b/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_filtered_key.json
new file mode 100644 (file)
index 0000000..187ce02
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "languages": [
+    {"key": "ws", "name": "Whitespace"}
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_filtered_name.json b/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_filtered_name.json
new file mode 100644 (file)
index 0000000..9f167f6
--- /dev/null
@@ -0,0 +1,7 @@
+{
+  "languages": [
+    {"key": "ac", "name": "ArnoldC"},
+    {"key": "lol", "name": "LOLCODE"},
+    {"key": "ook", "name": "Ook!"}
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_limited.json b/server/sonar-server/src/test/resources/org/sonar/server/language/ws/LanguageWsTest/list_limited.json
new file mode 100644 (file)
index 0000000..513d8b1
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "languages": [
+    {"key": "ac", "name": "ArnoldC"},
+    {"key": "lol", "name": "LOLCODE"}
+  ]
+}