From fec91dbfd31b9535146cef1e1d47bb4601e43cf5 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Fri, 9 Nov 2012 17:44:29 +0100 Subject: [PATCH] Revert "SONAR-3945 - Drop GWT API" This reverts commit 5d5df25d59314d68c80b9f3b2fcd53a4154ef56c. --- pom.xml | 5 +- sonar-gwt-api/infinitest.args | 1 + sonar-gwt-api/pom.xml | 79 +++++++ .../java/org/sonar/gwt/Configuration.java | 97 +++++++++ .../main/java/org/sonar/gwt/JsonUtils.java | 203 ++++++++++++++++++ .../src/main/java/org/sonar/gwt/Links.java | 115 ++++++++++ .../src/main/java/org/sonar/gwt/Metrics.java | 110 ++++++++++ .../src/main/java/org/sonar/gwt/Utils.java | 83 +++++++ .../org/sonar/gwt/ui/ExpandCollapseLink.java | 55 +++++ .../src/main/java/org/sonar/gwt/ui/Icons.java | 160 ++++++++++++++ .../src/main/java/org/sonar/gwt/ui/Page.java | 92 ++++++++ .../java/org/sonar/gwt/ui/ViewerHeader.java | 138 ++++++++++++ .../sonar/wsclient/gwt/AbstractCallback.java | 67 ++++++ .../wsclient/gwt/AbstractListCallback.java | 69 ++++++ .../java/org/sonar/wsclient/gwt/Callback.java | 33 +++ .../java/org/sonar/wsclient/gwt/GwtUtils.java | 102 +++++++++ .../org/sonar/wsclient/gwt/ListCallback.java | 33 +++ .../java/org/sonar/wsclient/gwt/Sonar.java | 95 ++++++++ .../main/resources/org/sonar/Sonar.gwt.xml | 10 + .../main/resources/org/sonar/SonarDev.gwt.xml | 5 + .../main/resources/org/sonar/gwt/ui/empty.gif | Bin 0 -> 55 bytes .../main/resources/org/sonar/gwt/ui/help.png | Bin 0 -> 731 bytes .../org/sonar/gwt/ui/information.png | Bin 0 -> 724 bytes .../resources/org/sonar/gwt/ui/javaModule.png | Bin 0 -> 745 bytes .../org/sonar/gwt/ui/priorityBlocker.png | Bin 0 -> 672 bytes .../org/sonar/gwt/ui/priorityCritical.png | Bin 0 -> 412 bytes .../org/sonar/gwt/ui/priorityInfo.png | Bin 0 -> 461 bytes .../org/sonar/gwt/ui/priorityMajor.png | Bin 0 -> 437 bytes .../org/sonar/gwt/ui/priorityMinor.png | Bin 0 -> 519 bytes .../org/sonar/gwt/ui/qualifierClass.png | Bin 0 -> 416 bytes .../org/sonar/gwt/ui/qualifierDirectory.png | Bin 0 -> 390 bytes .../org/sonar/gwt/ui/qualifierField.png | Bin 0 -> 644 bytes .../org/sonar/gwt/ui/qualifierFile.png | Bin 0 -> 416 bytes .../org/sonar/gwt/ui/qualifierLibrary.png | Bin 0 -> 379 bytes .../org/sonar/gwt/ui/qualifierMethod.png | Bin 0 -> 628 bytes .../org/sonar/gwt/ui/qualifierModule.png | Bin 0 -> 562 bytes .../org/sonar/gwt/ui/qualifierPackage.png | Bin 0 -> 481 bytes .../org/sonar/gwt/ui/qualifierProject.png | Bin 0 -> 575 bytes .../org/sonar/gwt/ui/qualifierUnitTest.png | Bin 0 -> 542 bytes .../org/sonar/gwt/ui/qualifierView.png | Bin 0 -> 571 bytes .../org/sonar/gwt/ui/statusError.png | Bin 0 -> 1297 bytes .../resources/org/sonar/gwt/ui/statusOk.png | Bin 0 -> 1297 bytes .../org/sonar/gwt/ui/statusWarning.png | Bin 0 -> 1278 bytes .../main/resources/org/sonar/gwt/ui/zoom.png | Bin 0 -> 387 bytes 44 files changed, 1550 insertions(+), 2 deletions(-) create mode 100644 sonar-gwt-api/infinitest.args create mode 100644 sonar-gwt-api/pom.xml create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/Configuration.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/JsonUtils.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/Links.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/Metrics.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/Utils.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ExpandCollapseLink.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Icons.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/ui/Page.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/gwt/ui/ViewerHeader.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractCallback.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/AbstractListCallback.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Callback.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/GwtUtils.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/ListCallback.java create mode 100644 sonar-gwt-api/src/main/java/org/sonar/wsclient/gwt/Sonar.java create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/Sonar.gwt.xml create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/SonarDev.gwt.xml create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/empty.gif create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/help.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/information.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/javaModule.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityBlocker.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityCritical.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityInfo.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMajor.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/priorityMinor.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierClass.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierDirectory.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierField.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierFile.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierLibrary.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierMethod.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierModule.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierPackage.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierProject.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierUnitTest.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/qualifierView.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusError.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusOk.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/statusWarning.png create mode 100644 sonar-gwt-api/src/main/resources/org/sonar/gwt/ui/zoom.png diff --git a/pom.xml b/pom.xml index 24db6e7984a..0a31b81cb04 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ sonar-deprecated sonar-duplications sonar-graph + sonar-gwt-api sonar-java-api sonar-markdown sonar-maven-plugin @@ -75,7 +76,7 @@ 1.1-SNAPSHOT 1.3.167 6.1.25 - sonar-core-gwt + sonar-gwt-api,sonar-core-gwt UTF-8 2.2.1 1.5 @@ -566,7 +567,7 @@ org.codehaus.sonar sonar-gwt-api - 3.3.1 + ${project.version} org.codehaus.sonar diff --git a/sonar-gwt-api/infinitest.args b/sonar-gwt-api/infinitest.args new file mode 100644 index 00000000000..ed9f41dadc7 --- /dev/null +++ b/sonar-gwt-api/infinitest.args @@ -0,0 +1 @@ +-Djava.awt.headless=true \ No newline at end of file diff --git a/sonar-gwt-api/pom.xml b/sonar-gwt-api/pom.xml new file mode 100644 index 00000000000..988c2b136bb --- /dev/null +++ b/sonar-gwt-api/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + org.codehaus.sonar + sonar + 3.4-SNAPSHOT + + sonar-gwt-api + jar + Sonar :: GWT API + + + + + org.codehaus.sonar + sonar-ws-client + + + org.codehaus.sonar + sonar-ws-client + sources + provided + ${project.version} + + + com.google.gwt + gwt-user + + + com.google.gwt + gwt-incubator + + + + + + + + src/main/java + + + src/main/resources + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + src-dependencies + generate-sources + + unpack + + + + + org.codehaus.sonar + sonar-ws-client + ${project.version} + sources + jar + true + ${project.build.directory}/classes + **/services/*.java,**/unmarshallers/*.java + + + true + true + + + + + + + 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 getParameterKeys() { + return getDictionaryKeys("config"); + } + + public static Set 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 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¶m1=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() { + + @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 += "
"; + values += "
"; + } + names += "" + measure.getMetricName() + ": "; + 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 implements Callback { + + 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 implements ListCallback { + + private Widget loadingWidget = null; + + protected AbstractListCallback(Widget loadingWidget) { + this.loadingWidget = loadingWidget; + } + + protected AbstractListCallback() { + } + + public void onResponse(List result, JavaScriptObject json) { + hideLoadingWidget(); + doOnResponse(result); + } + + protected abstract void doOnResponse(List 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 { + + 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 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 { + + void onResponse(List 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 void find(final Query query, final Callback callback) { + JsonUtils.requestJson(getUrl(query), new JsonUtils.JSONHandler() { + public void onResponse(JavaScriptObject obj) { + Unmarshaller 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 void findAll(final Query query, final ListCallback callback) { + JsonUtils.requestJson(getUrl(query), new JsonUtils.JSONHandler() { + public void onResponse(JavaScriptObject obj) { + Unmarshaller 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 @@ + + + + + + + + + + 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 @@ + + + + + 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 0000000000000000000000000000000000000000..eef3db1dfe0eab6bb9e4130755e31110a4e12ef2 GIT binary patch literal 55 zcmZ?wbhEHb6krfwXkdT>#h)ykTnvm1Iv_qshJlH%r+?+?xBQFeY`N9F*^ZUL8UXdn B3+n&? literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..34c0de006c3fe00bad9b73994d946351b3279657 GIT binary patch literal 731 zcmV<10wn#3P)JtZ**pMP2-E-o4Lnd)_^74uG8h;jaTNd6=tl9q`qTeNwr> z&|hpxT5hGuS#z8}ZQRQ}Q=oD%>^XZX;0_*QbC-dOqBFR6Qn33|7+nenh8KhEQw79& zk}b0&l3SsDn7&0JnfF0B?m)xn2D*t&=nNd4n#DXmZ&3Xv+5{n=!=${Xe&UDuvVhc6BMpXB#!WT|qdc_Zwbq7pZ zpt4fnbZF5wZHL7Z#giTbnH6-(J&cP=Kp-}w>Z1YNE`9p44l@QXqVxfFqYV1yoG5G8 zpz4DTcJCgzA{~6H(9al*A z5y%aG=b?URhNPHimJqG#0*$hQODTp;M#OXS>YA25$ktbSYRlHfCmK`A|R(;^K zt5MjjK>LI-!>@2b<0MAZE~w3Z+^iX=u0I@OofuNSaE^Vikw|K7J5X6Dyc92^v_*#E zrWri%(?MbIKxy*fYUStTT1KAZ6cvHWlb6Ht^LIgxM3xu;kc9x73O}t|V}= zLVWs^|8V2cSnjpzQT~<65%Lmmh|c3k=nLh8_n@Dtas1)^0gDhU7p N002ovPDHLkV1gvUP-_4H literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d2e8818b95f8276c2fe5b79d987174d618582a2c GIT binary patch literal 724 zcmV;_0xSKAP)YIz!?z1eRM^{oLMy_Cz?NUj{-SrgyWT+8H~rLYj;gOaFOM=G(A{HqfEzdl{2 zinH18j`pnpy1#$aF5(6c?}(>%HPw#y?A13P<%D=`&7O4cfKTXoznL?akE0)|uk=D%#I(F2hG?E^G7=ZQu z^uE?cMhi=b2ogL#IPMIM(>FAZ6^nJ2r6^)-c98=gw_vP2y>bN`+2)4YD)Q4socD+q zGz5AMwxht%@Dv&XU?|Kj(vjMV`lxxeLB*m$aSGN|2;LKdl6yYSo3g`OhZm0%hqHnj zz99>ZHyHcd6vsh8MywANS)_yX0%kka^%ZB@%GKNJb6CL?CTQ21wN>+Vdu6+ z#)?bayZzfTruuBQ|3cpyl{-)VltJyq^zLNxz`it%o7Mx$%Y`xn_eU7d<)@8_^=A9O zTC4Iu={kNnt?Eyq;S8bNga(W;1>mYdZanD!=D(lmeexHmKZ1K5!{$!_0000TbNSu#xz`JT*Z(Y!gS-g& z7C)iv0jUnhdeZ=0QKHl*{`@=t?3UGikAQ?$E21>DEBxq`9>?B>0p1c_)i&vk2~N5N z{A)mH6CimA9DNFCdI9|qpuTQ`Bw0Jp6)Q`q0sAu<_D(+#R0agr03nUQ-ZtQn3268N z+#6j&k?|X{I%eP#shXe$#N{z;|19v_3YexyV=|uHzBS~UXK}h=9Ng3w;1>)b+cbxO z1l=e#AX?3^<{6;rGw^I0m|h_3-tX8Ue+-_o8$sF+5LQe=+p`FM;sts@SQf)JO#=EW6mtN640eoqH+s(DGdB{ z7UYqqFC8PzM%Ex^MsQ`!*?hP97W`!A?4r_cmjb$#O4(_JP606~gN z_U%z>1nRAB1@u^|!nSdUk_r(hPF|~hHSe*2)KbN2s%+`3 z+Ldmw(FjN_l_1q%qY;o=D&9$hjYdG{H9f(wo=U}0RIPfN4UlS_w}=;;o8c|j&$yGy zalluScGKf*_>trPnj9hD=_}3e=jXJn{*|hD*++EvrDJa+S(o1;o>10Fs>|IE-d)z^ b!Of~aXjDmdQc?xT00000NkvXXu0mjfQ0`a% literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..68b75c4158fbd165d4f97f20eeb6a99c1fc7596d GIT binary patch literal 672 zcmV;R0$=@!P)(Zgtn7V4;XBi;Jp7 zH!dWgpbH_;Q?u9M%I9-v&$H31zsmghVH{)b;J9Z^nT^>s->bdAB+fQ%9P`|Q`vS+==U8AK zH2j-v$L?TNRShujlNd!>+dN#Y!D$oR-8_%=b01uf@or_Li!aR@zY zsa%;(wn4jPob=}9Y|w)vc2yebQRS2UA~`iY1|;t)m*yz?{X*UVmi-4!x^T>8NRlc0 zWGH|+hgu%$RwaQsP2&Png7`Akf$cCiTBb86nSc#~pP&PptenerNfFyiDQHo#;7RD( zxF+EKAQM5CJ~dCfrf@qAMjZtZ>rtziQpmCj{<<>Fdzyj@%smkJF4aO?IAw;X9VlY7 z@52R=uF-}C>7-%nH7KyY_4whw=B{M=PXNJBlIY7C+h;|lKgJkmDFK-b4ag!NqziNe znF-SKK${gDW1lnuUzUr8eS66uO8XaKbSpS)Kh#=a>z8T*Evgb{&-`<(m9t~rQ0XHT zk#|Pq`K+7dxQk>enkU)d9KMW1R9XZeJ~! zcLyeYRM_gx>*mkJ;(mQfPMbV>Y)BsN8NlJ=fp4`M&G`*?&f_hL5l$Qc0000Ys$3z;(yEM@N>1F~U;gd)_S0tW^L7MSK;I->udSjk<0YWn}kO76i9T~W9pNNV8# zu6e1t;QuGqvR^>#`I=J9)p|y(AogP``Ok~g5r!~eF~q4`f%pG2YdNqYHxUjF3l1hD zJ_ZI?AfF8+_RL29bEB*PNZtjTFI*=o3I2lEz{~@r1)#Py1F;?ugIzK~N%%XEcEe_X z9aICzHenF^o~7Kcdls@F4Tpi)5atr7T2zo`47LFTj6sSX0ySSVm-&CqRQlfoAR8$5 z35b;m1tK>@v-F?q<}&|ofUueLzw4&be;-=Of(&^H#7ejVQ55WKbLs!rO(lVvr2bzw zlLE0Jw3*budzLaF=RX5t8*E`<1dDed{)fcICg#L2XaE3NNQhj{bNf>O0000%5b#~LfWdjL3Q%5})n%?C zSl)OFR8iPsM+}2~7wIrfI5Hc|cA00y;4n*?30Yo$5|k0K#2HK{t_WpzpQ|k3GFMjg z|NsABF~3E|jM@`D80@C=GlKZ;3$3`E=gNq>&Qst#_ZFgt!Ed1nBh;+_Xc!FK=PR>; zy)ws>A6<>bbOuHSw|VMt1Dxha{&$=$`5$P*2V_Iw^0TFYYGlCbKzxVUg3JuE{R|A- zkDf#*nj>|=5vag@p7LD~KkaxNSln?ANVC*`mpLkPV1|3mHG$}Io~wjv(;UfHAX{AL z%H4$UrT>65yUtbG2Gi^?hYKZ8frdz<7~%+at|Zu2u;zJ+*I}CVXD~1_paY;S3@!^q z&|D%7HpFe7;v3{J@tUuTJ;m8iQ)h5p%!_O~W~|IpVPwDu>?Z3mxGfR_D{`6@!r{Bf zN((0EI9ry9fmmR>0F`euOM(fOz=#4~3q27W3*71eC}5NiVjLQ700000NkvXXu0mjf DJNC#J literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d06543bf6277a745078529e3c934842c46f9ada1 GIT binary patch literal 437 zcmV;m0ZRUfP)+dCX5c~&$!D3fT=}& zRw*vgJ#P5^U#*`DgZtX9*V*GTl9n2V2f?|vtAfY#6uT&+oCuB@nx8?mt;GBm0qzx(lfM|$!T-p&Iu5^#vObx>PfmQU$Iw_)OH{`)DM2`^gV6-PjDEkA0Lpj#JRG`sJ!|`znjT?6ADKyckPQuCAJ{-3SakG-yWXCAU;-x9S f%y&uPIv@ELw6v`~(=7>{00000NkvXXu0mjfaDUAG literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..57fc3145d34f10ea54e333b899c2a29008ff4bea GIT binary patch literal 519 zcmV+i0{H!jP)w*LPQc9m@nFr1c|6Q9z62@GzC4=_nPTwI7%9RT|7%*B0G8BzcM002ov JPDHLkV1lGa-a!BW literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1664e25c8b50160089710e75cc105b218bbd1e49 GIT binary patch literal 416 zcmV;R0bl-!P)V{QECN z^Isq*BUP8-56Hm33=G1&%nZ5JM;P&X;V)2Q`SeR*zkm$+55^2&dQzSN1HnK9dAlJ= z8y*fI@B9T4fB!*TM1%qV8ER);2HW@#$@c$1gC-Uj5;g#2OI5r!(BJ>ThW-7EaLFHH zTmVwoI2RTM2-`t)Kd~+-iGhRxJUahD0vDPr2#0~B04qE}fx`ftEg&w!YrvgH4`208 z-SF+px4#U3e*XohL{J#~{sW25kDtH&5fNqjhSPv;3rlrL&CURrVDUeLPi`#$0000< KMNUMnLSTaHU$YSa literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b135ef92eec475ae36f421425b852ff3eb339b1e GIT binary patch literal 390 zcmV;10eSw3P)D;i>g+kXb7A zAt@;}b=`J;Ib*xx2Z$JSco^n|=b2$(H~?HP^dz%@O_;LtZl5ZMyB2g$u?fzRzWz~; zVhZNooN>G;t83u`ZZk#;{IWmM?$pM>qO8sxMKQm1iJ8p{OnT2TzOFFFHUi*XQk-|m zadUMnNQ{B$ZKoBWH^`R_lyrh(g`iL+rxARX2|h{$*&@Mff#5kukjNTPk{TvFzGOq- z?Ta9iHY~!aZ?*;>bOfp>2_2{L3Ql4bh-azRK!yfhYGUX~uZ#C}@mSSxaHBN^L^(D=@UO?;ZB| klif17bU6Drf8pN)Kje1&o&U^8g8%>k07*qoM6N<$f&iYU3;+NC literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7afc0a1b27bece18d61fea5bd327d7d71e105383 GIT binary patch literal 644 zcmV-~0(n^*go90bxEoVThB@pITZe38Z)l#>lTC1&5jjnPn!lBKkW*9@w z44NS1&#;MrU?LvioCBQ0`SE@`hpf@io4okG7w?|$=h^pppH~Awvme!t$IY60X%!h1 z*%i5VWZ${d*4OR^X!1MtBh;F=AkgyysVo!1h6tA#;ZlKn8-ra(JZjBefTo49hf5rj z7KlWF2pND|0V>}B_6tz>04DaFophWC{DIU1wEh?8-t%lm6ss&mJ_nIYLFT@LlxG2Y z0-%O~>?;&!JL!JwLAUCu2N} zoldBpdVpPEVvLhb*2))IM?0OK`>IagKfJ7&-WCi2Bz^a~lfQxW(Likn4 z6(u(t#?3ow_Z#TG{{W;g26^ok9MS$WYa&b3w<_?g& z4^qqqVfiYA1q-Sn3plT_0bu8|ejeqJGO$ld-gijPIiWLMft(uzzt|3L?h-0dGb#ZS zwmdBj5e(_jlT9!akf~vijb0?b+MzSHL(IOe8A}lpn6L@-lo4}Jk2efaJJfS@fQ|Q- zKzTsY4kUuNan{%d;pfYmu^2L<5N<_kw3+VfIMDEnwMCk8o($6ScNsa}17Ybp_-GqS zGm3dyF@J7Fa`+5A+Ie_-w?+C3d22h=7xSD-V{QECN z^Isq*BUP8-56Hm33=G1&%nZ5JM;P&X;V)2Q`SeR*zkm$+55^2&dQzSN1HnK9dAlJ= z8y*fI@B9T4fB!*TM1%qV8ER);2HW@#$@c$1gC-Uj5;g#2OI5r!(BJ>ThW-7EaLFHH zTmVwoI2RTM2-`t)Kd~+-iGhRxJUahD0vDPr2#0~B04qE}fx`ftEg&w!YrvgH4`208 z-SF+px4#U3e*XohL{J#~{sW25kDtH&5fNqjhSPv;3rlrL&CURrVDUeLPi`#$0000< KMNUMnLSTaHU$YSa literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5250d7d57d20257ca1ed30abf7a20730e6782727 GIT binary patch literal 379 zcmV->0fhdEP)7D<( zO>OZSu>ReT=Ktp>2>eeBvi|?!OU?fiZCwA|;`IN2`JC|ob{fO~3IiSd2E6+C`hWfT zN&g-50{%aL_u_xi>9+rNxxW8zUibOGH-h1Ro}t!%JkU z-IC}2hXpF!fDhl&|355X_@Cis0oUXkrTHH@3_u1H&iV5{s%jT`2Ef#GMY&=cfXfRM z8-Sb+@Opt57vK%VH=mdP-?7Q?e@K-5|5qOu{9m_9{l7zs8Hx*LpZx!yyW{SE=a@PS z1G-~#0?v4ZYo5_I)x8~)<#Wb4MD2`{xyJ2eubeY3O5tbBl+A9#)L1$jpFv3nG|P>| ZU;vW_oS~X0jGaIR$FAhT9(haY}3SEy5RO1=En|utI?;+c(=8Bn0fm2)$ zizE>N<8(sa+>M}zf!j0&>X-%#GgF|4uY;ma0rV8e)ech3{3}@Vi()hg#%h7Q=`0Wn zfqgUt>S#N#U<0eyf|9q^6d1QYzA1>2c`(yv$d7jdkwvfuJt&0=@J@s6*K7;iW@Im@ zs!CACpBYl(5)DSGvsf$(|o|c zQzQM6I2!la!k1eT*}>Bs8R#J7W+%z&+PJW$Az?pK+PP*c|Nm#&4Zi@U3ZfSr%T>q# O0000;;O1hHwx;szs4duJXK>=l}M5e%&2jQ1k|VK1Nkpj|A&v4h$R{+}BecHh=*XP?VY% zGaIihmrRbT>B(^#diNh^dUBi^Z*Ny|_|)O{?$*wu{3<QD_p zL&DW5Zrpix1{kHvQ>D&ek-|&rQ~?3wp;7=BfeTQztS-C;HqqeG-~UM% z)2OGcQ44Vy2vG6C`KVZun|pcm^fURkgQ$X2NC~DjqAS0+aN9$b8g+t70i2JD1uTdU zQsUKnW$a=nfhfLHtQdwKOz~;O;ThD})o<8$Bm7Q=7#AxJWp=5;O5pHaf)&@yvR}kY zrdpmqoLFk+4|er`X)l)2P32h4S1Z^k#zsP3Qb_3IoxSq-H2-iiH}*DgW>1JA2nBIy z!A}}gLXZEDF3;Q_JaLzwY-riiVdpOxRb@TC0|Y$}5>kr%ivR!s07*qoM6N<$g2b@? A>i_@% literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d82d46278601fee4a30b387c55b5ee1ebfca4d82 GIT binary patch literal 481 zcmV<70UrK|P)+00HR zwAs$q+1EJ_=dkQXl#5T#^Zb5&KhH}&5&)9l@T)KpWaTNOl%dGh!D0RwDMKNF>y;&E zC?z~XKv)YkiAh^vdp=Yl7To?uPjikV(XQVF`xXV}r|U2`S%ukg1!jh2goV*!7J%=P)(o*%)Aj(A$XSu?(=)j;T(^uvYF=t2wojnb}Oo0fYIl} zHRDh3FKq|_a5Hq$58(4c--B8Fdn&$m500?CbhjCPHoa)mhIBlQH5Mo3kclqn$l#4i z-|t{W6|S{EBI5{Ki@bbaaWF)DHHQxcUd$QRK1ayJ)5K!yq*v#@{9zypB3V#t^Kn=4 zV#^qBhsL;9OF*^Bp=^@!m%E# z6*s^ISW$W&FA_@{M8R6c=78k!2EgYh#(sZ_sIhBl);M9d~XU-b%)z^?f?o{D>xY`1Xxi{*YBn0!)rv9(Any2 zE0X`*&{2XP!n-o2Uez8V`}N+f=of)*~E zsHF4m3|5rOXZ9hvRMBhz5N&Lz+tt`mS74yGx*jgq?GNlsBr`rE>b>4Sh2+vzpyPb) zzgIcjda68McsV)0EP}rySew(&FPZ-T7V<9=S@B&7^{j668aL&JLWK5=(0 z6g9;2m$+I*UcO*)bpr!(aa?*ciU^2+D2OP9P}NXnhXHZ5iZ&bkh$09>)QnEnM$B{V z!zf-L_lB5KD5)A=*s(cr6LTp#Q=^bLhY(QM&SI7tbZsz#wCVt4}s`X4=J z_E5mVav5*Xj#Ex(Kw)vEPPUNp^vZi08xh{KBNR16Kmo-#)mAp0qb1OaQoKUF`H^fs zWpemAOUn)RAE+QA6hi(`3n-tE6hI{_4=p zDwr82ASi>igx7CBGc()a$&VLkWdelw#G1OaBo|7ff) g#(|m9i;y1u2H}=eFW7W@SO5S307*qoM6N<$f}^DLx&QzG literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a1e700dc4c6d841799a4a39b83daeef841cf9ece GIT binary patch literal 571 zcmV-B0>u4^P)yuaPjPJR;vZwu%fUq)~I zJ-o3r&R>6LLNnuuWf@Pr$*G&!gPoC!O@W8y24}L6WHc$Z)Rb4e#j~Xf!t8?DCK#F%%|Fn_f$%*9e$kp6_{Z+z!XRt(_@YYMlS|mM-(?A$?pP-L;H!DQ7n~({vY3N+ zcoO|rlBU2HqD;483l6zrnZ!Z~Lg61L=x`_a$io7nkBXRoy$Rpw9aGSmDr0$N72aS1 zTh%Hus}g#LSdwetgj`c_w1*wvcVbGST#7zd&juz8DmXL3A^)ue|7Z%jVL;v}V_qxKf>K4t5mtft=?nTtCQ;KgB|mLR^8|gWg7md`yn`nH~@7Cl$j177e zAN)8mEVylqMxM4JkN=Jks0wSC-QY()XV(%hs7~Ziy~i^#k?tqepejx zzAW}bMf}IA_y@%aZ>ths)@FRJN%&ls_@XiEO+)6J#+-M}d5>F4pLJBcYOj6WS^KKD z`b~HJn@RPb8dASBBz>q78pL$Ba^^|<+EC1P7_H%O0)4t~C z6Iz~6Y<)AS*BVc1=uUJ=O4_l_&gZ~Ed)+hl>`bmYaVkA{GCeJK?!<+wCnqiA5Hs-DylvB| z6Bh!)y~UU~E!x^6UcO36S+R1}k1B2k)-98AN=&X88-+Z1DzeC;f$7x8X|J+Yy_784 zG|6b<8VAO`2N*&{e=d;lB|mLR^7dwIXHJI%SPA6^%+2 zlNtk)dPCJ_WzBvSlYT?HR%^R%Yr7t6`x!P?3)Ot4+j^{5b6Q~RvcNcSn{LQvlbEe` zQTxpNW;+HgaEe>$k+Q)jXIohA_VB!|5&2sqvvvlQY>zJ49#gPCykJLU;m+vdT``6G z;>-6W)NW6!*_BeeC#`m0di{>fm;+WZhiuZ0cw`;&$UN?ubHuCUP-M}mko-f5c}IXK zDeq`<{;`yTgUN+Qk_(Qf79US5Ih;~-BBSI)M%l^CvQt@=2UF?}X4W0guRNJubtbp| zR6+B;-1b97tw&26P8BztDQZ4f-hQ&O^GI3uiHZs5>ZcuVo_4xz`kB^gXFFycZ=Z3x zZPuyw8E4vOp6!}@u6yRi?wJ>QW?ku>eSPBmOB3hbn6&WP)Wz4Qt-dsS{q+Uwt}k47 zXX*Mo%QoL!y7BJvEjO2LxwUN5?G;;Zuh?>T)t38fwmw|9{o(rU4>#<4ylwyE9S5H5 zy!P(W%{Nz`eR=%$`|FQCKYaQ1>CfNafB*gc|NlQQ3P!;|g#hF0BcB);7#T`}{DOgT zF_Hm8@OO4qU_2b~ba4!k2v7de&nBTTrE}d3#z_qe3%%UjHtpf?anN63aq_(WN{tEp zN(y_$GVd0ceRkw(mHFMT9^N^#*J}|MiY_84q z)>?B)>eZu|OE(*tm}bh^netxcElt$AmFeTac=1Su_5WLKzXT+wUMR?$urP@AT-Lp* z7cXt<+W9CUx@FI&E1^@LrigATxuL-K_`{k0OP6|1Tuf-OoExlUWNJENzUawf8=W&T c8vB4HnqJ^!@nF+}?VvQ}>FVdQ&MBb@06R-T?*IS* literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a3dfc6806a3d2530b51cb3c5613a2c3e99a3f210 GIT binary patch literal 1278 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^8|gBi?+bJ&g*a-J;b zJyR!ms$TPatJuX(nae%W*Cs36oS}Scw(6aE>US4v-e019b)oImMRs==TR&K?`*4-v z(@o|twp(7B>~d{R?2QE>cQ?8}-|qZuoBQ*fF0b~wJlzrVba%#!{YkG6N4`1`_wIPi z>(k+1uKRtu7V_y@=%?#ppRR|0xfby0TEyoY;a_hAe!UU&^=8PIo8ez?MSQy*_2pLd zmzyzPZUIs3w>vRk?!>)2mGS&Q?b{QD@6Q&$Ia&4YOy##*N#E|LJl)^%;&A)BbFCjP zHhsL(`r%T~hs*t+ulIhuKKIj&DX-71{&;=Sm-{P!JnjDRY|77R-O&m9NtFz7U z)x}s@=Zs9KDGyVUr32HcxWa$O)R>rF{knD0Z;}J!(K!Oj%CWMt&bFrQE+7B%7#+0C zT)Fb)%gmLUnkOUea(K!P{i)ewb0=obn>9LTe0qco?jK@g=#86Mxz%pcbx^YNboFyt I=akR{0MNBaW&i*H literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..47a5307461fe2749ca593ff33672f18c0394c2ee GIT binary patch literal 387 zcmV-}0et?6P)Nklsre%j0v-EsNiGZduZXGYeyP9iJ7x=;)MSGa?NDYF?Q(-0@0?1H5U8_wOh z8x7P{1jKnjoCU;*2j`ZB?(6icC1}8@`7yiBo<9`{)RY6nnLwNh#1VV?le2a;c~%lM z;OO+wMaLEwfo$~w;y54o?@vu;4Y|(8NHqgZ+U^_xDHj9++Jc zvb#4a>%{EjTetVN{XerH>($mWcZ(HCW{h|Z+0*JJv!~5FZEvej?al_zszVc^&)h#U z;s2x4)Bf*l3cB0lqh&}^+Spv?qIsYva?iPCh5z@o2E16BWa3G30s}f*d1bm~-|94r hz@>3U%)>1I007)@wE?N=6Tbie002ovPDHLkV1jM@y&?br literal 0 HcmV?d00001 -- 2.39.5