aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-gwt-api/src
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2012-11-09 17:44:29 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2012-11-12 09:51:10 +0100
commitfec91dbfd31b9535146cef1e1d47bb4601e43cf5 (patch)
treec42c51735b87185f1950139373b59c47471f3b10 /sonar-gwt-api/src
parent28ea5343cecd54729ddf2bc4008a1220414e54ec (diff)
downloadsonarqube-fec91dbfd31b9535146cef1e1d47bb4601e43cf5.tar.gz
sonarqube-fec91dbfd31b9535146cef1e1d47bb4601e43cf5.zip
Revert "SONAR-3945 - Drop GWT API"
This reverts commit 5d5df25d59314d68c80b9f3b2fcd53a4154ef56c.
Diffstat (limited to 'sonar-gwt-api/src')
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/Configuration.java97
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/JsonUtils.java203
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/Links.java115
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/Metrics.java110
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/Utils.java83
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ExpandCollapseLink.java55
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Icons.java160
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Page.java92
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ViewerHeader.java138
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractCallback.java67
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractListCallback.java69
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Callback.java33
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/GwtUtils.java102
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/ListCallback.java33
-rw-r--r--sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Sonar.java95
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/Sonar.gwt.xml10
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/SonarDev.gwt.xml5
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/empty.gifbin0 -> 55 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/help.pngbin0 -> 731 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/information.pngbin0 -> 724 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/javaModule.pngbin0 -> 745 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityBlocker.pngbin0 -> 672 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityCritical.pngbin0 -> 412 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityInfo.pngbin0 -> 461 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMajor.pngbin0 -> 437 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMinor.pngbin0 -> 519 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierClass.pngbin0 -> 416 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierDirectory.pngbin0 -> 390 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierField.pngbin0 -> 644 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierFile.pngbin0 -> 416 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierLibrary.pngbin0 -> 379 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierMethod.pngbin0 -> 628 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierModule.pngbin0 -> 562 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierPackage.pngbin0 -> 481 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierProject.pngbin0 -> 575 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierUnitTest.pngbin0 -> 542 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierView.pngbin0 -> 571 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusError.pngbin0 -> 1297 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusOk.pngbin0 -> 1297 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusWarning.pngbin0 -> 1278 bytes
-rw-r--r--sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/zoom.pngbin0 -> 387 bytes
41 files changed, 1467 insertions, 0 deletions
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/Configuration.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/Configuration.java
new file mode 100644
index 00000000000..5c6f960eb7d
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/Configuration.java
@@ -0,0 +1,97 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.i18n.client.Dictionary;
+
+import java.util.Set;
+
+public final class Configuration {
+
+ private Configuration() {
+ // only static methods
+ }
+
+ public static String getSonarVersion() {
+ return getParameter("version");
+ }
+
+ /**
+ * Get the id of the selected resource. Can be null if none resource is selected.
+ */
+ public static String getResourceId() {
+ return getParameter("resource_key");
+ }
+
+ public static String getParameter(String key) {
+ return getParameter(key, null);
+ }
+
+ public static String getParameter(String key, String defaultValue) {
+ String result = getDictionaryEntry("config", key);
+ if (result == null) {
+ result = defaultValue;
+ }
+ return result;
+ }
+
+ public static native void setParameter(String key, String val) /*-{
+ $wnd.config[key] = val;
+ }-*/;
+
+ public static String getRequestParameter(String key) {
+ return getDictionaryEntry("rp", key);
+ }
+
+ public static String getRequestParameter(String key, String defaultValue) {
+ String value = getRequestParameter(key);
+ return (value!=null ? value : defaultValue);
+ }
+
+ public static Set<String> getParameterKeys() {
+ return getDictionaryKeys("config");
+ }
+
+ public static Set<String> getRequestParameterKeys() {
+ return getDictionaryKeys("rp");
+ }
+
+ private static String getDictionaryEntry(String dictionaryName, String key) {
+ try {
+ Dictionary dic = Dictionary.getDictionary(dictionaryName);
+ if (dic != null) {
+ return dic.get(key);
+ }
+ return null;
+
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static Set<String> getDictionaryKeys(String dictionaryName) {
+ Dictionary dic = Dictionary.getDictionary(dictionaryName);
+ if (dic != null) {
+ return dic.keySet();
+ }
+ return null;
+ }
+
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/JsonUtils.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/JsonUtils.java
new file mode 100644
index 00000000000..ca64c74ca81
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/JsonUtils.java
@@ -0,0 +1,203 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.core.client.JavaScriptException;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.http.client.URL;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.json.client.*;
+
+import java.util.Date;
+
+public final class JsonUtils {
+ private static int requestId = 0;
+
+ private JsonUtils() {
+ // only static methods
+ }
+
+ public interface JSONHandler {
+ void onResponse(JavaScriptObject obj);
+
+ void onTimeout();
+
+ void onError(int errorCode, String errorMessage);
+ }
+
+ public static void requestJson(String url, JSONHandler handler) {
+ if (!url.endsWith("&") && !url.endsWith("?")) {
+ url += "&";
+ }
+ if (!url.contains("format=json")) {
+ url += "format=json&";
+ }
+ if (!url.contains("callback=")) {
+ // IMPORTANT : the url should ended with ?callback= or &callback= for JSONP calls
+ url += "callback=";
+ }
+ makeJSONRequest(requestId++, URL.encode(url), handler);
+ }
+
+ public static native void makeJSONRequest(int requestId, String url, JSONHandler handler)
+ /*-{
+ var callback = "callback" + requestId;
+
+ // create SCRIPT tag, and set SRC attribute equal to JSON feed URL + callback function name
+ var script = document.createElement("script");
+ script.setAttribute("src", url + callback);
+ script.setAttribute("type", "text/javascript");
+
+ window[callback] = function(jsonObj) {
+ @org.sonar.gwt.JsonUtils::dispatchJSON(Lcom/google/gwt/core/client/JavaScriptObject;Lorg/sonar/gwt/JsonUtils$JSONHandler;)(jsonObj, handler);
+ window[callback + "done"] = true;
+ }
+
+ setTimeout(function() {
+ if (!window[callback + "done"]) {
+ handler.@org.sonar.gwt.JsonUtils.JSONHandler::onTimeout();
+ }
+
+ // cleanup
+ document.body.removeChild(script);
+ if (window[callback]) {
+ delete window[callback];
+ }
+ if (window[callback + "done"]) {
+ delete window[callback + "done"];
+ }
+ }, 120000);
+
+ document.body.appendChild(script);
+ }-*/;
+
+ public static void dispatchJSON(JavaScriptObject jsonObj, JSONHandler handler) {
+ JSONObject obj = new JSONObject(jsonObj);
+ if (obj.isObject() != null) {
+ if (obj.containsKey("err_code")) {
+ handler.onError(new Double(obj.get("err_code").isNumber().doubleValue()).intValue(),
+ obj.get("err_msg").isString().stringValue());
+ return;
+ }
+ }
+ handler.onResponse(jsonObj);
+ }
+
+ public static String getString(JSONObject json, String field) {
+ return getAsString(json.get(field));
+ }
+
+ public static Date getDate(JSONObject json, String field) {
+ String date = getString(json, field);
+ if (date != null) {
+ return parseDateTime(date);
+ }
+ return null;
+ }
+
+ public static Boolean getBoolean(JSONObject json, String field) {
+ JSONValue jsonValue;
+ JSONBoolean jsonBoolean;
+ if ((jsonValue = json.get(field)) == null) {
+ return null;
+ }
+ if ((jsonBoolean = jsonValue.isBoolean()) == null) {
+ return null;
+ }
+ return jsonBoolean.booleanValue();
+ }
+
+ public static Double getDouble(JSONObject json, String field) {
+ JSONValue jsonValue;
+ JSONNumber jsonNumber;
+ if ((jsonValue = json.get(field)) == null) {
+ return null;
+ }
+ if ((jsonNumber = jsonValue.isNumber()) == null) {
+ return null;
+ }
+ return jsonNumber.doubleValue();
+ }
+
+ public static Integer getInteger(JSONObject json, String field) {
+ final Double d = getDouble(json, field);
+ if (d != null) {
+ return d.intValue();
+ }
+ return null;
+ }
+
+ public static JSONObject getArray(JSONValue json, int i) {
+ if (json instanceof JSONArray) {
+ return ((JSONArray) json).get(i).isObject();
+ }
+ if (json instanceof JSONObject) {
+ return ((JSONObject) json).get(Integer.toString(i)).isObject();
+ }
+ throw new JavaScriptException("Not implemented");
+ }
+
+ public static int getArraySize(JSONValue array) {
+ if (array instanceof JSONArray) {
+ return ((JSONArray) array).size();
+ }
+ if (array instanceof JSONObject) {
+ return ((JSONObject) array).size();
+ }
+ throw new JavaScriptException("Not implemented");
+ }
+
+ public static String getAsString(JSONValue jsonValue) {
+ if (jsonValue == null) {
+ return null;
+ }
+ JSONString jsonString;
+ if ((jsonString = jsonValue.isString()) == null) {
+ JSONNumber jsonNumber = jsonValue.isNumber();
+ return jsonNumber != null ? jsonNumber.toString() : null;
+ }
+ return jsonString.stringValue();
+ }
+
+ public static Double getAsDouble(JSONValue jsonValue) {
+ if (jsonValue == null) {
+ return null;
+ }
+ JSONNumber jsonNumber;
+ if ((jsonNumber = jsonValue.isNumber()) == null) {
+ JSONString jsonString = jsonValue.isString();
+ return jsonString != null ? Double.parseDouble(jsonString.toString()) : null;
+ }
+ return jsonNumber.doubleValue();
+ }
+
+ /**
+ * @since 2.5
+ */
+ public static Date parseDateTime(String dateTime) {
+ DateTimeFormat frmt = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ if (dateTime.endsWith("Z") && dateTime.length() > 2) {
+ // see SONAR-1182
+ dateTime = dateTime.substring(0, dateTime.length() - 2) + "+0000";
+ }
+ return frmt.parse(dateTime);
+ }
+
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/Links.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/Links.java
new file mode 100644
index 00000000000..ae1b3172c3d
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/Links.java
@@ -0,0 +1,115 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.user.client.Window;
+
+public final class Links {
+
+ public static final String DEFAULT_POPUP_HTML_FEATURES = "height=800,width=900,scrollbars=1,resizable=1";
+
+ private Links() {
+ // only static methods
+ }
+
+ public static String baseUrl() {
+ return Configuration.getParameter("sonar_url");
+ }
+
+ public static String apiUrl() {
+ return baseUrl() + "/api";
+ }
+
+
+ public static String urlForResource(String resourceIdOrKey) {
+ return urlForMeasure(resourceIdOrKey, null);
+ }
+
+ public static String urlForMeasure(String resourceIdOrKey, String metricKey) {
+ String url = baseUrl() + "/resource/index/" + resourceIdOrKey;
+ if (metricKey != null) {
+ url += "?metric=" + metricKey;
+ }
+ return url;
+ }
+
+ /**
+ *
+ * @param resourceIdOrKey
+ * @param pageId
+ * @param query additional query parameters. Can be null. Example "layout=false&param1=val1"
+ */
+ public static String urlForResourcePage(String resourceIdOrKey, String pageId, String query) {
+ String url = baseUrl() + "/plugins/resource/";
+ if (resourceIdOrKey != null) {
+ url += resourceIdOrKey;
+ }
+ url += "?page=";
+ url += pageId;
+ if (query != null) {
+ url += "&";
+ url += query;
+ }
+ return url;
+ }
+
+ public static String urlForRule(String ruleIdOrKey, boolean showLayout) {
+ return baseUrl() + "/rules/show/" + ruleIdOrKey + "?layout=" + showLayout;
+ }
+
+ public static String urlForDrilldown(String resourceIdOrKey, String metricKey) {
+ return baseUrl() + "/drilldown/measures/" + resourceIdOrKey + "?metric=" + metricKey;
+ }
+
+ public static void openResourcePopup(final String resourceIdOrKey) {
+ openMeasurePopup(resourceIdOrKey, null);
+ }
+
+ /**
+ * Open the resource in a popup with HTML features like: height=800,width=900,scrollbars=1,resizable=1
+ *
+ * @param resourceIdOrKey the id or key of the resource to display, not null
+ * @param metricKey the metric to highlight (optional : can be null)
+ */
+ public static void openMeasurePopup(final String resourceIdOrKey, final String metricKey) {
+ openMeasurePopup(resourceIdOrKey, metricKey, DEFAULT_POPUP_HTML_FEATURES);
+ }
+
+
+ public static void openMeasurePopup(final String resourceKey, final String metricKey, final String htmlFeatures) {
+ String url = urlForMeasure(resourceKey, metricKey);
+ Window.open(url, "resource", htmlFeatures);
+ }
+
+
+ public static void openResourcePage(final String pageId, final String resourceIdOrKey, final String query) {
+ String url = urlForResourcePage(pageId, resourceIdOrKey, query);
+ Window.Location.assign(url);
+ }
+
+ public static void openRulePopup(final String ruleIdOrKey) {
+ openRulePopup(ruleIdOrKey, DEFAULT_POPUP_HTML_FEATURES);
+ }
+
+ public static void openRulePopup(final String ruleIdOrKey, final String htmlFeatures) {
+ String url = urlForRule(ruleIdOrKey, false);
+ Window.open(url, "rule", htmlFeatures);
+ }
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/Metrics.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/Metrics.java
new file mode 100644
index 00000000000..2529f46bee5
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/Metrics.java
@@ -0,0 +1,110 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+/**
+ * Keys of core metrics
+ */
+public interface Metrics {
+
+ String LINES = "lines";
+ String NCLOC = "ncloc";
+ String GENERATED_NCLOC = "generated_ncloc";
+ String GENERATED_LINES = "generated_lines";
+ String CLASSES = "classes";
+ String FILES = "files";
+ String DIRECTORIES = "directories";
+ String PACKAGES = "packages";
+ String FUNCTIONS = "functions";
+ String PARAGRAPHS = "paragraphs";
+ String ACCESSORS = "accessors";
+ String STATEMENTS = "statements";
+ String PUBLIC_API = "public_api";
+ String COMPLEXITY = "complexity";
+ String CLASS_COMPLEXITY = "class_complexity";
+ String FUNCTION_COMPLEXITY = "function_complexity";
+ String PARAGRAPH_COMPLEXITY = "paragraph_complexity";
+ String FILE_COMPLEXITY = "file_complexity";
+ String CLASS_COMPLEXITY_DISTRIBUTION = "class_complexity_distribution";
+ String FUNCTION_COMPLEXITY_DISTRIBUTION = "function_complexity_distribution";
+ String COMMENT_LINES = "comment_lines";
+ String COMMENT_LINES_DENSITY = "comment_lines_density";
+ String COMMENT_BLANK_LINES = "comment_blank_lines";
+ String PUBLIC_DOCUMENTED_API_DENSITY = "public_documented_api_density";
+ String PUBLIC_UNDOCUMENTED_API = "public_undocumented_api";
+ String COMMENTED_OUT_CODE_LINES = "commented_out_code_lines";
+ String TESTS = "tests";
+ String TEST_EXECUTION_TIME = "test_execution_time";
+ String TEST_ERRORS = "test_errors";
+ String SKIPPED_TESTS = "skipped_tests";
+ String TEST_FAILURES = "test_failures";
+ String TEST_SUCCESS_DENSITY = "test_success_density";
+ String TEST_DATA = "test_data";
+ String COVERAGE = "coverage";
+ String LINES_TO_COVER = "lines_to_cover";
+ String UNCOVERED_LINES = "uncovered_lines";
+ String LINE_COVERAGE = "line_coverage";
+ String COVERAGE_LINE_HITS_DATA = "coverage_line_hits_data";
+ String CONDITIONS_TO_COVER = "conditions_to_cover";
+ String UNCOVERED_CONDITIONS = "uncovered_conditions";
+ String BRANCH_COVERAGE = "branch_coverage";
+ String BRANCH_COVERAGE_HITS_DATA = "branch_coverage_hits_data";
+ String DUPLICATED_LINES = "duplicated_lines";
+ String DUPLICATED_BLOCKS = "duplicated_blocks";
+ String DUPLICATED_FILES = "duplicated_files";
+ String DUPLICATED_LINES_DENSITY = "duplicated_lines_density";
+ String DUPLICATIONS_DATA = "duplications_data";
+ String USABILITY = "usability";
+ String RELIABILITY = "reliability";
+ String EFFICIENCY = "efficiency";
+ String PORTABILITY = "portability";
+ String MAINTAINABILITY = "maintainability";
+ String WEIGHTED_VIOLATIONS = "weighted_violations";
+ String VIOLATIONS_DENSITY = "violations_density";
+ String VIOLATIONS = "violations";
+ String BLOCKER_VIOLATIONS = "blocker_violations";
+ String CRITICAL_VIOLATIONS = "critical_violations";
+ String MAJOR_VIOLATIONS = "major_violations";
+ String MINOR_VIOLATIONS = "minor_violations";
+ String INFO_VIOLATIONS = "info_violations";
+ String DEPTH_IN_TREE = "dit";
+ String NUMBER_OF_CHILDREN = "noc";
+ String RFC = "rfc";
+ String RFC_DISTRIBUTION = "rfc_distribution";
+ String LCOM4 = "lcom4";
+ String LCOM4_DISTRIBUTION = "lcom4_distribution";
+ String AFFERENT_COUPLINGS = "ca";
+ String EFFERENT_COUPLINGS = "ce";
+ String ABSTRACTNESS = "abstractness";
+ String INSTABILITY = "instability";
+ String DISTANCE = "distance";
+ String DEPENDENCY_MATRIX = "dsm";
+ String PACKAGE_CYCLES = "package_cycles";
+ String PACKAGE_TANGLE_INDEX = "package_tangle_index";
+ String PACKAGE_TANGLES = "package_tangles";
+ String PACKAGE_FEEDBACK_EDGES = "package_feedback_edges";
+ String PACKAGE_EDGES_WEIGHT = "package_edges_weight";
+ String FILE_CYCLES = "file_cycles";
+ String FILE_TANGLE_INDEX = "file_tangle_index";
+ String FILE_TANGLES = "file_tangles";
+ String FILE_FEEDBACK_EDGES = "file_feedback_edges";
+ String FILE_EDGES_WEIGHT = "file_edges_weight";
+ String ALERT_STATUS = "alert_status";
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/Utils.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/Utils.java
new file mode 100644
index 00000000000..eb6b09aad94
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/Utils.java
@@ -0,0 +1,83 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import java.util.Date;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+
+public final class Utils {
+
+ private Utils() {
+ // only static methods
+ }
+
+ /**
+ * @return width in pixels of the GWT component in the Sonar page
+ */
+ public static int getPageWidth() {
+ return DOM.getElementById("gwtpage").getClientWidth();
+ }
+
+ public static String escapeHtml(String maybeHtml) {
+ final Element div = DOM.createDiv();
+ DOM.setInnerText(div, maybeHtml);
+ return DOM.getInnerHTML(div);
+ }
+
+ public static String formatPercent(String percentage) {
+ return percentage == null || percentage.equals("") ? "" : formatPercent(new Double(percentage));
+ }
+
+ public static String formatPercent(double percentage) {
+ return NumberFormat.getFormat("0.0").format(percentage) + "%";
+ }
+
+ public static String formatNumber(String number) {
+ return number == null || number.equals("") ? "" : formatNumber(new Double(number));
+ }
+
+ public static String formatNumber(double number) {
+ return NumberFormat.getDecimalFormat().format(number);
+ }
+
+ /**
+ * @since 2.5
+ */
+ public static String formatDate(Date date) {
+ return date == null ? "" : DateTimeFormat.getShortDateFormat().format(date);
+ }
+
+ public static native void showError(String message) /*-{
+ $wnd.error(message);
+ }-*/;
+
+ public static native void showWarning(String message) /*-{
+ $wnd.warning(message);
+ }-*/;
+
+ public static native void showInfo(String message) /*-{
+ $wnd.info(message);
+ }-*/;
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ExpandCollapseLink.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ExpandCollapseLink.java
new file mode 100644
index 00000000000..00dcdb32d97
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ExpandCollapseLink.java
@@ -0,0 +1,55 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt.ui;
+
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.Hyperlink;
+import com.google.gwt.user.client.ui.Widget;
+
+public class ExpandCollapseLink extends Hyperlink {
+
+ private Widget expandOrCollapse;
+
+ public ExpandCollapseLink(Widget expandOrCollapse) {
+ super();
+ this.expandOrCollapse = expandOrCollapse;
+ setText(getLinkLabel(!expandOrCollapse.isVisible()));
+ getElement().setId("expand-" + expandOrCollapse.getElement().getId());
+ setStyleName("expandCollapseLink");
+ final ExpandCollapseLink link = this;
+ this.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ link.toggle();
+ }
+ });
+ getElement().getFirstChildElement().setAttribute("href", "#");
+ }
+
+ public void toggle() {
+ boolean visible = expandOrCollapse.isVisible();
+ setText(getLinkLabel(visible));
+ expandOrCollapse.setVisible(!visible);
+ }
+
+ protected String getLinkLabel(boolean show) {
+ return (show ? "expand" : "collapse");
+ }
+
+} \ No newline at end of file
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Icons.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Icons.java
new file mode 100644
index 00000000000..e703a69466c
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Icons.java
@@ -0,0 +1,160 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.AbstractImagePrototype;
+import com.google.gwt.user.client.ui.ImageBundle;
+
+/**
+ * All icons are 16x16 pixels
+ */
+public final class Icons {
+ private static IconBundle INSTANCE;
+
+ private Icons() {
+ // only static methods
+ }
+
+ public static IconBundle get() {
+ if (INSTANCE == null) {
+ INSTANCE = GWT.create(IconBundle.class);
+ }
+ return INSTANCE;
+ }
+
+ public static AbstractImagePrototype forQualifier(final String qualifier) {
+ AbstractImagePrototype image;
+ if ("FIL".equals(qualifier)) {
+ image = get().qualifierFile();
+ } else if ("CLA".equals(qualifier)) {
+ image = get().qualifierClass();
+
+ } else if ("PAC".equals(qualifier)) {
+ image = get().qualifierPackage();
+
+ } else if ("DIR".equals(qualifier)) {
+ image = get().qualifierDirectory();
+
+ } else if ("BRC".equals(qualifier)) {
+ image = get().qualifierModule();
+
+ } else if ("TRK".equals(qualifier)) {
+ image = get().qualifierProject();
+
+ } else if ("UTS".equals(qualifier)) {
+ image = get().qualifierUnitTest();
+
+ } else if ("FLD".equals(qualifier)) {
+ image = get().qualifierField();
+
+ } else if ("MET".equals(qualifier)) {
+ image = get().qualifierMethod();
+
+ } else if ("LIB".equals(qualifier)) {
+ image = get().qualifierLibrary();
+
+ } else {
+ image = get().empty();
+ }
+ return image;
+ }
+
+ /**
+ * @since 2.2
+ * @deprecated since 2.5 use {@link Icons#forSeverity(String)}
+ */
+ @Deprecated
+ public static AbstractImagePrototype forPriority(final String priority) {
+ return forSeverity(priority);
+ }
+
+ /**
+ * @since 2.5
+ */
+ public static AbstractImagePrototype forSeverity(final String severity) {
+ AbstractImagePrototype image;
+ if ("BLOCKER".equals(severity)) {
+ image = get().priorityBlocker();
+
+ } else if ("CRITICAL".equals(severity)) {
+ image = get().priorityCritical();
+
+ } else if ("MAJOR".equals(severity)) {
+ image = get().priorityMajor();
+
+ } else if ("MINOR".equals(severity)) {
+ image = get().priorityMinor();
+
+ } else if ("INFO".equals(severity)) {
+ image = get().priorityInfo();
+
+ } else {
+ image = get().empty();
+ }
+ return image;
+ }
+
+ public static interface IconBundle extends ImageBundle {
+ AbstractImagePrototype empty();
+
+ AbstractImagePrototype zoom();
+
+ AbstractImagePrototype information();
+
+ AbstractImagePrototype help();
+
+ AbstractImagePrototype qualifierField();
+
+ AbstractImagePrototype qualifierMethod();
+
+ AbstractImagePrototype qualifierClass();
+
+ AbstractImagePrototype qualifierFile();
+
+ AbstractImagePrototype qualifierUnitTest();
+
+ AbstractImagePrototype qualifierDirectory();
+
+ AbstractImagePrototype qualifierPackage();
+
+ AbstractImagePrototype qualifierProject();
+
+ AbstractImagePrototype qualifierModule();
+
+ AbstractImagePrototype qualifierLibrary();
+
+ AbstractImagePrototype statusOk();
+
+ AbstractImagePrototype statusError();
+
+ AbstractImagePrototype statusWarning();
+
+ AbstractImagePrototype priorityBlocker();
+
+ AbstractImagePrototype priorityCritical();
+
+ AbstractImagePrototype priorityMajor();
+
+ AbstractImagePrototype priorityMinor();
+
+ AbstractImagePrototype priorityInfo();
+ }
+} \ No newline at end of file
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Page.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Page.java
new file mode 100644
index 00000000000..34a146b2e76
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Page.java
@@ -0,0 +1,92 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt.ui;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import org.sonar.wsclient.gwt.GwtUtils;
+import org.sonar.wsclient.services.Resource;
+import org.sonar.wsclient.services.WSUtils;
+import org.sonar.wsclient.unmarshallers.ResourceUnmarshaller;
+
+public abstract class Page implements EntryPoint {
+
+ private static final ResourceUnmarshaller RESOURCE_UNMARSHALLER = new ResourceUnmarshaller();
+
+ public final void onModuleLoad() {
+ export(GWT.getModuleName(), this);
+ load();
+ onResourceLoad();
+ }
+
+ private void load() {
+ Widget widget = doOnModuleLoad();
+ if (widget != null) {
+ getRootPanel().add(widget);
+ }
+ }
+
+ protected Widget doOnModuleLoad() {
+ return null;
+ }
+
+ public final void onResourceLoad() {
+ JavaScriptObject json = loadResource();
+ if (json != null) {
+ if (WSUtils.getINSTANCE() == null) {
+ WSUtils.setInstance(new GwtUtils()); // TODO dirty hack to initialize WSUtils
+ }
+ String jsonStr = (new JSONObject(json)).toString();
+ Resource resource = RESOURCE_UNMARSHALLER.toModel(jsonStr);
+
+ RootPanel container = getRootPanel();
+ container.clear();
+
+ Widget currentWidget = doOnResourceLoad(resource);
+ if (currentWidget != null) {
+ container.add(currentWidget);
+ }
+ }
+ }
+
+ protected Widget doOnResourceLoad(Resource resource) {
+ return null;
+ }
+
+ protected final RootPanel getRootPanel() {
+ RootPanel result = RootPanel.get("gwtpage-" + GWT.getModuleName());
+ if (result == null) {
+ result = RootPanel.get("gwtpage");
+ }
+ return result;
+ }
+
+ private native JavaScriptObject loadResource()/*-{
+ return $wnd.config['resource'];
+ }-*/;
+
+ private native void export(String gwtId, Page page)/*-{
+ $wnd.modules[gwtId]=function() {page.@org.sonar.gwt.ui.Page::onResourceLoad()()};
+ }-*/;
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ViewerHeader.java b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ViewerHeader.java
new file mode 100644
index 00000000000..2e17bf0e212
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ViewerHeader.java
@@ -0,0 +1,138 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt.ui;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Panel;
+import org.sonar.wsclient.gwt.AbstractCallback;
+import org.sonar.wsclient.gwt.Sonar;
+import org.sonar.wsclient.services.Measure;
+import org.sonar.wsclient.services.Resource;
+import org.sonar.wsclient.services.ResourceQuery;
+
+public abstract class ViewerHeader extends Composite {
+ private String[] metrics;
+ private FlowPanel header;
+
+ public ViewerHeader(Resource resource, String[] metrics) {
+ this.metrics = metrics;
+ header = new FlowPanel();
+ header.setStyleName("gwt-ViewerHeader");
+ initWidget(header);
+ loadMeasures(resource);
+ }
+
+ public String[] getMetrics() {
+ return metrics;
+ }
+
+ private void loadMeasures(Resource resource) {
+ ResourceQuery query = ResourceQuery.createForMetrics(resource.getKey(), metrics).setVerbose(true);
+ Sonar.getInstance().find(query, new AbstractCallback<Resource>() {
+
+ @Override
+ protected void doOnResponse(Resource resource) {
+ display(header, resource);
+ }
+ });
+ }
+
+ protected abstract void display(FlowPanel header, Resource resource);
+
+ protected static class MeasureLabel {
+ private String metricName;
+ private String value;
+
+ public MeasureLabel(Measure measure) {
+ if (measure != null) {
+ this.metricName = measure.getMetricName();
+ this.value = measure.getFormattedValue();
+ }
+ }
+
+ public MeasureLabel(Measure measure, String metricName, String defaultValue) {
+ this.metricName = metricName;
+ if (measure != null) {
+ this.value = measure.getFormattedValue();
+ } else {
+ this.value = defaultValue;
+ }
+ }
+
+ public String getMetricName() {
+ return metricName;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public boolean hasValue() {
+ return value != null;
+ }
+ }
+
+ protected void addCell(Panel panel, Measure... measures) {
+ if (measures != null) {
+ String names = "";
+ String values = "";
+ boolean first = true;
+ for (Measure measure : measures) {
+ if (measure != null && measure.getFormattedValue() != null) {
+ if (!first) {
+ names += "<br/>";
+ values += "<br/>";
+ }
+ names += "<b>" + measure.getMetricName() + "</b>: ";
+ values += measure.getFormattedValue();
+ first = false;
+ }
+ }
+
+ if (!first) {
+ HTML html = new HTML(names);
+ html.setStyleName("metric");
+ panel.add(html);
+
+ html = new HTML(values);
+ html.setStyleName("value");
+ panel.add(html);
+ }
+ }
+ }
+
+ protected void addCell(Panel panel, String metric, String value) {
+ HTML html = new HTML(metric);
+ html.setStyleName("metric");
+ panel.add(html);
+
+ html = new HTML(value);
+ html.setStyleName("value");
+ panel.add(html);
+ }
+
+ protected void addBigCell(Panel panel, String html) {
+ HTML htmlDiv = new HTML(html);
+ htmlDiv.setStyleName("big");
+ panel.add(htmlDiv);
+ }
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractCallback.java b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractCallback.java
new file mode 100644
index 00000000000..0e68df67f80
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractCallback.java
@@ -0,0 +1,67 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.user.client.ui.Widget;
+import org.sonar.wsclient.services.Model;
+
+public abstract class AbstractCallback<MODEL extends Model> implements Callback<MODEL> {
+
+ private Widget loadingWidget = null;
+
+ protected AbstractCallback(Widget loadingWidget) {
+ this.loadingWidget = loadingWidget;
+ }
+
+ protected AbstractCallback() {
+ }
+
+ public void onResponse(MODEL result, JavaScriptObject json) {
+ hideLoadingWidget();
+ doOnResponse(result);
+ }
+
+ protected abstract void doOnResponse(MODEL result);
+
+ public final void onTimeout() {
+ doOnTimeout();
+ hideLoadingWidget();
+ }
+
+ public final void onError(int errorCode, String errorMessage) {
+ doOnError(errorCode, errorMessage);
+ hideLoadingWidget();
+ }
+
+ protected void doOnError(int errorCode, String errorMessage) {
+
+ }
+
+ protected void doOnTimeout() {
+
+ }
+
+ private void hideLoadingWidget() {
+ if (loadingWidget != null) {
+ loadingWidget.removeFromParent();
+ }
+ }
+} \ No newline at end of file
diff --git a/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractListCallback.java b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractListCallback.java
new file mode 100644
index 00000000000..15197362327
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractListCallback.java
@@ -0,0 +1,69 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.user.client.ui.Widget;
+import org.sonar.wsclient.services.Model;
+
+import java.util.List;
+
+public abstract class AbstractListCallback<MODEL extends Model> implements ListCallback<MODEL> {
+
+ private Widget loadingWidget = null;
+
+ protected AbstractListCallback(Widget loadingWidget) {
+ this.loadingWidget = loadingWidget;
+ }
+
+ protected AbstractListCallback() {
+ }
+
+ public void onResponse(List<MODEL> result, JavaScriptObject json) {
+ hideLoadingWidget();
+ doOnResponse(result);
+ }
+
+ protected abstract void doOnResponse(List<MODEL> result);
+
+ public final void onTimeout() {
+ doOnTimeout();
+ hideLoadingWidget();
+ }
+
+ public final void onError(int errorCode, String errorMessage) {
+ doOnError(errorCode, errorMessage);
+ hideLoadingWidget();
+ }
+
+ protected void doOnError(int errorCode, String errorMessage) {
+
+ }
+
+ protected void doOnTimeout() {
+
+ }
+
+ private void hideLoadingWidget() {
+ if (loadingWidget != null) {
+ loadingWidget.removeFromParent();
+ }
+ }
+} \ No newline at end of file
diff --git a/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Callback.java b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Callback.java
new file mode 100644
index 00000000000..c2cd8e0b35c
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Callback.java
@@ -0,0 +1,33 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import org.sonar.wsclient.services.Model;
+
+public interface Callback<MODEL extends Model> {
+
+ void onResponse(MODEL result, JavaScriptObject json);
+
+ void onTimeout();
+
+ void onError(int errorCode, String errorMessage);
+
+} \ No newline at end of file
diff --git a/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/GwtUtils.java b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/GwtUtils.java
new file mode 100644
index 00000000000..70b139cab25
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/GwtUtils.java
@@ -0,0 +1,102 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.json.client.JSONValue;
+import org.sonar.gwt.JsonUtils;
+import org.sonar.wsclient.services.WSUtils;
+
+import java.util.Date;
+import java.util.Set;
+
+public class GwtUtils extends WSUtils {
+ @Override
+ public String format(Date date, String format) {
+ return DateTimeFormat.getFormat(format).format(date);
+ }
+
+ @Override
+ public String encodeUrl(String url) {
+ return com.google.gwt.http.client.URL.encode(url);
+ }
+
+ @Override
+ public Object getField(Object json, String field) {
+ return ((JSONObject) json).get(field);
+ }
+
+ @Override
+ public String getString(Object json, String field) {
+ return JsonUtils.getString((JSONObject) json, field);
+ }
+
+ @Override
+ public Boolean getBoolean(Object json, String field) {
+ return JsonUtils.getBoolean((JSONObject) json, field);
+ }
+
+ @Override
+ public Integer getInteger(Object json, String field) {
+ return JsonUtils.getInteger((JSONObject) json, field);
+ }
+
+ @Override
+ public Double getDouble(Object json, String field) {
+ return JsonUtils.getDouble((JSONObject) json, field);
+ }
+
+ @Override
+ public Long getLong(Object json, String field) {
+ Double d = JsonUtils.getDouble((JSONObject) json, field);
+ if (d != null) {
+ return d.longValue();
+ }
+ return null;
+ }
+
+ @Override
+ public Date getDateTime(Object json, String field) {
+ return JsonUtils.getDate((JSONObject) json, field);
+ }
+
+ @Override
+ public int getArraySize(Object array) {
+ return JsonUtils.getArraySize((JSONValue) array);
+ }
+
+ @Override
+ public Object getArrayElement(Object array, int i) {
+ return JsonUtils.getArray((JSONValue) array, i);
+ }
+
+ @Override
+ public Object parse(String jsonStr) {
+ return JSONParser.parse(jsonStr);
+ }
+
+ @Override
+ public Set<String> getFields(Object json) {
+ return ((JSONObject) json).keySet();
+ }
+
+}
diff --git a/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/ListCallback.java b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/ListCallback.java
new file mode 100644
index 00000000000..e9c9f5f55b0
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/ListCallback.java
@@ -0,0 +1,33 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import org.sonar.wsclient.services.Model;
+
+import java.util.List;
+
+public interface ListCallback<MODEL extends Model> {
+
+ void onResponse(List<MODEL> result, JavaScriptObject json);
+ void onTimeout();
+ void onError(int errorCode, String errorMessage);
+
+} \ No newline at end of file
diff --git a/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Sonar.java b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Sonar.java
new file mode 100644
index 00000000000..ee439203d2d
--- /dev/null
+++ b/sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Sonar.java
@@ -0,0 +1,95 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * 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.gwt;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.i18n.client.Dictionary;
+import com.google.gwt.json.client.JSONObject;
+import org.sonar.gwt.JsonUtils;
+import org.sonar.wsclient.services.Model;
+import org.sonar.wsclient.services.Query;
+import org.sonar.wsclient.services.WSUtils;
+import org.sonar.wsclient.unmarshallers.Unmarshaller;
+import org.sonar.wsclient.unmarshallers.Unmarshallers;
+
+public class Sonar {
+ static {
+ WSUtils.setInstance(new GwtUtils());
+ }
+
+ private static Sonar instance = null;
+
+ private final String host;
+
+ public Sonar(String host) {
+ this.host = host;
+ }
+
+ /**
+ * To be used in Sonar extensions only, else use constructors.
+ */
+ public static Sonar getInstance() {
+ if (instance == null) {
+ Dictionary dic = Dictionary.getDictionary("config");
+ instance = new Sonar(dic.get("sonar_url"));
+ }
+ return instance;
+ }
+
+ public <MODEL extends Model> void find(final Query<MODEL> query, final Callback<MODEL> callback) {
+ JsonUtils.requestJson(getUrl(query), new JsonUtils.JSONHandler() {
+ public void onResponse(JavaScriptObject obj) {
+ Unmarshaller<MODEL> unmarshaller = Unmarshallers.forModel(query.getModelClass());
+ String json = (new JSONObject(obj)).toString();
+ callback.onResponse(unmarshaller.toModel(json), obj);
+ }
+
+ public void onTimeout() {
+ callback.onTimeout();
+ }
+
+ public void onError(int errorCode, String errorMessage) {
+ callback.onError(errorCode, errorMessage);
+ }
+ });
+ }
+
+ public <MODEL extends Model> void findAll(final Query<MODEL> query, final ListCallback<MODEL> callback) {
+ JsonUtils.requestJson(getUrl(query), new JsonUtils.JSONHandler() {
+ public void onResponse(JavaScriptObject obj) {
+ Unmarshaller<MODEL> unmarshaller = Unmarshallers.forModel(query.getModelClass());
+ String json = (new JSONObject(obj)).toString();
+ callback.onResponse(unmarshaller.toModels(json), obj);
+ }
+
+ public void onTimeout() {
+ callback.onTimeout();
+ }
+
+ public void onError(int errorCode, String errorMessage) {
+ callback.onError(errorCode, errorMessage);
+ }
+ });
+ }
+
+ private String getUrl(Query query) {
+ return host + query.getUrl();
+ }
+}
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/Sonar.gwt.xml b/sonar-gwt-api/src/main/resources/org/sonar/Sonar.gwt.xml
new file mode 100644
index 00000000000..ab4d95c0a2c
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/Sonar.gwt.xml
@@ -0,0 +1,10 @@
+<module>
+
+ <inherits name='com.google.gwt.user.User'/>
+ <inherits name="com.google.gwt.json.JSON"/>
+ <inherits name="com.google.gwt.http.HTTP"/>
+ <inherits name="com.google.gwt.i18n.I18N"/>
+ <inherits name="com.google.gwt.gen2.table.Table"/>
+ <source path="gwt" />
+ <source path="wsclient" />
+</module>
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/SonarDev.gwt.xml b/sonar-gwt-api/src/main/resources/org/sonar/SonarDev.gwt.xml
new file mode 100644
index 00000000000..65d1c1d8faf
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/SonarDev.gwt.xml
@@ -0,0 +1,5 @@
+<module>
+ <!-- optimization of dev environments -->
+ <set-property name="user.agent" value="gecko1_8" />
+ <set-property name="locale" value="default"/>
+</module>
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/empty.gif b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/empty.gif
new file mode 100644
index 00000000000..eef3db1dfe0
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/empty.gif
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/help.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/help.png
new file mode 100644
index 00000000000..34c0de006c3
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/help.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/information.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/information.png
new file mode 100644
index 00000000000..d2e8818b95f
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/information.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/javaModule.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/javaModule.png
new file mode 100644
index 00000000000..fe39cb27144
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/javaModule.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityBlocker.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityBlocker.png
new file mode 100644
index 00000000000..68b75c4158f
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityBlocker.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityCritical.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityCritical.png
new file mode 100644
index 00000000000..1ba28a111fd
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityCritical.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityInfo.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityInfo.png
new file mode 100644
index 00000000000..4b42197b237
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityInfo.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMajor.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMajor.png
new file mode 100644
index 00000000000..d06543bf627
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMajor.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMinor.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMinor.png
new file mode 100644
index 00000000000..57fc3145d34
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMinor.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierClass.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierClass.png
new file mode 100644
index 00000000000..1664e25c8b5
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierClass.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierDirectory.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierDirectory.png
new file mode 100644
index 00000000000..b135ef92eec
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierDirectory.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierField.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierField.png
new file mode 100644
index 00000000000..7afc0a1b27b
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierField.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierFile.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierFile.png
new file mode 100644
index 00000000000..1664e25c8b5
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierFile.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierLibrary.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierLibrary.png
new file mode 100644
index 00000000000..5250d7d57d2
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierLibrary.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierMethod.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierMethod.png
new file mode 100644
index 00000000000..892026cb013
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierMethod.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierModule.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierModule.png
new file mode 100644
index 00000000000..53de3b70fa6
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierModule.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierPackage.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierPackage.png
new file mode 100644
index 00000000000..d82d4627860
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierPackage.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierProject.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierProject.png
new file mode 100644
index 00000000000..b32e51c5f42
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierProject.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierUnitTest.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierUnitTest.png
new file mode 100644
index 00000000000..dd00dff89f2
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierUnitTest.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierView.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierView.png
new file mode 100644
index 00000000000..a1e700dc4c6
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierView.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusError.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusError.png
new file mode 100644
index 00000000000..0da4d846a66
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusError.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusOk.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusOk.png
new file mode 100644
index 00000000000..fb454cefd5c
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusOk.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusWarning.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusWarning.png
new file mode 100644
index 00000000000..a3dfc6806a3
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusWarning.png
Binary files differ
diff --git a/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/zoom.png b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/zoom.png
new file mode 100644
index 00000000000..47a5307461f
--- /dev/null
+++ b/sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/zoom.png
Binary files differ