aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2014-01-19 22:28:34 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2014-01-19 22:28:34 +0100
commit7e93f91f06dc47fcda0f69ece9ed284e6489ef10 (patch)
tree893bcafbff82cf0491ca755f2701c23c9a389839
parent90272d5ed5bdc0f5bde964c615388e81517e8414 (diff)
downloadsonarqube-7e93f91f06dc47fcda0f69ece9ed284e6489ef10.tar.gz
sonarqube-7e93f91f06dc47fcda0f69ece9ed284e6489ef10.zip
SONAR-5010 public API for Java web services
-rw-r--r--sonar-plugin-api/pom.xml5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/JsonWriter.java)42
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/text/WriterException.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/WriterException.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/text/XmlWriter.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/XmlWriter.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/text/package-info.java (renamed from sonar-plugin-api/src/test/java/org/sonar/api/BaseModelTestCase.java)20
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/Request.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/Request.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/RequestHandler.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/RequestHandler.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/Response.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/Response.java)19
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/SimpleRequest.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/SimpleRequest.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/SimpleResponse.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/SimpleResponse.java)31
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/WebService.java (renamed from sonar-server/src/main/java/org/sonar/server/ws/WebService.java)10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ws/package-info.java24
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java (renamed from sonar-server/src/test/java/org/sonar/server/ws/JsonWriterTest.java)31
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/text/XmlWriterTest.java (renamed from sonar-server/src/test/java/org/sonar/server/ws/XmlWriterTest.java)2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/web/ws/SimpleRequestTest.java (renamed from sonar-server/src/test/java/org/sonar/server/ws/SimpleRequestTest.java)4
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/web/ws/WebServiceTest.java (renamed from sonar-server/src/test/java/org/sonar/server/ws/WebServiceTest.java)41
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java6
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ws/ServletRequest.java2
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java12
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java5
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb36
-rw-r--r--sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java5
-rw-r--r--sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java14
24 files changed, 258 insertions, 65 deletions
diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml
index f6662a75c2a..b916f1dd6f7 100644
--- a/sonar-plugin-api/pom.xml
+++ b/sonar-plugin-api/pom.xml
@@ -14,6 +14,11 @@
<name>SonarQube :: Plugin API</name>
<dependencies>
<dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/JsonWriter.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java
index 66a122d68dc..b5d1ebb1d96 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/JsonWriter.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.utils.text;
import javax.annotation.Nullable;
import java.io.Writer;
@@ -39,9 +39,16 @@ public class JsonWriter {
this.stream.setLenient(false);
}
+ // for unit testing
+ JsonWriter(com.google.gson.stream.JsonWriter stream) {
+ this.stream = stream;
+ }
+
/**
* Begins encoding a new array. Each call to this method must be paired with
* a call to {@link #endArray}. Output is <code>[</code>.
+ *
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter beginArray() {
try {
@@ -54,6 +61,7 @@ public class JsonWriter {
/**
* Ends encoding the current array. Output is <code>]</code>.
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter endArray() {
try {
@@ -67,6 +75,7 @@ public class JsonWriter {
/**
* Begins encoding a new object. Each call to this method must be paired
* with a call to {@link #endObject}. Output is <code>{</code>.
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter beginObject() {
try {
@@ -79,6 +88,7 @@ public class JsonWriter {
/**
* Ends encoding the current object. Output is <code>}</code>.
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter endObject() {
try {
@@ -91,6 +101,7 @@ public class JsonWriter {
/**
* Encodes the property name. Output is <code>"theName":</code>.
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter name(String name) {
try {
@@ -103,6 +114,7 @@ public class JsonWriter {
/**
* Encodes {@code value}. Output is <code>true</code> or <code>false</code>.
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter value(boolean value) {
try {
@@ -113,6 +125,9 @@ public class JsonWriter {
}
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter value(double value) {
try {
stream.value(value);
@@ -122,6 +137,9 @@ public class JsonWriter {
}
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter value(@Nullable String value) {
try {
stream.value(value);
@@ -131,6 +149,9 @@ public class JsonWriter {
}
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter value(long value) {
try {
stream.value(value);
@@ -140,6 +161,9 @@ public class JsonWriter {
}
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter value(@Nullable Number value) {
try {
stream.value(value);
@@ -151,27 +175,43 @@ public class JsonWriter {
/**
* Encodes the property name and value. Output is for example <code>"theName":123</code>.
+ * @throws org.sonar.api.utils.text.WriterException on any failure
*/
public JsonWriter prop(String name, @Nullable Number value) {
return name(name).value(value);
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter prop(String name, @Nullable String value) {
return name(name).value(value);
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter prop(String name, boolean value) {
return name(name).value(value);
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter prop(String name, long value) {
return name(name).value(value);
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public JsonWriter prop(String name, double value) {
return name(name).value(value);
}
+ /**
+ * @throws org.sonar.api.utils.text.WriterException on any failure
+ */
public void close() {
try {
stream.close();
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/WriterException.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/WriterException.java
index 9c9376c1375..a11bf7c6962 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/WriterException.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/WriterException.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.utils.text;
/**
* @since 4.2
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/XmlWriter.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/XmlWriter.java
index 2f5e2e50cd4..e9527358a4f 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/XmlWriter.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/XmlWriter.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.utils.text;
import javax.annotation.Nullable;
import javax.xml.stream.XMLOutputFactory;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/BaseModelTestCase.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/package-info.java
index ada6c76712a..1c11215f8d5 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/BaseModelTestCase.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/package-info.java
@@ -17,22 +17,8 @@
* 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.api;
+@ParametersAreNonnullByDefault
+package org.sonar.api.utils.text;
-import static org.junit.Assert.assertEquals;
+import javax.annotation.ParametersAreNonnullByDefault;
-public abstract class BaseModelTestCase {
-
- protected String overFillString(int maxSize) {
- StringBuilder overFilled = new StringBuilder();
- for (int i = 0; i < 50 + maxSize; i++) {
- overFilled.append("x");
- }
- return overFilled.toString();
- }
-
- protected void assertAbbreviated(int maxSize, String value) {
- assertEquals(maxSize, value.length());
- assertEquals('.', value.charAt(maxSize - 1));
- }
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/Request.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/Request.java
index bb7111620d6..0aac4f12665 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/Request.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/Request.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.web.ws;
import javax.annotation.CheckForNull;
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/RequestHandler.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/RequestHandler.java
index c4783b1c8a6..c7cc37ad1a2 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/RequestHandler.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/RequestHandler.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.web.ws;
import org.sonar.api.ServerExtension;
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/Response.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/Response.java
index 8296c40ef30..6bcb3e75443 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/Response.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/Response.java
@@ -17,8 +17,12 @@
* 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.ws;
+package org.sonar.api.web.ws;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.utils.text.XmlWriter;
+
+import java.io.OutputStream;
import java.io.Writer;
/**
@@ -26,15 +30,16 @@ import java.io.Writer;
*
* @since 4.2
*/
-public abstract class Response {
+public interface Response {
+
+ int status();
- public abstract JsonWriter newJsonWriter();
+ Response setStatus(int httpStatus);
- public abstract XmlWriter newXmlWriter();
+ JsonWriter newJsonWriter();
- public abstract Writer writer();
+ XmlWriter newXmlWriter();
- public abstract int status();
+ OutputStream output();
- public abstract Response setStatus(int httpStatus);
}
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/SimpleRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/SimpleRequest.java
index 014537e7ce1..5a89ca46dd6 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/SimpleRequest.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/SimpleRequest.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.web.ws;
import com.google.common.collect.Maps;
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/SimpleResponse.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/SimpleResponse.java
index e686ecf90cf..0e70a571657 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/SimpleResponse.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/SimpleResponse.java
@@ -17,29 +17,38 @@
* 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.ws;
+package org.sonar.api.web.ws;
-import javax.servlet.http.HttpServletResponse;
-import java.io.StringWriter;
-import java.io.Writer;
+import org.apache.commons.io.Charsets;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.utils.text.XmlWriter;
-public class SimpleResponse extends Response {
- private int httpStatus = HttpServletResponse.SC_OK;
- private final Writer writer = new StringWriter();
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+public class SimpleResponse implements Response {
+ private int httpStatus = 200;
+ private final ByteArrayOutputStream output = new ByteArrayOutputStream();
@Override
public JsonWriter newJsonWriter() {
- return JsonWriter.of(writer);
+ return JsonWriter.of(new OutputStreamWriter(output, Charsets.UTF_8));
}
@Override
public XmlWriter newXmlWriter() {
- return XmlWriter.of(writer);
+ return XmlWriter.of(new OutputStreamWriter(output, Charsets.UTF_8));
}
@Override
- public Writer writer() {
- return writer;
+ public OutputStream output() {
+ return output;
+ }
+
+ // for unit testing
+ public String outputAsString() {
+ return new String(output.toByteArray(), Charsets.UTF_8);
}
@Override
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/WebService.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/WebService.java
index 01d029e9825..0b8c680891e 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/WebService.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/WebService.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.web.ws;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -69,7 +69,9 @@ public interface WebService extends ServerExtension {
private final Map<String, NewAction> actions = Maps.newHashMap();
private NewController(Context context, String path) {
- // TODO check format of path
+ if (StringUtils.isBlank(path)) {
+ throw new IllegalArgumentException("Web service path can't be empty");
+ }
this.context = context;
this.path = path;
}
@@ -191,6 +193,9 @@ public interface WebService extends ServerExtension {
this.description = newAction.description;
this.since = StringUtils.defaultIfBlank(newAction.since, controller.since);
this.post = newAction.post;
+ if (newAction.handler == null) {
+ throw new IllegalStateException("RequestHandler is not set on action " + path);
+ }
this.handler = newAction.handler;
}
@@ -219,7 +224,6 @@ public interface WebService extends ServerExtension {
return post;
}
- @CheckForNull
public RequestHandler handler() {
return handler;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/package-info.java
new file mode 100644
index 00000000000..b5fcdf6e8d1
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ws/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.api.web.ws;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-server/src/test/java/org/sonar/server/ws/JsonWriterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java
index f99f99074eb..4fe227d8be4 100644
--- a/sonar-server/src/test/java/org/sonar/server/ws/JsonWriterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java
@@ -17,15 +17,21 @@
* 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.ws;
+package org.sonar.api.utils.text;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.utils.text.WriterException;
+import java.io.IOException;
import java.io.StringWriter;
+import java.util.concurrent.atomic.AtomicInteger;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class JsonWriterTest {
@@ -70,6 +76,19 @@ public class JsonWriterTest {
}
@Test
+ public void type_of_values() throws Exception {
+ writer.beginObject()
+ .prop("aBoolean", true)
+ .prop("aInt", 123)
+ .prop("aLong", 1000L)
+ .prop("aDouble", 3.14)
+ .prop("aNumber", new AtomicInteger(123456789))
+ .prop("aString", "bar")
+ .endObject().close();
+ expect("{\"aBoolean\":true,\"aInt\":123,\"aLong\":1000,\"aDouble\":3.14,\"aNumber\":123456789,\"aString\":\"bar\"}");
+ }
+
+ @Test
public void ignore_null_values() throws Exception {
writer.beginObject()
.prop("nullNumber", (Number) null)
@@ -100,4 +119,14 @@ public class JsonWriterTest {
thrown.expect(WriterException.class);
writer.beginObject().endArray().close();
}
+
+ @Test
+ public void fail_to_begin_array() throws Exception {
+ com.google.gson.stream.JsonWriter gson = mock(com.google.gson.stream.JsonWriter.class);
+ when(gson.beginArray()).thenThrow(new IOException("the reason"));
+ thrown.expect(WriterException.class);
+ thrown.expectMessage("Fail to write JSON: the reason");
+
+ new JsonWriter(gson).beginArray();
+ }
}
diff --git a/sonar-server/src/test/java/org/sonar/server/ws/XmlWriterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/XmlWriterTest.java
index 9302b4318f5..4aa1f98b443 100644
--- a/sonar-server/src/test/java/org/sonar/server/ws/XmlWriterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/XmlWriterTest.java
@@ -17,7 +17,7 @@
* 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.ws;
+package org.sonar.api.utils.text;
import org.junit.Rule;
import org.junit.Test;
diff --git a/sonar-server/src/test/java/org/sonar/server/ws/SimpleRequestTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/web/ws/SimpleRequestTest.java
index c5164d4317a..b6120c5cc39 100644
--- a/sonar-server/src/test/java/org/sonar/server/ws/SimpleRequestTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/web/ws/SimpleRequestTest.java
@@ -17,10 +17,12 @@
* 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.ws;
+package org.sonar.api.web.ws;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
+import org.sonar.api.web.ws.Request;
+import org.sonar.api.web.ws.SimpleRequest;
import static org.fest.assertions.Assertions.assertThat;
diff --git a/sonar-server/src/test/java/org/sonar/server/ws/WebServiceTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/web/ws/WebServiceTest.java
index 7f17e67b33c..0485597ee18 100644
--- a/sonar-server/src/test/java/org/sonar/server/ws/WebServiceTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/web/ws/WebServiceTest.java
@@ -17,9 +17,13 @@
* 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.ws;
+package org.sonar.api.web.ws;
import org.junit.Test;
+import org.sonar.api.web.ws.Request;
+import org.sonar.api.web.ws.RequestHandler;
+import org.sonar.api.web.ws.Response;
+import org.sonar.api.web.ws.WebService;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
@@ -98,6 +102,7 @@ public class WebServiceTest {
WebService.Action createAction = controller.action("create");
assertThat(createAction).isNotNull();
assertThat(createAction.key()).isEqualTo("create");
+ assertThat(createAction.toString()).isEqualTo("api/metric/create");
// overrides controller version
assertThat(createAction.since()).isEqualTo("4.1");
assertThat(createAction.isPost()).isTrue();
@@ -109,7 +114,7 @@ public class WebServiceTest {
@Override
public void define(Context context) {
NewController controller = context.newController("rule");
- controller.newAction("index");
+ controller.newAction("index").setHandler(mock(RequestHandler.class));
controller.done();
}
}.define(context);
@@ -136,6 +141,23 @@ public class WebServiceTest {
}
@Test
+ public void fail_if_no_action_handler() {
+ try {
+ new WebService() {
+ @Override
+ public void define(Context context) {
+ NewController controller = context.newController("rule");
+ controller.newAction("show");
+ controller.done();
+ }
+ }.define(context);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("RequestHandler is not set on action rule/show");
+ }
+ }
+
+ @Test
public void fail_if_duplicated_action_keys() {
try {
new WebService() {
@@ -170,6 +192,21 @@ public class WebServiceTest {
}
@Test
+ public void fail_if_no_ws_path() {
+ try {
+ new WebService() {
+ @Override
+ public void define(Context context) {
+ context.newController(null).done();
+ }
+ }.define(context);
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Web service path can't be empty");
+ }
+ }
+
+ @Test
public void handle_request() throws Exception {
MetricWebService metricWs = new MetricWebService();
metricWs.define(context);
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java b/sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java
index 6f84efe8304..9d5afcbc995 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java
+++ b/sonar-server/src/main/java/org/sonar/server/ws/ListingWebService.java
@@ -19,6 +19,12 @@
*/
package org.sonar.server.ws;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.web.ws.Request;
+import org.sonar.api.web.ws.RequestHandler;
+import org.sonar.api.web.ws.Response;
+import org.sonar.api.web.ws.WebService;
+
import java.util.List;
/**
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/ServletRequest.java b/sonar-server/src/main/java/org/sonar/server/ws/ServletRequest.java
index 0b20e1d3ac0..e38e53975b3 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/ServletRequest.java
+++ b/sonar-server/src/main/java/org/sonar/server/ws/ServletRequest.java
@@ -19,6 +19,8 @@
*/
package org.sonar.server.ws;
+import org.sonar.api.web.ws.Request;
+
import javax.servlet.http.HttpServletRequest;
public class ServletRequest extends Request {
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java b/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java
index fc21e30faca..97c03a98989 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java
+++ b/sonar-server/src/main/java/org/sonar/server/ws/ServletResponse.java
@@ -19,11 +19,15 @@
*/
package org.sonar.server.ws;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.utils.text.XmlWriter;
+import org.sonar.api.web.ws.Response;
+
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.io.Writer;
+import java.io.OutputStream;
-public class ServletResponse extends Response {
+public class ServletResponse implements Response {
private final HttpServletResponse source;
@@ -50,9 +54,9 @@ public class ServletResponse extends Response {
}
@Override
- public Writer writer() {
+ public OutputStream output() {
try {
- return source.getWriter();
+ return source.getOutputStream();
} catch (IOException e) {
throw new IllegalStateException(e);
}
diff --git a/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java b/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java
index 4a1fc653394..84037f4e460 100644
--- a/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java
+++ b/sonar-server/src/main/java/org/sonar/server/ws/WebServiceEngine.java
@@ -21,9 +21,12 @@ package org.sonar.server.ws;
import org.picocontainer.Startable;
import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.web.ws.Request;
+import org.sonar.api.web.ws.Response;
+import org.sonar.api.web.ws.WebService;
import javax.servlet.http.HttpServletResponse;
-import java.io.StringWriter;
import java.util.List;
/**
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb
index 6b06249c14a..8ff82b92ebf 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/java_ws_controller.rb
@@ -40,6 +40,8 @@ class Api::JavaWsController < Api::ApiController
engine = Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerWs::WebServiceEngine.java_class)
engine.execute(ws_request, ws_response, params[:wspath], params[:wsaction])
- render :text => ws_response.writer(), :status => ws_response.status(), :content_type => media_type
+
+ # response is already written to HttpServletResponse. No need to feed :text
+ render :text => '', :status => ws_response.status(), :content_type => media_type
end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb
index 158fc98daf3..8d5a686080c 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb
@@ -60,6 +60,42 @@ class IssuesController < ApplicationController
end
+ # GET /issues/init?[id=<optional filter id>]
+ def page_init
+ hash = {}
+ hash[:canBulkChange]=logged_in?
+ hash[:canManageFilter]=logged_in?
+
+ if logged_in?
+ favorite_filters = Internal.issues.findFavouriteIssueFiltersForCurrentUser()
+ hash[:favorites] = favorite_filters.map do |filter|
+ {
+ :id => filter.id().to_i,
+ :name => filter.name(),
+ :user => filter.user(),
+ :shared => filter.shared()
+ # no need to export description and query fields
+ }
+ end
+ end
+
+ if params[:id]
+ filter = Internal.issues.findIssueFilter(params[:id].to_i)
+ hash[:filter] = {
+ :id => filter.id().to_i,
+ :name => filter.name(),
+ :user => filter.user(),
+ :shared => filter.shared(),
+ :description => filter.description(),
+ :query => filter.data()
+ }
+ end
+
+ respond_to do |format|
+ format.json { render :json => hash, :status => 200 }
+ end
+ end
+
# Load existing filter
# GET /issues/filter/<filter id>
def filter
diff --git a/sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java b/sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java
index 05cf1e35718..95227dd8dc6 100644
--- a/sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/ws/ListingWebServiceTest.java
@@ -22,8 +22,7 @@ package org.sonar.server.ws;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
-
-import java.io.StringWriter;
+import org.sonar.api.web.ws.*;
import static org.fest.assertions.Assertions.assertThat;
@@ -62,7 +61,7 @@ public class ListingWebServiceTest {
JSONAssert.assertEquals(
IOUtils.toString(getClass().getResource("/org/sonar/server/ws/ListingWebServiceTest/index.json")),
- response.writer().toString(), true
+ response.outputAsString(), true
);
}
diff --git a/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java b/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java
index 6976b1e4dfa..5565f7e1598 100644
--- a/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java
@@ -19,10 +19,10 @@
*/
package org.sonar.server.ws;
-import com.google.common.collect.Maps;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.sonar.api.web.ws.*;
import static org.fest.assertions.Assertions.assertThat;
@@ -52,7 +52,7 @@ public class WebServiceEngineTest {
SimpleResponse response = new SimpleResponse();
engine.execute(request, response, "api/system", "health");
- assertThat(response.writer().toString()).isEqualTo("good");
+ assertThat(response.outputAsString()).isEqualTo("good");
assertThat(response.status()).isEqualTo(200);
}
@@ -62,7 +62,7 @@ public class WebServiceEngineTest {
SimpleResponse response = new SimpleResponse();
engine.execute(request, response, "api/xxx", "health");
- assertThat(response.writer().toString()).isEqualTo("{\"errors\":[{\"msg\":\"Unknown web service: api/xxx\"}]}");
+ assertThat(response.outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"Unknown web service: api/xxx\"}]}");
assertThat(response.status()).isEqualTo(400);
}
@@ -72,7 +72,7 @@ public class WebServiceEngineTest {
SimpleResponse response = new SimpleResponse();
engine.execute(request, response, "api/system", "xxx");
- assertThat(response.writer().toString()).isEqualTo("{\"errors\":[{\"msg\":\"Unknown action: api/system/xxx\"}]}");
+ assertThat(response.outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"Unknown action: api/system/xxx\"}]}");
assertThat(response.status()).isEqualTo(400);
}
@@ -82,7 +82,7 @@ public class WebServiceEngineTest {
SimpleResponse response = new SimpleResponse();
engine.execute(request, response, "api/system", "ping");
- assertThat(response.writer().toString()).isEqualTo("{\"errors\":[{\"msg\":\"Method POST is required\"}]}");
+ assertThat(response.outputAsString()).isEqualTo("{\"errors\":[{\"msg\":\"Method POST is required\"}]}");
assertThat(response.status()).isEqualTo(405);
}
@@ -94,7 +94,7 @@ public class WebServiceEngineTest {
.setHandler(new RequestHandler() {
@Override
public void handle(Request request, Response response) throws Exception {
- response.writer().write("good");
+ response.output().write("good".getBytes());
}
});
newController.newAction("ping")
@@ -102,7 +102,7 @@ public class WebServiceEngineTest {
.setHandler(new RequestHandler() {
@Override
public void handle(Request request, Response response) throws Exception {
- response.writer().write("pong");
+ response.output().write("pong".getBytes());
}
});
newController.done();