aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-ws-client
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 /sonar-ws-client
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 'sonar-ws-client')
-rw-r--r--sonar-ws-client/pom.xml90
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/Host.java65
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/JdkUtils.java45
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/Sonar.java90
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectionException.java37
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java51
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectorFactory.java32
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java180
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java167
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java67
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/CreateQuery.java31
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/DeleteQuery.java29
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Dependency.java159
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyQuery.java153
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTree.java128
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTreeQuery.java88
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Event.java114
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventCreateQuery.java49
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventQuery.java114
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Favourite.java84
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteCreateQuery.java39
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteDeleteQuery.java38
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteQuery.java35
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Measure.java190
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Metric.java114
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/MetricQuery.java57
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Model.java23
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Property.java63
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/PropertyQuery.java57
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java31
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Resource.java210
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/ResourceQuery.java250
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Server.java46
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/ServerQuery.java37
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Source.java51
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/SourceQuery.java105
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyCreateQuery.java75
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyDeleteQuery.java50
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyQuery.java67
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Violation.java110
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/ViolationQuery.java134
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/WSUtils.java20
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/AbstractUnmarshaller.java58
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshaller.java54
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshaller.java42
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/EventUnmarshaller.java38
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/FavouriteUnmarshaller.java37
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/JsonUtils.java94
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/MetricUnmarshaller.java39
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshaller.java33
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshaller.java90
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ServerUnmarshaller.java42
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/SourceUnmarshaller.java40
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshaller.java32
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshallers.java50
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshaller.java49
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/EmptyServlet.java33
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/MetricServlet.java39
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/ServerServlet.java38
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/SonarTest.java138
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/AbstractQueryTest.java86
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/DependencyQueryTest.java53
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/EventQueryTest.java105
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/MeasureTest.java49
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/MetricQueryTest.java41
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/PropertyQueryTest.java40
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceQueryTest.java76
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceTest.java37
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/ServerQueryTest.java37
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/SourceQueryTest.java46
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyCreateQueryTest.java36
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyDeleteQueryTest.java35
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/services/ViolationQueryTest.java46
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshallerTest.java69
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshallerTest.java65
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/EventUnmarshallerTest.java46
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/JsonUtilsTest.java84
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/MetricUnmarshallerTest.java66
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshallerTest.java59
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshallerTest.java108
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ServerUnmarshallerTest.java39
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/SourceUnmarshallerTest.java55
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/UnmarshallersTest.java19
-rw-r--r--sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshallerTest.java67
-rw-r--r--sonar-ws-client/src/test/resources/dependencies/many.json137
-rw-r--r--sonar-ws-client/src/test/resources/dependencies/single.json15
-rw-r--r--sonar-ws-client/src/test/resources/dependency_tree/many_depths.json1
-rw-r--r--sonar-ws-client/src/test/resources/dependency_tree/single_depth.json1
-rw-r--r--sonar-ws-client/src/test/resources/metrics/many_metrics.json1
-rw-r--r--sonar-ws-client/src/test/resources/metrics/one_metric.json1
-rw-r--r--sonar-ws-client/src/test/resources/properties/many.json1
-rw-r--r--sonar-ws-client/src/test/resources/properties/single.json1
-rw-r--r--sonar-ws-client/src/test/resources/resources/many-resources-with-measures.json1
-rw-r--r--sonar-ws-client/src/test/resources/resources/many-resources.json1
-rw-r--r--sonar-ws-client/src/test/resources/resources/single-resource-with-measures.json1
-rw-r--r--sonar-ws-client/src/test/resources/resources/single-resource-with-trends.json29
-rw-r--r--sonar-ws-client/src/test/resources/resources/single-resource.json1
-rw-r--r--sonar-ws-client/src/test/resources/sources/from_line_to_line.json1
-rw-r--r--sonar-ws-client/src/test/resources/sources/source.json1
-rw-r--r--sonar-ws-client/src/test/resources/violations/violation-without-optional-fields.json3
-rw-r--r--sonar-ws-client/src/test/resources/violations/violations.json4
101 files changed, 6085 insertions, 0 deletions
diff --git a/sonar-ws-client/pom.xml b/sonar-ws-client/pom.xml
new file mode 100644
index 00000000000..2875ed54b10
--- /dev/null
+++ b/sonar-ws-client/pom.xml
@@ -0,0 +1,90 @@
+<?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.3-SNAPSHOT</version>
+ </parent>
+ <artifactId>sonar-ws-client</artifactId>
+ <packaging>jar</packaging>
+ <name>Sonar :: Web Service Client</name>
+ <description>Java library to request Sonar web services</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.googlecode.json-simple</groupId>
+ <artifactId>json-simple</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.0</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <!-- for httpclient 4.0 -->
+ <groupId>net.jcip</groupId>
+ <artifactId>jcip-annotations</artifactId>
+ <version>1.0</version>
+ <!--
+ Annotations are only _required_ during a build
+ They are not needed at run-time
+ Provided means that the dependency is not transitive.
+ -->
+ <scope>provided</scope>
+ </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>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-servlet-tester</artifactId>
+ <version>6.1.6</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/Host.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/Host.java
new file mode 100644
index 00000000000..b2beaad138b
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/Host.java
@@ -0,0 +1,65 @@
+/*
+ * 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.wsclient;
+
+public class Host {
+
+ private String host;
+ private String username;
+ private String password;
+
+ public Host(String host) {
+ this.host = host;
+ }
+
+ public Host(String host, String username, String password) {
+ this.host = host;
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public Host setHost(String host) {
+ this.host = host;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public Host setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public Host setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/JdkUtils.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/JdkUtils.java
new file mode 100644
index 00000000000..464fe78cb31
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/JdkUtils.java
@@ -0,0 +1,45 @@
+/*
+ * 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.wsclient;
+
+import org.sonar.wsclient.services.WSUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public final class JdkUtils extends WSUtils {
+
+ public String format(Date date, String format) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+ return dateFormat.format(date);
+ }
+
+ public String encodeUrl(String url) {
+ try {
+ return URLEncoder.encode(url, "UTF-8");
+
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/Sonar.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/Sonar.java
new file mode 100644
index 00000000000..22acd92d2f4
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/Sonar.java
@@ -0,0 +1,90 @@
+/*
+ * 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.wsclient;
+
+import org.sonar.wsclient.connectors.Connector;
+import org.sonar.wsclient.connectors.ConnectorFactory;
+import org.sonar.wsclient.services.*;
+import org.sonar.wsclient.unmarshallers.Unmarshaller;
+import org.sonar.wsclient.unmarshallers.Unmarshallers;
+
+import java.util.Collections;
+import java.util.List;
+
+public class Sonar {
+
+ static {
+ WSUtils.setInstance(new JdkUtils());
+ }
+
+ private Connector connector;
+
+ public Sonar(Connector connector) {
+ this.connector = connector;
+ }
+
+ public Connector getConnector() {
+ return connector;
+ }
+
+ public <MODEL extends Model> MODEL find(Query<MODEL> query) {
+ String json = connector.execute(query);
+ MODEL result = null;
+ if (json != null) {
+ Unmarshaller<MODEL> unmarshaller = Unmarshallers.forModel(query.getModelClass());
+ result = unmarshaller.toModel(json);
+ }
+ return result;
+ }
+
+ public <MODEL extends Model> List<MODEL> findAll(Query<MODEL> query) {
+ String json = connector.execute(query);
+ List<MODEL> result;
+ if (json == null) {
+ result = Collections.emptyList();
+ } else {
+ Unmarshaller<MODEL> unmarshaller = Unmarshallers.forModel(query.getModelClass());
+ result = unmarshaller.toModels(json);
+ }
+ return result;
+ }
+
+ public <MODEL extends Model> MODEL create(CreateQuery<MODEL> query) {
+ String json = connector.execute(query);
+ MODEL result = null;
+ if (json != null) {
+ Unmarshaller<MODEL> unmarshaller = Unmarshallers.forModel(query.getModelClass());
+ result = unmarshaller.toModel(json);
+ }
+ return result;
+ }
+
+ public void delete(DeleteQuery query) {
+ connector.execute(query);
+ }
+
+ public static Sonar create(String host) {
+ return new Sonar(ConnectorFactory.create(new Host(host)));
+ }
+
+ public static Sonar create(String host, String username, String password) {
+ return new Sonar(ConnectorFactory.create(new Host(host, username, password)));
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectionException.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectionException.java
new file mode 100644
index 00000000000..370fe02c533
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectionException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.wsclient.connectors;
+
+public class ConnectionException extends RuntimeException {
+ public ConnectionException() {
+ }
+
+ public ConnectionException(String s) {
+ super(s);
+ }
+
+ public ConnectionException(String s, Throwable throwable) {
+ super(s, throwable);
+ }
+
+ public ConnectionException(Throwable throwable) {
+ super(throwable);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java
new file mode 100644
index 00000000000..f6c7f1477b3
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java
@@ -0,0 +1,51 @@
+/*
+ * 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.wsclient.connectors;
+
+import org.sonar.wsclient.services.CreateQuery;
+import org.sonar.wsclient.services.DeleteQuery;
+import org.sonar.wsclient.services.Query;
+
+/**
+ * @since 2.1
+ */
+public abstract class Connector {
+
+ protected static final int TIMEOUT_MS = 30000;
+
+ /**
+ * @return JSON response or null if 404 NOT FOUND error
+ * @throws ConnectionException if connection error or HTTP status not in (200, 404)
+ */
+ public abstract String execute(Query query);
+
+ /**
+ * @return JSON response or null if 404 NOT FOUND error
+ * @since 2.2
+ */
+ public abstract String execute(CreateQuery query);
+
+ /**
+ * @return JSON response or null if 404 NOT FOUND error
+ * @since 2.2
+ */
+ public abstract String execute(DeleteQuery query);
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectorFactory.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectorFactory.java
new file mode 100644
index 00000000000..e47ffa144d4
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/ConnectorFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.wsclient.connectors;
+
+import org.sonar.wsclient.Host;
+
+public final class ConnectorFactory {
+
+ private ConnectorFactory() {
+ }
+
+ public static Connector create(Host server) {
+ return new HttpClient3Connector(server);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java
new file mode 100644
index 00000000000..da660d1eb27
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java
@@ -0,0 +1,180 @@
+/*
+ * 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.wsclient.connectors;
+
+import org.apache.commons.httpclient.*;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+import org.apache.commons.httpclient.util.URIUtil;
+import org.sonar.wsclient.Host;
+import org.sonar.wsclient.services.CreateQuery;
+import org.sonar.wsclient.services.DeleteQuery;
+import org.sonar.wsclient.services.Query;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * @since 2.1
+ */
+public class HttpClient3Connector extends Connector {
+
+ private static final int MAX_TOTAL_CONNECTIONS = 40;
+ private static final int MAX_HOST_CONNECTIONS = 4;
+
+ private final Host server;
+ private HttpClient httpClient;
+
+ public HttpClient3Connector(final Host server) {
+ this.server = server;
+ createClient();
+ }
+
+ public HttpClient3Connector(Host server, HttpClient httpClient) {
+ this.httpClient = httpClient;
+ this.server = server;
+ }
+
+ private void createClient() {
+ final HttpConnectionManagerParams params = new HttpConnectionManagerParams();
+ params.setConnectionTimeout(TIMEOUT_MS);
+ params.setSoTimeout(TIMEOUT_MS);
+ params.setDefaultMaxConnectionsPerHost(MAX_HOST_CONNECTIONS);
+ params.setMaxTotalConnections(MAX_TOTAL_CONNECTIONS);
+ final MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
+ connectionManager.setParams(params);
+ this.httpClient = new HttpClient(connectionManager);
+ configureCredentials();
+ }
+
+ private void configureCredentials() {
+ if (server.getUsername() != null) {
+ httpClient.getParams().setAuthenticationPreemptive(true);
+ Credentials defaultcreds = new UsernamePasswordCredentials(server.getUsername(), server.getPassword());
+ httpClient.getState().setCredentials(AuthScope.ANY, defaultcreds);
+ }
+ }
+
+ public String execute(Query query) {
+ return executeRequest(newGetRequest(query));
+ }
+
+ public String execute(CreateQuery query) {
+ return executeRequest(newPostRequest(query));
+ }
+
+ public String execute(DeleteQuery query) {
+ return executeRequest(newDeleteRequest(query));
+ }
+
+ private String executeRequest(HttpMethodBase method) {
+ String json = null;
+ try {
+ httpClient.executeMethod(method);
+ if (method.getStatusCode() == HttpStatus.SC_OK) {
+ json = getResponseBodyAsString(method);
+
+ } else if (method.getStatusCode() != HttpStatus.SC_NOT_FOUND) {
+ throw new ConnectionException("HTTP error: " + method.getStatusCode() + ", msg: " + method.getStatusText() + ", query: " + method);
+ }
+
+ } catch (HttpException e) {
+ throw new ConnectionException("Query: " + method, e);
+
+ } catch (IOException e) {
+ throw new ConnectionException("Query: " + method, e);
+
+ } finally {
+ if (method != null) {
+ method.releaseConnection();
+ }
+ }
+ return json;
+ }
+
+ private HttpMethodBase newGetRequest(Query query) {
+ try {
+ String url = server.getHost() + URIUtil.encodeQuery(query.getUrl());
+ HttpMethodBase method = new GetMethod(url);
+ method.setRequestHeader("Accept", "application/json");
+ return method;
+
+ } catch (URIException e) {
+ throw new ConnectionException("Query: " + query, e);
+ }
+ }
+
+ private HttpMethodBase newPostRequest(CreateQuery query) {
+ try {
+ String url = server.getHost() + URIUtil.encodeQuery(query.getUrl());
+ HttpMethodBase method = new PostMethod(url);
+ method.setRequestHeader("Accept", "application/json");
+ return method;
+
+ } catch (URIException e) {
+ throw new ConnectionException("Query: " + query, e);
+ }
+ }
+
+ private HttpMethodBase newDeleteRequest(DeleteQuery query) {
+ try {
+ String url = server.getHost() + URIUtil.encodeQuery(query.getUrl());
+ HttpMethodBase method = new DeleteMethod(url);
+ method.setRequestHeader("Accept", "application/json");
+ return method;
+
+ } catch (URIException e) {
+ throw new ConnectionException("Query: " + query, e);
+ }
+ }
+
+ private String getResponseBodyAsString(HttpMethod method) {
+ BufferedReader reader = null;
+ try {
+ final InputStream inputStream = method.getResponseBodyAsStream();
+ reader = new BufferedReader(new InputStreamReader(inputStream));
+ final StringBuilder sb = new StringBuilder();
+ String line;
+
+ while ((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ return sb.toString();
+
+ } catch (IOException e) {
+ throw new ConnectionException("Can not read response", e);
+
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+
+ } catch (Exception e) {
+ // TODO
+ }
+ }
+ }
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java
new file mode 100644
index 00000000000..73d1d15630f
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java
@@ -0,0 +1,167 @@
+/*
+ * 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.wsclient.connectors;
+
+import org.apache.http.*;
+import org.apache.http.auth.*;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+import org.sonar.wsclient.Host;
+import org.sonar.wsclient.services.CreateQuery;
+import org.sonar.wsclient.services.DeleteQuery;
+import org.sonar.wsclient.services.Query;
+
+import java.io.IOException;
+
+/**
+ * @since 2.1
+ */
+public class HttpClient4Connector extends Connector {
+
+ private Host server;
+
+ public HttpClient4Connector(Host server) {
+ this.server = server;
+ }
+
+ public String execute(Query query) {
+ return executeRequest(newGetMethod(query));
+ }
+
+ public String execute(CreateQuery query) {
+ return executeRequest(newPostMethod(query));
+ }
+
+ public String execute(DeleteQuery query) {
+ return executeRequest(newDeleteMethod(query));
+ }
+
+ private String executeRequest(HttpRequestBase request) {
+ String json = null;
+ DefaultHttpClient client = createClient();
+ try {
+ BasicHttpContext context = createLocalContext(client);
+ HttpResponse response = client.execute(request, context);
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ json = EntityUtils.toString(entity);
+
+ } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_FOUND) {
+ throw new ConnectionException("HTTP error: " + response.getStatusLine().getStatusCode() + ", msg: " + response.getStatusLine().getReasonPhrase() + ", query: " + request.toString());
+ }
+ }
+
+ } catch (IOException e) {
+ throw new ConnectionException("Query: " + request.getURI(), e);
+
+ } finally {
+ client.getConnectionManager().shutdown();
+ }
+ return json;
+ }
+
+ private DefaultHttpClient createClient() {
+ DefaultHttpClient client = new DefaultHttpClient();
+ HttpParams params = client.getParams();
+ HttpConnectionParams.setConnectionTimeout(params, TIMEOUT_MS);
+ HttpConnectionParams.setSoTimeout(params, TIMEOUT_MS);
+ if (server.getUsername() != null) {
+ client.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(server.getUsername(), server.getPassword()));
+ }
+ return client;
+ }
+
+ private BasicHttpContext createLocalContext(DefaultHttpClient client) {
+ BasicHttpContext localcontext = new BasicHttpContext();
+
+ if (server.getUsername() != null) {
+ // Generate BASIC scheme object and stick it to the local
+ // execution context
+ BasicScheme basicAuth = new BasicScheme();
+ localcontext.setAttribute("preemptive-auth", basicAuth);
+
+ // Add as the first request interceptor
+ client.addRequestInterceptor(new PreemptiveAuth(), 0);
+ }
+ return localcontext;
+ }
+
+ private HttpGet newGetMethod(Query query) {
+ HttpGet get = new HttpGet(server.getHost() + query.getUrl());
+ setJsonHeader(get);
+ return get;
+ }
+
+ private HttpDelete newDeleteMethod(DeleteQuery query) {
+ HttpDelete delete = new HttpDelete(server.getHost() + query.getUrl());
+ setJsonHeader(delete);
+ return delete;
+ }
+
+ private HttpPost newPostMethod(CreateQuery query) {
+ HttpPost post = new HttpPost(server.getHost() + query.getUrl());
+ setJsonHeader(post);
+ return post;
+ }
+
+ private void setJsonHeader(HttpRequestBase request) {
+ request.setHeader("Accept", "application/json");
+ }
+
+ static final class PreemptiveAuth implements HttpRequestInterceptor {
+ public void process(
+ final HttpRequest request,
+ final HttpContext context) throws HttpException {
+
+ AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
+
+ // If no auth scheme avaialble yet, try to initialize it preemptively
+ if (authState.getAuthScheme() == null) {
+ AuthScheme authScheme = (AuthScheme) context.getAttribute("preemptive-auth");
+ CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
+ HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+ if (authScheme != null) {
+ Credentials creds = credsProvider.getCredentials(
+ new AuthScope(
+ targetHost.getHostName(),
+ targetHost.getPort()));
+ if (creds == null) {
+ throw new HttpException("No credentials for preemptive authentication");
+ }
+ authState.setAuthScheme(authScheme);
+ authState.setCredentials(creds);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java
new file mode 100644
index 00000000000..f2133b5fe02
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java
@@ -0,0 +1,67 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.Date;
+
+/**
+ * @since 2.2
+ */
+public abstract class AbstractQuery<MODEL extends Model> {
+
+ /**
+ * Must start with a slash, for example: /api/metrics
+ */
+ public abstract String getUrl();
+
+ protected static void appendUrlParameter(StringBuilder url, String paramKey, Object paramValue) {
+ if (paramValue != null) {
+ url.append(paramKey)
+ .append('=')
+ .append(paramValue)
+ .append('&');
+ }
+ }
+
+ protected static void appendUrlParameter(StringBuilder url, String paramKey, Object[] paramValues) {
+ if (paramValues != null) {
+ url.append(paramKey).append('=');
+ for (int index = 0; index < paramValues.length; index++) {
+ if (index > 0) {
+ url.append(',');
+ }
+ if (paramValues[index] != null) {
+ url.append(paramValues[index]);
+ }
+ }
+ url.append('&');
+ }
+ }
+
+ protected static void appendUrlParameter(StringBuilder url, String paramKey, Date paramValue, boolean includeTime) {
+ if (paramValue != null) {
+ String format = (includeTime ? "yyyy-MM-dd'T'HH:mm:ssZ" : "yyyy-MM-dd");
+ url.append(paramKey)
+ .append('=')
+ .append(WSUtils.getINSTANCE().encodeUrl(WSUtils.getINSTANCE().format(paramValue, format)))
+ .append('&');
+ }
+ }
+} \ No newline at end of file
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/CreateQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/CreateQuery.java
new file mode 100644
index 00000000000..f43200604d8
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/CreateQuery.java
@@ -0,0 +1,31 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * POST HTTP request
+ *
+ * @since 2.2
+ */
+public abstract class CreateQuery<MODEL extends Model> extends AbstractQuery<MODEL> {
+
+ public abstract Class<MODEL> getModelClass();
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DeleteQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DeleteQuery.java
new file mode 100644
index 00000000000..0126452bfa7
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DeleteQuery.java
@@ -0,0 +1,29 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * DELETE HTTP request
+ *
+ * @since 2.2
+ */
+public abstract class DeleteQuery<MODEL extends Model> extends AbstractQuery<MODEL> {
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Dependency.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Dependency.java
new file mode 100644
index 00000000000..e6d84d6a1f1
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Dependency.java
@@ -0,0 +1,159 @@
+/*
+ * 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.wsclient.services;
+
+public class Dependency extends Model {
+
+ private String id;
+ private long fromId;
+ private long toId;
+ private String usage;
+ private int weight;
+ private String fromKey;
+ private String fromName;
+ private String fromQualifier;
+ private String toKey;
+ private String toName;
+ private String toQualifier;
+
+ public String getId() {
+ return id;
+ }
+
+ public Dependency setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public long getFromId() {
+ return fromId;
+ }
+
+ public Dependency setFromId(long fromId) {
+ this.fromId = fromId;
+ return this;
+ }
+
+ public long getToId() {
+ return toId;
+ }
+
+ public Dependency setToId(long toId) {
+ this.toId = toId;
+ return this;
+ }
+
+ public String getFromKey() {
+ return fromKey;
+ }
+
+ public Dependency setFromKey(String fromKey) {
+ this.fromKey = fromKey;
+ return this;
+ }
+
+ public String getToKey() {
+ return toKey;
+ }
+
+ public Dependency setToKey(String toKey) {
+ this.toKey = toKey;
+ return this;
+ }
+
+ public String getUsage() {
+ return usage;
+ }
+
+ public Dependency setUsage(String usage) {
+ this.usage = usage;
+ return this;
+ }
+
+ public Integer getWeight() {
+ return weight;
+ }
+
+ public Dependency setWeight(Integer weight) {
+ this.weight = weight;
+ return this;
+ }
+
+ public String getFromName() {
+ return fromName;
+ }
+
+ public Dependency setFromName(String fromName) {
+ this.fromName = fromName;
+ return this;
+ }
+
+ public String getFromQualifier() {
+ return fromQualifier;
+ }
+
+ public Dependency setFromQualifier(String fromQualifier) {
+ this.fromQualifier = fromQualifier;
+ return this;
+ }
+
+ public String getToName() {
+ return toName;
+ }
+
+ public Dependency setToName(String toName) {
+ this.toName = toName;
+ return this;
+ }
+
+ public String getToQualifier() {
+ return toQualifier;
+ }
+
+ public Dependency setToQualifier(String toQualifier) {
+ this.toQualifier = toQualifier;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Dependency that = (Dependency) o;
+ return id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append(fromKey)
+ .append(" -> ")
+ .append(toKey)
+ .toString();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyQuery.java
new file mode 100644
index 00000000000..7d5f10601d5
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyQuery.java
@@ -0,0 +1,153 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * The web service "dependency" is since Sonar 2.0
+ */
+public class DependencyQuery extends Query<Dependency> {
+ public static final String BASE_URL = "/api/dependencies";
+
+ private String resourceIdOrKey = null;
+ private String direction = null;
+ private String parentId = null;
+ private String id = null;
+ public static final String INCOMING_DIRECTION = "in";
+ public static final String OUTGOING_DIRECTION = "out";
+
+ public String getResourceIdOrKey() {
+ return resourceIdOrKey;
+ }
+
+ public DependencyQuery setResourceIdOrKey(String resourceIdOrKey) {
+ this.resourceIdOrKey = resourceIdOrKey;
+ return this;
+ }
+
+ public DependencyQuery setResourceId(long resourceId) {
+ this.resourceIdOrKey = String.valueOf(resourceId);
+ return this;
+ }
+
+ public String getDirection() {
+ return direction;
+ }
+
+ public DependencyQuery setDirection(String direction) {
+ this.direction = direction;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append('?');
+ if (resourceIdOrKey != null) {
+ url.append("resource=").append(resourceIdOrKey).append('&');
+ }
+ if (direction != null) {
+ url.append("dir=").append(direction).append('&');
+ }
+ if (parentId !=null) {
+ url.append("parent=").append(parentId).append('&');
+ }
+ if (id !=null) {
+ url.append("id=").append(id).append('&');
+ }
+ return url.toString();
+ }
+
+ public String getParentId() {
+ return parentId;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public DependencyQuery setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public DependencyQuery setParentId(String parentId) {
+ this.parentId = parentId;
+ return this;
+ }
+
+ @Override
+ public Class<Dependency> getModelClass() {
+ return Dependency.class;
+ }
+
+ /**
+ * Resources that depend upon a resource
+ *
+ * @param resourceIdOrKey the target resource. Can be the primary key (a number) or the logical key (String)
+ */
+ public static DependencyQuery createForIncomingDependencies(String resourceIdOrKey) {
+ DependencyQuery query = new DependencyQuery();
+ query.setResourceIdOrKey(resourceIdOrKey);
+ query.setDirection(INCOMING_DIRECTION);
+ return query;
+ }
+
+ /**
+ * Resources that are depended upon a resource = all the resources that a resource depends upon
+ *
+ * @param resourceIdOrKey the target resource. Can be the primary key (an integer) or the logical key (String)
+ */
+ public static DependencyQuery createForOutgoingDependencies(String resourceIdOrKey) {
+ DependencyQuery query = new DependencyQuery();
+ query.setResourceIdOrKey(resourceIdOrKey);
+ query.setDirection(OUTGOING_DIRECTION);
+ return query;
+ }
+
+ /**
+ * Resources that depend upon or are depended upon a resource. It equals the merge of createForIncomingDependencies(resourceIdOrKey)
+ * and createForOutgoingDependencies(resourceIdOrKey)
+ *
+ * @param resourceIdOrKey the target resource. Can be the primary key (an integer) or the logical key (String)
+ */
+ public static DependencyQuery createForResource(String resourceIdOrKey) {
+ DependencyQuery query = new DependencyQuery();
+ query.setResourceIdOrKey(resourceIdOrKey);
+ return query;
+ }
+
+ public static DependencyQuery createForResource(long resourceId) {
+ DependencyQuery query = new DependencyQuery();
+ query.setResourceId(resourceId);
+ return query;
+ }
+
+ public static DependencyQuery createForSubDependencies(String dependencyId) {
+ DependencyQuery query = new DependencyQuery();
+ query.setParentId(dependencyId);
+ return query;
+ }
+
+ public static DependencyQuery createForId(String id) {
+ DependencyQuery query = new DependencyQuery();
+ query.setId(id);
+ return query;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTree.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTree.java
new file mode 100644
index 00000000000..86c3eb377a4
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTree.java
@@ -0,0 +1,128 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.List;
+
+/**
+ * Experimental
+ */
+public class DependencyTree extends Model {
+ private String depId;
+ private String resourceId;
+ private String resourceKey;
+ private String resourceName;
+ private String usage;
+ private String resourceScope;
+ private String resourceQualifier;
+ private String resourceVersion;
+ private int weight;
+ private List<DependencyTree> to;
+
+ public String getDepId() {
+ return depId;
+ }
+
+ public DependencyTree setDepId(String depId) {
+ this.depId = depId;
+ return this;
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public DependencyTree setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ return this;
+ }
+
+ public String getResourceKey() {
+ return resourceKey;
+ }
+
+ public DependencyTree setResourceKey(String resourceKey) {
+ this.resourceKey = resourceKey;
+ return this;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public DependencyTree setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ return this;
+ }
+
+ public String getUsage() {
+ return usage;
+ }
+
+ public DependencyTree setUsage(String usage) {
+ this.usage = usage;
+ return this;
+ }
+
+ public String getResourceScope() {
+ return resourceScope;
+ }
+
+ public DependencyTree setResourceScope(String resourceScope) {
+ this.resourceScope = resourceScope;
+ return this;
+ }
+
+ public String getResourceQualifier() {
+ return resourceQualifier;
+ }
+
+ public DependencyTree setResourceQualifier(String resourceQualifier) {
+ this.resourceQualifier = resourceQualifier;
+ return this;
+ }
+
+ public String getResourceVersion() {
+ return resourceVersion;
+ }
+
+ public DependencyTree setResourceVersion(String resourceVersion) {
+ this.resourceVersion = resourceVersion;
+ return this;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public DependencyTree setWeight(int weight) {
+ this.weight = weight;
+ return this;
+ }
+
+ public List<DependencyTree> getTo() {
+ return to;
+ }
+
+ public DependencyTree setTo(List<DependencyTree> to) {
+ this.to = to;
+ return this;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTreeQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTreeQuery.java
new file mode 100644
index 00000000000..b5dad433259
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/DependencyTreeQuery.java
@@ -0,0 +1,88 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * @since 2.1
+ */
+public class DependencyTreeQuery extends Query<DependencyTree> {
+ private static final String BASE_URL = "/api/dependency_tree";
+
+ private String resourceId;
+ private String[] scopes;
+
+ public DependencyTreeQuery(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public String[] getScopes() {
+ return scopes;
+ }
+
+ public DependencyTreeQuery setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ return this;
+ }
+
+ public DependencyTreeQuery setScopes(String... scopes) {
+ this.scopes = scopes;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append("?resource=")
+ .append(resourceId)
+ .append("&");
+ if (scopes != null) {
+ url.append("scopes=");
+ if (scopes != null) {
+ for (int index = 0; index < scopes.length; index++) {
+ if (index > 0) {
+ url.append(',');
+ }
+ if (scopes[index] != null) {
+ url.append(scopes[index]);
+ }
+ }
+ url.append('&');
+ }
+ }
+ return url.toString();
+ }
+
+ @Override
+ public Class<DependencyTree> getModelClass() {
+ return DependencyTree.class;
+ }
+
+ public static DependencyTreeQuery createForResource(String resourceIdOrKey) {
+ return new DependencyTreeQuery(resourceIdOrKey);
+ }
+
+ public static DependencyTreeQuery createForProject(String projectIdOrKey) {
+ return new DependencyTreeQuery(projectIdOrKey).setScopes(Resource.SCOPE_SET);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Event.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Event.java
new file mode 100644
index 00000000000..e2181170655
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Event.java
@@ -0,0 +1,114 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.Date;
+
+public class Event extends Model {
+
+ private String id;
+ private String name;
+ private String category;
+ private String description;
+ private String resourceKey;
+ private Date date;
+ private String data;
+
+ public String getId() {
+ return id;
+ }
+
+ public Event setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Event setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public Event setCategory(String category) {
+ this.category = category;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public Event setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public Event setDate(Date date) {
+ this.date = date;
+ return this;
+ }
+
+ public String getResourceKey() {
+ return resourceKey;
+ }
+
+ public Event setResourceKey(String resourceKey) {
+ this.resourceKey = resourceKey;
+ return this;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public Event setData(String data) {
+ this.data = data;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Event event = (Event) o;
+ return !(id != null ? !id.equals(event.id) : event.id != null);
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventCreateQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventCreateQuery.java
new file mode 100644
index 00000000000..9c3e1e3231a
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventCreateQuery.java
@@ -0,0 +1,49 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * @author Evgeny Mandrikov
+ * @since 2.2
+ */
+public class EventCreateQuery extends CreateQuery<Event> {
+ private Event event;
+
+ public EventCreateQuery(Event event) {
+ this.event = event;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(EventQuery.BASE_URL);
+ url.append('?');
+ appendUrlParameter(url, "resource", event.getResourceKey());
+ appendUrlParameter(url, "category", event.getCategory());
+ appendUrlParameter(url, "name", event.getName());
+ appendUrlParameter(url, "description", event.getDescription());
+ appendUrlParameter(url, "data", event.getData());
+ return url.toString();
+ }
+
+ @Override
+ public Class<Event> getModelClass() {
+ return Event.class;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventQuery.java
new file mode 100644
index 00000000000..3e7dfdbe809
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/EventQuery.java
@@ -0,0 +1,114 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.Date;
+
+public class EventQuery extends Query<Event> {
+ public static final String BASE_URL = "/api/events";
+
+ private String resourceKey;
+ private String[] categories;
+ private Date fromDate;
+ private boolean includeFromTime;
+ private Date toDate;
+ private boolean includeToTime;
+
+ public EventQuery() {
+ }
+
+ public EventQuery(String resourceKey) {
+ this.resourceKey = resourceKey;
+ }
+
+ public Date getFrom() {
+ return fromDate;
+ }
+
+ public EventQuery setFrom(Date fromDate, boolean includeTime) {
+ this.fromDate = fromDate;
+ this.includeFromTime = includeTime;
+ return this;
+ }
+
+ public boolean isIncludeFromTime() {
+ return includeFromTime;
+ }
+
+ public Date getTo() {
+ return toDate;
+ }
+
+ public EventQuery setTo(Date toDate, boolean includeTime) {
+ this.toDate = toDate;
+ this.includeToTime = includeTime;
+ return this;
+ }
+
+ public boolean isIncludeToTime() {
+ return includeToTime;
+ }
+
+ public String getResourceKey() {
+ return resourceKey;
+ }
+
+ public EventQuery setResourceKey(String resourceKey) {
+ this.resourceKey = resourceKey;
+ return this;
+ }
+
+ public String[] getCategories() {
+ return categories;
+ }
+
+ public EventQuery setCategories(String[] categories) {
+ this.categories = categories;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append('?');
+ appendUrlParameter(url, "resource", resourceKey);
+ appendUrlParameter(url, "categories", categories);
+ if (fromDate != null) {
+ if (includeFromTime) {
+ appendUrlParameter(url, "fromDateTime", fromDate, true);
+ } else {
+ appendUrlParameter(url, "fromDate", fromDate, false);
+ }
+ }
+ if (toDate != null) {
+ if (includeToTime) {
+ appendUrlParameter(url, "toDateTime", toDate, true);
+ } else {
+ appendUrlParameter(url, "toDate", toDate, false);
+ }
+ }
+ return url.toString();
+ }
+
+ @Override
+ public Class<Event> getModelClass() {
+ return Event.class;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Favourite.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Favourite.java
new file mode 100644
index 00000000000..67917846984
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Favourite.java
@@ -0,0 +1,84 @@
+/*
+ * 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.wsclient.services;
+
+public class Favourite extends Model {
+
+ private Integer id;
+ private String key;
+ private String name;
+ private String scope;
+ private String qualifier;
+ private String language;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public Favourite setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Favourite setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Favourite setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public Favourite setScope(String scope) {
+ this.scope = scope;
+ return this;
+ }
+
+ public String getQualifier() {
+ return qualifier;
+ }
+
+ public Favourite setQualifier(String qualifier) {
+ this.qualifier = qualifier;
+ return this;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public Favourite setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteCreateQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteCreateQuery.java
new file mode 100644
index 00000000000..62484b1c17e
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteCreateQuery.java
@@ -0,0 +1,39 @@
+/*
+ * 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.wsclient.services;
+
+public class FavouriteCreateQuery extends CreateQuery<Favourite> {
+
+ private String idOrKey;
+
+ public FavouriteCreateQuery(String idOrKey) {
+ this.idOrKey = idOrKey;
+ }
+
+ @Override
+ public String getUrl() {
+ return new StringBuilder().append(FavouriteQuery.BASE_URL).append("?key=").append(idOrKey).toString();
+ }
+
+ @Override
+ public Class<Favourite> getModelClass() {
+ return Favourite.class;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteDeleteQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteDeleteQuery.java
new file mode 100644
index 00000000000..00af7895cd3
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteDeleteQuery.java
@@ -0,0 +1,38 @@
+/*
+ * 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.wsclient.services;
+
+public class FavouriteDeleteQuery extends DeleteQuery {
+
+ private String idOrKey;
+
+ public FavouriteDeleteQuery(String idOrKey) {
+ this.idOrKey = idOrKey;
+ }
+
+ public String getIdOrKey() {
+ return idOrKey;
+ }
+
+ @Override
+ public String getUrl() {
+ return new StringBuilder().append(FavouriteQuery.BASE_URL).append('/').append(idOrKey).toString();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteQuery.java
new file mode 100644
index 00000000000..314389e8fa4
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/FavouriteQuery.java
@@ -0,0 +1,35 @@
+/*
+ * 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.wsclient.services;
+
+public class FavouriteQuery extends Query<Favourite> {
+
+ public static final String BASE_URL = "/api/favourites";
+
+ @Override
+ public Class<Favourite> getModelClass() {
+ return Favourite.class;
+ }
+
+ @Override
+ public String getUrl() {
+ return BASE_URL;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Measure.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Measure.java
new file mode 100644
index 00000000000..eb3cae9b9f6
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Measure.java
@@ -0,0 +1,190 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class Measure extends Model {
+
+ private String metricKey;
+ private String metricName;
+ private Double value;
+ private String formattedValue;
+ private String data;
+ private String characteristicKey;
+ private String characteristicName;
+
+ private Integer trend;
+ private Integer var;
+
+ private String ruleKey;
+ private String ruleName;
+ private String ruleCategory;
+ private String rulePriority;
+
+ public String getMetricKey() {
+ return metricKey;
+ }
+
+ public Measure setMetricKey(String metricKey) {
+ this.metricKey = metricKey;
+ return this;
+ }
+
+ public String getMetricName() {
+ return metricName;
+ }
+
+ public Measure setMetricName(String metricName) {
+ this.metricName = metricName;
+ return this;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public Integer getIntValue() {
+ if (value==null) {
+ return null;
+ }
+ return value.intValue();
+ }
+
+ public Measure setValue(Double value) {
+ this.value = value;
+ return this;
+ }
+
+ public String getFormattedValue() {
+ return formattedValue;
+ }
+
+ public String getFormattedValue(String defaultValue) {
+ if (formattedValue==null) {
+ return defaultValue;
+ }
+ return formattedValue;
+ }
+
+ public Measure setFormattedValue(String formattedValue) {
+ this.formattedValue = formattedValue;
+ return this;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public Map<String,String> getDataAsMap() {
+ return getDataAsMap(",");
+ }
+
+ public Map<String,String> getDataAsMap(String separator) {
+ if (data==null) {
+ return null;
+ }
+ Map<String,String> map = new LinkedHashMap<String,String>();
+ String[] parts = data.split(separator);
+ for (String part : parts) {
+ String[] kv = part.split("=");
+ map.put(kv[0], kv[1]);
+ }
+ return map;
+ }
+
+ public Measure setData(String data) {
+ this.data = data;
+ return this;
+ }
+
+ public Integer getTrend() {
+ return trend;
+ }
+
+ public Measure setTrend(Integer trend) {
+ this.trend = trend;
+ return this;
+ }
+
+ public Integer getVar() {
+ return var;
+ }
+
+ public Measure setVar(Integer var) {
+ this.var = var;
+ return this;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public Measure setRuleKey(String ruleKey) {
+ this.ruleKey = ruleKey;
+ return this;
+ }
+
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public Measure setRuleName(String ruleName) {
+ this.ruleName = ruleName;
+ return this;
+ }
+
+ public String getRuleCategory() {
+ return ruleCategory;
+ }
+
+ public Measure setRuleCategory(String ruleCategory) {
+ this.ruleCategory = ruleCategory;
+ return this;
+ }
+
+ public String getRulePriority() {
+ return rulePriority;
+ }
+
+ public Measure setRulePriority(String rulePriority) {
+ this.rulePriority = rulePriority;
+ return this;
+ }
+
+ public String getCharacteristicKey() {
+ return characteristicKey;
+ }
+
+ public String getCharacteristicName() {
+ return characteristicName;
+ }
+
+ public Measure setCharacteristicKey(String s) {
+ this.characteristicKey = s;
+ return this;
+ }
+
+ public Measure setCharacteristicName(String s) {
+ this.characteristicName = s;
+ return this;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Metric.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Metric.java
new file mode 100644
index 00000000000..07ede19e5db
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Metric.java
@@ -0,0 +1,114 @@
+/*
+ * 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.wsclient.services;
+
+public class Metric extends Model {
+
+ private String key;
+ private String name;
+ private int direction;
+ private String domain;
+ private String description;
+ private String type;
+ private Boolean userManaged;
+ private Boolean hidden;
+
+ public String getKey() {
+ return key;
+ }
+
+ public Metric setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Metric setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public int getDirection() {
+ return direction;
+ }
+
+ public Metric setDirection(int direction) {
+ this.direction = direction;
+ return this;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public Metric setDomain(String domain) {
+ this.domain = domain;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public Metric setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public Metric setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Boolean getHidden() {
+ return hidden;
+ }
+
+ public Metric setHidden(Boolean hidden) {
+ this.hidden = hidden;
+ return this;
+ }
+
+ public Boolean getUserManaged() {
+ return userManaged;
+ }
+
+ public Metric setUserManaged(Boolean userManaged) {
+ this.userManaged = userManaged;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append(name)
+ .append("(")
+ .append(key)
+ .append(")")
+ .toString();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/MetricQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/MetricQuery.java
new file mode 100644
index 00000000000..6870cde0da8
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/MetricQuery.java
@@ -0,0 +1,57 @@
+/*
+ * 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.wsclient.services;
+
+public final class MetricQuery extends Query<Metric> {
+ public static final String BASE_URL = "/api/metrics";
+
+ private String key;
+
+ private MetricQuery() {
+ }
+
+ private MetricQuery(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder sb = new StringBuilder(BASE_URL);
+ if (key != null && !"".equals(key)) {
+ sb.append("/");
+ sb.append(key);
+ }
+ sb.append("?");
+ return sb.toString();
+ }
+
+ @Override
+ public Class<Metric> getModelClass() {
+ return Metric.class;
+ }
+
+ public static MetricQuery all() {
+ return new MetricQuery();
+ }
+
+ public static MetricQuery byKey(String metricKey) {
+ return new MetricQuery(metricKey);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Model.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Model.java
new file mode 100644
index 00000000000..3f864877549
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Model.java
@@ -0,0 +1,23 @@
+/*
+ * 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.wsclient.services;
+
+public abstract class Model {
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Property.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Property.java
new file mode 100644
index 00000000000..fd86599c106
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Property.java
@@ -0,0 +1,63 @@
+/*
+ * 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.wsclient.services;
+
+public class Property extends Model {
+
+ private String key;
+ private String value;
+
+ public Property(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Property() {
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Property setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public Property setValue(String value) {
+ this.value = value;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append('[')
+ .append(key)
+ .append(':')
+ .append(value)
+ .append(']')
+ .toString();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/PropertyQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/PropertyQuery.java
new file mode 100644
index 00000000000..1e005cac291
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/PropertyQuery.java
@@ -0,0 +1,57 @@
+/*
+ * 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.wsclient.services;
+
+public class PropertyQuery extends Query<Property> {
+ public static final String BASE_URL = "/api/properties";
+
+ private String key = null;
+
+ public String getKey() {
+ return key;
+ }
+
+ public PropertyQuery setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ String url = BASE_URL;
+ if (key != null) {
+ url += "/" + key;
+ }
+ return url + "?";
+ }
+
+ @Override
+ public Class<Property> getModelClass() {
+ return Property.class;
+ }
+
+ public static PropertyQuery createForAll() {
+ return new PropertyQuery();
+ }
+
+ public static PropertyQuery createForKey(String key) {
+ return new PropertyQuery().setKey(key);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java
new file mode 100644
index 00000000000..345fc109cc3
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java
@@ -0,0 +1,31 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * GET HTTP request
+ *
+ * @since 2.1
+ */
+public abstract class Query<MODEL extends Model> extends AbstractQuery<MODEL> {
+
+ public abstract Class<MODEL> getModelClass();
+
+} \ No newline at end of file
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Resource.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Resource.java
new file mode 100644
index 00000000000..9c0db8178e2
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Resource.java
@@ -0,0 +1,210 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.Collections;
+import java.util.List;
+
+public class Resource extends Model {
+
+ /* SCOPES */
+ public static final String SCOPE_SET = "PRJ";
+ public static final String SCOPE_SPACE = "DIR";
+ public static final String SCOPE_ENTITY = "FIL";
+
+ /* QUALIFIERS */
+ public static final String QUALIFIER_VIEW = "VW";
+ public static final String QUALIFIER_SUBVIEW = "SVW";
+ public static final String QUALIFIER_LIB = "LIB";
+ public static final String QUALIFIER_PROJECT = "TRK";
+ public static final String QUALIFIER_MODULE = "BRC";
+ public static final String QUALIFIER_PACKAGE = "PAC";
+ public static final String QUALIFIER_DIRECTORY = "DIR";
+ public static final String QUALIFIER_FILE = "FIL";
+ public static final String QUALIFIER_CLASS = "CLA";
+ public static final String QUALIFIER_UNIT_TEST_CLASS = "UTS";
+
+ /* LANGUAGES */
+ public static final String LANGUAGE_JAVA = "java";
+
+ private Integer id;
+ private String key;
+ private String name;
+ private String longName;
+ private String scope;
+ private String qualifier;
+ private String language;
+ private String version;
+ private Integer copy;
+ private String description;
+ private List<Measure> measures;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public Resource setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Resource setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public Resource setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getName(boolean longFormatIfDefined) {
+ if (longFormatIfDefined && longName != null && !"".equals(longName)) {
+ return longName;
+ }
+ return name;
+ }
+
+ public String getLongName() {
+ return longName;
+ }
+
+ public Resource setLongName(String longName) {
+ this.longName = longName;
+ return this;
+ }
+
+ public Resource setName(String s) {
+ this.name = s;
+ return this;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public Resource setScope(String scope) {
+ this.scope = scope;
+ return this;
+ }
+
+ public String getQualifier() {
+ return qualifier;
+ }
+
+ public Resource setQualifier(String qualifier) {
+ this.qualifier = qualifier;
+ return this;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public Resource setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public Resource setVersion(String version) {
+ this.version = version;
+ return this;
+ }
+
+ public Integer getCopy() {
+ return copy;
+ }
+
+ public Resource setCopy(Integer copy) {
+ this.copy = copy;
+ return this;
+ }
+
+ public List<Measure> getMeasures() {
+ if (measures == null) {
+ return Collections.emptyList();
+ }
+ return measures;
+ }
+
+ public Measure getMeasure(String metricKey) {
+ for (Measure measure : getMeasures()) {
+ if (metricKey.equals(measure.getMetricKey())) {
+ return measure;
+ }
+ }
+ return null;
+ }
+
+ public Double getMeasureValue(String metricKey) {
+ Measure measure = getMeasure(metricKey);
+ if (measure != null) {
+ return measure.getValue();
+ }
+ return null;
+ }
+
+ public Integer getMeasureIntValue(String metricKey) {
+ Double d = getMeasureValue(metricKey);
+ if (d != null) {
+ return d.intValue();
+ }
+ return null;
+ }
+
+ public String getMeasureFormattedValue(String metricKey, String defaultValue) {
+ Measure measure = getMeasure(metricKey);
+ if (measure != null) {
+ return measure.getFormattedValue(defaultValue);
+ }
+ return defaultValue;
+ }
+
+ public void setMeasures(List<Measure> measures) {
+ this.measures = measures;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("[id=")
+ .append(id)
+ .append(",key=")
+ .append(key)
+ .append("]")
+ .toString();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ResourceQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ResourceQuery.java
new file mode 100644
index 00000000000..8836b9f2bb0
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ResourceQuery.java
@@ -0,0 +1,250 @@
+/*
+ * 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.wsclient.services;
+
+public class ResourceQuery extends Query<Resource> {
+ public static final String BASE_URL = "/api/resources";
+
+ public final static int DEPTH_UNLIMITED = -1;
+
+ private Integer depth;
+ private String resourceKeyOrId;
+ private Integer limit;
+ private String[] scopes;
+ private String[] qualifiers;
+ private String[] metrics;
+ private String[] rules;
+ private String[] ruleCategories;
+ private String[] rulePriorities;
+ private String[] characteristicKeys;
+ private String model;
+ private boolean excludeRules = true;
+ private boolean excludeRuleCategories = true;
+ private boolean excludeRulePriorities = true;
+ private Boolean includeTrends = null;
+ private Boolean verbose = Boolean.FALSE;
+
+ public ResourceQuery() {
+ }
+
+ public ResourceQuery(String resourceKeyOrId) {
+ this.resourceKeyOrId = resourceKeyOrId;
+ }
+
+ public ResourceQuery(long resourceId) {
+ this.resourceKeyOrId = String.valueOf(resourceId);
+ }
+
+ public Integer getDepth() {
+ return depth;
+ }
+
+ public ResourceQuery setDepth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public ResourceQuery setAllDepths() {
+ return setDepth(DEPTH_UNLIMITED);
+ }
+
+ public String getResourceKeyOrId() {
+ return resourceKeyOrId;
+ }
+
+ public ResourceQuery setResourceKeyOrId(String resourceKeyOrId) {
+ this.resourceKeyOrId = resourceKeyOrId;
+ return this;
+ }
+
+ public ResourceQuery setResourceId(int resourceId) {
+ this.resourceKeyOrId = Integer.toString(resourceId);
+ return this;
+ }
+
+ public ResourceQuery setCharacteristicKeys(String model, String... keys) {
+ this.model=model;
+ this.characteristicKeys = keys;
+ return this;
+ }
+
+
+ public Integer getLimit() {
+ return limit;
+ }
+
+ public ResourceQuery setLimit(Integer limit) {
+ this.limit = limit;
+ return this;
+ }
+
+ public String[] getScopes() {
+ return scopes;
+ }
+
+ public ResourceQuery setScopes(String... scopes) {
+ this.scopes = scopes;
+ return this;
+ }
+
+ public String[] getQualifiers() {
+ return qualifiers;
+ }
+
+ public ResourceQuery setQualifiers(String... qualifiers) {
+ this.qualifiers = qualifiers;
+ return this;
+ }
+
+ public String[] getMetrics() {
+ return metrics;
+ }
+
+ public ResourceQuery setMetrics(String... metrics) {
+ this.metrics = metrics;
+ return this;
+ }
+
+ public String[] getRules() {
+ return rules;
+ }
+
+ public ResourceQuery setRules(String... rules) {
+ this.rules = rules;
+ this.excludeRules = false;
+ return this;
+ }
+
+ public String[] getRuleCategories() {
+ return ruleCategories;
+ }
+
+ /**
+ * @param ruleCategories values: Maintainability, Usability, Reliability, Efficiency, Portability
+ */
+ public ResourceQuery setRuleCategories(String... ruleCategories) {
+ this.ruleCategories = ruleCategories;
+ this.excludeRuleCategories = false;
+ return this;
+ }
+
+ public String[] getRulePriorities() {
+ return rulePriorities;
+ }
+
+ /**
+ * @param rulePriorities values: BLOCKER, CRITICAL, MAJOR, MINOR, INFO
+ */
+ public ResourceQuery setRulePriorities(String... rulePriorities) {
+ this.rulePriorities = rulePriorities;
+ this.excludeRulePriorities = false;
+ return this;
+ }
+
+ public boolean isExcludeRules() {
+ return excludeRules;
+ }
+
+ public ResourceQuery setExcludeRules(boolean excludeRules) {
+ this.excludeRules = excludeRules;
+ return this;
+ }
+
+ public boolean isExcludeRuleCategories() {
+ return excludeRuleCategories;
+ }
+
+ public ResourceQuery setExcludeRuleCategories(boolean excludeRuleCategories) {
+ this.excludeRuleCategories = excludeRuleCategories;
+ return this;
+ }
+
+ public boolean isExcludeRulePriorities() {
+ return excludeRulePriorities;
+ }
+
+ public ResourceQuery setExcludeRulePriorities(boolean excludeRulePriorities) {
+ this.excludeRulePriorities = excludeRulePriorities;
+ return this;
+ }
+
+ public Boolean isVerbose() {
+ return verbose;
+ }
+
+ public ResourceQuery setVerbose(Boolean verbose) {
+ this.verbose = verbose;
+ return this;
+ }
+
+ public Boolean isIncludeTrends() {
+ return includeTrends;
+ }
+
+ public ResourceQuery setIncludeTrends(Boolean includeTrends) {
+ this.includeTrends = includeTrends;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append('?');
+ appendUrlParameter(url, "resource", resourceKeyOrId);
+ appendUrlParameter(url, "metrics", metrics);
+ appendUrlParameter(url, "scopes", scopes);
+ appendUrlParameter(url, "qualifiers", qualifiers);
+ appendUrlParameter(url, "depth", depth);
+ appendUrlParameter(url, "limit", limit);
+ appendRuleField(url, "rules", excludeRules, rules);
+ appendRuleField(url, "rule_categories", excludeRuleCategories, ruleCategories);
+ appendRuleField(url, "rule_priorities", excludeRulePriorities, rulePriorities);
+ appendUrlParameter(url, "includetrends", includeTrends);
+ appendUrlParameter(url, "model", model);
+ appendUrlParameter(url, "characteristics", characteristicKeys);
+ appendUrlParameter(url, "verbose", verbose);
+ return url.toString();
+ }
+
+ private void appendRuleField(StringBuilder url, String field, boolean excludeField, String[] list) {
+ if (!excludeField) {
+ if (list == null || list.length == 0) {
+ appendUrlParameter(url, field, true);
+ } else {
+ appendUrlParameter(url, field, list);
+ }
+ }
+ }
+
+ @Override
+ public final Class<Resource> getModelClass() {
+ return Resource.class;
+ }
+
+ public static ResourceQuery createForMetrics(String resourceKeyOrId, String... metricKeys) {
+ return new ResourceQuery(resourceKeyOrId)
+ .setMetrics(metricKeys);
+ }
+
+ public static ResourceQuery createForResource(Resource resource, String... metricKeys) {
+ return new ResourceQuery(resource.getId().toString())
+ .setMetrics(metricKeys);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Server.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Server.java
new file mode 100644
index 00000000000..4919fbb123d
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Server.java
@@ -0,0 +1,46 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class Server extends Model {
+ private String id;
+ private String version;
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Server setVersion(String version) {
+ this.version = version;
+ return this;
+ }
+
+ public Server setId(String id) {
+ this.id = id;
+ return this;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ServerQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ServerQuery.java
new file mode 100644
index 00000000000..ef88ed16df6
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ServerQuery.java
@@ -0,0 +1,37 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class ServerQuery extends Query<Server> {
+ public static final String BASE_URL = "/api/server/index";
+
+ @Override
+ public String getUrl() {
+ return BASE_URL;
+ }
+
+ @Override
+ public Class<Server> getModelClass() {
+ return Server.class;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Source.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Source.java
new file mode 100644
index 00000000000..b703f725c89
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Source.java
@@ -0,0 +1,51 @@
+/*
+ * 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.wsclient.services;
+
+import java.util.Collection;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class Source extends Model {
+
+ private SortedMap<Integer, String> lines = new TreeMap<Integer, String>();
+
+ public Collection<String> getLines() {
+ return lines.values();
+ }
+
+ public SortedMap<Integer, String> getLinesById() {
+ return lines;
+ }
+
+ public String getLine(int index) {
+ return lines.get(index);
+ }
+
+ public int size() {
+ return lines.size();
+ }
+
+ public Source addLine(int index, String line) {
+ lines.put(index, line);
+ return this;
+ }
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/SourceQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/SourceQuery.java
new file mode 100644
index 00000000000..2d79d662640
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/SourceQuery.java
@@ -0,0 +1,105 @@
+/*
+ * 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.wsclient.services;
+
+public class SourceQuery extends Query<Source> {
+ public static final String BASE_URL = "/api/sources";
+
+ private String resourceKeyOrId;
+ private int from = 0;
+ private int to = 0;
+ private boolean highlightedSyntax = false;
+
+ public SourceQuery(String resourceKeyOrId) {
+ this.resourceKeyOrId = resourceKeyOrId;
+ }
+
+ public String getResourceKeyOrId() {
+ return resourceKeyOrId;
+ }
+
+ public SourceQuery setResourceKeyOrId(String resourceKeyOrId) {
+ this.resourceKeyOrId = resourceKeyOrId;
+ return this;
+ }
+
+ public int getFrom() {
+ return from;
+ }
+
+ /**
+ * Get only a few lines
+ *
+ * @param from Index of the first line, starts to 1
+ * @param excludedTo Index of the last line (excluded).
+ */
+ public SourceQuery setFromLineToLine(int from, int excludedTo) {
+ this.from = from;
+ this.to = excludedTo;
+ return this;
+ }
+
+ public SourceQuery setLinesFromLine(int from, int length) {
+ this.from = from;
+ this.to = from + length;
+ return this;
+ }
+
+ public int getTo() {
+ return to;
+ }
+
+ public boolean isHighlightedSyntax() {
+ return highlightedSyntax;
+ }
+
+ public SourceQuery setHighlightedSyntax(boolean b) {
+ this.highlightedSyntax = b;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append("?resource=")
+ .append(resourceKeyOrId)
+ .append("&");
+ if (from > 0 && to > 0) {
+ url.append("from=").append(from).append("&to=").append(to).append("&");
+ }
+ if (highlightedSyntax) {
+ url.append("color=true&");
+ }
+ return url.toString();
+ }
+
+ @Override
+ public Class<Source> getModelClass() {
+ return Source.class;
+ }
+
+ public static SourceQuery create(String resourceKeyOrId) {
+ return new SourceQuery(resourceKeyOrId);
+ }
+
+ public static SourceQuery createWithHighlightedSyntax(String resourceKeyOrId) {
+ return new SourceQuery(resourceKeyOrId).setHighlightedSyntax(true);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyCreateQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyCreateQuery.java
new file mode 100644
index 00000000000..baeba6806f7
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyCreateQuery.java
@@ -0,0 +1,75 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * @since 2.2
+ */
+public class UserPropertyCreateQuery extends CreateQuery<Property> {
+
+ private String key;
+ private String value;
+
+ public UserPropertyCreateQuery() {
+ }
+
+ public UserPropertyCreateQuery(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public UserPropertyCreateQuery(Property property) {
+ this.key = property.getKey();
+ this.value = property.getValue();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public UserPropertyCreateQuery setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public UserPropertyCreateQuery setValue(String value) {
+ this.value = value;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(UserPropertyQuery.BASE_URL);
+ sb.append('?');
+ appendUrlParameter(sb, "key", key);
+ appendUrlParameter(sb, "value", value);
+ return sb.toString();
+ }
+
+ @Override
+ public Class<Property> getModelClass() {
+ return Property.class;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyDeleteQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyDeleteQuery.java
new file mode 100644
index 00000000000..1f4defd58b2
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyDeleteQuery.java
@@ -0,0 +1,50 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * @since 2.2
+ */
+public class UserPropertyDeleteQuery extends DeleteQuery {
+
+ private String key;
+
+ public UserPropertyDeleteQuery(String key) {
+ this.key = key;
+ }
+
+ public UserPropertyDeleteQuery(Property property) {
+ this.key = property.getKey();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public UserPropertyDeleteQuery setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ return new StringBuilder().append(UserPropertyQuery.BASE_URL).append('/').append(key).toString();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyQuery.java
new file mode 100644
index 00000000000..d52b08f3fcf
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/UserPropertyQuery.java
@@ -0,0 +1,67 @@
+/*
+ * 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.wsclient.services;
+
+/**
+ * Get properties of the authenticated user.
+ *
+ * @since 2.2
+ */
+public class UserPropertyQuery extends Query<Property> {
+ public static final String BASE_URL = "/api/user_properties";
+
+ private String key = null;
+
+ /**
+ * Get all user properties
+ */
+ public UserPropertyQuery() {
+ }
+
+ /**
+ * Get only one specific user property
+ */
+ public UserPropertyQuery(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public UserPropertyQuery setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ String url = BASE_URL;
+ if (key != null) {
+ url += "/" + key;
+ }
+ return url + "?";
+ }
+
+ @Override
+ public Class<Property> getModelClass() {
+ return Property.class;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Violation.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Violation.java
new file mode 100644
index 00000000000..4bbf784e3ee
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Violation.java
@@ -0,0 +1,110 @@
+/*
+ * 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.wsclient.services;
+
+public class Violation extends Model {
+
+ private String message = null;
+ private String priority = null;
+ private Integer line = null;
+ private String ruleKey = null;
+ private String ruleName = null;
+ private String resourceKey = null;
+ private String resourceName = null;
+ private String resourceScope = null;
+ private String resourceQualifier = null;
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+ public Integer getLine() {
+ return line;
+ }
+
+ public void setLine(Integer line) {
+ this.line = line;
+ }
+
+ public String getResourceKey() {
+ return resourceKey;
+ }
+
+ public void setResourceKey(String resourceKey) {
+ this.resourceKey = resourceKey;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public Violation setRuleKey(String s) {
+ this.ruleKey = s;
+ return this;
+ }
+
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public Violation setRuleName(String ruleName) {
+ this.ruleName = ruleName;
+ return this;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public Violation setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ return this;
+ }
+
+ public String getResourceScope() {
+ return resourceScope;
+ }
+
+ public Violation setResourceScope(String resourceScope) {
+ this.resourceScope = resourceScope;
+ return this;
+ }
+
+ public String getResourceQualifier() {
+ return resourceQualifier;
+ }
+
+ public Violation setResourceQualifier(String resourceQualifier) {
+ this.resourceQualifier = resourceQualifier;
+ return this;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ViolationQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ViolationQuery.java
new file mode 100644
index 00000000000..9cfddcfb3b4
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/ViolationQuery.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.wsclient.services;
+
+public class ViolationQuery extends Query<Violation> {
+ public static final String BASE_URL = "/api/violations";
+
+ private String[] scopes;
+ private String[] qualifiers;
+ private String[] ruleKeys;
+ private String[] categories;
+ private String[] priorities;
+ private int depth = 0;
+ private String resourceKeyOrId;
+
+ public ViolationQuery(String resourceKeyOrId) {
+ this.resourceKeyOrId = resourceKeyOrId;
+ }
+
+ public String[] getScopes() {
+ return scopes;
+ }
+
+ public ViolationQuery setScopes(String... scopes) {
+ this.scopes = scopes;
+ return this;
+ }
+
+ public String[] getQualifiers() {
+ return qualifiers;
+ }
+
+ public ViolationQuery setQualifiers(String... qualifiers) {
+ this.qualifiers = qualifiers;
+ return this;
+ }
+
+ public String[] getRuleKeys() {
+ return ruleKeys;
+ }
+
+ public ViolationQuery setRuleKeys(String... ruleKeys) {
+ this.ruleKeys = ruleKeys;
+ return this;
+ }
+
+ public String[] getCategories() {
+ return categories;
+ }
+
+ public ViolationQuery setCategories(String... categories) {
+ this.categories = categories;
+ return this;
+ }
+
+ public String[] getPriorities() {
+ return priorities;
+ }
+
+ public ViolationQuery setPriorities(String... priorities) {
+ this.priorities = priorities;
+ return this;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public ViolationQuery setDepth(int depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append("?resource=")
+ .append(resourceKeyOrId)
+ .append("&");
+
+ if (depth != 0) {
+ url.append("depth").append(depth).append("&");
+ }
+ append(url, "scopes", scopes);
+ append(url, "qualifiers", qualifiers);
+ append(url, "rules", ruleKeys);
+ append(url, "categories", categories);
+ append(url, "priorities", priorities);
+ return url.toString();
+ }
+
+ private void append(StringBuilder url, String paramKey, Object[] paramValues) {
+ if (paramValues != null && paramValues.length > 0) {
+ url.append(paramKey).append('=');
+ for (int index = 0; index < paramValues.length; index++) {
+ if (index > 0) {
+ url.append(',');
+ }
+ url.append(paramValues[index]);
+ }
+ url.append('&');
+ }
+ }
+
+ @Override
+ public Class<Violation> getModelClass() {
+ return Violation.class;
+ }
+
+ public static ViolationQuery createForResource(Resource resource) {
+ return new ViolationQuery(resource.getId().toString());
+ }
+
+ public static ViolationQuery createForResource(String resourceIdOrKey) {
+ return new ViolationQuery(resourceIdOrKey);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/WSUtils.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/WSUtils.java
new file mode 100644
index 00000000000..61e5940cb0f
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/WSUtils.java
@@ -0,0 +1,20 @@
+package org.sonar.wsclient.services;
+
+import java.util.Date;
+
+public abstract class WSUtils {
+
+ private static WSUtils INSTANCE = null;
+
+ public static void setInstance(WSUtils utils) {
+ INSTANCE = utils;
+ }
+
+ public static WSUtils getINSTANCE() {
+ return INSTANCE;
+ }
+
+ public abstract String format(Date date, String format);
+
+ public abstract String encodeUrl(String url);
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/AbstractUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/AbstractUnmarshaller.java
new file mode 100644
index 00000000000..d906f4ad9d8
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/AbstractUnmarshaller.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.wsclient.unmarshallers;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.sonar.wsclient.services.Model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class AbstractUnmarshaller<MODEL extends Model> implements Unmarshaller<MODEL> {
+
+ public final MODEL toModel(String json) {
+ MODEL result = null;
+ JSONArray array = (JSONArray) JSONValue.parse(json);
+ if (array.size() >= 1) {
+ JSONObject elt = (JSONObject) array.get(0);
+ if (elt != null) {
+ result = parse(elt);
+ }
+ }
+ return result;
+
+ }
+
+ public final List<MODEL> toModels(String json) {
+ List<MODEL> result = new ArrayList<MODEL>();
+ JSONArray array = (JSONArray) JSONValue.parse(json);
+ for (Object anArray : array) {
+ JSONObject elt = (JSONObject) anArray;
+ if (elt != null) {
+ result.add(parse(elt));
+ }
+ }
+ return result;
+ }
+
+ protected abstract MODEL parse(JSONObject elt);
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshaller.java
new file mode 100644
index 00000000000..f326ba02176
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshaller.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.wsclient.unmarshallers;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.DependencyTree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DependencyTreeUnmarshaller extends AbstractUnmarshaller<DependencyTree> {
+ @Override
+ protected DependencyTree parse(JSONObject json) {
+ DependencyTree tree = new DependencyTree()
+ .setDepId(JsonUtils.getString(json, "did"))
+ .setResourceId(JsonUtils.getString(json, "rid"))
+ .setResourceKey(JsonUtils.getString(json, "k"))
+ .setResourceName(JsonUtils.getString(json, "n"))
+ .setResourceScope(JsonUtils.getString(json, "s"))
+ .setResourceQualifier(JsonUtils.getString(json, "q"))
+ .setResourceVersion(JsonUtils.getString(json, "v"))
+ .setUsage(JsonUtils.getString(json, "u"))
+ .setWeight(JsonUtils.getInteger(json, "w"));
+
+ List<DependencyTree> to = new ArrayList<DependencyTree>();
+ tree.setTo(to);
+
+ JSONArray toJson = (JSONArray) json.get("to");
+ if (toJson != null) {
+ for (Object aToJson : toJson) {
+ to.add(parse((JSONObject) aToJson));
+ }
+ }
+ return tree;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshaller.java
new file mode 100644
index 00000000000..803753aede7
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshaller.java
@@ -0,0 +1,42 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Dependency;
+
+public class DependencyUnmarshaller extends AbstractUnmarshaller<Dependency> {
+
+ @Override
+ protected Dependency parse(JSONObject json) {
+ return new Dependency()
+ .setId(JsonUtils.getString(json, "id"))
+ .setFromId(JsonUtils.getLong(json, "fi"))
+ .setToId(JsonUtils.getLong(json, "ti"))
+ .setFromKey(JsonUtils.getString(json, "fk"))
+ .setToKey(JsonUtils.getString(json, "tk"))
+ .setUsage(JsonUtils.getString(json, "u"))
+ .setWeight(JsonUtils.getInteger(json, "w"))
+ .setFromName(JsonUtils.getString(json, "fn"))
+ .setFromQualifier(JsonUtils.getString(json, "fq"))
+ .setToName(JsonUtils.getString(json, "tn"))
+ .setToQualifier(JsonUtils.getString(json, "tq"));
+ }
+} \ No newline at end of file
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/EventUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/EventUnmarshaller.java
new file mode 100644
index 00000000000..2f7878e55ef
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/EventUnmarshaller.java
@@ -0,0 +1,38 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Event;
+
+public class EventUnmarshaller extends AbstractUnmarshaller<Event> {
+
+ @Override
+ protected Event parse(JSONObject json) {
+ return new Event()
+ .setId(JsonUtils.getString(json, "id"))
+ .setResourceKey(JsonUtils.getString(json, "rk"))
+ .setName(JsonUtils.getString(json, "n"))
+ .setCategory(JsonUtils.getString(json, "c"))
+ .setDate(JsonUtils.getDateTime(json, "dt"))
+ .setDescription(JsonUtils.getString(json, "ds"))
+ .setData(JsonUtils.getString(json, "data"));
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/FavouriteUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/FavouriteUnmarshaller.java
new file mode 100644
index 00000000000..ab93ef28082
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/FavouriteUnmarshaller.java
@@ -0,0 +1,37 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Favourite;
+
+public class FavouriteUnmarshaller extends AbstractUnmarshaller<Favourite> {
+
+ @Override
+ protected Favourite parse(JSONObject json) {
+ return new Favourite()
+ .setId(JsonUtils.getInteger(json, "id"))
+ .setKey(JsonUtils.getString(json, "key"))
+ .setName(JsonUtils.getString(json, "name"))
+ .setScope(JsonUtils.getString(json, "scope"))
+ .setQualifier(JsonUtils.getString(json, "qualifier"))
+ .setLanguage(JsonUtils.getString(json, "lang"));
+ }
+}
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
new file mode 100644
index 00000000000..598812dc7e7
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/JsonUtils.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.wsclient.unmarshallers;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+public final class JsonUtils {
+
+ private JsonUtils() {
+ // only static methods
+ }
+
+ public static String getString(Map obj, String field) {
+ Object value = obj.get(field);
+ if (value != null) {
+ return (String) value;
+ }
+ return null;
+ }
+
+ public static Integer getInteger(Map obj, String field) {
+ Object value = obj.get(field);
+ if (value != null) {
+ return ((Long) value).intValue();
+ }
+ return null;
+ }
+
+ public static Boolean getBoolean(Map obj, String field) {
+ Object value = obj.get(field);
+ if (value != null) {
+ return (Boolean)value;
+ }
+ return null;
+ }
+
+ public static Long getLong(Map obj, String field) {
+ Object value = obj.get(field);
+ if (value != null) {
+ return (Long) value;
+ }
+ return null;
+ }
+
+ public static Double getDouble(Map obj, String field) {
+ Object value = obj.get(field);
+ if (value != null) {
+ return (Double) value;
+ }
+ return null;
+ }
+
+ public static Date getDateTime(Map obj, String field) {
+ return parseDate(obj, field, "yyyy-MM-dd'T'HH:mm:ssZ");
+ }
+
+ public static Date getDate(Map obj, String field) {
+ return parseDate(obj, field, "yyyy-MM-dd");
+ }
+
+ private static Date parseDate(Map obj, String field, String format) {
+ String value = getString(obj, field);
+ if (value != null) {
+ try {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(format);
+ return dateFormat.parse(value);
+
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return null;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/MetricUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/MetricUnmarshaller.java
new file mode 100644
index 00000000000..d90101b833d
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/MetricUnmarshaller.java
@@ -0,0 +1,39 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Metric;
+
+public class MetricUnmarshaller extends AbstractUnmarshaller<Metric> {
+
+ @Override
+ protected Metric parse(JSONObject json) {
+ return new Metric()
+ .setKey((String) json.get("key"))
+ .setName((String) json.get("name"))
+ .setDomain((String) json.get("domain"))
+ .setDescription((String) json.get("description"))
+ .setDirection(JsonUtils.getInteger(json, "direction"))
+ .setType(JsonUtils.getString(json, "val_type"))
+ .setUserManaged(JsonUtils.getBoolean(json, "user_managed"))
+ .setHidden(JsonUtils.getBoolean(json, "hidden"));
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshaller.java
new file mode 100644
index 00000000000..cf71b47c32b
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshaller.java
@@ -0,0 +1,33 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Property;
+
+public class PropertyUnmarshaller extends AbstractUnmarshaller<Property> {
+
+ @Override
+ protected Property parse(JSONObject json) {
+ return new Property()
+ .setKey((String) json.get("key"))
+ .setValue((String) json.get("value"));
+ }
+} \ No newline at end of file
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshaller.java
new file mode 100644
index 00000000000..87a31147a9f
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshaller.java
@@ -0,0 +1,90 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Measure;
+import org.sonar.wsclient.services.Resource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ResourceUnmarshaller extends AbstractUnmarshaller<Resource> {
+
+ @Override
+ protected Resource parse(JSONObject json) {
+ Resource resource = new Resource();
+ parseResourceFields(json, resource);
+ parseMeasures(json, resource);
+ return resource;
+ }
+
+ private void parseResourceFields(JSONObject json, Resource resource) {
+ resource.setId(JsonUtils.getInteger(json, "id"))
+ .setKey(JsonUtils.getString(json, "key"))
+ .setName(JsonUtils.getString(json, "name"))
+ .setLongName(JsonUtils.getString(json, "lname"))
+ .setScope(JsonUtils.getString(json, "scope"))
+ .setQualifier(JsonUtils.getString(json, "qualifier"))
+ .setLanguage(JsonUtils.getString(json, "lang"))
+ .setDescription(JsonUtils.getString(json, "description"))
+ .setVersion(JsonUtils.getString(json, "version"));
+ }
+
+ private void parseMeasures(JSONObject json, Resource resource) {
+ JSONArray measuresJson = (JSONArray) json.get("msr");
+ if (measuresJson != null) {
+ resource.setMeasures(parseMeasures(measuresJson));
+ }
+ }
+
+ private List<Measure> parseMeasures(JSONArray measuresJson) {
+ List<Measure> projectMeasures = new ArrayList<Measure>();
+ int len = measuresJson.size();
+ for (int i = 0; i < len; i++) {
+ JSONObject measureJson = (JSONObject) measuresJson.get(i);
+ if (measureJson != null) {
+ Measure measure = parseMeasure(measureJson);
+ projectMeasures.add(measure);
+ }
+ }
+ return projectMeasures;
+ }
+
+ private Measure parseMeasure(JSONObject json) {
+ Measure measure = new Measure();
+ measure
+ .setMetricKey(JsonUtils.getString(json, "key"))
+ .setMetricName(JsonUtils.getString(json, "name"))
+ .setValue(JsonUtils.getDouble(json, "val"))
+ .setFormattedValue(JsonUtils.getString(json, "frmt_val"))
+ .setTrend(JsonUtils.getInteger(json, "trend"))
+ .setVar(JsonUtils.getInteger(json, "var"))
+ .setData(JsonUtils.getString(json, "data"))
+ .setRuleKey(JsonUtils.getString(json, "rule_key"))
+ .setRuleName(JsonUtils.getString(json, "rule_name"))
+ .setRuleCategory(JsonUtils.getString(json, "rule_category"))
+ .setRulePriority(JsonUtils.getString(json, "rule_priority"))
+ .setCharacteristicKey(JsonUtils.getString(json, "ctic_key"))
+ .setCharacteristicName(JsonUtils.getString(json, "ctic_name"));
+ return measure;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ServerUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ServerUnmarshaller.java
new file mode 100644
index 00000000000..d980876e3f8
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ServerUnmarshaller.java
@@ -0,0 +1,42 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.sonar.wsclient.services.Server;
+
+import java.util.List;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class ServerUnmarshaller implements Unmarshaller<Server> {
+ public Server toModel(String json) {
+ JSONObject map = (JSONObject) JSONValue.parse(json);
+ return new Server()
+ .setId(JsonUtils.getString(map, "id"))
+ .setVersion(JsonUtils.getString(map, "version"));
+ }
+
+ public List<Server> toModels(String json) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/SourceUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/SourceUnmarshaller.java
new file mode 100644
index 00000000000..cbda6b4c5d0
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/SourceUnmarshaller.java
@@ -0,0 +1,40 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Source;
+
+import java.util.Map;
+
+public class SourceUnmarshaller extends AbstractUnmarshaller<Source> {
+
+ @Override
+ protected Source parse(JSONObject json) {
+ Source source = new Source();
+
+ for (Object o : json.entrySet()) {
+ Map.Entry<String, String> entry = (Map.Entry<String, String>) o;
+ source.addLine(Integer.parseInt(entry.getKey()), entry.getValue());
+ }
+
+ return source;
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshaller.java
new file mode 100644
index 00000000000..bed74add09a
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshaller.java
@@ -0,0 +1,32 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.sonar.wsclient.services.Model;
+
+import java.util.List;
+
+public interface Unmarshaller<MODEL extends Model> {
+
+ MODEL toModel(String json);
+
+ List<MODEL> toModels(String json);
+
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshallers.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshallers.java
new file mode 100644
index 00000000000..3523f1ce836
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/Unmarshallers.java
@@ -0,0 +1,50 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.sonar.wsclient.services.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class Unmarshallers {
+ private Unmarshallers() {
+ }
+
+ private static Map<Class, Unmarshaller> unmarshallers;
+
+ static {
+ unmarshallers = new HashMap<Class, Unmarshaller>();
+ unmarshallers.put(Metric.class, new MetricUnmarshaller());
+ unmarshallers.put(Dependency.class, new DependencyUnmarshaller());
+ unmarshallers.put(Resource.class, new ResourceUnmarshaller());
+ unmarshallers.put(Property.class, new PropertyUnmarshaller());
+ unmarshallers.put(Source.class, new SourceUnmarshaller());
+ unmarshallers.put(Violation.class, new ViolationUnmarshaller());
+ unmarshallers.put(Server.class, new ServerUnmarshaller());
+ unmarshallers.put(DependencyTree.class, new DependencyTreeUnmarshaller());
+ unmarshallers.put(Event.class, new EventUnmarshaller());
+ unmarshallers.put(Favourite.class, new FavouriteUnmarshaller());
+ }
+
+ public static <MODEL extends Model> Unmarshaller<MODEL> forModel(Class<MODEL> modelClass) {
+ return unmarshallers.get(modelClass);
+ }
+}
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshaller.java
new file mode 100644
index 00000000000..ab8a91fa96a
--- /dev/null
+++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshaller.java
@@ -0,0 +1,49 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.sonar.wsclient.services.Violation;
+
+public class ViolationUnmarshaller extends AbstractUnmarshaller<Violation> {
+
+ @Override
+ protected Violation parse(JSONObject json) {
+ Violation violation = new Violation();
+ violation.setMessage(JsonUtils.getString(json, "message"));
+ violation.setLine(JsonUtils.getInteger(json, "line"));
+ violation.setPriority(JsonUtils.getString(json, "priority"));
+
+ JSONObject rule = (JSONObject)json.get("rule");
+ if (rule!=null) {
+ violation.setRuleKey(JsonUtils.getString(rule, "key"));
+ violation.setRuleName(JsonUtils.getString(rule, "name"));
+ }
+
+ JSONObject resource = (JSONObject)json.get("resource");
+ if (resource!=null) {
+ violation.setResourceKey(JsonUtils.getString(resource, "key"));
+ violation.setResourceName(JsonUtils.getString(resource, "name"));
+ violation.setResourceQualifier(JsonUtils.getString(resource, "qualifier"));
+ violation.setResourceScope(JsonUtils.getString(resource, "scope"));
+ }
+ return violation;
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/EmptyServlet.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/EmptyServlet.java
new file mode 100644
index 00000000000..d4c74cdb08b
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/EmptyServlet.java
@@ -0,0 +1,33 @@
+/*
+ * 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.wsclient;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+
+public class EmptyServlet extends GenericServlet {
+ @Override
+ public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+ response.getWriter().println("[]");
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/MetricServlet.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/MetricServlet.java
new file mode 100644
index 00000000000..b81c6dcbfa3
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/MetricServlet.java
@@ -0,0 +1,39 @@
+/*
+ * 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.wsclient;
+
+import org.apache.commons.io.IOUtils;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class MetricServlet extends GenericServlet {
+ @Override
+ public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+ PrintWriter out = response.getWriter();
+
+ String json = IOUtils.toString(MetricServlet.class.getResourceAsStream("/metrics/many_metrics.json"));
+ out.println(json);
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/ServerServlet.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/ServerServlet.java
new file mode 100644
index 00000000000..48cd7636977
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/ServerServlet.java
@@ -0,0 +1,38 @@
+/*
+ * 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.wsclient;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class ServerServlet extends GenericServlet {
+ @Override
+ public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+ PrintWriter out = response.getWriter();
+ out.println("{\"id\":\"123456789\",\"version\":\"2.0\"}");
+ }
+} \ No newline at end of file
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/SonarTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/SonarTest.java
new file mode 100644
index 00000000000..5546dde1910
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/SonarTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.wsclient;
+
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mortbay.jetty.testing.ServletTester;
+import org.sonar.wsclient.connectors.ConnectionException;
+import org.sonar.wsclient.connectors.HttpClient3Connector;
+import org.sonar.wsclient.connectors.HttpClient4Connector;
+import org.sonar.wsclient.services.*;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.number.OrderingComparisons.greaterThan;
+import static org.junit.Assert.assertThat;
+
+@RunWith(value = Parameterized.class)
+public class SonarTest {
+
+ private static ServletTester tester;
+ private static String baseUrl;
+ private Sonar sonar;
+
+ public SonarTest(Sonar sonar) {
+ this.sonar = sonar;
+ }
+
+ /**
+ * This kicks off an instance of the Jetty
+ * servlet container so that we can hit it.
+ * We register an echo service that simply
+ * returns the parameters passed to it.
+ */
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() throws Exception {
+ tester = new ServletTester();
+ tester.setContextPath("/");
+ tester.addServlet(ServerServlet.class, "/api/server/index");
+ tester.addServlet(MetricServlet.class, "/api/metrics");
+ tester.addServlet(EmptyServlet.class, "/api/empty");
+ baseUrl = tester.createSocketConnector(true);
+ tester.start();
+
+ return Arrays.asList(new Object[][]{
+ {new Sonar(new HttpClient4Connector(new Host(baseUrl)))},
+ {new Sonar(new HttpClient3Connector(new Host(baseUrl)))}
+ });
+ }
+
+
+ @AfterClass
+ public static void stopServer() throws Exception {
+ tester.stop();
+ }
+
+ @Test
+ public void findAll() {
+ Collection<Metric> metrics = sonar.findAll(MetricQuery.all());
+ assertThat(metrics.size(), greaterThan(1));
+ }
+
+ @Test
+ public void findEmptyResults() {
+ Query<Metric> query = new EmptyQuery();
+ Collection<Metric> metrics = sonar.findAll(query);
+ assertThat(metrics.size(), is(0));
+ }
+
+ @Test
+ public void urlWithCharactersToEncode() {
+ sonar.find(new QueryWithInvalidCharacters());
+ // no exception
+ }
+
+ @Test
+ public void returnNullWhenSingleResultNotFound() {
+ Query<Metric> query = new EmptyQuery();
+ assertThat(sonar.find(query), nullValue());
+ }
+
+ @Test(expected = ConnectionException.class)
+ public void failWhenConnectionIsClosed() throws Exception {
+ Sonar fakeSonar = Sonar.create("http://localhost:70");
+ fakeSonar.findAll(MetricQuery.all());
+ }
+
+ @Test
+ public void getVersion() {
+ Server server = sonar.find(new ServerQuery());
+ assertThat(server.getId(), is("123456789"));
+ assertThat(server.getVersion(), is("2.0"));
+ }
+
+ static class EmptyQuery extends Query<Metric> {
+ public String getUrl() {
+ return "/api/empty";
+ }
+
+ public Class<Metric> getModelClass() {
+ return Metric.class;
+ }
+ }
+
+ static class QueryWithInvalidCharacters extends Query<Metric> {
+ public String getUrl() {
+ // [] must be encoded
+ return "/api/violations?resource=myproject:[default]:Foo";
+ }
+
+ public Class<Metric> getModelClass() {
+ return Metric.class;
+ }
+ }
+}
+
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/AbstractQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/AbstractQueryTest.java
new file mode 100644
index 00000000000..b15ae8386a1
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/AbstractQueryTest.java
@@ -0,0 +1,86 @@
+package org.sonar.wsclient.services;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.sonar.wsclient.JdkUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import static junit.framework.Assert.assertEquals;
+
+public class AbstractQueryTest {
+
+ @BeforeClass
+ public static void before() {
+ WSUtils.setInstance(new JdkUtils());
+ }
+
+ @AfterClass
+ public static void after() {
+ WSUtils.setInstance(null);
+ }
+
+ @Test
+ public void appendUrlParameter() {
+ StringBuilder url = new StringBuilder();
+ AbstractQuery.appendUrlParameter(url, "foo", "bar");
+ assertEquals("foo=bar&", url.toString());
+ AbstractQuery.appendUrlParameter(url, "foo2", "bar2");
+ assertEquals("foo=bar&foo2=bar2&", url.toString());
+ }
+
+ @Test
+ public void appendUrlBooleanParameter() {
+ StringBuilder url = new StringBuilder();
+ AbstractQuery.appendUrlParameter(url, "foo", Boolean.TRUE);
+ assertEquals("foo=true&", url.toString());
+ }
+
+ @Test
+ public void appendUrlIntParameter() {
+ StringBuilder url = new StringBuilder();
+ AbstractQuery.appendUrlParameter(url, "foo", 9);
+ assertEquals("foo=9&", url.toString());
+ }
+
+ @Test
+ public void appendUrlArrayParameter() {
+ StringBuilder url = new StringBuilder();
+ AbstractQuery.appendUrlParameter(url, "foo", new String[]{"bar", "bar2"});
+ assertEquals("foo=bar,bar2&", url.toString());
+ }
+
+ @Test
+ public void appendUrlNullParameter() {
+ StringBuilder url = new StringBuilder();
+ AbstractQuery.appendUrlParameter(url, "foo", null);
+ assertEquals("", url.toString());
+ }
+
+ @Test
+ public void appendUrlDateParameter() throws ParseException {
+ StringBuilder url = new StringBuilder();
+ Date date = new SimpleDateFormat("dd/MM/yyyy").parse("25/12/2009");
+ AbstractQuery.appendUrlParameter(url, "date", date, false);
+ assertEquals("date=2009-12-25&", url.toString());
+ }
+
+ @Test
+ public void appendUrlDateTimeParameter() throws ParseException {
+ TimeZone defaultTimeZone = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("PST"));
+ StringBuilder url = new StringBuilder();
+ Date date = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse("25/12/2009 15:59");
+ AbstractQuery.appendUrlParameter(url, "date", date, true);
+ assertEquals("date=2009-12-25T15%3A59%3A00-0800&", url.toString());
+
+ } finally {
+ TimeZone.setDefault(defaultTimeZone);
+ }
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/DependencyQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/DependencyQueryTest.java
new file mode 100644
index 00000000000..291c3a00d6d
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/DependencyQueryTest.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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class DependencyQueryTest {
+
+ @Test
+ public void createAllDependencies() {
+ DependencyQuery query = DependencyQuery.createForResource("12");
+ assertThat(query.getUrl(), is("/api/dependencies?resource=12&"));
+ assertThat(query.getResourceIdOrKey(), is("12"));
+ assertThat(query.getDirection(), nullValue());
+ }
+
+ @Test
+ public void incomingDependencies() {
+ DependencyQuery query = DependencyQuery.createForIncomingDependencies("12");
+ assertThat(query.getUrl(), is("/api/dependencies?resource=12&dir=" + DependencyQuery.INCOMING_DIRECTION + "&"));
+ assertThat(query.getResourceIdOrKey(), is("12"));
+ assertThat(query.getDirection(), is(DependencyQuery.INCOMING_DIRECTION));
+ }
+
+ @Test
+ public void outgoingDependencies() {
+ DependencyQuery query = DependencyQuery.createForOutgoingDependencies("12");
+ assertThat(query.getUrl(), is("/api/dependencies?resource=12&dir=" + DependencyQuery.OUTGOING_DIRECTION + "&"));
+ assertThat(query.getResourceIdOrKey(), is("12"));
+ assertThat(query.getDirection(), is(DependencyQuery.OUTGOING_DIRECTION));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/EventQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/EventQueryTest.java
new file mode 100644
index 00000000000..5eec4d1180e
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/EventQueryTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.wsclient.JdkUtils;
+
+import java.util.Date;
+
+import static org.junit.Assert.*;
+
+public final class EventQueryTest {
+
+ @Before
+ public void before() {
+ // WSUtils is called during getUrl()
+ // It has to be initialized.
+ WSUtils.setInstance(new JdkUtils());
+ }
+
+ @Test
+ public void from() {
+ EventQuery query = new EventQuery();
+ query.setResourceKey("key");
+ Date from = new Date();
+ query.setFrom(from, true);
+ assertEquals(from, query.getFrom());
+ assertEquals(true, query.isIncludeFromTime());
+ }
+
+ @Test
+ public void to() {
+ EventQuery query = new EventQuery();
+ query.setResourceKey("key");
+ Date to = new Date();
+ query.setTo(to, true);
+ assertEquals(to, query.getTo());
+ assertEquals(true, query.isIncludeToTime());
+ }
+
+ @Test
+ public void urlWithTime() {
+ EventQuery query = new EventQuery("key");
+ query.setCategories(new String[]{"category"});
+ Date date = new Date();
+ query.setTo(date, true);
+ query.setFrom(date, true);
+
+ assertNotNull(query.getResourceKey());
+ assertNotNull(query.getCategories());
+
+ final String url = query.getUrl();
+ assertNotNull(url);
+ assertTrue(url.contains("fromDateTime"));
+ assertTrue(url.contains("toDateTime"));
+ }
+
+ @Test
+ public void urlWithoutTime() {
+ EventQuery query = new EventQuery("key");
+ query.setCategories(new String[]{"category"});
+ Date date = new Date();
+ query.setTo(date, false);
+ query.setFrom(date, false);
+
+ final String url = query.getUrl();
+ assertNotNull(url);
+ assertFalse(url.contains("fromDateTime"));
+ assertFalse(url.contains("toDateTime"));
+ assertTrue(url.contains("fromDate"));
+ assertTrue(url.contains("toDate"));
+ }
+
+ @Test
+ public void urlWithoutDate() {
+ EventQuery query = new EventQuery("key");
+ query.setCategories(new String[]{"category"});
+
+ final String url = query.getUrl();
+ assertNotNull(url);
+ assertFalse(url.contains("fromDateTime"));
+ assertFalse(url.contains("toDateTime"));
+ assertFalse(url.contains("fromDate"));
+ assertFalse(url.contains("toDate"));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/MeasureTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/MeasureTest.java
new file mode 100644
index 00000000000..a466a515484
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/MeasureTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class MeasureTest {
+
+ @Test
+ public void getDataAsMap() {
+ Measure measure = new Measure().setData("foo=1,bar=2,hello=3");
+ Map<String,String> map = measure.getDataAsMap();
+ assertThat(map.get("foo"), is("1"));
+ assertThat(map.get("bar"), is("2"));
+ assertThat(map.get("hello"), is("3"));
+ assertThat(map.get("unknown"), nullValue());
+
+ // sorted map
+ Iterator<String> keys = map.keySet().iterator();
+ assertThat(keys.next(), is("foo"));
+ assertThat(keys.next(), is("bar"));
+ assertThat(keys.next(), is("hello"));
+ assertThat(keys.hasNext(), is(false));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/MetricQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/MetricQueryTest.java
new file mode 100644
index 00000000000..01eeaa93384
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/MetricQueryTest.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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class MetricQueryTest {
+
+ @Test
+ public void all() {
+ assertThat(MetricQuery.all().getUrl(), is("/api/metrics?"));
+ assertThat(MetricQuery.all().getModelClass().getName(), is(Metric.class.getName()));
+ }
+
+ @Test
+ public void byKey() {
+ assertThat(MetricQuery.byKey("ncloc").getUrl(), is("/api/metrics/ncloc?"));
+ assertThat(MetricQuery.byKey("ncloc").getModelClass().getName(), is(Metric.class.getName()));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/PropertyQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/PropertyQueryTest.java
new file mode 100644
index 00000000000..8becf06df5a
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/PropertyQueryTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class PropertyQueryTest {
+
+ @Test
+ public void all() {
+ assertThat(PropertyQuery.createForAll().getUrl(), is("/api/properties?"));
+ assertThat(PropertyQuery.createForAll().getModelClass().getName(), is(Property.class.getName()));
+ }
+
+ @Test
+ public void byKey() {
+ assertThat(PropertyQuery.createForKey("myprop").getUrl(), is("/api/properties/myprop?"));
+ assertThat(PropertyQuery.createForKey("myprop").getModelClass().getName(), is(Property.class.getName()));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceQueryTest.java
new file mode 100644
index 00000000000..4c180bd240f
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceQueryTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class ResourceQueryTest {
+
+ @Test
+ public void resource() {
+ ResourceQuery query = new ResourceQuery("org.foo:bar");
+ assertThat(query.getUrl(), is("/api/resources?resource=org.foo:bar&verbose=false&"));
+ assertThat(query.getResourceKeyOrId(), is("org.foo:bar"));
+ assertThat(query.isVerbose(), is(false));
+ }
+
+ @Test
+ public void measures() {
+ ResourceQuery query = new ResourceQuery();
+ query.setMetrics("loc", "coverage", "lines");
+ assertThat(query.getUrl(), is("/api/resources?metrics=loc,coverage,lines&verbose=false&"));
+ assertThat(query.getResourceKeyOrId(), nullValue());
+ assertThat(query.getMetrics(), is(new String[]{"loc", "coverage", "lines"}));
+ }
+
+ @Test
+ public void measuresWithTrends() {
+ ResourceQuery query = new ResourceQuery();
+ query.setIncludeTrends(true);
+
+ assertThat(query.getUrl(), is("/api/resources?includetrends=true&verbose=false&"));
+ }
+
+ @Test
+ public void measuresOnRules() {
+ ResourceQuery query = new ResourceQuery().setMetrics("violations");
+ query.setRules("ruleA", "ruleB");
+ assertThat(query.getUrl(), is("/api/resources?metrics=violations&rules=ruleA,ruleB&verbose=false&"));
+ }
+
+ @Test
+ public void measuresOnRulePriorities() {
+ ResourceQuery query = new ResourceQuery().setMetrics("violations");
+ query.setRulePriorities("MAJOR,MINOR");
+
+ assertThat(query.getUrl(), is("/api/resources?metrics=violations&rule_priorities=MAJOR,MINOR&verbose=false&"));
+ }
+
+ @Test
+ public void build() {
+ ResourceQuery query = ResourceQuery.createForMetrics("org.foo", "ncloc", "lines");
+ assertThat(query.getResourceKeyOrId(), is("org.foo"));
+ assertThat(query.getMetrics(), is(new String[]{"ncloc", "lines"}));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceTest.java
new file mode 100644
index 00000000000..0d28f9cd1e1
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ResourceTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class ResourceTest {
+
+ @Test
+ public void doNotReturnNullMeasures() {
+ assertThat(new Resource().getMeasures().isEmpty(), is(true));
+ assertThat(new Resource().getMeasure("loc"), nullValue());
+ assertThat(new Resource().getMeasureIntValue("loc"), nullValue());
+ assertThat(new Resource().getMeasureValue("loc"), nullValue());
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ServerQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ServerQueryTest.java
new file mode 100644
index 00000000000..e4ac4b68445
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ServerQueryTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class ServerQueryTest {
+ @Test
+ public void index() {
+ ServerQuery query = new ServerQuery();
+ assertThat(query.getUrl(), is("/api/server/index"));
+ assertThat(query.getModelClass().getName(), is(Server.class.getName()));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/SourceQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/SourceQueryTest.java
new file mode 100644
index 00000000000..51dfc9bd34b
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/SourceQueryTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class SourceQueryTest {
+
+ @Test
+ public void create() {
+ assertThat(SourceQuery.create("myproject:org.foo.Bar").getUrl(), is("/api/sources?resource=myproject:org.foo.Bar&"));
+ assertThat(SourceQuery.create("myproject:org.foo.Bar").getModelClass().getName(), is(Source.class.getName()));
+ }
+
+ @Test
+ public void createWithHighlightedSyntax() {
+ assertThat(SourceQuery.createWithHighlightedSyntax("myproject:org.foo.Bar").getUrl(), is("/api/sources?resource=myproject:org.foo.Bar&color=true&"));
+ assertThat(SourceQuery.createWithHighlightedSyntax("myproject:org.foo.Bar").getModelClass().getName(), is(Source.class.getName()));
+ }
+
+ @Test
+ public void getOnlyAFewLines() {
+ assertThat(SourceQuery.create("myproject:org.foo.Bar").setFromLineToLine(10, 30).getUrl(), is("/api/sources?resource=myproject:org.foo.Bar&from=10&to=30&"));
+ assertThat(SourceQuery.create("myproject:org.foo.Bar").setLinesFromLine(10, 20).getUrl(), is("/api/sources?resource=myproject:org.foo.Bar&from=10&to=30&"));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyCreateQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyCreateQueryTest.java
new file mode 100644
index 00000000000..b2e1f16353f
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyCreateQueryTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class UserPropertyCreateQueryTest {
+
+ @Test
+ public void create() {
+ UserPropertyCreateQuery query = new UserPropertyCreateQuery("foo", "bar");
+ assertThat(query.getUrl(), is("/api/user_properties?key=foo&value=bar&"));
+ assertThat(query.getModelClass().getName(), is(Property.class.getName()));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyDeleteQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyDeleteQueryTest.java
new file mode 100644
index 00000000000..3d4b5df474b
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/UserPropertyDeleteQueryTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.wsclient.services;
+
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class UserPropertyDeleteQueryTest {
+
+ @Test
+ public void create() {
+ UserPropertyDeleteQuery query = new UserPropertyDeleteQuery("foo");
+ assertThat(query.getUrl(), is("/api/user_properties/foo"));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ViolationQueryTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ViolationQueryTest.java
new file mode 100644
index 00000000000..a90b04d70b0
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/services/ViolationQueryTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.wsclient.services;
+
+import org.hamcrest.core.Is;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ViolationQueryTest {
+
+ @Test
+ public void resourceViolations() {
+ ViolationQuery query = ViolationQuery.createForResource("myproject:org.foo:bar");
+ assertThat(query.getUrl(), is("/api/violations?resource=myproject:org.foo:bar&"));
+ assertThat(query.getModelClass().getName(), Is.is(Violation.class.getName()));
+ }
+
+ @Test
+ public void resourceTreeViolations() {
+ ViolationQuery query = ViolationQuery.createForResource("myproject")
+ .setDepth(-1)
+ .setPriorities("MAJOR", "BLOCKER")
+ .setQualifiers("FIL")
+ .setRuleKeys("checkstyle:foo", "pmd:bar");
+ assertThat(query.getUrl(), is("/api/violations?resource=myproject&depth-1&qualifiers=FIL&rules=checkstyle:foo,pmd:bar&priorities=MAJOR,BLOCKER&"));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshallerTest.java
new file mode 100644
index 00000000000..3d30f1b9cff
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyTreeUnmarshallerTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.DependencyTree;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class DependencyTreeUnmarshallerTest {
+ @Test
+ public void singleDepthOfDependencies() throws IOException {
+ List<DependencyTree> trees = new DependencyTreeUnmarshaller().toModels("[]");
+ assertThat(trees.size(), is(0));
+
+ trees = new DependencyTreeUnmarshaller().toModels(loadFile("/dependency_tree/single_depth.json"));
+ assertThat(trees.size(), is(2));
+ assertThat(trees.get(0).getDepId(), is("12345"));
+ assertThat(trees.get(0).getResourceId(), is("2000"));
+ assertThat(trees.get(0).getResourceName(), is("Commons Lang"));
+ assertThat(trees.get(0).getResourceVersion(), is("1.4"));
+ assertThat(trees.get(0).getResourceScope(), is("PRJ"));
+ assertThat(trees.get(0).getResourceQualifier(), is("LIB"));
+ assertThat(trees.get(0).getUsage(), is("compile"));
+ assertThat(trees.get(0).getWeight(), is(1));
+ assertThat(trees.get(0).getTo().size(), is(0));
+ }
+
+ @Test
+ public void manyDepthsOfDependencies() throws IOException {
+ List<DependencyTree> trees = new DependencyTreeUnmarshaller().toModels(loadFile("/dependency_tree/many_depths.json"));
+ assertThat(trees.size(), is(1));
+ List<DependencyTree> secondLevelTrees = trees.get(0).getTo();
+ assertThat(secondLevelTrees.size(), is(2));
+
+ assertThat(secondLevelTrees.get(0).getDepId(), is("12346"));
+ assertThat(secondLevelTrees.get(0).getResourceName(), is("SLF4J"));
+
+ assertThat(secondLevelTrees.get(1).getDepId(), is("12347"));
+ assertThat(secondLevelTrees.get(1).getResourceName(), is("Commons Lang"));
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(DependencyTreeUnmarshallerTest.class.getResourceAsStream(path));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshallerTest.java
new file mode 100644
index 00000000000..985a05cd7fa
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/DependencyUnmarshallerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.Dependency;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class DependencyUnmarshallerTest {
+
+ @Test
+ public void toModel() throws IOException {
+ Dependency dependency = new DependencyUnmarshaller().toModel("[]");
+ assertThat(dependency, nullValue());
+
+ dependency = new DependencyUnmarshaller().toModel(loadFile("/dependencies/single.json"));
+ assertThat(dependency.getId(), is("1649"));
+ assertThat(dependency.getFromKey(), is("org.apache.shiro:shiro-core:org.apache.shiro.authc.pam"));
+ assertThat(dependency.getToKey(), is("org.apache.shiro:shiro-core:org.apache.shiro.realm"));
+ assertThat(dependency.getUsage(), is("USES"));
+ assertThat(dependency.getWeight(), is(5));
+ assertThat(dependency.getFromName(), is("pam"));
+ assertThat(dependency.getToName(), is("realm"));
+ assertThat(dependency.getFromQualifier(), is("PAC"));
+ assertThat(dependency.getToQualifier(), is("PAC"));
+ }
+
+ @Test
+ public void toModels() throws IOException {
+ Collection<Dependency> dependencies = new DependencyUnmarshaller().toModels("[]");
+ assertThat(dependencies.size(), is(0));
+
+ dependencies = new DependencyUnmarshaller().toModels(loadFile("/dependencies/many.json"));
+ assertThat(dependencies.size(), is(15));
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(DependencyUnmarshallerTest.class.getResourceAsStream(path));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/EventUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/EventUnmarshallerTest.java
new file mode 100644
index 00000000000..556ebc88cb2
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/EventUnmarshallerTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Test;
+import org.sonar.wsclient.services.Event;
+
+public class EventUnmarshallerTest {
+
+ @Test
+ public void toModel() throws Exception {
+ List<Event> events = new EventUnmarshaller().toModels("[{\"id\": \"10\", \"n\": \"foo\", \"ds\": \"desc\", \"c\": \"categ\", \"dt\": \"2009-12-25T15:59:23+0000\"}]");
+ Event event = events.get(0);
+ assertThat(event.getId(), is("10"));
+ assertThat(event.getName(), is("foo"));
+ assertThat(event.getDescription(), is("desc"));
+ assertThat(event.getCategory(), is("categ"));
+ final Date expectedDate = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ssZZZZ").parse("2009-12-25T15:59:23+0000");
+ assertThat(event.getDate(), is(expectedDate));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/JsonUtilsTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/JsonUtilsTest.java
new file mode 100644
index 00000000000..dde72bf07a1
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/JsonUtilsTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.TimeZone;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class JsonUtilsTest {
+
+ @Test
+ public void getIntFields() {
+ JSONObject obj = (JSONObject) JSONValue.parse("{\"one\": 1, \"two\": 2}");
+ assertThat(JsonUtils.getInteger(obj, "one"), is(1));
+ assertThat(JsonUtils.getInteger(obj, "two"), is(2));
+ assertThat(JsonUtils.getInteger(obj, "three"), nullValue());
+ }
+
+ @Test
+ public void getLongFields() {
+ JSONObject obj = (JSONObject) JSONValue.parse("{\"one\": 1, \"two\": 2}");
+ assertThat(JsonUtils.getLong(obj, "one"), is(1l));
+ assertThat(JsonUtils.getLong(obj, "two"), is(2l));
+ assertThat(JsonUtils.getLong(obj, "three"), nullValue());
+ }
+
+ @Test
+ public void getStringFields() {
+ JSONObject obj = (JSONObject) JSONValue.parse("{\"one\": \"1\", \"two\": \"2\"}");
+ assertThat(JsonUtils.getString(obj, "one"), is("1"));
+ assertThat(JsonUtils.getString(obj, "two"), is("2"));
+ assertThat(JsonUtils.getString(obj, "three"), nullValue());
+ }
+
+ @Test
+ public void getDateField() {
+ JSONObject obj = (JSONObject) JSONValue.parse("{\"foo\": \"2009-12-25\", \"two\": \"2\"}");
+ Date date = JsonUtils.getDate(obj, "foo");
+ assertThat(date.getDate(), is(25));
+ assertThat(date.getMonth(), is(11));
+ assertThat(date.getYear(), is(109));
+ }
+
+ @Test
+ public void getDateTimeField() {
+ TimeZone defaultTimeZone = TimeZone.getDefault();
+ try {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ JSONObject obj = (JSONObject) JSONValue.parse("{\"foo\": \"2009-12-25T15:59:59-0100\", \"two\": \"2\"}");
+ Date date = JsonUtils.getDateTime(obj, "foo");
+ assertThat(date.getDate(), is(25));
+ assertThat(date.getMonth(), is(11));
+ assertThat(date.getYear(), is(109));
+ assertThat(date.getHours(), is(16));
+ assertThat(date.getMinutes(), is(59));
+ } finally {
+ TimeZone.setDefault(defaultTimeZone);
+ }
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/MetricUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/MetricUnmarshallerTest.java
new file mode 100644
index 00000000000..9acb259edcd
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/MetricUnmarshallerTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.Metric;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class MetricUnmarshallerTest {
+
+ @Test
+ public void toModel() throws IOException {
+ Metric metric = new MetricUnmarshaller().toModel("[]");
+ assertThat(metric, nullValue());
+
+ metric = new MetricUnmarshaller().toModel(loadFile("/metrics/one_metric.json"));
+ assertThat(metric.getKey(), is("ncloc"));
+ assertThat(metric.getName(), is("Lines of code"));
+ assertThat(metric.getDescription(), is("Non Commenting Lines of Code"));
+ assertThat(metric.getType(), is("INT"));
+ assertTrue(metric.getHidden());
+ }
+
+
+
+ @Test
+ public void toModels() throws IOException {
+ Collection<Metric> metrics = new MetricUnmarshaller().toModels("[]");
+ assertThat(metrics.size(), is(0));
+
+ metrics = new MetricUnmarshaller().toModels(loadFile("/metrics/one_metric.json"));
+ assertThat(metrics.size(), is(1));
+
+ metrics = new MetricUnmarshaller().toModels(loadFile("/metrics/many_metrics.json"));
+ assertThat(metrics.size(), is(10));
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(MetricUnmarshallerTest.class.getResourceAsStream(path));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshallerTest.java
new file mode 100644
index 00000000000..6a788964e04
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/PropertyUnmarshallerTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.Property;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class PropertyUnmarshallerTest {
+ @Test
+ public void toModel() throws IOException {
+ Property property = new PropertyUnmarshaller().toModel("[]");
+ assertThat(property, nullValue());
+
+ property = new PropertyUnmarshaller().toModel(loadFile("/properties/single.json"));
+ assertThat(property.getKey(), is("myprop"));
+ assertThat(property.getValue(), is("myvalue"));
+ }
+
+ @Test
+ public void toModels() throws IOException {
+ Collection<Property> properties = new PropertyUnmarshaller().toModels("[]");
+ assertThat(properties.size(), is(0));
+
+ properties = new PropertyUnmarshaller().toModels(loadFile("/properties/single.json"));
+ assertThat(properties.size(), is(1));
+
+ properties = new PropertyUnmarshaller().toModels(loadFile("/properties/many.json"));
+ assertThat(properties.size(), is(3));
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(PropertyUnmarshallerTest.class.getResourceAsStream(path));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshallerTest.java
new file mode 100644
index 00000000000..d3b78033a69
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ResourceUnmarshallerTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.Resource;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+
+public class ResourceUnmarshallerTest {
+
+ @Test
+ public void singleResource() throws IOException {
+ String json = loadFile("/resources/single-resource.json");
+ assertSonar(new ResourceUnmarshaller().toModel(json));
+
+ List<Resource> resources = new ResourceUnmarshaller().toModels(json);
+ assertThat(resources.size(), is(1));
+ assertSonar(resources.get(0));
+ }
+
+ @Test
+ public void singleResourceWithMeasures() throws IOException {
+ Resource resource = new ResourceUnmarshaller().toModel(loadFile("/resources/single-resource-with-measures.json"));
+ assertSonar(resource);
+
+ assertThat(resource.getMeasures().size(), is(2));
+ assertThat(resource.getMeasureIntValue("lines"), is(47798));
+ assertThat(resource.getMeasureIntValue("ncloc"), is(27066));
+ assertThat(resource.getMeasureIntValue("unknown"), nullValue());
+ }
+
+ @Test
+ public void singleResourceWithTrends() throws IOException {
+ Resource resource = new ResourceUnmarshaller().toModel(loadFile("/resources/single-resource-with-trends.json"));
+ assertSonar(resource);
+
+ assertThat(resource.getMeasures().size(), is(2));
+ assertThat(resource.getMeasureIntValue("lines"), is(47798));
+ assertThat(resource.getMeasureIntValue("ncloc"), is(27066));
+ assertThat(resource.getMeasure("lines").getTrend(), is(0));
+ assertThat(resource.getMeasure("lines").getVar(), is(2));
+ assertThat(resource.getMeasure("ncloc").getTrend(), is(1));
+ assertThat(resource.getMeasure("ncloc").getVar(), is(1));
+ }
+
+ @Test
+ public void manyResources() throws IOException {
+ List<Resource> resources = new ResourceUnmarshaller().toModels(loadFile("/resources/many-resources.json"));
+
+ assertThat(resources.size(), is(19));
+ for (Resource resource : resources) {
+ assertThat(resource.getKey(), not(nullValue()));
+ assertThat(resource.getId(), not(nullValue()));
+ assertThat(resource.getMeasures().isEmpty(), is(true));
+ }
+ }
+
+ @Test
+ public void manyResourcesWithMeasures() throws IOException {
+ List<Resource> resources = new ResourceUnmarshaller().toModels(loadFile("/resources/many-resources-with-measures.json"));
+
+ assertThat(resources.size(), is(17));
+ for (Resource resource : resources) {
+ assertThat(resource.getKey(), not(nullValue()));
+ assertThat(resource.getId(), not(nullValue()));
+ assertThat(resource.getMeasures().size(), is(2));
+ }
+ }
+
+ private void assertSonar(Resource resource) {
+ assertThat(resource.getId(), is(48569));
+ assertThat(resource.getKey(), is("org.codehaus.sonar:sonar"));
+ assertThat(resource.getName(), is("Sonar"));
+ assertThat(resource.getScope(), is("PRJ"));
+ assertThat(resource.getQualifier(), is("TRK"));
+ assertThat(resource.getLanguage(), is("java"));
+ assertThat(resource.getDescription(), is("Embrace Quality"));
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(ResourceUnmarshallerTest.class.getResourceAsStream(path));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ServerUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ServerUnmarshallerTest.java
new file mode 100644
index 00000000000..4db8b113aa9
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ServerUnmarshallerTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.junit.Test;
+import org.sonar.wsclient.services.Server;
+
+import java.io.IOException;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class ServerUnmarshallerTest {
+
+ @Test
+ public void toModel() throws IOException {
+ Server server = new ServerUnmarshaller().toModel("{\"id\":\"123456789\", \"version\":\"2.0-SNAPSHOT\"}");
+ assertThat(server.getId(), is("123456789"));
+ assertThat(server.getVersion(), is("2.0-SNAPSHOT"));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/SourceUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/SourceUnmarshallerTest.java
new file mode 100644
index 00000000000..1e5558865f1
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/SourceUnmarshallerTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.Source;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class SourceUnmarshallerTest {
+
+ @Test
+ public void toModel() throws IOException {
+ Source source = new SourceUnmarshaller().toModel("[]");
+ assertThat(source, nullValue());
+
+ source = new SourceUnmarshaller().toModel(loadFile("/sources/source.json"));
+ assertThat(source.getLines().size(), is(236));
+ assertThat(source.getLine(3), is(" * Copyright (C) 2009 SonarSource SA"));
+ }
+
+ @Test
+ public void fromLineToLine() throws IOException {
+ Source source = new SourceUnmarshaller().toModel(loadFile("/sources/from_line_to_line.json"));
+ assertThat(source.getLines().size(), is(15));
+ assertThat(source.getLine(1), nullValue());
+ assertThat(source.getLine(3), is(" * Copyright (C) 2009 SonarSource SA"));
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(PropertyUnmarshallerTest.class.getResourceAsStream(path));
+ }
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/UnmarshallersTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/UnmarshallersTest.java
new file mode 100644
index 00000000000..798e5250a35
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/UnmarshallersTest.java
@@ -0,0 +1,19 @@
+package org.sonar.wsclient.unmarshallers;
+
+import org.junit.Test;
+import org.sonar.wsclient.services.Metric;
+import org.sonar.wsclient.services.Model;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class UnmarshallersTest {
+
+ @Test
+ public void forModel() {
+ assertThat(Unmarshallers.forModel(Metric.class), is(MetricUnmarshaller.class));
+ assertThat(Unmarshallers.forModel(Model.class), nullValue());
+ }
+
+}
diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshallerTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshallerTest.java
new file mode 100644
index 00000000000..ff879b6ebaf
--- /dev/null
+++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/unmarshallers/ViolationUnmarshallerTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.wsclient.unmarshallers;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.sonar.wsclient.services.Violation;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+
+public class ViolationUnmarshallerTest {
+
+ @Test
+ public void toModels() throws IOException {
+ Violation violation = new ViolationUnmarshaller().toModel("[]");
+ assertThat(violation, nullValue());
+
+ List<Violation> violations = new ViolationUnmarshaller().toModels(loadFile("/violations/violations.json"));
+ assertThat(violations.size(), is(2));
+
+ violation = violations.get(0);
+ assertThat(violation.getMessage(), is("throw java.lang.Exception"));
+ assertThat(violation.getLine(), is(97));
+ assertThat(violation.getPriority(), is("MAJOR"));
+ assertThat(violation.getRuleKey(), is("pmd:SignatureDeclareThrowsException"));
+ assertThat(violation.getRuleName(), is("Signature Declare Throws Exception"));
+ assertThat(violation.getResourceKey(), is("org.apache.excalibur.components:excalibur-pool-instrumented:org.apache.avalon.excalibur.pool.TraceableResourceLimitingPool"));
+ assertThat(violation.getResourceName(), is("TraceableResourceLimitingPool"));
+ assertThat(violation.getResourceQualifier(), is("CLA"));
+ assertThat(violation.getResourceScope(), is("FIL"));
+ }
+
+ @Test
+ public void violationWithoutLineNumber() throws IOException {
+ Violation violation = new ViolationUnmarshaller().toModel(loadFile("/violations/violation-without-optional-fields.json"));
+ assertThat(violation.getMessage(), not(nullValue()));
+ assertThat(violation.getLine(), nullValue());
+ }
+
+ private static String loadFile(String path) throws IOException {
+ return IOUtils.toString(MetricUnmarshallerTest.class.getResourceAsStream(path));
+ }
+
+}
diff --git a/sonar-ws-client/src/test/resources/dependencies/many.json b/sonar-ws-client/src/test/resources/dependencies/many.json
new file mode 100644
index 00000000000..75e1d00e365
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/dependencies/many.json
@@ -0,0 +1,137 @@
+[
+ {
+ "id":"1649",
+ "fi": 33,
+ "ti": 45,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.authc.pam",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":5
+ },
+ {
+ "id":"1686",
+ "fi": 333,
+ "ti": 453,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.authz.permission",
+ "u":"USES",
+ "w":3
+ },
+ {
+ "id":"1690",
+ "fi": 334,
+ "ti": 454,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.util",
+ "u":"USES",
+ "w":2
+ },
+ {
+ "id":"1693",
+ "fi": 335,
+ "ti": 455,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.authc.credential",
+ "u":"USES",
+ "w":3
+ },
+ {
+ "id":"1697",
+ "fi": 336,
+ "ti": 456,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.authc",
+ "u":"USES",
+ "w":16
+ },
+ {
+ "id":"1714",
+ "fi": 337,
+ "ti": 457,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.cache",
+ "u":"USES",
+ "w":6
+ },
+ {
+ "id":"1721",
+ "fi": 3338,
+ "ti": 4258,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.authz",
+ "u":"USES",
+ "w":9
+ },
+ {
+ "id":"1731",
+ "fi": 343,
+ "ti": 4445,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.subject",
+ "u":"USES",
+ "w":3
+ },
+ {
+ "id":"1735",
+ "fi": 3443,
+ "ti": 455,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm.ldap",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":1
+ },
+ {
+ "id":"1775",
+ "fi": 373,
+ "ti": 6645,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.mgt",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":2
+ },
+ {
+ "id":"1886",
+ "fi": 339,
+ "ti": 495,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm.jdbc",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":1
+ },
+ {
+ "id":"1962",
+ "fi": 373,
+ "ti": 485,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.config",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":4
+ },
+ {
+ "id":"1995",
+ "fi": 363,
+ "ti": 445,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm.jndi",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":2
+ },
+ {
+ "id":"2098",
+ "fi": 333,
+ "ti": 415,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.realm.text",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":1
+ },
+ {
+ "id":"2119",
+ "fi": 332,
+ "ti": 451,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.authz",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":1
+ }
+] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/dependencies/single.json b/sonar-ws-client/src/test/resources/dependencies/single.json
new file mode 100644
index 00000000000..3afb73ceeab
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/dependencies/single.json
@@ -0,0 +1,15 @@
+[
+ {
+ "id":"1649",
+ "fi": 33,
+ "ti": 45,
+ "fk":"org.apache.shiro:shiro-core:org.apache.shiro.authc.pam",
+ "tk":"org.apache.shiro:shiro-core:org.apache.shiro.realm",
+ "u":"USES",
+ "w":5,
+ "fn": "pam",
+ "fq": "PAC",
+ "tn": "realm",
+ "tq": "PAC"
+ }
+] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/dependency_tree/many_depths.json b/sonar-ws-client/src/test/resources/dependency_tree/many_depths.json
new file mode 100644
index 00000000000..9a9ccb6a2c4
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/dependency_tree/many_depths.json
@@ -0,0 +1 @@
+[{"did":"12345","rid":"2000","n":"Logback","s":"LIB","q":"LIB","w":1,"u":"compile","v":"1.4","to":[{"did":"12346","rid":"2001","n":"SLF4J","s":"LIB","q":"LIB","w":1,"u":"compile","v":"0.9"},{"did":"12347","rid":"2002","n":"Commons Lang","s":"LIB","q":"LIB","w":1,"u":"compile","v":"1.4"}]}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/dependency_tree/single_depth.json b/sonar-ws-client/src/test/resources/dependency_tree/single_depth.json
new file mode 100644
index 00000000000..434a2da2cb2
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/dependency_tree/single_depth.json
@@ -0,0 +1 @@
+[{"did":"12345","rid":"2000","n":"Commons Lang","s":"PRJ","q":"LIB","w":1,"u":"compile","v":"1.4"},{"did":"12346","rid":"2001","n":"Commons IO","s":"PRJ","q":"LIB","w":1,"u":"compile","v":"2.4"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/metrics/many_metrics.json b/sonar-ws-client/src/test/resources/metrics/many_metrics.json
new file mode 100644
index 00000000000..e7104a6a43e
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/metrics/many_metrics.json
@@ -0,0 +1 @@
+[{"key":"packages","name":"Packages","description":"Packages","domain":"Size","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"classes","name":"Classes","description":"Classes","domain":"Size","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"ncloc","name":"Lines of code","description":"Non Commenting Lines of Code","domain":"Size","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"functions","name":"Methods","description":"Methods","domain":"Size","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"duplicated_lines","name":"Duplicated lines","description":"Duplicated lines","domain":"Duplication","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"test_errors","name":"Unit test errors","description":"Number of unit test errors","domain":"Tests","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"skipped_tests","name":"Skipped unit tests","description":"Number of skipped unit tests","domain":"Tests","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"test_failures","name":"Unit test failures","description":"Number of unit test failures","domain":"Tests","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"tests","name":"Unit tests","description":"Number of unit tests","domain":"Tests","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT"},{"key":"test_execution_time","name":"Unit tests duration","description":"Execution duration of unit tests ","domain":"Tests","qualitative":false,"user_managed":false,"direction":-1,"val_type":"MILLISEC"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/metrics/one_metric.json b/sonar-ws-client/src/test/resources/metrics/one_metric.json
new file mode 100644
index 00000000000..17a163b5b82
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/metrics/one_metric.json
@@ -0,0 +1 @@
+[{"key":"ncloc","name":"Lines of code","description":"Non Commenting Lines of Code","domain":"Size","qualitative":false,"user_managed":false,"direction":-1,"val_type":"INT","hidden":true}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/properties/many.json b/sonar-ws-client/src/test/resources/properties/many.json
new file mode 100644
index 00000000000..87d57bf7297
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/properties/many.json
@@ -0,0 +1 @@
+[{"key":"myprop","value":"myvalue"},{"key":"myprop2","value":"myvalue2"},{"key":"myprop3","value":"myvalue3"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/properties/single.json b/sonar-ws-client/src/test/resources/properties/single.json
new file mode 100644
index 00000000000..f1f0be4b0a5
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/properties/single.json
@@ -0,0 +1 @@
+[{"key":"myprop","value":"myvalue"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/resources/many-resources-with-measures.json b/sonar-ws-client/src/test/resources/resources/many-resources-with-measures.json
new file mode 100644
index 00000000000..b11780d979a
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/resources/many-resources-with-measures.json
@@ -0,0 +1 @@
+[{"id":38909,"key":"org.codehaus.sonar:sonar-plugin-api","name":"Sonar API","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:27:25+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":9955.0,"frmt_val":"9,955"},{"key":"lines","val":19679.0,"frmt_val":"19,679"}]},{"id":94156,"key":"org.codehaus.sonar:sonar-squid","name":"Sonar Squid","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:29:42+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":4757.0,"frmt_val":"4,757"},{"key":"lines","val":8279.0,"frmt_val":"8,279"}]},{"id":182945,"key":"org.codehaus.sonar:sonar-colorizer","name":"Sonar Code Colorizer","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:32:32+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":829.0,"frmt_val":"829"},{"key":"lines","val":1566.0,"frmt_val":"1,566"}]},{"id":39023,"key":"org.codehaus.sonar:sonar-core","name":"Sonar core","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:32:57+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":2471.0,"frmt_val":"2,471"},{"key":"lines","val":3830.0,"frmt_val":"3,830"}]},{"id":88480,"key":"org.codehaus.sonar.runtime:sonar-core-maven-plugin","name":"Sonar batch","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:33:57+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Sonar batch","msr":[{"key":"ncloc","val":1790.0,"frmt_val":"1,790"},{"key":"lines","val":2835.0,"frmt_val":"2,835"}]},{"id":39141,"key":"org.codehaus.sonar:sonar-web","name":"Sonar web","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:34:42+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":1359.0,"frmt_val":"1,359"},{"key":"lines","val":1992.0,"frmt_val":"1,992"}]},{"id":39212,"key":"org.codehaus.sonar:sonar-application","name":"Sonar application","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:35:38+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Package the standalone distribution","msr":[{"key":"ncloc","val":163.0,"frmt_val":"163"},{"key":"lines","val":230.0,"frmt_val":"230"}]},{"id":48696,"key":"org.codehaus.sonar.plugins:sonar-plugin-core","name":"Sonar plugin core","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:35:53+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":1913.0,"frmt_val":"1,913"},{"key":"lines","val":3318.0,"frmt_val":"3,318"}]},{"id":39200,"key":"org.codehaus.sonar.plugins:sonar-plugin-checkstyle","name":"Sonar Checkstyle plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:05+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":488.0,"frmt_val":"488"},{"key":"lines","val":770.0,"frmt_val":"770"}]},{"id":39218,"key":"org.codehaus.sonar.plugins:sonar-plugin-pmd","name":"Sonar PMD plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:21+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":478.0,"frmt_val":"478"},{"key":"lines","val":762.0,"frmt_val":"762"}]},{"id":48767,"key":"org.codehaus.sonar.plugins:sonar-plugin-cobertura","name":"Sonar Cobertura plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:37+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":286.0,"frmt_val":"286"},{"key":"lines","val":396.0,"frmt_val":"396"}]},{"id":48774,"key":"org.codehaus.sonar.plugins:sonar-plugin-clover","name":"Sonar Clover plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:52+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":471.0,"frmt_val":"471"},{"key":"lines","val":727.0,"frmt_val":"727"}]},{"id":48796,"key":"org.codehaus.sonar.plugins:sonar-plugin-surefire","name":"Sonar Surefire plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:08+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":393.0,"frmt_val":"393"},{"key":"lines","val":575.0,"frmt_val":"575"}]},{"id":48806,"key":"org.codehaus.sonar.plugins:sonar-plugin-googleanalytics","name":"Sonar Google analytics plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:21+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":65.0,"frmt_val":"65"},{"key":"lines","val":120.0,"frmt_val":"120"}]},{"id":48810,"key":"org.codehaus.sonar.plugins:sonar-plugin-findbugs","name":"Sonar Findbugs plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:29+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":862.0,"frmt_val":"862"},{"key":"lines","val":1447.0,"frmt_val":"1,447"}]},{"id":48790,"key":"org.codehaus.sonar.plugins:sonar-plugin-cpd","name":"Sonar CPD plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:47+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":347.0,"frmt_val":"347"},{"key":"lines","val":552.0,"frmt_val":"552"}]},{"id":94200,"key":"org.codehaus.sonar.plugins:sonar-plugin-squid","name":"Sonar Squid plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:59+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"ncloc","val":439.0,"frmt_val":"439"},{"key":"lines","val":720.0,"frmt_val":"720"}]}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/resources/many-resources.json b/sonar-ws-client/src/test/resources/resources/many-resources.json
new file mode 100644
index 00000000000..30211af02e6
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/resources/many-resources.json
@@ -0,0 +1 @@
+[{"id":38909,"key":"org.codehaus.sonar:sonar-plugin-api","name":"Sonar API","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:27:25+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":94156,"key":"org.codehaus.sonar:sonar-squid","name":"Sonar Squid","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:29:42+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":182945,"key":"org.codehaus.sonar:sonar-colorizer","name":"Sonar Code Colorizer","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:32:32+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":222615,"key":"org.codehaus.sonar:sonar-client","name":"Sonar Client","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:32:50+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":172279,"key":"org.codehaus.sonar.archetypes:sonar-archetypes","name":"Sonar archetypes","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:32:53+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":39023,"key":"org.codehaus.sonar:sonar-core","name":"Sonar core","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:32:57+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":88480,"key":"org.codehaus.sonar.runtime:sonar-core-maven-plugin","name":"Sonar batch","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:33:57+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Sonar batch"},{"id":39141,"key":"org.codehaus.sonar:sonar-web","name":"Sonar web","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:34:42+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":39212,"key":"org.codehaus.sonar:sonar-application","name":"Sonar application","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:35:38+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Package the standalone distribution"},{"id":48696,"key":"org.codehaus.sonar.plugins:sonar-plugin-core","name":"Sonar plugin core","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:35:53+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":39200,"key":"org.codehaus.sonar.plugins:sonar-plugin-checkstyle","name":"Sonar Checkstyle plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:05+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":39218,"key":"org.codehaus.sonar.plugins:sonar-plugin-pmd","name":"Sonar PMD plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:21+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":48767,"key":"org.codehaus.sonar.plugins:sonar-plugin-cobertura","name":"Sonar Cobertura plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:37+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":48774,"key":"org.codehaus.sonar.plugins:sonar-plugin-clover","name":"Sonar Clover plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:39:52+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":48796,"key":"org.codehaus.sonar.plugins:sonar-plugin-surefire","name":"Sonar Surefire plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:08+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":48806,"key":"org.codehaus.sonar.plugins:sonar-plugin-googleanalytics","name":"Sonar Google analytics plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:21+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":48810,"key":"org.codehaus.sonar.plugins:sonar-plugin-findbugs","name":"Sonar Findbugs plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:29+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":48790,"key":"org.codehaus.sonar.plugins:sonar-plugin-cpd","name":"Sonar CPD plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:47+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"},{"id":94200,"key":"org.codehaus.sonar.plugins:sonar-plugin-squid","name":"Sonar Squid plugin","scope":"PRJ","qualifier":"BRC","date":"2010-01-01T22:40:59+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/resources/single-resource-with-measures.json b/sonar-ws-client/src/test/resources/resources/single-resource-with-measures.json
new file mode 100644
index 00000000000..5449b1a01ba
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/resources/single-resource-with-measures.json
@@ -0,0 +1 @@
+[{"id":48569,"key":"org.codehaus.sonar:sonar","name":"Sonar","scope":"PRJ","qualifier":"TRK","date":"2010-01-01T22:27:25+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality","msr":[{"key":"lines","val":47798.0,"frmt_val":"47,798"},{"key":"ncloc","val":27066.0,"frmt_val":"27,066"}]}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/resources/single-resource-with-trends.json b/sonar-ws-client/src/test/resources/resources/single-resource-with-trends.json
new file mode 100644
index 00000000000..b67714ed06b
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/resources/single-resource-with-trends.json
@@ -0,0 +1,29 @@
+[
+ {
+ "id":48569,
+ "key":"org.codehaus.sonar:sonar",
+ "name":"Sonar",
+ "scope":"PRJ",
+ "qualifier":"TRK",
+ "date":"2010-01-01T22:27:25+00:00",
+ "lang":"java",
+ "version":"1.13-SNAPSHOT",
+ "description":"Embrace Quality",
+ "msr":[
+ {
+ "key":"lines",
+ "val":47798.0,
+ "frmt_val":"47,798",
+ "trend":0,
+ "var":2
+ },
+ {
+ "key":"ncloc",
+ "val":27066.0,
+ "frmt_val":"27,066",
+ "trend":1,
+ "var":1
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/resources/single-resource.json b/sonar-ws-client/src/test/resources/resources/single-resource.json
new file mode 100644
index 00000000000..f8b52f1cd18
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/resources/single-resource.json
@@ -0,0 +1 @@
+[{"id":48569,"key":"org.codehaus.sonar:sonar","name":"Sonar","scope":"PRJ","qualifier":"TRK","date":"2010-01-01T22:27:25+00:00","lang":"java","version":"1.13-SNAPSHOT","description":"Embrace Quality"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/sources/from_line_to_line.json b/sonar-ws-client/src/test/resources/sources/from_line_to_line.json
new file mode 100644
index 00000000000..c4c7ed00509
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/sources/from_line_to_line.json
@@ -0,0 +1 @@
+[{"3":" * Copyright (C) 2009 SonarSource SA","4":" * mailto:contact AT sonarsource DOT com","5":" *","6":" * Sonar is free software; you can redistribute it and\/or","7":" * modify it under the terms of the GNU Lesser General Public","8":" * License as published by the Free Software Foundation; either","9":" * version 3 of the License, or (at your option) any later version.","10":" *","11":" * Sonar is distributed in the hope that it will be useful,","12":" * but WITHOUT ANY WARRANTY; without even the implied warranty of","13":" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU","14":" * Lesser General Public License for more details.","15":" *","16":" * You should have received a copy of the GNU Lesser General Public","17":" * License along with Sonar; if not, write to the Free Software"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/sources/source.json b/sonar-ws-client/src/test/resources/sources/source.json
new file mode 100644
index 00000000000..5042d43778e
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/sources/source.json
@@ -0,0 +1 @@
+[{"1":"\/*","2":" * Sonar, open source software quality management tool.","3":" * Copyright (C) 2009 SonarSource SA","4":" * mailto:contact AT sonarsource DOT com","5":" *","6":" * Sonar is free software; you can redistribute it and\/or","7":" * modify it under the terms of the GNU Lesser General Public","8":" * License as published by the Free Software Foundation; either","9":" * version 3 of the License, or (at your option) any later version.","10":" *","11":" * Sonar is distributed in the hope that it will be useful,","12":" * but WITHOUT ANY WARRANTY; without even the implied warranty of","13":" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU","14":" * Lesser General Public License for more details.","15":" *","16":" * You should have received a copy of the GNU Lesser General Public","17":" * License along with Sonar; if not, write to the Free Software","18":" * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02","19":" *\/","20":"package org.sonar.api.utils;","21":"","22":"import com.google.common.collect.Multiset;","23":"import org.apache.commons.collections.Bag;","24":"import org.apache.commons.lang.StringUtils;","25":"import org.apache.commons.lang.math.NumberUtils;","26":"import org.sonar.api.rules.RulePriority;","27":"import org.slf4j.LoggerFactory;","28":"","29":"import java.util.HashMap;","30":"import java.util.Map;","31":"","32":"\/**","33":" * Util class to format key\/value data. Output is a string representation ready to be","34":" * injected into the database","35":" *","36":" * @since 1.10","37":" *\/","38":"public final class KeyValueFormat {","39":"","40":" private KeyValueFormat() {","41":" }","42":"","43":" \/**","44":" * Transforms a string with the following format : &quot;key1=value1;key2=value2...&quot;","45":" * into a Map&lt;KEY, VALUE&gt;. Requires to implement the transform(key,value) method","46":" *","47":" * @param data the input string","48":" * @param transformer the interface to implement","49":" * @return a Map of &lt;key, value&gt;","50":" *\/","51":" public static &lt;KEY, VALUE&gt; Map&lt;KEY, VALUE&gt; parse(String data, Transformer&lt;KEY, VALUE&gt; transformer) {","52":" Map&lt;String, String&gt; rawData = parse(data);","53":" Map&lt;KEY, VALUE&gt; map = new HashMap&lt;KEY, VALUE&gt;();","54":" for (Map.Entry&lt;String, String&gt; entry : rawData.entrySet()) {","55":" KeyValue&lt;KEY, VALUE&gt; keyVal = transformer.transform(entry.getKey(), entry.getValue());","56":" if (keyVal != null) {","57":" map.put(keyVal.getKey(), keyVal.getValue());","58":" }","59":" }","60":" return map;","61":" }","62":"","63":" \/**","64":" * Transforms a string with the following format : &quot;key1=value1;key2=value2...&quot;","65":" * into a Map&lt;String,String&gt;","66":" *","67":" * @param data the string to parse","68":" * @return a map","69":" *\/","70":" public static Map&lt;String, String&gt; parse(String data) {","71":" Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();","72":" String[] pairs = StringUtils.split(data, &quot;;&quot;);","73":" for (String pair : pairs) {","74":" String[] keyValue = StringUtils.split(pair, &quot;=&quot;);","75":" String key = keyValue[0];","76":" String value = (keyValue.length == 2 ? keyValue[1] : &quot;&quot;);","77":" map.put(key, value);","78":" }","79":" return map;","80":" }","81":"","82":" \/**","83":" * Transforms a map&lt;KEY,VALUE&gt; into a string with the format : &quot;key1=value1;key2=value2...&quot;","84":" *","85":" * @param map the map to transform","86":" * @return the formatted string","87":" *\/","88":" public static &lt;KEY, VALUE&gt; String format(Map&lt;KEY, VALUE&gt; map) {","89":" StringBuilder sb = new StringBuilder();","90":" boolean first = true;","91":" for (Map.Entry&lt;?, ?&gt; entry : map.entrySet()) {","92":" if (!first) {","93":" sb.append(&quot;;&quot;);","94":" }","95":" sb.append(entry.getKey().toString());","96":" sb.append(&quot;=&quot;);","97":" if (entry.getValue() != null) {","98":" sb.append(entry.getValue());","99":" }","100":" first = false;","101":" }","102":"","103":" return sb.toString();","104":" }","105":"","106":" \/**","107":" * @since 1.11","108":" * @deprecated use Multiset from google collections instead of commons-collections bags","109":" *\/","110":" public static String format(Bag bag) {","111":" return format(bag, 0);","112":" }","113":"","114":" \/**","115":" * @since 1.11","116":" * @deprecated use Multiset from google collections instead of commons-collections bags","117":" *\/","118":" public static String format(Bag bag, int var) {","119":" StringBuilder sb = new StringBuilder();","120":" boolean first = true;","121":" for (Object obj : bag.uniqueSet()) {","122":" if (!first) {","123":" sb.append(&quot;;&quot;);","124":" }","125":" sb.append(obj.toString());","126":" sb.append(&quot;=&quot;);","127":" sb.append(bag.getCount(obj) + var);","128":" first = false;","129":" }","130":"","131":" return sb.toString();","132":" }","133":"","134":" \/**","135":" * Transforms a Multiset&lt;?&gt; into a string with the format : &quot;key1=count1;key2=count2...&quot;","136":" *","137":" * @param set the set to transform","138":" * @return the formatted string","139":" *\/","140":" public static String format(Multiset&lt;?&gt; set) {","141":" StringBuilder sb = new StringBuilder();","142":" boolean first = true;","143":" for (Multiset.Entry&lt;?&gt; entry : set.entrySet()) {","144":" if (!first) {","145":" sb.append(&quot;;&quot;);","146":" }","147":" sb.append(entry.getElement().toString());","148":" sb.append(&quot;=&quot;);","149":" sb.append(entry.getCount());","150":" first = false;","151":" }","152":" return sb.toString();","153":" }","154":"","155":" \/**","156":" * Transforms a Object... into a string with the format : &quot;object1=object2;object3=object4...&quot;","157":" *","158":" * @param objects the object list to transform","159":" * @return the formatted string","160":" *\/","161":" public static String format(Object... objects) {","162":" StringBuilder sb = new StringBuilder();","163":" boolean first = true;","164":" if (objects != null) {","165":" for (int i = 0; i &lt; objects.length; i++) {","166":" if (!first) {","167":" sb.append(&quot;;&quot;);","168":" }","169":" sb.append(objects[i++].toString());","170":" sb.append(&quot;=&quot;);","171":" sb.append(objects[i]);","172":" first = false;","173":" }","174":" }","175":" return sb.toString();","176":" }","177":"","178":" public interface Transformer&lt;KEY, VALUE&gt; {","179":" KeyValue&lt;KEY, VALUE&gt; transform(String key, String value);","180":" }","181":"","182":" \/**","183":" * Implementation of Transformer&lt;String, Double&gt;","184":" *\/","185":" public static class StringNumberPairTransformer implements Transformer&lt;String, Double&gt; {","186":"","187":" public KeyValue&lt;String, Double&gt; transform(String key, String value) {","188":" return new KeyValue&lt;String, Double&gt;(key, toDouble(value));","189":" }","190":" }","191":"","192":" \/**","193":" * Implementation of Transformer&lt;Double, Double&gt;","194":" *\/","195":" public static class DoubleNumbersPairTransformer implements Transformer&lt;Double, Double&gt; {","196":"","197":" public KeyValue&lt;Double, Double&gt; transform(String key, String value) {","198":" return new KeyValue&lt;Double, Double&gt;(toDouble(key), toDouble(value));","199":" }","200":" }","201":"","202":" \/**","203":" * Implementation of Transformer&lt;Integer, Integer&gt;","204":" *\/","205":" public static class IntegerNumbersPairTransformer implements Transformer&lt;Integer, Integer&gt; {","206":"","207":" public KeyValue&lt;Integer, Integer&gt; transform(String key, String value) {","208":" return new KeyValue&lt;Integer, Integer&gt;(toInteger(key), toInteger(value));","209":" }","210":" }","211":"","212":" \/**","213":" * Implementation of Transformer&lt;RulePriority, Integer&gt;","214":" *\/","215":" public static class RulePriorityNumbersPairTransformer implements Transformer&lt;RulePriority, Integer&gt; {","216":"","217":" public KeyValue&lt;RulePriority, Integer&gt; transform(String key, String value) {","218":" try {","219":" if (StringUtils.isBlank(value)) { value = &quot;0&quot;; }","220":" return new KeyValue&lt;RulePriority, Integer&gt;(RulePriority.valueOf(key.toUpperCase()), Integer.parseInt(value));","221":" }","222":" catch (Exception e) {","223":" LoggerFactory.getLogger(RulePriorityNumbersPairTransformer.class).warn(&quot;Property &quot; + key + &quot; has invalid value: &quot; + value, e);","224":" return null;","225":" }","226":" }","227":" }","228":"","229":" private static Double toDouble(String value) {","230":" return StringUtils.isBlank(value) ? null : NumberUtils.toDouble(value);","231":" }","232":"","233":" private static Integer toInteger(String value) {","234":" return StringUtils.isBlank(value) ? null : NumberUtils.toInt(value);","235":" }","236":"}"}] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/violations/violation-without-optional-fields.json b/sonar-ws-client/src/test/resources/violations/violation-without-optional-fields.json
new file mode 100644
index 00000000000..acfffe3e152
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/violations/violation-without-optional-fields.json
@@ -0,0 +1,3 @@
+[
+ {"message":"throw java.lang.Exception","priority":"MAJOR","rule":{"key":"pmd:SignatureDeclareThrowsException","name":"Signature Declare Throws Exception","category":"Maintainability"},"resource":{"key":"org.apache.excalibur.components:excalibur-pool-instrumented:org.apache.avalon.excalibur.pool.TraceableResourceLimitingPool","name":"TraceableResourceLimitingPool","scope":"FIL","qualifier":"CLA","language":"java"}},
+] \ No newline at end of file
diff --git a/sonar-ws-client/src/test/resources/violations/violations.json b/sonar-ws-client/src/test/resources/violations/violations.json
new file mode 100644
index 00000000000..ec9fb7b682a
--- /dev/null
+++ b/sonar-ws-client/src/test/resources/violations/violations.json
@@ -0,0 +1,4 @@
+[
+ {"message":"throw java.lang.Exception","line":97,"priority":"MAJOR","rule":{"key":"pmd:SignatureDeclareThrowsException","name":"Signature Declare Throws Exception","category":"Maintainability"},"resource":{"key":"org.apache.excalibur.components:excalibur-pool-instrumented:org.apache.avalon.excalibur.pool.TraceableResourceLimitingPool","name":"TraceableResourceLimitingPool","scope":"FIL","qualifier":"CLA","language":"java"}},
+ {"message":"The user-supplied array 'threads' is stored directly.","line":242,"priority":"MAJOR","rule":{"key":"pmd:ArrayIsStoredDirectly","name":"Security - Array is stored directly","category":"Reliability"},"resource":{"key":"org.apache.excalibur.components:excalibur-pool-instrumented:org.apache.avalon.excalibur.pool.TraceableResourceLimitingPool","name":"TraceableResourceLimitingPool","scope":"FIL","qualifier":"CLA","language":"java"}}
+] \ No newline at end of file