aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api/src/main/java/org/sonar/api/web
diff options
context:
space:
mode:
authorsimonbrandhof <simon.brandhof@gmail.com>2010-09-06 14:08:06 +0000
committersimonbrandhof <simon.brandhof@gmail.com>2010-09-06 14:08:06 +0000
commitaeadc1f9129274949daaa57738c7c4550bdfbc7b (patch)
tree08dadf5ef7474fc41d1d48f74648f1ba8b55f34d /sonar-plugin-api/src/main/java/org/sonar/api/web
downloadsonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.tar.gz
sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.zip
SONAR-236 remove deprecated code from checkstyle plugin + display default value of rule parameters in Q profile console
Diffstat (limited to 'sonar-plugin-api/src/main/java/org/sonar/api/web')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java36
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractRubyTemplate.java100
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/CodeColorizerFormat.java73
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/DefaultTab.java37
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Footer.java33
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/GwtExtension.java29
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/GwtPage.java31
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/NavigationSection.java45
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Page.java27
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceLanguage.java42
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceQualifier.java42
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceScope.java42
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsPage.java32
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWebservice.java41
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWidget.java40
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Section.java29
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/UserRole.java45
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/View.java32
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Webservice.java36
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Widget.java26
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractPage.java50
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractViewer.java216
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/ResourceDictionary.java59
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/Utils.java154
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/AbstractResourceQuery.java40
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/BaseQueryCallback.java52
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/FileSource.java37
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JSONHandlerDispatcher.java48
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JsonUtils.java182
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Measure.java152
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/MetricsQuery.java104
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Properties.java44
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/PropertiesQuery.java75
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Property.java52
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Query.java25
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/QueryCallBack.java32
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resource.java187
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resources.java63
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResourcesQuery.java256
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResponsePOJO.java27
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Rule.java57
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SequentialQueries.java112
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SourcesQuery.java101
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violation.java80
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violations.java87
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ViolationsQuery.java162
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/VoidResponse.java24
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/WSMetrics.java243
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/widgets/LoadingLabel.java34
49 files changed, 3573 insertions, 0 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java
new file mode 100644
index 00000000000..be9d0415405
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java
@@ -0,0 +1,36 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * @since 1.10
+ * @deprecated override org.sonar.api.web.AbstractRubyTemplate and implement org.sonar.api.web.RubyRailsWidget
+ */
+@Deprecated
+public abstract class AbstractDashboardWidget extends AbstractRubyTemplate implements RubyRailsWidget {
+
+ public String getId() {
+ return getClass().toString();
+ }
+
+ public String getTitle() {
+ return getClass().toString();
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractRubyTemplate.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractRubyTemplate.java
new file mode 100644
index 00000000000..a9f9c22428c
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractRubyTemplate.java
@@ -0,0 +1,100 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * It's useful in development environment to see browser rendering in real time while editing the template. To do that, just
+ * return an absolute path in the method getTemplatePath() :<br/>
+ * <pre>
+ * <code>
+ * protected String getTemplatePath() {
+ * return "/tmp/sample_dashboard_widget.erb";
+ * }
+ * </code>
+ * </pre>
+ * Build and deploy the plugin in /extensions/plugins. The file /tmp/sample_dashboard_widget.erb will be reloaded on each request.
+ * <p/>
+ * <br/>
+ * In production environment, you have to return the classloader path, for example "/org/sonar/myplugin/sample_dashboard_widget.erb".
+ *
+ * @since 1.11
+ */
+public abstract class AbstractRubyTemplate {
+
+ private String cache = null;
+
+ public String getTemplate() {
+ String result = loadTemplateFromCache();
+ try {
+ if (result == null) {
+ result = loadTemplateFromClasspath();
+ }
+ if (result == null) {
+ result = loadTemplateFromAbsolutePath();
+ }
+ return result;
+
+ } catch (IOException e) {
+ throw new SonarException("Can not read the file " + getTemplatePath(), e);
+ }
+ }
+
+ private String loadTemplateFromAbsolutePath() throws IOException {
+ File file = new File(getTemplatePath());
+ if (file.exists()) {
+ // the result is not cached
+ return FileUtils.readFileToString(file);
+ }
+ throw new FileNotFoundException(getTemplatePath());
+ }
+
+ private String loadTemplateFromClasspath() throws IOException {
+ InputStream input = getClass().getResourceAsStream(getTemplatePath());
+ try {
+ if (input != null) {
+ cache = IOUtils.toString(input);
+ return cache;
+ }
+ } finally {
+ IOUtils.closeQuietly(input);
+ }
+ return null;
+ }
+
+ protected String loadTemplateFromCache() {
+ return cache;
+ }
+
+ /**
+ * the path of the template. In production environment, it's the classloader path (for example "/org/sonar/my_template.erb").
+ * In dev mode, it's useful to return an absolute path (for example C:/temp/my_template.erb). In such a case the result is not cached.
+ */
+ protected abstract String getTemplatePath();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/CodeColorizerFormat.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/CodeColorizerFormat.java
new file mode 100644
index 00000000000..21d2894aeea
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/CodeColorizerFormat.java
@@ -0,0 +1,73 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import org.sonar.api.ServerExtension;
+import org.sonar.channel.Channel;
+import org.sonar.colorizer.HtmlCodeBuilder;
+import org.sonar.colorizer.Tokenizer;
+
+import java.util.List;
+
+/**
+ * Extend the library sonar-colorizer to support new languages. By default only Java sources are colorized in Sonar.
+ *
+ * @since 1.12
+ */
+public abstract class CodeColorizerFormat implements ServerExtension {
+
+ private String languageKey;
+
+ /**
+ * @param languageKey the unique sonar key. Not null.
+ */
+ protected CodeColorizerFormat(String languageKey) {
+ this.languageKey = languageKey;
+ }
+
+ public final String getLanguageKey() {
+ return languageKey;
+ }
+
+ /**
+ * sonar-colorizer tokenizers for HTML output.
+ * @return a not null list (empty if no tokenizers)
+ */
+ public abstract List<Tokenizer> getTokenizers();
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof CodeColorizerFormat)) {
+ return false;
+ }
+
+ CodeColorizerFormat format = (CodeColorizerFormat) o;
+ return languageKey.equals(format.languageKey);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return languageKey.hashCode();
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/DefaultTab.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/DefaultTab.java
new file mode 100644
index 00000000000..27bb8cc9bfe
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/DefaultTab.java
@@ -0,0 +1,37 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @since 2.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface DefaultTab {
+
+ // default value is all metrics
+ String[] metrics() default {};
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Footer.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Footer.java
new file mode 100644
index 00000000000..0bf9f56ee21
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Footer.java
@@ -0,0 +1,33 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import org.sonar.api.ServerExtension;
+
+/**
+ * @since 1.10
+ */
+public interface Footer extends ServerExtension {
+
+ /**
+ * Static HTML (no Ruby on Rails nor GWT)
+ */
+ String getHtml();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/GwtExtension.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/GwtExtension.java
new file mode 100644
index 00000000000..1281aa966c7
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/GwtExtension.java
@@ -0,0 +1,29 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import org.sonar.api.ServerExtension;
+
+/**
+ * @since 1.10
+ */
+public interface GwtExtension extends ServerExtension {
+ String getGwtId();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/GwtPage.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/GwtPage.java
new file mode 100644
index 00000000000..b4942b2a6c8
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/GwtPage.java
@@ -0,0 +1,31 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * @since 1.11
+ */
+public abstract class GwtPage implements Page, GwtExtension {
+
+ public final String getId() {
+ return getGwtId();
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/NavigationSection.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/NavigationSection.java
new file mode 100644
index 00000000000..7a669c5a048
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/NavigationSection.java
@@ -0,0 +1,45 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The Page is displayed only in listed sections. This annotation is ignored on Widgets.
+ *
+ * @since 1.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface NavigationSection {
+
+ public static final String HOME = "home";
+ public static final String RESOURCE = "resource";
+ public static final String RESOURCE_TAB = "resource_tab";
+ public static final String CONFIGURATION = "configuration";
+
+
+ String[] value() default {HOME};
+
+}
+
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Page.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Page.java
new file mode 100644
index 00000000000..ebed61f4f0a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Page.java
@@ -0,0 +1,27 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * @since 2.0
+ */
+public interface Page extends View {
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceLanguage.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceLanguage.java
new file mode 100644
index 00000000000..7c8a80d3af8
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceLanguage.java
@@ -0,0 +1,42 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The view is displayed only if the selected resource has the same language.
+ *
+ * @since 1.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ResourceLanguage {
+
+ /**
+ * An empty value means all resource scopes.
+ */
+ String[] value() default {};
+
+}
+
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceQualifier.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceQualifier.java
new file mode 100644
index 00000000000..7b6a02cfa0a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceQualifier.java
@@ -0,0 +1,42 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The view is displayed only if the selected resource has the same qualifier.
+ *
+ * @since 1.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ResourceQualifier {
+
+ /**
+ * An empty value means all resource scopes.
+ */
+ String[] value() default {};
+
+}
+
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceScope.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceScope.java
new file mode 100644
index 00000000000..82c1e7ea4db
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ResourceScope.java
@@ -0,0 +1,42 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * The view is displayed only if the selected resource has the same qualifier.
+ *
+ * @since 1.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ResourceScope {
+
+ /**
+ * An empty value means all resource scopes.
+ */
+ String[] value() default {};
+
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsPage.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsPage.java
new file mode 100644
index 00000000000..7f802040597
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsPage.java
@@ -0,0 +1,32 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * @since 1.11
+ */
+public interface RubyRailsPage extends Page {
+
+ /**
+ * @return Content of the Ruby on Rails template
+ */
+ String getTemplate();
+
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWebservice.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWebservice.java
new file mode 100644
index 00000000000..5746873914e
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWebservice.java
@@ -0,0 +1,41 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+
+/**
+ * <b>EXPERIMENTAL</b>
+ * <p/>
+ * Interface to create a ruby web service extension point using the Ruby On Rails controller API (ActionController)
+ * The method getTemplate() return the ROR controller code, the name of the controller class defined in the template
+ * MUST match the following name scheme : Api::$Webservice.getId()Controller I.E : Webservice.getId() = TestWS > Api::TestWSController.
+ * The plugin will be deployed with the following URL scheme: http://sonarhost/api/plugins/$Webservice.getId()/:action/:id
+ * :action is the name of the controller method to call, :id is a param that will be passed to the controller, these 2 params are not mandatory
+ * and will call the index controler method if not specified.
+ *
+ * @since 1.11
+ */
+public interface RubyRailsWebservice extends Webservice {
+
+ /**
+ * @return Content of the Ruby on Rails web service controller class
+ */
+ String getTemplate();
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWidget.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWidget.java
new file mode 100644
index 00000000000..be2d0418919
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/RubyRailsWidget.java
@@ -0,0 +1,40 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * Widget in project dashboard page. It's recommended to also extend AbstractRubyTemplate :
+ * <p/>
+ * <code>
+ * public class MyWidget extends AbstractRubyTemplate implements RubyRailsWidget {
+ * protected String getTemplatePath() {
+ * return "/myplugin/my_template.erb";
+ * }
+ * }
+ * </code>
+ *
+ * @since 1.11
+ */
+public interface RubyRailsWidget extends Widget {
+ /**
+ * @return content of the Ruby on Rails template
+ */
+ String getTemplate();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Section.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Section.java
new file mode 100644
index 00000000000..8f118df0660
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Section.java
@@ -0,0 +1,29 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * @since 1.10
+ * @deprecated add annotation org.sonar.api.web.NavigationSection to View extensions
+ */
+@Deprecated
+public enum Section {
+ HOME, PROJECT, CONFIGURATION
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/UserRole.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/UserRole.java
new file mode 100644
index 00000000000..227497903e5
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/UserRole.java
@@ -0,0 +1,45 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @since 1.11
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface UserRole {
+
+ /**
+ * @deprecated use the constant USER since 1.12.
+ */
+ @Deprecated public static final String VIEWER = "user";
+
+ public static final String USER = "user";
+ public static final String ADMIN = "admin";
+ public static final String CODEVIEWER = "codeviewer";
+
+ String[] value() default {};
+
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/View.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/View.java
new file mode 100644
index 00000000000..3e3dfabc9d4
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/View.java
@@ -0,0 +1,32 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import org.sonar.api.ServerExtension;
+
+/**
+ * @since 1.11
+ */
+public interface View extends ServerExtension {
+
+ String getId();
+
+ String getTitle();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Webservice.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Webservice.java
new file mode 100644
index 00000000000..9610b0183c8
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Webservice.java
@@ -0,0 +1,36 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+import org.sonar.api.ServerExtension;
+
+/**
+ * Interface to create a web service extension point
+ *
+ * @since 1.11
+ */
+public interface Webservice extends ServerExtension {
+
+ /**
+ * @return The id of the web service
+ */
+ String getId();
+
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Widget.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Widget.java
new file mode 100644
index 00000000000..016dc481391
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Widget.java
@@ -0,0 +1,26 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web;
+
+/**
+ * @since 1.11
+ */
+public interface Widget extends View {
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractPage.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractPage.java
new file mode 100644
index 00000000000..9e0842af352
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractPage.java
@@ -0,0 +1,50 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * @deprecated since 2.0, use the lib sonar-gwt-api
+ */
+@Deprecated
+public abstract class AbstractPage implements EntryPoint {
+
+ protected void displayView(Widget widget) {
+ Element loading = DOM.getElementById("loading");
+ if (loading != null) {
+ DOM.removeChild(getRootPanel().getElement(), loading);
+ }
+ getRootPanel().add(widget);
+ }
+
+ protected RootPanel getRootPanel() {
+ RootPanel rootPanel = RootPanel.get("gwtpage-" + GWT.getModuleName());
+ if (rootPanel == null) {
+ rootPanel = RootPanel.get("gwtpage");
+ }
+ return rootPanel;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractViewer.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractViewer.java
new file mode 100644
index 00000000000..0d442fd541a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/AbstractViewer.java
@@ -0,0 +1,216 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import org.sonar.api.web.gwt.client.webservices.*;
+
+import java.util.Arrays;
+
+public abstract class AbstractViewer implements EntryPoint {
+
+ public static final String HTML_ROOT_ID = "resource_viewers";
+
+ private Resource resource;
+ private String renderedResourceKey = "";
+ private Panel widgetPanel = null;
+ private boolean standAloneMode = true;
+
+ public void onModuleLoad() {
+ exportJavascript();
+ }
+
+ /**
+ * Export GWT javascript methods to load and control the plugin, must export currently 2 method :
+ * I.E for plugin GWT id : foo.bar.MyPlugin, class foo.bar.client.MyPlugin :
+ * <p/>
+ * $wnd.load_foo_bar_MyPlugin = function() {
+ * called to the plugin init from JS
+ * obj.@foo.bar.client.MyPlugin::loadContainer()();
+ * }
+ * $wnd.on_resource_loaded_foo_bar_MyPlugin = function() {
+ * called when a resource JSON object has been refreshed within the page
+ * obj.@foo.bar.client.MyPlugin::onResourceLoaded()();
+ * }
+ */
+ protected abstract void exportJavascript();
+
+ /**
+ * When multiple widgets are bound to the same HTML div, this method will indicate
+ * If the resource widget is the default one to show when the widget is initialized
+ *
+ * @param metric the metric for which the widget is shown, cannot be null
+ * @param resource the resource bound to the widget
+ * @return true or false
+ */
+ protected abstract boolean isDefault(WSMetrics.Metric metric, Resource resource);
+
+ /**
+ * Finds if a given metric is in the provided metrics list
+ *
+ * @param metric the metric to search
+ * @param metricsList the metric list
+ * @return true or false if not found
+ */
+ protected boolean isMetricInList(WSMetrics.Metric metric, WSMetrics.Metric... metricsList) {
+ return Arrays.asList(metricsList).contains(metric);
+ }
+
+ /**
+ * When multiple widgets are in the same page, this method will indicate if the widget
+ * can be shown for the given resource
+ *
+ * @param resource the resource bound to the page
+ * @return true or false
+ */
+ protected abstract boolean isForResource(Resource resource);
+
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ private Resource loadResource() {
+ JavaScriptObject resourceJson = getResourceJSONObject();
+ if (resourceJson != null) {
+ Resource resourceLoaded = ResourcesQuery.parseResources(resourceJson).get(0);
+ String currentMetricKey = ResourceDictionary.getViewerMetricKey();
+ Boolean isDefaultForMetric = false;
+ if (currentMetricKey != null) {
+ isDefaultForMetric = isDefault(WSMetrics.get(currentMetricKey), resourceLoaded);
+ }
+ exportJSBooleanVariable("is_default_for_metric", Utils.widgetGWTIdJSEncode(getGwtId()), isDefaultForMetric);
+ exportJSBooleanVariable("is_for_resource", Utils.widgetGWTIdJSEncode(getGwtId()), isForResource(resourceLoaded));
+ return resourceLoaded;
+ }
+ return null;
+ }
+
+ /**
+ * Called when a resource JSON object has been loaded within the page
+ */
+ public final void onResourceLoaded() {
+ resource = loadResource();
+ standAloneMode = false;
+ }
+
+ /**
+ * Called to render the widget for the given resource object loaded via the onResourceLoaded() method call
+ */
+ public final void loadContainer() {
+ String resourceKey = ResourceDictionary.getViewerResourceKey();
+ if (resourceKey != null) {
+ if (!standAloneMode && resource == null) {
+ Utils.showError("Unable to find JSON resource object, unable to render widget");
+ return;
+ } else if (standAloneMode && resource == null) {
+ getResourceJsonObject(resourceKey);
+ return;
+ }
+ String currentResourceKey = isANumber(resourceKey) ? resource.getId().toString() : resource.getKey();
+ if (!renderedResourceKey.equals(currentResourceKey)) {
+ // resource key has changed reload if not in standalone mode
+ if (!standAloneMode) {
+ resource = loadResource();
+ }
+
+ if (widgetPanel == null) {
+ RootPanel rootPanel = RootPanel.get(HTML_ROOT_ID);
+ if (rootPanel == null) {
+ Utils.showError("Unable to find root panel " + HTML_ROOT_ID + " in page");
+ }
+ widgetPanel = new FlowPanel();
+ widgetPanel.setStyleName("gwt-ResourceTab");
+ String panelId = "tab-" + Utils.widgetGWTIdJSEncode(getGwtId());
+ widgetPanel.getElement().setId(panelId);
+ registerTab(panelId);
+ widgetPanel.setVisible(false);
+ rootPanel.add(widgetPanel);
+ }
+
+ renderedResourceKey = resourceKey;
+
+ if (widgetPanel != null) {
+ widgetPanel.clear();
+ widgetPanel.add(render(resource));
+ }
+ }
+ }
+
+ if (widgetPanel != null) {
+ widgetPanel.setVisible(true);
+ }
+ }
+
+ private static native void registerTab(Object tabId) /*-{
+ $wnd.registeredTabs.push(tabId);
+ }-*/;
+
+
+ private native void exportJSBooleanVariable(String varPrefix, String encodedGWTId, boolean value)/*-{
+ $wnd.config[varPrefix + "_" + encodedGWTId] = value;
+ }-*/;
+
+ /**
+ * Return the GWT id of the widget
+ */
+ protected abstract String getGwtId();
+
+ /**
+ * Renders the widget for the current resource
+ */
+ protected abstract Widget render(Resource resource);
+
+ /**
+ * Return a JavaScriptObject object containing all the measure available for the current resource key
+ *
+ * @return the JavaScriptObject instance, should never be null
+ */
+ protected native JavaScriptObject getResourceJSONObject()/*-{
+ return $wnd.config['current_resource'];
+ }-*/;
+
+
+ private boolean isANumber(String resourceKey) {
+ boolean isIdResourceKey = true;
+ try {
+ Integer.parseInt(resourceKey);
+ } catch (NumberFormatException ex) {
+ isIdResourceKey = false;
+ }
+ return isIdResourceKey;
+ }
+
+ private void getResourceJsonObject(String resourceKey) {
+ ResourcesQuery.get(resourceKey).execute(new StandAloneResourceHandler());
+ }
+
+ public class StandAloneResourceHandler extends BaseQueryCallback<Resources> {
+ public void onResponse(Resources resources, JavaScriptObject jsonResponse) {
+ resource = resources.firstResource();
+ loadContainer();
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/ResourceDictionary.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/ResourceDictionary.java
new file mode 100644
index 00000000000..7e45a702174
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/ResourceDictionary.java
@@ -0,0 +1,59 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client;
+
+import com.google.gwt.i18n.client.Dictionary;
+
+public final class ResourceDictionary {
+
+ public final static String CONF_PERMALINK_BASE = "permalink_url_base";
+ public final static String CONF_RESOURCE_KEY = "resource_key";
+ public final static String CONF_V_RESOURCE_KEY = "viewer_resource_key";
+ public final static String CONF_V_PLUGIN_KEY = "viewer_plugin_key";
+ public final static String CONF_V_METRIC_KEY = "metric";
+
+ private ResourceDictionary() {
+ }
+
+ public static String getPermaLinkURLBase() {
+ return Utils.getConfiguration(CONF_PERMALINK_BASE);
+ }
+
+ public static String getResourceKey() {
+ return Utils.getConfiguration(CONF_RESOURCE_KEY);
+ }
+
+ public static String getViewerResourceKey() {
+ return Utils.getConfiguration(CONF_V_RESOURCE_KEY);
+ }
+
+ public static String getViewerPluginKey() {
+ return Utils.getConfiguration(CONF_V_PLUGIN_KEY);
+ }
+
+ public static String getViewerMetricKey() {
+ return Utils.getConfiguration(CONF_V_METRIC_KEY);
+ }
+
+ public static Dictionary getResourceViewers() {
+ return Dictionary.getDictionary("resource_viewers");
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/Utils.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/Utils.java
new file mode 100644
index 00000000000..7bcee0fe809
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/Utils.java
@@ -0,0 +1,154 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client;
+
+import com.google.gwt.i18n.client.Dictionary;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Window;
+import org.sonar.api.web.gwt.client.webservices.Resource;
+
+import java.util.Set;
+
+/**
+ * A class of web utility
+ *
+ * @since 1.10
+ */
+public final class Utils {
+ private Utils() {
+ }
+
+ public static String getConfiguration(String key) {
+ return getConfiguration(key, null);
+ }
+
+ public static String getConfiguration(String key, String defaultValue) {
+ String result = getDictionaryEntry("config", key);
+ if (result == null) {
+ result = defaultValue;
+ }
+ return result;
+ }
+
+ public static native void setConfiguration(String key, String val) /*-{
+ $wnd.config[key] = val;
+ }-*/;
+
+ public static String getRequestParameter(String key) {
+ return getDictionaryEntry("request_parameters", key);
+ }
+
+ public static Set<String> getConfigurationKeys() {
+ return getDictionaryKeys("config");
+ }
+
+ public static Set<String> getRequestParameterNames() {
+ return getDictionaryKeys("request_parameters");
+ }
+
+ 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;
+ }
+
+ public static String widgetGWTIdJSEncode(String widgetGWTId) {
+ return widgetGWTId.replace('.', '_');
+ }
+
+ public static String getServerUrl() {
+ return getConfiguration("sonar_url");
+ }
+
+ public static String getServerApiUrl() {
+ return getServerUrl() + "/api";
+ }
+
+ 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);
+ }
+
+ 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);
+ }-*/;
+
+ /**
+ * Display the resource in a popup.
+ *
+ * @param resource the resource to display, not null
+ * @param metricKey the metric to highlight (optional : can be null)
+ */
+ public static void openResourcePopup(final Resource resource, final String metricKey) {
+ String url = Utils.getServerUrl() + "/resource/index/" + resource.getId();
+ if (metricKey != null) {
+ url += "?" + ResourceDictionary.CONF_V_METRIC_KEY + "=" + metricKey;
+ }
+ Window.open(url, "resource", "height=800,width=900,scrollbars=1,resizable=1");
+ }
+
+ public static String getUrlToRuleDescription(final String ruleKey, final boolean showLayout) {
+ return Utils.getServerUrl() + "/rules/show/" + ruleKey + "?layout=" + showLayout;
+ }
+}
+
+
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/AbstractResourceQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/AbstractResourceQuery.java
new file mode 100644
index 00000000000..9c2e6c2de8a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/AbstractResourceQuery.java
@@ -0,0 +1,40 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+
+public abstract class AbstractResourceQuery<R extends ResponsePOJO> extends Query<R> {
+
+ private String resourceKey;
+
+ protected AbstractResourceQuery(String resourceKey) {
+ super();
+ this.resourceKey = resourceKey;
+ }
+
+ public String getResourceKey() {
+ return resourceKey;
+ }
+
+ public void setResourceKey(String resourceKey) {
+ this.resourceKey = resourceKey;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/BaseQueryCallback.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/BaseQueryCallback.java
new file mode 100644
index 00000000000..119422740a5
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/BaseQueryCallback.java
@@ -0,0 +1,52 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import org.sonar.api.web.gwt.client.Utils;
+import org.sonar.api.web.gwt.client.widgets.LoadingLabel;
+
+public abstract class BaseQueryCallback<P extends ResponsePOJO> implements QueryCallBack<P> {
+
+ private LoadingLabel loading;
+
+ public BaseQueryCallback() {
+ this(null);
+ }
+
+ public BaseQueryCallback(LoadingLabel loading) {
+ super();
+ this.loading = loading;
+ }
+
+ public void onError(int errorCode, String errorMessage) {
+ Utils.showError("Error received from server : " + errorCode + " - " + errorMessage);
+ if (loading != null) {
+ loading.removeFromParent();
+ }
+ }
+
+ public void onTimeout() {
+ Utils.showWarning("JSON query response timeout");
+ if (loading != null) {
+ loading.removeFromParent();
+ }
+ }
+
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/FileSource.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/FileSource.java
new file mode 100644
index 00000000000..82224296a97
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/FileSource.java
@@ -0,0 +1,37 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.Map;
+
+public class FileSource extends ResponsePOJO {
+
+ private Map<Integer, String> sourceLines;
+
+ public FileSource(Map<Integer, String> sourceLines) {
+ super();
+ this.sourceLines = sourceLines;
+ }
+
+ public Map<Integer, String> getLines() {
+ return sourceLines;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JSONHandlerDispatcher.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JSONHandlerDispatcher.java
new file mode 100644
index 00000000000..ee70c4993bd
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JSONHandlerDispatcher.java
@@ -0,0 +1,48 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+public abstract class JSONHandlerDispatcher<P extends ResponsePOJO> implements JsonUtils.JSONHandler {
+
+ private QueryCallBack<P> callBack;
+
+ public JSONHandlerDispatcher(QueryCallBack<P> callBack) {
+ super();
+ this.callBack = callBack;
+ }
+
+ public abstract P parseResponse(JavaScriptObject obj);
+
+ public void onError(int errorCode, String errorMessage) {
+ callBack.onError(errorCode, errorMessage);
+ }
+
+ public void onResponse(JavaScriptObject obj) {
+ P responseObj = parseResponse(obj);
+ callBack.onResponse(responseObj, obj);
+ }
+
+ public void onTimeout() {
+ callBack.onTimeout();
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JsonUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JsonUtils.java
new file mode 100644
index 00000000000..42a11919474
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/JsonUtils.java
@@ -0,0 +1,182 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.Date;
+
+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.JSONArray;
+import com.google.gwt.json.client.JSONBoolean;
+import com.google.gwt.json.client.JSONNumber;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.google.gwt.json.client.JSONValue;
+
+public final class JsonUtils {
+ private static int requestId = 0;
+
+ private JsonUtils() {
+
+ }
+
+ 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.api.web.gwt.client.webservices.JsonUtils::dispatchJSON(Lcom/google/gwt/core/client/JavaScriptObject;Lorg/sonar/api/web/gwt/client/webservices/JsonUtils$JSONHandler;)(jsonObj, handler);
+ window[callback + "done"] = true;
+ }
+
+ setTimeout(function() {
+ if (!window[callback + "done"]) {
+ handler.@org.sonar.api.web.gwt.client.webservices.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) {
+ JSONValue jsonValue;
+ JSONString jsonString;
+ if ((jsonValue = json.get(field)) == null) {
+ return null;
+ }
+ if ((jsonString = jsonValue.isString()) == null) {
+ JSONNumber jsonNumber = jsonValue.isNumber();
+ return jsonNumber != null ? jsonNumber.toString() : null;
+ }
+ return jsonString.stringValue();
+ }
+
+ public static Date getDate(JSONObject json, String field) {
+ DateTimeFormat frmt = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ String date = getString(json, field);
+ if (date!=null && date.endsWith("Z") && date.length()>2) {
+ // see SONAR-1182
+ date = date.substring(0, date.length()-2) + "+00:00";
+ }
+ return frmt.parse(date);
+ }
+
+ 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");
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Measure.java
new file mode 100644
index 00000000000..a9cc3c5aee5
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Measure.java
@@ -0,0 +1,152 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class Measure {
+ private String metric;
+ private String metricName;
+ private Double value;
+ private String formattedValue;
+ private String data;
+
+ private String ruleKey;
+ private String ruleName;
+ private String ruleCategory;
+ private String rulePriority;
+
+ private Date date;
+
+ public Measure() {
+ }
+
+ public Measure(String metric, Double value, String formattedValue) {
+ this.metric = metric;
+ this.value = value;
+ this.formattedValue = formattedValue;
+ }
+
+ public String getMetric() {
+ return metric;
+ }
+
+ public void setMetric(String metric) {
+ this.metric = metric;
+ }
+
+ public Double getValue() {
+ return value;
+ }
+
+ public void setValue(Double value) {
+ this.value = value;
+ }
+
+ public String getFormattedValue() {
+ return formattedValue;
+ }
+
+ public void setFormattedValue(String formattedValue) {
+ this.formattedValue = formattedValue;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public Map<String, String> getDataAsMap() {
+ Map<String, String> map = new TreeMap<String, String>();
+ if (data != null) {
+ String[] strings = data.split(";");
+ for (String string : strings) {
+ String[] keyValue = string.split("=");
+ map.put(keyValue[0], keyValue[1]);
+ }
+ }
+ return map;
+
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String getMetricName() {
+ return metricName;
+ }
+
+ public void setMetricName(String metricName) {
+ this.metricName = metricName;
+ }
+
+ public String getRuleKey() {
+ return ruleKey;
+ }
+
+ public void setRuleKey(String s) {
+ this.ruleKey = s;
+ }
+
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public void setRuleName(String ruleName) {
+ this.ruleName = ruleName;
+ }
+
+ public String getRuleCategory() {
+ return ruleCategory;
+ }
+
+ public void setRuleCategory(String s) {
+ this.ruleCategory = s;
+ }
+
+ public String getRulePriority() {
+ return rulePriority;
+ }
+
+ public void setRulePriority(String rulePriority) {
+ this.rulePriority = rulePriority;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ @Override
+ public String toString() {
+ return "Measure{" +
+ "metric='" + metric + '\'' +
+ ", metric_name='" + metricName + '\'' +
+ ", val='" + value + '\'' +
+ ", f_val='" + formattedValue + '\'' +
+ '}';
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/MetricsQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/MetricsQuery.java
new file mode 100644
index 00000000000..b63268842a8
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/MetricsQuery.java
@@ -0,0 +1,104 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.sonar.api.web.gwt.client.Utils;
+import org.sonar.api.web.gwt.client.webservices.WSMetrics.MetricsList;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+
+public final class MetricsQuery extends Query<MetricsList> {
+
+ private Boolean userManaged;
+ private List<WSMetrics.Metric.ValueType> excludedTypes = new ArrayList<WSMetrics.Metric.ValueType>();
+
+ public static MetricsQuery get() {
+ return new MetricsQuery();
+ }
+
+ private MetricsQuery() {
+ super();
+ }
+
+ public Boolean isUserManaged() {
+ return userManaged;
+ }
+
+ public MetricsQuery setUserManaged(Boolean userManaged) {
+ this.userManaged = userManaged;
+ return this;
+ }
+
+ public MetricsQuery excludeTypes(WSMetrics.Metric.ValueType... types) {
+ for (WSMetrics.Metric.ValueType valueType : types) {
+ excludedTypes.add(valueType);
+ }
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.getServerApiUrl() + "/metrics?";
+ }
+
+ @Override
+ public void execute(QueryCallBack<MetricsList> callback) {
+ JsonUtils.requestJson(this.toString(), new JSONHandlerDispatcher<MetricsList>(callback) {
+ @Override
+ public MetricsList parseResponse(JavaScriptObject obj) {
+ return parseMetrics(obj);
+ }
+ });
+ }
+
+ private MetricsList parseMetrics(JavaScriptObject json) {
+ JSONArray array = new JSONArray(json);
+ MetricsList list = new MetricsList();
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject jsStock = array.get(i).isObject();
+ if (jsStock != null) {
+ WSMetrics.Metric m = parseMetric(jsStock);
+ boolean skip = (isUserManaged() != null && (!isUserManaged() && m.isUserManaged())) || excludedTypes.contains(m.getType());
+ if (!skip) {
+ list.getMetrics().add(m);
+ }
+ }
+ }
+ return list;
+ }
+
+ private WSMetrics.Metric parseMetric(JSONObject json) {
+ String key = JsonUtils.getString(json, "key");
+ String name = JsonUtils.getString(json, "name");
+ String description = JsonUtils.getString(json, "description");
+ String domain = JsonUtils.getString(json, "domain");
+ String type = JsonUtils.getString(json, "val_type");
+ boolean qualitative = JsonUtils.getBoolean(json, "qualitative");
+ boolean userManaged = JsonUtils.getBoolean(json, "user_managed");
+ Integer direction = JsonUtils.getInteger(json, "direction");
+ return new WSMetrics.Metric(key, name, description, domain, qualitative, userManaged, direction, WSMetrics.Metric.ValueType.valueOf(type));
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Properties.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Properties.java
new file mode 100644
index 00000000000..a31ea97ff62
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Properties.java
@@ -0,0 +1,44 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.List;
+
+public class Properties extends ResponsePOJO {
+
+ private List<Property> properties;
+
+ public Properties(List<Property> properties) {
+ this.properties = properties;
+ }
+
+ public List<Property> getProperties() {
+ return properties;
+ }
+
+ public String get(String key, String defaultValue) {
+ for (Property property : properties) {
+ if( property.getKey().equals(key)) {
+ return property.getValue();
+ }
+ }
+ return defaultValue;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/PropertiesQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/PropertiesQuery.java
new file mode 100644
index 00000000000..0b8b5df53dc
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/PropertiesQuery.java
@@ -0,0 +1,75 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import org.sonar.api.web.gwt.client.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class PropertiesQuery extends Query<Properties> {
+
+ private String key;
+
+ public PropertiesQuery() {
+ }
+
+ public PropertiesQuery(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public String toString() {
+ String url = Utils.getServerApiUrl() + "/properties";
+ if (key != null) {
+ url += "/" + key;
+ }
+ return url + "?";
+ }
+
+ @Override
+ public void execute(QueryCallBack<Properties> callback) {
+ JsonUtils.requestJson(this.toString(), new JSONHandlerDispatcher<Properties>(callback) {
+ @Override
+ public Properties parseResponse(JavaScriptObject obj) {
+ return new Properties(parseProperties(obj));
+ }
+
+ private List<Property> parseProperties(JavaScriptObject obj) {
+ JSONArray array = new JSONArray(obj);
+ List<Property> properties = new ArrayList<Property>();
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject jsonObject = array.get(i).isObject();
+ if (jsonObject != null) {
+ properties.add(parseProperty(jsonObject));
+ }
+ }
+ return properties;
+ }
+
+ private Property parseProperty(JSONObject json) {
+ return new Property(JsonUtils.getString(json, "key"), JsonUtils.getString(json, "value"));
+ }
+ });
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Property.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Property.java
new file mode 100644
index 00000000000..21167df4688
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Property.java
@@ -0,0 +1,52 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+public class Property extends ResponsePOJO {
+
+ private String key;
+ private String value;
+
+ public Property() {
+ }
+
+ public Property(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Property setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public Property setValue(String value) {
+ this.value = value;
+ return this;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Query.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Query.java
new file mode 100644
index 00000000000..ea573ab0bb3
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Query.java
@@ -0,0 +1,25 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+public abstract class Query<R extends ResponsePOJO> {
+
+ public abstract void execute(final QueryCallBack<R> callback);
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/QueryCallBack.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/QueryCallBack.java
new file mode 100644
index 00000000000..431e07ebb9b
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/QueryCallBack.java
@@ -0,0 +1,32 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+public interface QueryCallBack<RESPONSE_POJO extends ResponsePOJO> {
+
+ void onResponse(RESPONSE_POJO response, JavaScriptObject jsonRawResponse);
+
+ void onTimeout();
+
+ void onError(int errorCode, String errorMessage);
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resource.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resource.java
new file mode 100644
index 00000000000..6389fc6aa9c
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resource.java
@@ -0,0 +1,187 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.List;
+
+public class Resource extends ResponsePOJO {
+ public static final String SCOPE_SET = "PRJ";
+ public static final String SCOPE_SPACE = "DIR";
+ public static final String SCOPE_ENTITY = "FIL";
+
+ @Deprecated
+ public static final String SCOPE_PROJECT = SCOPE_SET;
+ @Deprecated
+ public static final String SCOPE_DIRECTORY = SCOPE_SPACE;
+ @Deprecated
+ public static final String SCOPE_FILE = SCOPE_ENTITY;
+
+ public static final String QUALIFIER_PROJECT = "TRK";
+ public static final String QUALIFIER_MODULE = "BRC";
+ @Deprecated
+ public static final String QUALIFIER_PROJECT_TRUNK = QUALIFIER_PROJECT;
+ @Deprecated
+ public static final String QUALIFIER_PROJECT_BRANCH = QUALIFIER_MODULE;
+ public static final String QUALIFIER_PACKAGE = "PAC";
+ public static final String QUALIFIER_DIRECTORY = "DIR";
+ public static final String QUALIFIER_FILE = "FIL";
+ public static final String QUALIFIER_CLASS = "CLA";
+ public static final String QUALIFIER_UNIT_TEST = "UTS";
+
+ private Integer id;
+ private String key;
+ private String name;
+ private String longName;
+ private String qualifier;
+ private String scope;
+ private String language;
+ private Integer copy;
+ private List<Measure> measures;
+
+ public Resource() {
+ }
+
+ public Resource(Integer id, String key, String name, String scope, String qualifier, String language, Integer copy, List<Measure> measures) {
+ this.id = id;
+ this.key = key;
+ this.name = name;
+ this.qualifier = qualifier;
+ this.scope = scope;
+ this.language = language;
+ this.measures = measures;
+ this.copy = copy;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getName(boolean longFormatIfDefined) {
+ if (longFormatIfDefined && longName != null && !"".equals(longName)) {
+ return longName;
+ }
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLongName() {
+ return longName;
+ }
+
+ public void setLongName(String longName) {
+ this.longName = longName;
+ }
+
+ public String getQualifier() {
+ return qualifier;
+ }
+
+ public void setQualifier(String qualifier) {
+ this.qualifier = qualifier;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public Integer getCopy() {
+ return copy;
+ }
+
+ public void setCopy(Integer copy) {
+ this.copy = copy;
+ }
+
+ public List<Measure> getMeasures() {
+ return measures;
+ }
+
+ public Measure getMeasure(WSMetrics.Metric metric) {
+ if (measures != null) {
+ for (Measure measure : measures) {
+ if (measure.getMetric().equals(metric.getKey())) {
+ return measure;
+ }
+ }
+ }
+ return null;
+ }
+
+ public boolean hasMeasure(WSMetrics.Metric metric) {
+ return getMeasure(metric) != null;
+ }
+
+ public String getMeasureFormattedValue(WSMetrics.Metric metric, String defaultValue) {
+ Measure measure = getMeasure(metric);
+ if (measure != null) {
+ return measure.getFormattedValue();
+ }
+ return defaultValue;
+ }
+
+ public void setMeasures(List<Measure> measures) {
+ this.measures = measures;
+ }
+
+ public boolean matchesKey(String resourceKey) {
+ return resourceKey != null && (getId().toString().equals(resourceKey) || getKey().equals(resourceKey));
+ }
+
+ @Override
+ public String toString() {
+ return "Resource{" +
+ "id='" + id + '\'' +
+ ", key='" + key + '\'' +
+ ", name='" + name + '\'' +
+ ", longName='" + longName + '\'' +
+ ", scope='" + scope + '\'' +
+ ", qualifier='" + qualifier + '\'' +
+ ", language='" + language + '\'' +
+ ", measures=" + measures +
+ '}';
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resources.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resources.java
new file mode 100644
index 00000000000..b3a91971a88
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Resources.java
@@ -0,0 +1,63 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.List;
+
+public class Resources extends ResponsePOJO {
+
+ private List<Resource> resources;
+
+ public Resources(List<Resource> resources) {
+ super();
+ this.resources = resources;
+ }
+
+ public List<Resource> getResources() {
+ return resources;
+ }
+
+ public Resource firstResource() {
+ return resources.size() > 0 ? resources.get(0) : null;
+ }
+
+ public boolean onceContainsMeasure(WSMetrics.Metric metric) {
+ for (Resource resource : resources) {
+ if (resource.getMeasure(metric) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean allContainsMeasure(WSMetrics.Metric metric) {
+ for (Resource resource : resources) {
+ if (resource.getMeasure(metric) == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean isEmpty() {
+ return resources == null || resources.isEmpty();
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResourcesQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResourcesQuery.java
new file mode 100644
index 00000000000..fe6125e486a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResourcesQuery.java
@@ -0,0 +1,256 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONValue;
+import org.sonar.api.web.gwt.client.Utils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public final class ResourcesQuery extends AbstractResourceQuery<Resources> {
+
+ public final static int DEPTH_UNLIMITED = -1;
+
+ private Integer depth;
+ private Integer limit;
+ private String scopes;
+ private String qualifiers;
+ private String metrics;
+ private String rules;
+ private String ruleCategories;
+ private String rulePriorities;
+ private boolean verbose = false;
+
+ /**
+ * Alias for build()
+ */
+ public static ResourcesQuery get(String resourceKey) {
+ return new ResourcesQuery(resourceKey);
+ }
+
+ public static ResourcesQuery build(String resourceKey) {
+ return new ResourcesQuery(resourceKey);
+ }
+
+ public static ResourcesQuery build() {
+ return new ResourcesQuery(null);
+ }
+
+ private ResourcesQuery(String resourceKey) {
+ super(resourceKey);
+ }
+
+ public ResourcesQuery setDepth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public ResourcesQuery setRules(String s) {
+ this.rules = s;
+ return this;
+ }
+
+ public ResourcesQuery filterOnRules(boolean b) {
+ return setRules(b ? "true" : "false");
+ }
+
+ public ResourcesQuery filterOnRulePriorities(boolean b) {
+ return setRulePriorities(b ? "true" : "false");
+ }
+
+ public ResourcesQuery filterOnRuleCategories(boolean b) {
+ return setRuleCategories(b ? "true" : "false");
+ }
+
+ public ResourcesQuery setRulePriorities(String s) {
+ this.rulePriorities = s;
+ return this;
+ }
+
+ public ResourcesQuery setRuleCategories(String s) {
+ this.ruleCategories = s;
+ return this;
+ }
+
+ public ResourcesQuery setLimit(Integer limit) {
+ this.limit = limit;
+ return this;
+ }
+
+ public ResourcesQuery setScopes(String scopes) {
+ this.scopes = scopes;
+ return this;
+ }
+
+ public ResourcesQuery setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ return this;
+ }
+
+ public ResourcesQuery setQualifiers(String qualifiers) {
+ this.qualifiers = qualifiers;
+ return this;
+ }
+
+ public ResourcesQuery setMetrics(List<WSMetrics.Metric> metrics) {
+ this.metrics = getMetricsWSRequest(metrics);
+ return this;
+ }
+
+ public ResourcesQuery setMetric(WSMetrics.Metric m) {
+ this.metrics = m.getKey();
+ return this;
+ }
+
+ public ResourcesQuery setMetric(String metricKey) {
+ this.metrics = metricKey;
+ return this;
+ }
+
+ private String getMetricsWSRequest(List<WSMetrics.Metric> metrics) {
+ StringBuilder metricsDelimByComma = new StringBuilder(64);
+ for (WSMetrics.Metric metric : metrics) {
+ metricsDelimByComma.append(metric.getKey()).append(",");
+ }
+ return metricsDelimByComma.substring(0, metricsDelimByComma.length() - 1);
+ }
+
+ @Override
+ public String toString() {
+ String url = Utils.getServerApiUrl() + "/resources?";
+ if (getResourceKey() != null) {
+ url += "resource=" + getResourceKey() + "&";
+ }
+ if (metrics != null) {
+ url += "metrics=" + metrics + "&";
+ }
+ if (scopes != null) {
+ url += "scopes=" + scopes + "&";
+ }
+ if (qualifiers != null) {
+ url += "qualifiers=" + qualifiers + "&";
+ }
+ if (depth != null) {
+ url += "depth=" + depth + "&";
+ }
+ if (limit != null) {
+ url += "limit=" + limit + "&";
+ }
+ if (rules != null) {
+ url += "rules=" + rules + "&";
+ }
+ if (ruleCategories != null) {
+ url += "rule_categories=" + ruleCategories + "&";
+ }
+ if (rulePriorities != null) {
+ url += "rule_priorities=" + rulePriorities + "&";
+ }
+ if (verbose) {
+ url += "verbose=true&";
+ }
+ return url;
+ }
+
+ @Override
+ public void execute(QueryCallBack<Resources> callback) {
+ JsonUtils.requestJson(this.toString(), new JSONHandlerDispatcher<Resources>(callback) {
+ @Override
+ public Resources parseResponse(JavaScriptObject obj) {
+ return new Resources(parseResources(obj));
+ }
+ });
+ }
+
+ public static List<Resource> parseResources(JavaScriptObject json) {
+ JSONArray array = new JSONArray(json);
+ List<Resource> resources = new ArrayList<Resource>();
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject jsStock = array.get(i).isObject();
+ if (jsStock != null) {
+ resources.add(parseResource(jsStock));
+ }
+ }
+ return resources;
+ }
+
+ private static Resource parseResource(JSONObject json) {
+ Double id = JsonUtils.getDouble(json, "id");
+ String key = JsonUtils.getString(json, "key");
+ String name = JsonUtils.getString(json, "name");
+ String longName = JsonUtils.getString(json, "lname");
+ String qualifier = JsonUtils.getString(json, "qualifier");
+ String language = JsonUtils.getString(json, "lang");
+ String scope = JsonUtils.getString(json, "scope");
+ Integer copy = JsonUtils.getInteger(json, "copy");
+ Date date = JsonUtils.getDate(json, "date");
+
+ List<Measure> measures = null;
+ JSONValue measuresJson;
+ if ((measuresJson = json.get("msr")) != null) {
+ measures = parseMeasures(measuresJson, date);
+ }
+
+ final Resource resource = new Resource(id.intValue(), key, name, scope, qualifier, language, copy, measures);
+ resource.setLongName(longName);
+ return resource;
+ }
+
+ private static List<Measure> parseMeasures(JSONValue measures, Date date) {
+ List<Measure> projectMeasures = new ArrayList<Measure>();
+ int len = JsonUtils.getArraySize(measures);
+ for (int i = 0; i < len; i++) {
+ JSONObject measure = JsonUtils.getArray(measures, i);
+ if (measure != null) {
+ Measure measureEntry = parseMeasure(measure, date);
+ if (measureEntry != null) {
+ projectMeasures.add(measureEntry);
+ }
+ }
+ }
+ return projectMeasures;
+ }
+
+ private static Measure parseMeasure(JSONObject measure, Date date) {
+ String metric = JsonUtils.getString(measure, "key");
+ if (metric == null) {
+ return null;
+ }
+
+ final Measure m = new Measure(metric, JsonUtils.getDouble(measure, "val"), JsonUtils.getString(measure, "frmt_val"));
+ m.setData(JsonUtils.getString(measure, "data"));
+ String metricName = JsonUtils.getString(measure, "name");
+ if (metricName != null) {
+ m.setMetricName(metricName);
+ }
+
+ m.setRuleKey(JsonUtils.getString(measure, "rule_key"));
+ m.setRuleName(JsonUtils.getString(measure, "rule_name"));
+ m.setRuleCategory(JsonUtils.getString(measure, "rule_category"));
+ m.setRulePriority(JsonUtils.getString(measure, "rule_priority"));
+ m.setDate(date);
+ return m;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResponsePOJO.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResponsePOJO.java
new file mode 100644
index 00000000000..7accea548bf
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ResponsePOJO.java
@@ -0,0 +1,27 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+/**
+ * Marker class for WS query response objects
+ */
+public abstract class ResponsePOJO {
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Rule.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Rule.java
new file mode 100644
index 00000000000..c150e48c63b
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Rule.java
@@ -0,0 +1,57 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+public class Rule extends ResponsePOJO {
+ private String key;
+ private String name;
+ private String category;
+
+ public Rule(String key, String name, String category) {
+ this.key = key;
+ this.name = name;
+ this.category = category;
+ }
+
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SequentialQueries.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SequentialQueries.java
new file mode 100644
index 00000000000..dd827891912
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SequentialQueries.java
@@ -0,0 +1,112 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.user.client.Timer;
+
+public class SequentialQueries extends Query<VoidResponse> {
+
+ private List<AjaxQuery<?>> queries = new ArrayList<AjaxQuery<?>>();
+ private int sleepTimeBetweenCbChecks;
+
+ private SequentialQueries(int sleepTimeBetweenCbChecks) {
+ this.sleepTimeBetweenCbChecks = sleepTimeBetweenCbChecks;
+ }
+
+ public static SequentialQueries get() {
+ return new SequentialQueries(50);
+ }
+
+ public static SequentialQueries get(int sleepTimeBetweenCbChecks) {
+ return new SequentialQueries(sleepTimeBetweenCbChecks);
+ }
+
+ public <R extends ResponsePOJO> SequentialQueries add(Query<R> query, QueryCallBack<R> callback) {
+ queries.add(new AjaxQuery<R>(query, callback));
+ return this;
+ }
+
+ @Override
+ public void execute(final QueryCallBack<VoidResponse> callback) {
+ for (AjaxQuery<?> query : queries) {
+ query.execute();
+ }
+ Timer queriesMonitor = new Timer() {
+ @Override
+ public void run() {
+ boolean queriesExecuted = true;
+ for (AjaxQuery<?> query : queries) {
+ if (!query.isCompleted()) {
+ queriesExecuted = false;
+ break;
+ }
+ }
+ if (queriesExecuted) {
+ callback.onResponse(new VoidResponse(), null);
+ cancel();
+ }
+ }
+ };
+ queriesMonitor.scheduleRepeating(sleepTimeBetweenCbChecks);
+ }
+
+ private class AjaxQuery<R extends ResponsePOJO> {
+ private Query<R> query;
+ private QueryCallBack<R> callback;
+
+ private boolean completed = false;
+
+ public AjaxQuery(Query<R> query, QueryCallBack<R> callback) {
+ super();
+ this.query = query;
+ this.callback = callback;
+ }
+
+ private void execute() {
+ QueryCallBack<R> proxy = new QueryCallBack<R>() {
+ public void onError(int errorCode, String errorMessage) {
+ callback.onError(errorCode, errorMessage);
+ completed = true;
+ }
+
+ public void onResponse(R response, JavaScriptObject jsonRawResponse) {
+ callback.onResponse(response, jsonRawResponse);
+ completed = true;
+ }
+
+ public void onTimeout() {
+ callback.onTimeout();
+ completed = true;
+ }
+ };
+ query.execute(proxy);
+ }
+
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SourcesQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SourcesQuery.java
new file mode 100644
index 00000000000..1d1b0498df2
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/SourcesQuery.java
@@ -0,0 +1,101 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONValue;
+import org.sonar.api.web.gwt.client.Utils;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+public final class SourcesQuery extends AbstractResourceQuery<FileSource> {
+
+ private Integer from;
+ private Integer length;
+ private boolean color;
+
+ public static SourcesQuery get(String resourceKey) {
+ return new SourcesQuery(resourceKey);
+ }
+
+ private SourcesQuery(String resourceKey) {
+ super(resourceKey);
+ }
+
+ public SourcesQuery setFrom(Integer from) {
+ this.from = from;
+ return this;
+ }
+
+ public SourcesQuery setLength(Integer length) {
+ this.length = length;
+ return this;
+ }
+
+ public SourcesQuery setColor(boolean color) {
+ this.color = color;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String url = Utils.getServerApiUrl() + "/sources?resource=" + getResourceKey() + "&";
+ if (length > 0) {
+ url += "from=" + from + "&to=" + (from + length) + "&";
+ }
+ if (color) {
+ url += "color=true&";
+ }
+ return url;
+ }
+
+ @Override
+ public void execute(QueryCallBack<FileSource> callback) {
+ JsonUtils.requestJson(this.toString(), new JSONHandlerDispatcher<FileSource>(callback) {
+ @Override
+ public FileSource parseResponse(JavaScriptObject obj) {
+ return parseLines(obj);
+ }
+ });
+ }
+
+ private FileSource parseLines(JavaScriptObject obj) {
+ Map<Integer, String> sourceLines = new TreeMap<Integer, String>();
+ FileSource src = new FileSource(sourceLines);
+ JSONArray jsonArray = new JSONArray(obj);
+ if (jsonArray.size() == 0) return src;
+ JSONObject sources = jsonArray.get(0).isObject();
+ if (sources.size() == 0) return src;
+ int maxSize = new Double(Math.pow(2, 16)).intValue();
+ int currentLine = from == 0 ? 1 : from;
+ while (currentLine < maxSize) {
+ JSONValue line = sources.get(Integer.toString(currentLine));
+ if (line == null) {
+ break;
+ }
+ sourceLines.put(currentLine++, line.isString().stringValue());
+ }
+ return src;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violation.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violation.java
new file mode 100644
index 00000000000..6c9eae2ea87
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violation.java
@@ -0,0 +1,80 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+public class Violation {
+
+ private String message;
+ private String priority;
+ private int line;
+ private Rule rule;
+ private Resource resource;
+
+ public Violation(String message, String priority, int line, Rule rule, Resource resource) {
+ this.message = message;
+ this.priority = priority;
+ this.line = line;
+ this.rule = rule;
+ this.resource = resource;
+ }
+
+ public Violation() {
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getPriority() {
+ return priority;
+ }
+
+ public void setPriority(String priority) {
+ this.priority = priority;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public void setLine(int line) {
+ this.line = line;
+ }
+
+ public Rule getRule() {
+ return rule;
+ }
+
+ public void setRule(Rule rule) {
+ this.rule = rule;
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violations.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violations.java
new file mode 100644
index 00000000000..d525c5bf634
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/Violations.java
@@ -0,0 +1,87 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Violations extends ResponsePOJO {
+ private List<Violation> violations;
+ private Map<Integer, List<Violation>> byLines;
+
+ public Violations(List<Violation> violations) {
+ this.violations = violations;
+ }
+
+ public Violations() {
+ this.violations = new ArrayList<Violation>();
+ }
+
+ public void add(Violation v) {
+ violations.add(v);
+ byLines = null;
+ }
+
+ public List<Violation> getAll() {
+ return violations;
+ }
+
+
+ public Map<Integer, List<Violation>> getByLines() {
+ if (byLines == null) {
+ byLines = new HashMap<Integer, List<Violation>>();
+ for (Violation violation : violations) {
+ List<Violation> lineViolations = byLines.get(violation.getLine());
+ if (lineViolations == null) {
+ lineViolations = new ArrayList<Violation>();
+ byLines.put(violation.getLine(), lineViolations);
+ }
+ lineViolations.add(violation);
+ }
+ }
+ return byLines;
+ }
+
+ public String getLevelForLine(Integer line) {
+ List<Violation> lineViolations = getByLines().get(line);
+ String level = "";
+ if (lineViolations != null) {
+ for (Violation lineViolation : lineViolations) {
+ if ("BLOCKER".equals(lineViolation.getPriority()) || "CRITICAL".equals(lineViolation.getPriority()) || "MAJOR".equals(lineViolation.getPriority())) {
+ level = "error";
+
+ } else if (!"error".equals(level)) {
+ level = "warning";
+ }
+ }
+ }
+ return level;
+ }
+
+ public int countForLine(Integer line) {
+ List<Violation> lineViolations = getByLines().get(line);
+ if (lineViolations == null) {
+ return 0;
+ }
+ return lineViolations.size();
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ViolationsQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ViolationsQuery.java
new file mode 100644
index 00000000000..46442b6c995
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/ViolationsQuery.java
@@ -0,0 +1,162 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.json.client.JSONArray;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.google.gwt.json.client.JSONValue;
+import org.sonar.api.web.gwt.client.Utils;
+
+public final class ViolationsQuery extends AbstractResourceQuery<Violations> {
+
+ private String scopes;
+ private String qualifiers;
+ private String rules;
+ private String categories;
+ private String priorities;
+ private Integer depth;
+
+ private ViolationsQuery(String resourceKey) {
+ super(resourceKey);
+ }
+
+ public static ViolationsQuery create(String resourceKey) {
+ return new ViolationsQuery(resourceKey);
+ }
+
+ public String getScopes() {
+ return scopes;
+ }
+
+ public ViolationsQuery setScopes(String scopes) {
+ this.scopes = scopes;
+ return this;
+ }
+
+ public String getQualifiers() {
+ return qualifiers;
+ }
+
+ public ViolationsQuery setQualifiers(String qualifiers) {
+ this.qualifiers = qualifiers;
+ return this;
+ }
+
+ public String getRules() {
+ return rules;
+ }
+
+ public ViolationsQuery setRules(String rules) {
+ this.rules = rules;
+ return this;
+ }
+
+ public String getCategories() {
+ return categories;
+ }
+
+ public ViolationsQuery setCategories(String s) {
+ this.categories = s;
+ return this;
+ }
+
+ public Integer getDepth() {
+ return depth;
+ }
+
+ public ViolationsQuery setDepth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public String getPriorities() {
+ return priorities;
+ }
+
+ public ViolationsQuery setPriorities(String priorities) {
+ this.priorities = priorities;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String url = Utils.getServerApiUrl() + "/violations?resource=" + getResourceKey() + "&";
+ if (depth != null) {
+ url += "depth=" + depth + "&";
+ }
+ if (scopes != null) {
+ url += "scopes=" + scopes + "&";
+ }
+ if (qualifiers != null) {
+ url += "qualifiers=" + qualifiers + "&";
+ }
+ if (rules != null) {
+ url += "rules=" + rules + "&";
+ }
+ if (categories != null) {
+ url += "categories=" + categories + "&";
+ }
+ if (priorities != null) {
+ url += "priorities=" + priorities + "&";
+ }
+ return url;
+ }
+
+ @Override
+ public void execute(final QueryCallBack<Violations> callback) {
+ JsonUtils.requestJson(this.toString(), new JSONHandlerDispatcher<Violations>(callback) {
+ @Override
+ public Violations parseResponse(JavaScriptObject obj) {
+ return parseJSON(obj);
+ }
+ });
+ }
+
+ private Violations parseJSON(JavaScriptObject obj) {
+ Violations result = new Violations();
+ JSONArray jsonArray = new JSONArray(obj);
+ for (int i = 0; i < jsonArray.size(); i++) {
+ JSONObject jsViolation = jsonArray.get(i).isObject();
+ if (jsViolation == null) {
+ continue;
+ }
+ JSONString message = jsViolation.get("message").isString();
+ JSONString priority = jsViolation.get("priority").isString();
+ JSONValue lineJson = jsViolation.get("line");
+ int lineIndex = 0;
+ if (lineJson != null) {
+ lineIndex = (int) lineJson.isNumber().doubleValue();
+ }
+
+ JSONObject ruleObj = jsViolation.get("rule").isObject();
+ Rule rule = new Rule(
+ JsonUtils.getString(ruleObj, "key"),
+ JsonUtils.getString(ruleObj, "name"),
+ JsonUtils.getString(ruleObj, "category")
+ );
+
+ result.add(new Violation(message.stringValue(), priority.stringValue(), lineIndex, rule, null));
+ }
+ return result;
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/VoidResponse.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/VoidResponse.java
new file mode 100644
index 00000000000..9b8879f5c04
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/VoidResponse.java
@@ -0,0 +1,24 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+public class VoidResponse extends ResponsePOJO {
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/WSMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/WSMetrics.java
new file mode 100644
index 00000000000..b12e253fd2f
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/webservices/WSMetrics.java
@@ -0,0 +1,243 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.webservices;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class WSMetrics {
+
+ private WSMetrics() {
+ }
+
+ private final static List<Metric> DICTIONNARY = new ArrayList<Metric>();
+
+ public static final Metric NCLOC = add(new Metric("ncloc"));
+ public static final Metric LINES = add(new Metric("lines"));
+ public static final Metric CLASSES = add(new Metric("classes"));
+ public static final Metric PACKAGES = add(new Metric("packages"));
+ public static final Metric FUNCTIONS = add(new Metric("functions"));
+ public static final Metric ACCESSORS = add(new Metric("accessors"));
+ public static final Metric FILES = add(new Metric("files"));
+ public static final Metric DIRECTORIES = add(new Metric("directories"));
+ public static final Metric PUBLIC_API = add(new Metric("public_api"));
+
+ /* complexity */
+ public static final Metric COMPLEXITY = add(new Metric("complexity"));
+ public static final Metric CLASS_COMPLEXITY = add(new Metric("class_complexity"));
+ public static final Metric FUNCTION_COMPLEXITY = add(new Metric("function_complexity"));
+ public static final Metric FILE_COMPLEXITY = add(new Metric("file_complexity"));
+ public static final Metric STATEMENTS = add(new Metric("statements"));
+
+ public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = add(new Metric("class_complexity_distribution"));
+ public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = add(new Metric("function_complexity_distribution"));
+
+ /* comments */
+ public static final Metric COMMENT_LINES = add(new Metric("comment_lines"));
+ public static final Metric COMMENT_LINES_DENSITY = add(new Metric("comment_lines_density"));
+ public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = add(new Metric("public_documented_api_density"));
+ public static final Metric PUBLIC_UNDOCUMENTED_API = add(new Metric("public_undocumented_api"));
+ public static final Metric COMMENTED_OUT_CODE_LINES = add(new Metric("commented_out_code_lines"));
+
+ /* unit tests */
+ public static final Metric TESTS = add(new Metric("tests"));
+ public static final Metric TESTS_EXECUTION_TIME = add(new Metric("test_execution_time"));
+ public static final Metric TEST_ERRORS = add(new Metric("test_errors"));
+ public static final Metric SKIPPED_TESTS = add(new Metric("skipped_tests"));
+ public static final Metric TEST_FAILURES = add(new Metric("test_failures"));
+ public static final Metric TEST_SUCCESS_DENSITY = add(new Metric("test_success_density"));
+ public static final Metric TEST_DATA = add(new Metric("test_data"));
+
+ /* coverage */
+ public static final Metric COVERAGE = add(new Metric("coverage"));
+ public static final Metric LINE_COVERAGE = add(new Metric("line_coverage"));
+ public static final Metric UNCOVERED_LINES = add(new Metric("uncovered_lines"));
+ public static final Metric BRANCH_COVERAGE = add(new Metric("branch_coverage"));
+ public static final Metric UNCOVERED_CONDITIONS = add(new Metric("uncovered_conditions"));
+ public static final Metric COVERAGE_LINE_HITS_DATA = add(new Metric("coverage_line_hits_data"));
+ public static final Metric BRANCH_COVERAGE_HITS_DATA = add(new Metric("branch_coverage_hits_data"));
+
+ /* duplicated lines */
+ public static final Metric DUPLICATED_LINES = add(new Metric("duplicated_lines"));
+ public static final Metric DUPLICATED_BLOCKS = add(new Metric("duplicated_blocks"));
+ public static final Metric DUPLICATED_FILES = add(new Metric("duplicated_files"));
+ public static final Metric DUPLICATED_LINES_DENSITY = add(new Metric("duplicated_lines_density"));
+ public static final Metric DUPLICATIONS_DATA = add(new Metric("duplications_data"));
+
+ /* coding rules */
+ public static final Metric VIOLATIONS_DENSITY = add(new Metric("violations_density"));
+ public static final Metric VIOLATIONS = add(new Metric("violations"));
+ public static final Metric WEIGHTED_VIOLATIONS = add(new Metric("weighted_violations"));
+
+ /* design */
+ public static final Metric LCOM4 = add(new Metric("lcom4"));
+ public static final Metric RFC = add(new Metric("rfc"));
+
+ public static class MetricsList extends ResponsePOJO {
+
+ private List<Metric> metrics = new ArrayList<Metric>();
+
+ public List<Metric> getMetrics() {
+ return metrics;
+ }
+ }
+
+ /**
+ * Generates a callback that will update the metrics definitions from the WSMetrics metrics constants list with data
+ * received from a MetricsQuery call
+ *
+ * @param callback
+ * @return
+ */
+ public static QueryCallBack<MetricsList> getUpdateMetricsFromServer(final QueryCallBack<MetricsList> callback) {
+ return new QueryCallBack<MetricsList>() {
+ public void onResponse(MetricsList response, JavaScriptObject jsonRawResponse) {
+ for (Metric metric : response.getMetrics()) {
+ Metric WSMetricConstant = get(metric.getKey());
+ if (WSMetricConstant != null) {
+ WSMetricConstant.updateFrom(metric);
+ } else {
+ add(metric);
+ }
+ }
+ callback.onResponse(response, jsonRawResponse);
+ }
+
+ public void onError(int errorCode, String errorMessage) {
+ callback.onError(errorCode, errorMessage);
+ }
+
+ public void onTimeout() {
+ callback.onTimeout();
+ }
+ };
+ }
+
+ public static class Metric {
+ public enum ValueType {
+ INT, FLOAT, PERCENT, BOOL, STRING, MILLISEC, DATA, LEVEL, DISTRIB
+ }
+
+ private String key;
+ private String name;
+ private String description;
+ private String domain;
+ private boolean qualitative;
+ private boolean userManaged;
+ private int direction;
+ private ValueType type;
+
+ public Metric(String key) {
+ super();
+ this.key = key;
+ }
+
+ public Metric(String key, String name, String description, String domain,
+ boolean qualitative, boolean userManaged, int direction, ValueType type) {
+ super();
+ this.key = key;
+ this.name = name;
+ this.description = description;
+ this.domain = domain;
+ this.qualitative = qualitative;
+ this.userManaged = userManaged;
+ this.direction = direction;
+ this.type = type;
+ }
+
+ public void updateFrom(Metric metric) {
+ this.name = metric.getName();
+ this.description = metric.getDescription();
+ this.domain = metric.getDomain();
+ this.qualitative = metric.isQualitative();
+ this.userManaged = metric.isUserManaged();
+ this.direction = metric.getDirection();
+ this.type = metric.getType();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ValueType getType() {
+ return type;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public boolean isQualitative() {
+ return qualitative;
+ }
+
+ public boolean isUserManaged() {
+ return userManaged;
+ }
+
+ public int getDirection() {
+ return direction;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Metric)) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ Metric other = (Metric) obj;
+ return key.equals(other.getKey());
+ }
+ }
+
+ public static Metric add(Metric metric) {
+ if (!DICTIONNARY.contains(metric)) {
+ DICTIONNARY.add(metric);
+ }
+ return metric;
+ }
+
+ public static Metric get(String metricKey) {
+ for (Metric metric : DICTIONNARY) {
+ if (metric.getKey().equals(metricKey)) {
+ return metric;
+ }
+ }
+ return new Metric(metricKey);
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/widgets/LoadingLabel.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/widgets/LoadingLabel.java
new file mode 100644
index 00000000000..72d45bea4df
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/gwt/client/widgets/LoadingLabel.java
@@ -0,0 +1,34 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.api.web.gwt.client.widgets;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTML;
+
+public class LoadingLabel extends Composite {
+ public LoadingLabel() {
+ this("loading...");
+ getElement().setId("loading");
+ }
+
+ public LoadingLabel(String text) {
+ initWidget(new HTML("<div class='loading'>" + text + "</div>"));
+ }
+}