aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-05-17 16:00:59 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-05-19 15:15:36 +0200
commita1150367ee755be95f1cc605df983a928aa9136b (patch)
tree04defc5b2924fc48a846ec4c67efa798c0dc2687 /sonar-plugin-api
parentb58544df961c44b518dfbcc164b836ec23a03c69 (diff)
downloadsonarqube-a1150367ee755be95f1cc605df983a928aa9136b.tar.gz
sonarqube-a1150367ee755be95f1cc605df983a928aa9136b.zip
SONAR-6517 merge sonar-deprecated into sonar-plugin-api
It allows to use the shaded and relocated dependencies of sonar-plugin-api
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/pom.xml4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java78
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceCreationLock.java41
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceFilter.java45
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/SquidUtils.java62
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/charts/AbstractChart.java100
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/charts/Chart.java44
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/charts/ChartParameters.java186
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/charts/package-info.java23
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java176
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/checks/CheckFactory.java73
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/checks/NoSonarFilter.java71
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/Java.java80
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java121
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaPackage.java88
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/Method.java108
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectUtils.java50
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java119
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/RuleRepository.java82
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java235
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java38
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Section.java29
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/SquidUtilsTest.java41
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/charts/ChartParametersTest.java79
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/AbstractCheck.java32
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/AnnotationCheckFactoryTest.java199
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithIntegerProperty.java33
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithKey.java28
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithOverriddenPropertyKey.java35
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithPrimitiveProperties.java43
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithStringProperty.java36
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithUnsupportedPropertyType.java32
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithoutProperties.java29
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/ImplementedCheck.java28
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java90
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaFileTest.java114
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaPackageTest.java78
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaTest.java40
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/resources/MethodTest.java46
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/rules/AnnotationRuleParserTest.java171
40 files changed, 3007 insertions, 0 deletions
diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml
index 2e37e8f3498..f09e6a254ad 100644
--- a/sonar-plugin-api/pom.xml
+++ b/sonar-plugin-api/pom.xml
@@ -24,6 +24,10 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>jfree</groupId>
+ <artifactId>jfreechart</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java
new file mode 100644
index 00000000000..137437fae4f
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java
@@ -0,0 +1,78 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch;
+
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ProjectFileSystem;
+import org.sonar.api.resources.Resource;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.List;
+
+/**
+ * @since 1.10
+ * @deprecated since 4.2 Component indexing and source import are done by core and this extension is not used.
+ */
+@Deprecated
+@Phase(name = Phase.Name.PRE)
+public abstract class AbstractSourceImporter implements Sensor {
+
+ private Language language;
+
+ public AbstractSourceImporter(Language language) {
+ this.language = language;
+ }
+
+ @Override
+ public boolean shouldExecuteOnProject(Project project) {
+ return false;
+ }
+
+ @Override
+ public void analyse(Project project, SensorContext context) {
+ // Do not remove for backward compatibility
+ }
+
+ protected void onFinished() {
+
+ }
+
+ protected void analyse(ProjectFileSystem fileSystem, SensorContext context) {
+ // Do not remove for backward compatibility
+ }
+
+ protected void parseDirs(SensorContext context, List<File> files, List<File> sourceDirs, boolean unitTest, Charset sourcesEncoding) {
+ // Do not remove for backward compatibility
+ }
+
+ protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) {
+ return null;
+ }
+
+ protected boolean isEnabled(Project project) {
+ return false;
+ }
+
+ public Language getLanguage() {
+ return language;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceCreationLock.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceCreationLock.java
new file mode 100644
index 00000000000..1b485ddd96d
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceCreationLock.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch;
+
+import org.sonar.api.BatchSide;
+
+/**
+ * This lock is used to ensure that Sonar resources (files, packages, directories) are not created by buggy plugins
+ * when saving measures/violations on unknown resources.
+ *
+ * @since 2.3
+ * @deprecated since 4.2. File system is immutable and does not require this class anymore.
+ */
+@Deprecated
+@BatchSide
+public interface ResourceCreationLock {
+
+ /**
+ * Forbids the creation of resources when saving violations and measures. By default it's unlocked, so only warnings
+ * are logged. When locked, then an exception is thrown.
+ */
+ void lock();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceFilter.java
new file mode 100644
index 00000000000..23ab301d309
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ResourceFilter.java
@@ -0,0 +1,45 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch;
+
+import org.sonar.api.BatchSide;
+import org.sonar.api.ExtensionPoint;
+import org.sonar.api.resources.Resource;
+
+/**
+ * Filter resources to save. For example, ignore a resource if its path matches an exclusion pattern (defined on the project).
+ * Filters are applied to files, directories and packages only.
+ *
+ * If the method start(), without parameters, exists, then it is executed at startup.
+ *
+ * @since 1.12
+ * @deprecated since 4.2. Analysis is file-system oriented. See {@link org.sonar.api.scan.filesystem.InputFileFilter}
+ */
+@Deprecated
+@BatchSide
+@ExtensionPoint
+public interface ResourceFilter {
+
+ /**
+ * Return true if the resource must be ignored, else it's saved into database.
+ */
+ boolean isIgnored(Resource resource);
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SquidUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SquidUtils.java
new file mode 100644
index 00000000000..d215d11b83e
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SquidUtils.java
@@ -0,0 +1,62 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch;
+
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.JavaPackage;
+
+/**
+ * @deprecated since 4.2
+ */
+@Deprecated
+public final class SquidUtils {
+
+ private SquidUtils() {
+ // only static methods
+ }
+
+ /**
+ * @deprecated since 4.2 JavaFile is deprecated
+ */
+ @Deprecated
+ public static JavaFile convertJavaFileKeyFromSquidFormat(String key) {
+ throw unsupported();
+ }
+
+ /**
+ * @deprecated since 4.2 JavaPackage is deprecated
+ */
+ @Deprecated
+ public static JavaPackage convertJavaPackageKeyFromSquidFormat(String key) {
+ throw unsupported();
+ }
+
+ private static UnsupportedOperationException unsupported() {
+ return new UnsupportedOperationException("Not supported since v4.2. See http://redirect.sonarsource.com/doc/api-changes.html");
+ }
+
+ /**
+ * @deprecated since 4.0
+ */
+ @Deprecated
+ public static String convertToSquidKeyFormat(JavaFile file) {
+ throw new UnsupportedOperationException("Not supported since v4.0. Was badly implemented");
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/charts/AbstractChart.java b/sonar-plugin-api/src/main/java/org/sonar/api/charts/AbstractChart.java
new file mode 100644
index 00000000000..acbeb318b96
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/charts/AbstractChart.java
@@ -0,0 +1,100 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.charts;
+
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.Plot;
+import org.jfree.chart.renderer.AbstractRenderer;
+import org.jfree.chart.title.TextTitle;
+import org.jfree.data.Values2D;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+
+/**
+ * Base implementation to generate charts with JFreechart
+ *
+ * @since 1.10
+ * @deprecated in 4.5.1, replaced by Javascript charts
+ */
+@Deprecated
+public abstract class AbstractChart implements Chart {
+
+ public static final int FONT_SIZE = 13;
+ public static final Color OUTLINE_COLOR = new Color(51, 51, 51);
+ public static final Color GRID_COLOR = new Color(204, 204, 204);
+ public static final Color[] COLORS = new Color[] { Color.decode("#4192D9"), Color.decode("#800000"), Color.decode("#A7B307"),
+ Color.decode("#913C9F"), Color.decode("#329F4D") };
+
+ protected abstract Plot getPlot(ChartParameters params);
+
+ protected boolean hasLegend() {
+ return false;
+ }
+
+ /**
+ * Generates a JFreeChart chart using a set of parameters
+ *
+ * @param params the chart parameters
+ * @return the generated chart
+ */
+ @Override
+ public BufferedImage generateImage(ChartParameters params) {
+ JFreeChart chart = new JFreeChart(null, TextTitle.DEFAULT_FONT, getPlot(params), hasLegend());
+ improveChart(chart, params);
+ return chart.createBufferedImage(params.getWidth(), params.getHeight());
+ }
+
+ private void improveChart(JFreeChart jfrechart, ChartParameters params) {
+ Color background = Color.decode("#" + params.getValue(ChartParameters.PARAM_BACKGROUND_COLOR, "FFFFFF", false));
+ jfrechart.setBackgroundPaint(background);
+
+ jfrechart.setBorderVisible(false);
+ jfrechart.setAntiAlias(true);
+ jfrechart.setTextAntiAlias(true);
+ jfrechart.removeLegend();
+ }
+
+ @Override
+ public String toString() {
+ return getKey();
+ }
+
+ /**
+ * Helper to set color of series. If the parameter colorsHex is null, then default Sonar colors are used.
+ */
+ protected void configureColors(Values2D dataset, CategoryPlot plot, String[] colorsHex) {
+ Color[] colors = COLORS;
+ if (colorsHex != null && colorsHex.length > 0) {
+ colors = new Color[colorsHex.length];
+ for (int i = 0; i < colorsHex.length; i++) {
+ colors[i] = Color.decode("#" + colorsHex[i]);
+ }
+ }
+
+ dataset.getColumnCount();
+ AbstractRenderer renderer = (AbstractRenderer) plot.getRenderer();
+ for (int i = 0; i < dataset.getColumnCount(); i++) {
+ renderer.setSeriesPaint(i, colors[i % colors.length]);
+
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/charts/Chart.java b/sonar-plugin-api/src/main/java/org/sonar/api/charts/Chart.java
new file mode 100644
index 00000000000..fedd88138ce
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/charts/Chart.java
@@ -0,0 +1,44 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.charts;
+
+import org.sonar.api.ServerSide;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * Extension point to generate charts
+ *
+ * @since 1.10
+ * @deprecated in 4.5.1, replaced by Javascript charts
+ */
+@Deprecated
+@ServerSide
+public interface Chart {
+ String getKey();
+
+ /**
+ * The method to implement to generate the chart
+ *
+ * @param params the chart parameters
+ * @return the image generated
+ */
+ BufferedImage generateImage(ChartParameters params);
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/charts/ChartParameters.java b/sonar-plugin-api/src/main/java/org/sonar/api/charts/ChartParameters.java
new file mode 100644
index 00000000000..e898e621f21
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/charts/ChartParameters.java
@@ -0,0 +1,186 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.charts;
+
+import org.apache.commons.lang.CharEncoding;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.text.StrTokenizer;
+import org.sonar.api.utils.SonarException;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * The class to hold parameters to configure a chart
+ * @since 1.10
+ * @deprecated in 4.5.1, replaced by Javascript charts
+ */
+@Deprecated
+public class ChartParameters {
+ private static final String[] EMPTY = new String[0];
+
+ public static final String PARAM_WIDTH = "w";
+ public static final String PARAM_BACKGROUND_COLOR = "bgc";
+ public static final String PARAM_HEIGHT = "h";
+ public static final int MAX_WIDTH = 900;
+ public static final String PARAM_LOCALE = "locale";
+
+ public static final int MAX_HEIGHT = 900;
+ public static final int DEFAULT_WIDTH = 200;
+
+ public static final int DEFAULT_HEIGHT = 200;
+
+
+ private final Map<String, String> params;
+
+ /**
+ * Creates a ChartParameter based on a list of parameters
+ * @param params the list of parameters
+ */
+ public ChartParameters(Map<String, String> params) {
+ this.params = params;
+ }
+
+ /**
+ * Creates a Chartparameter based on a query string with a format key1=value1&key2=value2...
+ *
+ * @param queryString string
+ */
+ public ChartParameters(String queryString) {
+ this.params = new HashMap<>();
+ String[] groups = StringUtils.split(queryString, "&");
+ for (String group : groups) {
+ String[] keyval = StringUtils.split(group, "=");
+ params.put(keyval[0], keyval[1]);
+ }
+ }
+
+ /**
+ * Shortcut to getValue with no decoding and no default value
+ * @param key the param ket
+ * @return the value of the param
+ */
+ public String getValue(String key) {
+ return getValue(key, "", false);
+ }
+
+ /**
+ * Returns the [decoded or not] value of a param from its key or the default value
+ * if id does not exist
+ *
+ * @param key the param ket
+ * @param defaultValue the default value if not exist
+ * @param decode whther the value should be decoded
+ * @return the value of the param
+ */
+
+ public String getValue(String key, String defaultValue, boolean decode) {
+ String val = params.get(key);
+ if (decode) {
+ val = decode(val);
+ }
+ if (val == null) {
+ val = defaultValue;
+ }
+ return val;
+ }
+
+ /**
+ * Returns an array of a param values, given its key and the values delimiter
+ *
+ * @param key the param key
+ * @param delimiter the values delimiter
+ * @return the list of vaalues
+ */
+ public String[] getValues(String key, String delimiter) {
+ String value = params.get(key);
+ if (value != null) {
+ return StringUtils.split(value, delimiter);
+ }
+ return EMPTY;
+ }
+
+ /**
+ * Returns an array of a param values, given its key and the values delimiter
+ * Values can be decoded or not
+ *
+ * @param key the param key
+ * @param delimiter the values delimiter
+ * @param decode whether to decode values
+ * @return the list of vaalues
+ */
+ public String[] getValues(String key, String delimiter, boolean decode) {
+ String value = params.get(key);
+ if (value != null) {
+ if (decode) {
+ value = decode(value);
+ }
+ return new StrTokenizer(value, delimiter).setIgnoreEmptyTokens(false).getTokenArray();
+ }
+ return EMPTY;
+ }
+
+ /**
+ * Get the chart width
+ *
+ * @return width
+ */
+ public int getWidth() {
+ int width = Integer.parseInt(getValue(PARAM_WIDTH, "" + DEFAULT_WIDTH, false));
+ return Math.min(width, MAX_WIDTH);
+ }
+
+ /**
+ * Get the chart height
+ *
+ * @return height
+ */
+ public int getHeight() {
+ int height = Integer.parseInt(getValue(PARAM_HEIGHT, "" + DEFAULT_HEIGHT, false));
+ return Math.min(height, MAX_HEIGHT);
+ }
+
+ /**
+ * Get the Locale
+ *
+ * @return Locale
+ */
+ public Locale getLocale() {
+ String locale = getValue(PARAM_LOCALE);
+ if (StringUtils.isNotBlank(locale)) {
+ return new Locale(locale);
+ }
+ return Locale.ENGLISH;
+ }
+
+ private String decode(String val) {
+ if (val != null) {
+ try {
+ val = URLDecoder.decode(val, CharEncoding.UTF_8);
+ } catch (UnsupportedEncodingException e) {
+ throw new SonarException("Decoding chart parameter : " + val, e);
+ }
+ }
+ return val;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/charts/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/charts/package-info.java
new file mode 100644
index 00000000000..358d4bbef40
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/charts/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.api.charts;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java
new file mode 100644
index 00000000000..1629acf498f
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/checks/AnnotationCheckFactory.java
@@ -0,0 +1,176 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.rule.Checks;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.ActiveRuleParam;
+import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.api.utils.FieldUtils2;
+import org.sonar.api.utils.SonarException;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @since 2.3
+ * @deprecated since 4.2 use {@link Checks}
+ */
+@Deprecated
+public final class AnnotationCheckFactory extends CheckFactory {
+
+ private static final String CAN_NOT_INSTANTIATE_THE_CHECK_RELATED_TO_THE_RULE = "Can not instantiate the check related to the rule ";
+ private Map<String, Object> checksByKey = Maps.newHashMap();
+
+ private AnnotationCheckFactory(RulesProfile profile, String repositoryKey, Collection checks) {
+ super(profile, repositoryKey);
+ groupByKey(checks);
+ }
+
+ public static AnnotationCheckFactory create(RulesProfile profile, String repositoryKey, Collection checkClasses) {
+ AnnotationCheckFactory factory = new AnnotationCheckFactory(profile, repositoryKey, checkClasses);
+ factory.init();
+ return factory;
+ }
+
+ private void groupByKey(Collection checks) {
+ for (Object check : checks) {
+ String key = getRuleKey(check);
+ if (key != null) {
+ checksByKey.put(key, check);
+ }
+ }
+ }
+
+ @Override
+ public Object createCheck(ActiveRule activeRule) {
+ Object object = checksByKey.get(activeRule.getConfigKey());
+ if (object != null) {
+ return instantiate(activeRule, object);
+ }
+ return null;
+ }
+
+ private Object instantiate(ActiveRule activeRule, Object checkClassOrInstance) {
+ try {
+ Object check = checkClassOrInstance;
+ if (check instanceof Class) {
+ check = ((Class) checkClassOrInstance).newInstance();
+ }
+ configureFields(activeRule, check);
+ return check;
+
+ } catch (InstantiationException e) {
+ throw new SonarException(CAN_NOT_INSTANTIATE_THE_CHECK_RELATED_TO_THE_RULE + activeRule, e);
+
+ } catch (IllegalAccessException e) {
+ throw new SonarException(CAN_NOT_INSTANTIATE_THE_CHECK_RELATED_TO_THE_RULE + activeRule, e);
+ }
+ }
+
+ private void configureFields(ActiveRule activeRule, Object check) {
+ for (ActiveRuleParam param : activeRule.getActiveRuleParams()) {
+ Field field = getField(check, param.getKey());
+ if (field == null) {
+ throw new SonarException("The field " + param.getKey() + " does not exist or is not annotated with @RuleProperty in the class " + check.getClass().getName());
+ }
+ if (StringUtils.isNotBlank(param.getValue())) {
+ configureField(check, field, param.getValue());
+ }
+ }
+
+ }
+
+ private void configureField(Object check, Field field, String value) {
+ try {
+ field.setAccessible(true);
+
+ if (field.getType().equals(String.class)) {
+ field.set(check, value);
+
+ } else if ("int".equals(field.getType().getSimpleName())) {
+ field.setInt(check, Integer.parseInt(value));
+
+ } else if ("short".equals(field.getType().getSimpleName())) {
+ field.setShort(check, Short.parseShort(value));
+
+ } else if ("long".equals(field.getType().getSimpleName())) {
+ field.setLong(check, Long.parseLong(value));
+
+ } else if ("double".equals(field.getType().getSimpleName())) {
+ field.setDouble(check, Double.parseDouble(value));
+
+ } else if ("boolean".equals(field.getType().getSimpleName())) {
+ field.setBoolean(check, Boolean.parseBoolean(value));
+
+ } else if ("byte".equals(field.getType().getSimpleName())) {
+ field.setByte(check, Byte.parseByte(value));
+
+ } else if (field.getType().equals(Integer.class)) {
+ field.set(check, Integer.parseInt(value));
+
+ } else if (field.getType().equals(Long.class)) {
+ field.set(check, Long.parseLong(value));
+
+ } else if (field.getType().equals(Double.class)) {
+ field.set(check, Double.parseDouble(value));
+
+ } else if (field.getType().equals(Boolean.class)) {
+ field.set(check, Boolean.parseBoolean(value));
+
+ } else {
+ throw new SonarException("The type of the field " + field + " is not supported: " + field.getType());
+ }
+ } catch (IllegalAccessException e) {
+ throw new SonarException("Can not set the value of the field " + field + " in the class: " + check.getClass().getName(), e);
+ }
+ }
+
+ private Field getField(Object check, String key) {
+ List<Field> fields = FieldUtils2.getFields(check.getClass(), true);
+ for (Field field : fields) {
+ RuleProperty propertyAnnotation = field.getAnnotation(RuleProperty.class);
+ if (propertyAnnotation != null && (StringUtils.equals(key, field.getName()) || StringUtils.equals(key, propertyAnnotation.key()))) {
+ return field;
+ }
+ }
+ return null;
+ }
+
+ private String getRuleKey(Object annotatedClassOrObject) {
+ String key = null;
+ Rule ruleAnnotation = AnnotationUtils.getAnnotation(annotatedClassOrObject, Rule.class);
+ if (ruleAnnotation != null) {
+ key = ruleAnnotation.key();
+ }
+ Class clazz = annotatedClassOrObject.getClass();
+ if (annotatedClassOrObject instanceof Class) {
+ clazz = (Class) annotatedClassOrObject;
+ }
+ return StringUtils.defaultIfEmpty(key, clazz.getCanonicalName());
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/checks/CheckFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/checks/CheckFactory.java
new file mode 100644
index 00000000000..c6ad3b45092
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/checks/CheckFactory.java
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import com.google.common.collect.Maps;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRule;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @since 2.3
+ * @deprecated since 4.2 use {@link org.sonar.api.batch.rule.CheckFactory}
+ */
+@Deprecated
+public abstract class CheckFactory<C> {
+
+ private Map<ActiveRule, C> checkByActiveRule = Maps.newIdentityHashMap();
+ private Map<C, ActiveRule> activeRuleByCheck = Maps.newIdentityHashMap();
+ private RulesProfile profile;
+ private String repositoryKey;
+
+ protected CheckFactory(RulesProfile profile, String repositoryKey) {
+ this.repositoryKey = repositoryKey;
+ this.profile = profile;
+ }
+
+ protected void init() {
+ checkByActiveRule.clear();
+ activeRuleByCheck.clear();
+ for (ActiveRule activeRule : profile.getActiveRulesByRepository(repositoryKey)) {
+ C check = createCheck(activeRule);
+ checkByActiveRule.put(activeRule, check);
+ activeRuleByCheck.put(check, activeRule);
+ }
+ }
+
+ abstract C createCheck(ActiveRule activeRule);
+
+ public final String getRepositoryKey() {
+ return repositoryKey;
+ }
+
+ public final Collection<C> getChecks() {
+ return checkByActiveRule.values();
+ }
+
+ public final C getCheck(ActiveRule activeRule) {
+ return checkByActiveRule.get(activeRule);
+ }
+
+ public final ActiveRule getActiveRule(C check) {
+ return activeRuleByCheck.get(check);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/checks/NoSonarFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/checks/NoSonarFilter.java
new file mode 100644
index 00000000000..16aa183e3a5
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/checks/NoSonarFilter.java
@@ -0,0 +1,71 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.batch.IssueFilterChain;
+import org.sonar.api.resources.Resource;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @since 2.1
+ * @deprecated in 3.6. Replaced by {@link org.sonar.api.issue.NoSonarFilter}
+ */
+@Deprecated
+public class NoSonarFilter implements org.sonar.api.issue.batch.IssueFilter {
+
+ private final Map<String, Set<Integer>> noSonarLinesByKey = Maps.newHashMap();
+ private SonarIndex sonarIndex;
+
+ public NoSonarFilter(SonarIndex sonarIndex) {
+ this.sonarIndex = sonarIndex;
+ }
+
+ public void addResource(Resource model, Set<Integer> noSonarLines) {
+ if (model != null && noSonarLines != null) {
+ // Reload resource to handle backward compatibility of resource keys
+ Resource resource = sonarIndex.getResource(model);
+ if (resource != null) {
+ noSonarLinesByKey.put(resource.getEffectiveKey(), noSonarLines);
+ }
+ }
+ }
+
+ @Override
+ public boolean accept(Issue issue, IssueFilterChain chain) {
+ boolean accepted = true;
+ if (issue.line() != null) {
+ Set<Integer> noSonarLines = noSonarLinesByKey.get(issue.componentKey());
+ accepted = noSonarLines == null || !noSonarLines.contains(issue.line());
+ if (!accepted && StringUtils.containsIgnoreCase(issue.ruleKey().rule(), "nosonar")) {
+ accepted = true;
+ }
+ }
+ if (accepted) {
+ accepted = chain.accept(issue);
+ }
+ return accepted;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Java.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Java.java
new file mode 100644
index 00000000000..67b27bb4da8
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Java.java
@@ -0,0 +1,80 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.api.resources;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Java language implementation
+ * This class have been moved in the plugin sonar-java
+ *
+ * @since 1.10
+ * @deprecated in 3.6
+ */
+@Deprecated
+public class Java extends AbstractLanguage {
+
+ public static final Java INSTANCE = new Java();
+
+ /**
+ * Java key
+ */
+ public static final String KEY = "java";
+
+ /**
+ * Java name
+ */
+ public static final String NAME = "Java";
+
+ /**
+ * Default package name for classes without package def
+ */
+ public static final String DEFAULT_PACKAGE_NAME = "[default]";
+
+ /**
+ * Java files knows suffixes
+ */
+ public static final String[] SUFFIXES = {".java", ".jav"};
+
+ /**
+ * Default constructor
+ */
+ public Java() {
+ super(KEY, NAME);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see AbstractLanguage#getFileSuffixes()
+ */
+ @Override
+ public String[] getFileSuffixes() {
+ return SUFFIXES;
+ }
+
+ public static boolean isJavaFile(java.io.File file) {
+ String suffix = "." + StringUtils.lowerCase(StringUtils.substringAfterLast(file.getName(), "."));
+ return ArrayUtils.contains(SUFFIXES, suffix);
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java
new file mode 100644
index 00000000000..5d4c3eadff4
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaFile.java
@@ -0,0 +1,121 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * A class that represents a Java class. This class can either be a Test class or source class
+ *
+ * @since 1.10
+ * @deprecated since 4.2 use {@link org.sonar.api.resources.File}. See
+ * http://docs.codehaus.org/display/SONAR/API+Changes for more details
+ */
+@Deprecated
+public class JavaFile extends Resource {
+
+ @VisibleForTesting
+ JavaFile() {
+ }
+
+ public JavaFile(String packageName, String className) {
+ throw unsupported();
+ }
+
+ public JavaFile(String packageKey, String className, boolean unitTest) {
+ throw unsupported();
+ }
+
+ public JavaFile(String deprecatedKey) {
+ throw unsupported();
+ }
+
+ public JavaFile(String deprecatedKey, boolean unitTest) {
+ throw unsupported();
+ }
+
+ @Override
+ public JavaPackage getParent() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getDescription() {
+ throw unsupported();
+ }
+
+ @Override
+ public Language getLanguage() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getName() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getLongName() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getScope() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getQualifier() {
+ throw unsupported();
+ }
+
+ public boolean isUnitTest() {
+ throw unsupported();
+ }
+
+ @Override
+ public boolean matchFilePattern(String antPattern) {
+ throw unsupported();
+ }
+
+ public static JavaFile fromIOFile(File file, Project module, boolean unitTest) {
+ throw unsupported();
+ }
+
+ public static JavaFile fromRelativePath(String relativePath, boolean unitTest) {
+ throw unsupported();
+ }
+
+ public static JavaFile fromIOFile(File file, List<File> sourceDirs, boolean unitTest) {
+ throw unsupported();
+ }
+
+ public static JavaFile fromAbsolutePath(String path, List<File> sourceDirs, boolean unitTest) {
+ throw unsupported();
+ }
+
+ private static UnsupportedOperationException unsupported() {
+ throw new UnsupportedOperationException("Not supported since v4.2. See http://redirect.sonarsource.com/doc/api-changes.html");
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaPackage.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaPackage.java
new file mode 100644
index 00000000000..28909ce0ae9
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/JavaPackage.java
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+/**
+ * A class that represents a Java package in Sonar
+ *
+ * @since 1.10
+ * @deprecated since 4.2 use {@link Directory} instead
+ */
+@Deprecated
+public class JavaPackage extends Resource {
+
+ public static final String DEFAULT_PACKAGE_NAME = "[default]";
+
+ public JavaPackage() {
+ // For testing
+ }
+
+ public JavaPackage(String deprecatedKey) {
+ throw unsupported();
+ }
+
+ public boolean isDefault() {
+ throw unsupported();
+ }
+
+ @Override
+ public boolean matchFilePattern(String antPattern) {
+ throw unsupported();
+ }
+
+ @Override
+ public String getDescription() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getScope() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getQualifier() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getName() {
+ throw unsupported();
+ }
+
+ @Override
+ public Resource getParent() {
+ throw unsupported();
+ }
+
+ @Override
+ public String getLongName() {
+ throw unsupported();
+ }
+
+ @Override
+ public Language getLanguage() {
+ throw unsupported();
+ }
+
+ private static UnsupportedOperationException unsupported() {
+ throw new UnsupportedOperationException("Not supported since v4.2. See http://redirect.sonarsource.com/doc/api-changes.html");
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Method.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Method.java
new file mode 100644
index 00000000000..0e9b361eed4
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Method.java
@@ -0,0 +1,108 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+/**
+ * @deprecated in 4.2. Only file system components are managed by SQ core (files/directories).
+ */
+@Deprecated
+public class Method extends Resource {
+
+ public static final String SCOPE = Scopes.BLOCK_UNIT;
+
+ protected String qualifier;
+ protected Language language;
+
+ protected Method(String key, String qualifier, Language language) {
+ setKey(key);
+ this.qualifier = qualifier;
+ this.language = language;
+ }
+
+ @Override
+ public String getName() {
+ return getKey();
+ }
+
+ @Override
+ public String getLongName() {
+ return getKey();
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public final Language getLanguage() {
+ return language;
+ }
+
+ @Override
+ public final String getScope() {
+ return SCOPE;
+ }
+
+ @Override
+ public final String getQualifier() {
+ return qualifier;
+ }
+
+ @Override
+ public Resource getParent() {
+ return null;
+ }
+
+ @Override
+ public final boolean matchFilePattern(String antPattern) {
+ return false;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Method)) {
+ return false;
+ }
+ Method method = (Method) o;
+ if (!getKey().equals(method.getKey())) {
+ return false;
+ }
+ if (!qualifier.equals(method.qualifier)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public final int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + qualifier.hashCode();
+ result = 31 * result + getKey().hashCode();
+ return result;
+ }
+
+ public static Method createMethod(String key, Language language) {
+ return new Method(key, Qualifiers.METHOD, language);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectUtils.java
new file mode 100644
index 00000000000..d852edd82d6
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectUtils.java
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+import com.google.common.collect.Lists;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @since 1.10
+ * @deprecated see method comments
+ */
+@Deprecated
+public final class ProjectUtils {
+
+ private ProjectUtils() {
+ // utility class with only static methods
+ }
+
+ /**
+ * @since 2.7
+ * @deprecated in 4.2. Replaced by org.sonar.api.resources.InputFileUtils#toFiles()
+ */
+ @Deprecated
+ public static List<java.io.File> toIoFiles(Collection<InputFile> inputFiles) {
+ List<java.io.File> files = Lists.newArrayList();
+ for (InputFile inputFile : inputFiles) {
+ files.add(inputFile.getFile());
+ }
+ return files;
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java
new file mode 100644
index 00000000000..328b522e7a9
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java
@@ -0,0 +1,119 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.rules;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.PropertyType;
+import org.sonar.api.ServerSide;
+import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.api.utils.FieldUtils2;
+import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @since 2.3
+ * @deprecated in 4.2. Replaced by {@link org.sonar.api.server.rule.RulesDefinitionAnnotationLoader}
+ */
+@Deprecated
+@ServerSide
+public final class AnnotationRuleParser {
+
+ private static final Logger LOG = Loggers.get(AnnotationRuleParser.class);
+
+ public List<Rule> parse(String repositoryKey, Collection<Class> annotatedClasses) {
+ List<Rule> rules = Lists.newArrayList();
+ for (Class annotatedClass : annotatedClasses) {
+ rules.add(create(repositoryKey, annotatedClass));
+ }
+ return rules;
+ }
+
+ private Rule create(String repositoryKey, Class annotatedClass) {
+ org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(annotatedClass, org.sonar.check.Rule.class);
+ if (ruleAnnotation != null) {
+ return toRule(repositoryKey, annotatedClass, ruleAnnotation);
+ }
+ LOG.warn("The class " + annotatedClass.getCanonicalName() + " should be annotated with " + Rule.class);
+ return null;
+ }
+
+ private Rule toRule(String repositoryKey, Class clazz, org.sonar.check.Rule ruleAnnotation) {
+ String ruleKey = StringUtils.defaultIfEmpty(ruleAnnotation.key(), clazz.getCanonicalName());
+ String ruleName = StringUtils.defaultIfEmpty(ruleAnnotation.name(), null);
+ String description = StringUtils.defaultIfEmpty(ruleAnnotation.description(), null);
+ Rule rule = Rule.create(repositoryKey, ruleKey, ruleName);
+ rule.setDescription(description);
+ rule.setSeverity(RulePriority.fromCheckPriority(ruleAnnotation.priority()));
+ rule.setCardinality(ruleAnnotation.cardinality());
+ rule.setStatus(ruleAnnotation.status());
+ rule.setTags(ruleAnnotation.tags());
+
+ List<Field> fields = FieldUtils2.getFields(clazz, true);
+ for (Field field : fields) {
+ addRuleProperty(rule, field);
+ }
+ return rule;
+ }
+
+ private void addRuleProperty(Rule rule, Field field) {
+ org.sonar.check.RuleProperty propertyAnnotation = field.getAnnotation(org.sonar.check.RuleProperty.class);
+ if (propertyAnnotation != null) {
+ String fieldKey = StringUtils.defaultIfEmpty(propertyAnnotation.key(), field.getName());
+ RuleParam param = rule.createParameter(fieldKey);
+ param.setDescription(propertyAnnotation.description());
+ param.setDefaultValue(propertyAnnotation.defaultValue());
+ if (!StringUtils.isBlank(propertyAnnotation.type())) {
+ try {
+ param.setType(PropertyType.valueOf(propertyAnnotation.type().trim()).name());
+ } catch (IllegalArgumentException e) {
+ throw new SonarException("Invalid property type [" + propertyAnnotation.type() + "]", e);
+ }
+ } else {
+ param.setType(guessType(field.getType()).name());
+ }
+ }
+ }
+
+ private static final Function<Class<?>, PropertyType> TYPE_FOR_CLASS = Functions.forMap(
+ ImmutableMap.<Class<?>, PropertyType>builder()
+ .put(Integer.class, PropertyType.INTEGER)
+ .put(int.class, PropertyType.INTEGER)
+ .put(Float.class, PropertyType.FLOAT)
+ .put(float.class, PropertyType.FLOAT)
+ .put(Boolean.class, PropertyType.BOOLEAN)
+ .put(boolean.class, PropertyType.BOOLEAN)
+ .build(),
+ PropertyType.STRING);
+
+ @VisibleForTesting
+ static PropertyType guessType(Class<?> type) {
+ return TYPE_FOR_CLASS.apply(type);
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/RuleRepository.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/RuleRepository.java
new file mode 100644
index 00000000000..e7725ff73d1
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/RuleRepository.java
@@ -0,0 +1,82 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.rules;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.ExtensionPoint;
+import org.sonar.api.ServerSide;
+
+import java.util.List;
+
+/**
+ * @since 2.3
+ * @deprecated in 4.2. Replaced by org.sonar.api.server.rule.RulesDefinition
+ */
+@Deprecated
+@ServerSide
+@ExtensionPoint
+public abstract class RuleRepository {
+
+ private String key;
+ private String language;
+ private String name;
+
+ protected RuleRepository(String key, String language) {
+ this.key = key;
+ this.language = language;
+ }
+
+ public final String getKey() {
+ return key;
+ }
+
+ public final String getLanguage() {
+ return language;
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ public final String getName(boolean useKeyIfEmpty) {
+ if (useKeyIfEmpty) {
+ return StringUtils.defaultIfEmpty(name, key);
+ }
+ return name;
+ }
+
+ public final RuleRepository setName(String s) {
+ this.name = s;
+ return this;
+ }
+
+ public abstract List<Rule> createRules();
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("key", key)
+ .append("language", language)
+ .append("name", name)
+ .toString();
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java
new file mode 100644
index 00000000000..b7a0a3772c3
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java
@@ -0,0 +1,235 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.rules;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.io.Closeables;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.CharEncoding;
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.staxmate.SMInputFactory;
+import org.codehaus.staxmate.in.SMHierarchicCursor;
+import org.codehaus.staxmate.in.SMInputCursor;
+import org.sonar.api.PropertyType;
+import org.sonar.api.ServerSide;
+import org.sonar.api.utils.SonarException;
+import org.sonar.check.Cardinality;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @since 2.3
+ * @deprecated in 4.2. Replaced by org.sonar.api.server.rule.RulesDefinition and org.sonar.api.server.rule.RulesDefinitionXmlLoader
+ */
+@Deprecated
+@ServerSide
+public final class XMLRuleParser {
+ private static final Map<String, String> TYPE_MAP = typeMapWithDeprecatedValues();
+
+ public List<Rule> parse(File file) {
+ Reader reader = null;
+ try {
+ reader = new InputStreamReader(FileUtils.openInputStream(file), CharEncoding.UTF_8);
+ return parse(reader);
+
+ } catch (IOException e) {
+ throw new SonarException("Fail to load the file: " + file, e);
+
+ } finally {
+ Closeables.closeQuietly(reader);
+ }
+ }
+
+ /**
+ * Warning : the input stream is closed in this method
+ */
+ public List<Rule> parse(InputStream input) {
+ Reader reader = null;
+ try {
+ reader = new InputStreamReader(input, CharEncoding.UTF_8);
+ return parse(reader);
+
+ } catch (IOException e) {
+ throw new SonarException("Fail to load the xml stream", e);
+
+ } finally {
+ Closeables.closeQuietly(reader);
+ }
+ }
+
+ public List<Rule> parse(Reader reader) {
+ XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
+ xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
+ xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
+ // just so it won't try to load DTD in if there's DOCTYPE
+ xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
+ xmlFactory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
+ SMInputFactory inputFactory = new SMInputFactory(xmlFactory);
+ try {
+ SMHierarchicCursor rootC = inputFactory.rootElementCursor(reader);
+ rootC.advance(); // <rules>
+ List<Rule> rules = new ArrayList<>();
+
+ SMInputCursor rulesC = rootC.childElementCursor("rule");
+ while (rulesC.getNext() != null) {
+ // <rule>
+ Rule rule = Rule.create();
+ rules.add(rule);
+
+ processRule(rule, rulesC);
+ }
+ return rules;
+
+ } catch (XMLStreamException e) {
+ throw new SonarException("XML is not valid", e);
+ }
+ }
+
+ private static void processRule(Rule rule, SMInputCursor ruleC) throws XMLStreamException {
+ /* BACKWARD COMPATIBILITY WITH DEPRECATED FORMAT */
+ String keyAttribute = ruleC.getAttrValue("key");
+ if (StringUtils.isNotBlank(keyAttribute)) {
+ rule.setKey(StringUtils.trim(keyAttribute));
+ }
+
+ /* BACKWARD COMPATIBILITY WITH DEPRECATED FORMAT */
+ String priorityAttribute = ruleC.getAttrValue("priority");
+ if (StringUtils.isNotBlank(priorityAttribute)) {
+ rule.setSeverity(RulePriority.valueOf(StringUtils.trim(priorityAttribute)));
+ }
+
+ List<String> tags = Lists.newArrayList();
+ SMInputCursor cursor = ruleC.childElementCursor();
+
+ while (cursor.getNext() != null) {
+ String nodeName = cursor.getLocalName();
+
+ if (StringUtils.equalsIgnoreCase("name", nodeName)) {
+ rule.setName(StringUtils.trim(cursor.collectDescendantText(false)));
+
+ } else if (StringUtils.equalsIgnoreCase("description", nodeName)) {
+ rule.setDescription(StringUtils.trim(cursor.collectDescendantText(false)));
+
+ } else if (StringUtils.equalsIgnoreCase("key", nodeName)) {
+ rule.setKey(StringUtils.trim(cursor.collectDescendantText(false)));
+
+ } else if (StringUtils.equalsIgnoreCase("configKey", nodeName)) {
+ rule.setConfigKey(StringUtils.trim(cursor.collectDescendantText(false)));
+
+ } else if (StringUtils.equalsIgnoreCase("priority", nodeName)) {
+ rule.setSeverity(RulePriority.valueOf(StringUtils.trim(cursor.collectDescendantText(false))));
+
+ } else if (StringUtils.equalsIgnoreCase("cardinality", nodeName)) {
+ rule.setCardinality(Cardinality.valueOf(StringUtils.trim(cursor.collectDescendantText(false))));
+
+ } else if (StringUtils.equalsIgnoreCase("status", nodeName)) {
+ rule.setStatus(StringUtils.trim(cursor.collectDescendantText(false)));
+
+ } else if (StringUtils.equalsIgnoreCase("param", nodeName)) {
+ processParameter(rule, cursor);
+
+ } else if (StringUtils.equalsIgnoreCase("tag", nodeName)) {
+ tags.add(StringUtils.trim(cursor.collectDescendantText(false)));
+ }
+ }
+ if (Strings.isNullOrEmpty(rule.getKey())) {
+ throw new SonarException("Node <key> is missing in <rule>");
+ }
+ rule.setTags(tags.toArray(new String[tags.size()]));
+ }
+
+ private static void processParameter(Rule rule, SMInputCursor ruleC) throws XMLStreamException {
+ RuleParam param = rule.createParameter();
+
+ String keyAttribute = ruleC.getAttrValue("key");
+ if (StringUtils.isNotBlank(keyAttribute)) {
+ /* BACKWARD COMPATIBILITY WITH DEPRECATED FORMAT */
+ param.setKey(StringUtils.trim(keyAttribute));
+ }
+
+ String typeAttribute = ruleC.getAttrValue("type");
+ if (StringUtils.isNotBlank(typeAttribute)) {
+ /* BACKWARD COMPATIBILITY WITH DEPRECATED FORMAT */
+ param.setType(type(StringUtils.trim(typeAttribute)));
+ }
+
+ SMInputCursor paramC = ruleC.childElementCursor();
+ while (paramC.getNext() != null) {
+ String propNodeName = paramC.getLocalName();
+ String propText = StringUtils.trim(paramC.collectDescendantText(false));
+ if (StringUtils.equalsIgnoreCase("key", propNodeName)) {
+ param.setKey(propText);
+
+ } else if (StringUtils.equalsIgnoreCase("description", propNodeName)) {
+ param.setDescription(propText);
+
+ } else if (StringUtils.equalsIgnoreCase("type", propNodeName)) {
+ param.setType(type(propText));
+
+ } else if (StringUtils.equalsIgnoreCase("defaultValue", propNodeName)) {
+ param.setDefaultValue(propText);
+ }
+ }
+ if (Strings.isNullOrEmpty(param.getKey())) {
+ throw new SonarException("Node <key> is missing in <param>");
+ }
+ }
+
+ private static Map<String, String> typeMapWithDeprecatedValues() {
+ Map<String, String> map = Maps.newHashMap();
+ map.put("i", PropertyType.INTEGER.name());
+ map.put("s", PropertyType.STRING.name());
+ map.put("b", PropertyType.BOOLEAN.name());
+ map.put("r", PropertyType.REGULAR_EXPRESSION.name());
+ map.put("s{}", "s{}");
+ map.put("i{}", "i{}");
+ for (PropertyType propertyType : PropertyType.values()) {
+ map.put(propertyType.name(), propertyType.name());
+ }
+ return map;
+ }
+
+ @VisibleForTesting
+ static String type(String type) {
+ String validType = TYPE_MAP.get(type);
+ if (null != validType) {
+ return validType;
+ }
+
+ if (type.matches(".\\[.+\\]")) {
+ return type;
+ }
+ throw new SonarException("Invalid property type [" + type + "]");
+ }
+
+}
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..addab4dca69
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/AbstractDashboardWidget.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+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 {
+
+ @Override
+ public String getId() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public String getTitle() {
+ return getClass().getSimpleName();
+ }
+}
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..2add1884001
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Section.java
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+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/test/java/org/sonar/api/batch/SquidUtilsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/SquidUtilsTest.java
new file mode 100644
index 00000000000..643d24d575e
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/SquidUtilsTest.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch;
+
+import org.junit.Test;
+import org.sonar.api.resources.JavaFile;
+
+public class SquidUtilsTest {
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void convertJavaFileKeyFromSquidFormat() {
+ SquidUtils.convertJavaFileKeyFromSquidFormat("java/lang/String");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void shouldConvertJavaPackageKeyFromSquidFormat() {
+ SquidUtils.convertJavaPackageKeyFromSquidFormat("java/lang");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void shouldConvertToSquidKeyFormat() {
+ SquidUtils.convertToSquidKeyFormat(new JavaFile("com.foo.Bar"));
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/charts/ChartParametersTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/charts/ChartParametersTest.java
new file mode 100644
index 00000000000..7ef39e3b730
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/charts/ChartParametersTest.java
@@ -0,0 +1,79 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.charts;
+
+import org.junit.Test;
+
+import java.util.Locale;
+
+import static org.junit.Assert.*;
+
+public class ChartParametersTest {
+ @Test
+ public void shouldForbidHighSizeForSecurityReasons() {
+ String url = ChartParameters.PARAM_WIDTH + "=100000&" + ChartParameters.PARAM_HEIGHT + "=9999999";
+ ChartParameters params = new ChartParameters(url);
+ assertEquals(ChartParameters.MAX_WIDTH, params.getWidth());
+ assertEquals(ChartParameters.MAX_HEIGHT, params.getHeight());
+ }
+
+ @Test
+ public void shouldReadImageSizeFromParameters() {
+ String url = ChartParameters.PARAM_WIDTH + "=200&" + ChartParameters.PARAM_HEIGHT + "=300";
+ ChartParameters params = new ChartParameters(url);
+ assertEquals(200, params.getWidth());
+ assertEquals(300, params.getHeight());
+ }
+
+ @Test
+ public void shouldGetDefaultSizesIfNoParameters() {
+ ChartParameters params = new ChartParameters("foo=bar");
+ assertEquals(ChartParameters.DEFAULT_WIDTH, params.getWidth());
+ assertEquals(ChartParameters.DEFAULT_HEIGHT, params.getHeight());
+ }
+
+ @Test
+ public void shouldDecodeValue() {
+ ChartParameters params = new ChartParameters("foo=0%3D10,3%3D8");
+ assertEquals("0=10,3=8", params.getValue("foo", "", true));
+ assertEquals("0%3D10,3%3D8", params.getValue("foo"));
+ assertNull(params.getValue("bar", null, true));
+ }
+
+ @Test
+ public void shouldDecodeValues() {
+ ChartParameters params = new ChartParameters("foo=0%3D10,3%3D8|5%3D5,7%3D17");
+ assertArrayEquals(new String[]{"0%3D10,3%3D8", "5%3D5,7%3D17"}, params.getValues("foo", "|"));
+ assertArrayEquals(new String[]{"0=10,3=8", "5=5,7=17"}, params.getValues("foo", "|", true));
+ assertArrayEquals(new String[0], params.getValues("bar", "|", true));
+ }
+
+ @Test
+ public void getLocale() {
+ ChartParameters params = new ChartParameters("foo=0&locale=fr");
+ assertEquals(Locale.FRENCH, params.getLocale());
+
+ params = new ChartParameters("foo=0&locale=fr-CH");
+ assertEquals("fr-ch", params.getLocale().getLanguage());
+
+ params = new ChartParameters("foo=0");
+ assertEquals(Locale.ENGLISH, params.getLocale());
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/AbstractCheck.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/AbstractCheck.java
new file mode 100644
index 00000000000..fbdda5849f6
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/AbstractCheck.java
@@ -0,0 +1,32 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.RuleProperty;
+
+abstract class AbstractCheck {
+
+ @RuleProperty
+ private Integer max;
+
+ public Integer getMax() {
+ return max;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/AnnotationCheckFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/AnnotationCheckFactoryTest.java
new file mode 100644
index 00000000000..f783eade75f
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/AnnotationCheckFactoryTest.java
@@ -0,0 +1,199 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.utils.SonarException;
+
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+public class AnnotationCheckFactoryTest {
+
+ @org.junit.Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void createCheckWithoutProperties() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ ActiveRule activeRule = profile.activateRule(Rule.create("repo", "org.sonar.api.checks.CheckWithoutProperties", ""), null);
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithoutProperties.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertNotNull(check);
+ assertThat(check).isInstanceOf(CheckWithoutProperties.class);
+ }
+
+ @Test
+ public void createCheckWithStringProperty() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithStringProperty", "");
+ rule.createParameter("pattern");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("pattern", "foo");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithStringProperty.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertNotNull(check);
+ assertThat(check).isInstanceOf(CheckWithStringProperty.class);
+ assertThat(((CheckWithStringProperty) check).getPattern()).isEqualTo("foo");
+ }
+
+ @Test
+ public void failIfMissingProperty() {
+ thrown.expect(SonarException.class);
+
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithStringProperty", "");
+ rule.createParameter("unknown");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("unknown", "bar");
+ AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithStringProperty.class));
+ }
+
+ @Test
+ public void createCheckWithPrimitiveProperties() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithPrimitiveProperties", "");
+ rule.createParameter("max");
+ rule.createParameter("ignore");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ activeRule.setParameter("ignore", "true");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithPrimitiveProperties.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((CheckWithPrimitiveProperties) check).getMax()).isEqualTo(300);
+ assertThat(((CheckWithPrimitiveProperties) check).isIgnore()).isTrue();
+ }
+
+ @Test
+ public void createCheckWithIntegerProperty() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithIntegerProperty", "");
+ rule.createParameter("max");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithIntegerProperty.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((CheckWithIntegerProperty) check).getMax()).isEqualTo(300);
+ }
+
+ /**
+ * SONAR-3164
+ */
+ @Test
+ public void setValueOfInheritedField() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.ImplementedCheck", "");
+ rule.createParameter("max");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(ImplementedCheck.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((ImplementedCheck) check).getMax()).isEqualTo(300);
+ }
+
+ @Test
+ public void failIfPropertyTypeIsNotSupported() {
+ thrown.expect(SonarException.class);
+
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithUnsupportedPropertyType", "");
+ rule.createParameter("max");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("max", "300");
+ AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithUnsupportedPropertyType.class));
+ }
+
+ @Test
+ public void shouldOverridePropertyKey() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithOverriddenPropertyKey", "");
+ rule.createParameter("maximum");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("maximum", "300");
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithOverriddenPropertyKey.class));
+
+ Object check = factory.getCheck(activeRule);
+ assertThat(((CheckWithOverriddenPropertyKey) check).getMax()).isEqualTo(300);
+ }
+
+ @Test
+ public void shouldWorkWithClonedRules() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "CheckWithKey", "");
+ Rule clonedRule = Rule.create("repo", "CheckWithKey_2", "").setConfigKey("CheckWithKey").setTemplate(rule);
+
+ profile.activateRule(rule, null);
+ profile.activateRule(clonedRule, null);
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.<Class>asList(CheckWithKey.class));
+
+ assertThat(factory.getChecks()).doesNotContain(new Object[] {null});
+ }
+
+ /**
+ * SONAR-2900
+ */
+ @Test
+ public void create_accept_objects() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ ActiveRule activeRule = profile.activateRule(Rule.create("repo", "org.sonar.api.checks.CheckWithoutProperties", ""), null);
+ CheckWithoutProperties checkInstance = new CheckWithoutProperties();
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.asList(checkInstance));
+
+ Object check = factory.getCheck(activeRule);
+ assertNotNull(check);
+ assertSame(check, checkInstance);
+ }
+
+ @Test
+ public void create_instance_with_string_property() {
+ RulesProfile profile = RulesProfile.create("repo", "java");
+ Rule rule = Rule.create("repo", "org.sonar.api.checks.CheckWithStringProperty", "");
+ rule.createParameter("pattern");
+
+ ActiveRule activeRule = profile.activateRule(rule, null);
+ activeRule.setParameter("pattern", "foo");
+ CheckWithStringProperty checkInstance = new CheckWithStringProperty();
+ AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, "repo", Arrays.asList(checkInstance));
+
+ Object check = factory.getCheck(activeRule);
+ assertNotNull(check);
+ assertSame(check, checkInstance);
+ assertThat(checkInstance.getPattern()).isEqualTo("foo");
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithIntegerProperty.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithIntegerProperty.java
new file mode 100644
index 00000000000..1e48ebf494e
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithIntegerProperty.java
@@ -0,0 +1,33 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.*;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithIntegerProperty {
+
+ @RuleProperty
+ private Integer max;
+
+ public Integer getMax() {
+ return max;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithKey.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithKey.java
new file mode 100644
index 00000000000..47ac8e601f7
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithKey.java
@@ -0,0 +1,28 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(key = "CheckWithKey", priority = Priority.CRITICAL)
+public class CheckWithKey {
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithOverriddenPropertyKey.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithOverriddenPropertyKey.java
new file mode 100644
index 00000000000..7677ce5f791
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithOverriddenPropertyKey.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithOverriddenPropertyKey{
+
+ @RuleProperty(key = "maximum")
+ private int max = 50;
+
+ public int getMax() {
+ return max;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithPrimitiveProperties.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithPrimitiveProperties.java
new file mode 100644
index 00000000000..f33308bf5b4
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithPrimitiveProperties.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithPrimitiveProperties {
+
+ @RuleProperty(description = "Maximum threshold")
+ private int max = 50;
+
+ @RuleProperty
+ private boolean ignore;
+
+ public int getMax() {
+ return max;
+ }
+
+ public boolean isIgnore() {
+ return ignore;
+ }
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithStringProperty.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithStringProperty.java
new file mode 100644
index 00000000000..260fd41779a
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithStringProperty.java
@@ -0,0 +1,36 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithStringProperty {
+
+ @RuleProperty
+ private String pattern;
+
+ public String getPattern() {
+ return pattern;
+ }
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithUnsupportedPropertyType.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithUnsupportedPropertyType.java
new file mode 100644
index 00000000000..fd4def57f8d
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithUnsupportedPropertyType.java
@@ -0,0 +1,32 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.check.RuleProperty;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithUnsupportedPropertyType {
+
+ @RuleProperty
+ private StringBuilder max = null;
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithoutProperties.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithoutProperties.java
new file mode 100644
index 00000000000..b8facf9371a
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/CheckWithoutProperties.java
@@ -0,0 +1,29 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(priority = Priority.CRITICAL)
+class CheckWithoutProperties {
+
+}
+
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/ImplementedCheck.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/ImplementedCheck.java
new file mode 100644
index 00000000000..cb3c78d5793
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/ImplementedCheck.java
@@ -0,0 +1,28 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+
+@Rule(priority = Priority.CRITICAL)
+class ImplementedCheck extends AbstractCheck {
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java
new file mode 100644
index 00000000000..8656fa5d48a
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java
@@ -0,0 +1,90 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.checks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.batch.IssueFilterChain;
+import org.sonar.api.resources.File;
+import org.sonar.api.rule.RuleKey;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class NoSonarFilterTest {
+
+ private SonarIndex sonarIndex = mock(SonarIndex.class);
+ NoSonarFilter filter = new NoSonarFilter(sonarIndex);
+ private File javaFile;
+ IssueFilterChain chain = mock(IssueFilterChain.class);
+
+ @Before
+ public void prepare() {
+ when(chain.accept(isA(Issue.class))).thenReturn(true);
+ javaFile = File.create("org/foo/Bar.java");
+ javaFile.setEffectiveKey("struts:org/foo/Bar.java");
+ when(sonarIndex.getResource(javaFile)).thenReturn(javaFile);
+ }
+
+ @Test
+ public void ignoreLinesCommentedWithNoSonar() {
+ Set<Integer> noSonarLines = new HashSet<>();
+ noSonarLines.add(31);
+ noSonarLines.add(55);
+ filter.addResource(javaFile, noSonarLines);
+
+ Issue issue = mock(Issue.class);
+ when(issue.componentKey()).thenReturn("struts:org/foo/Bar.java");
+ when(issue.ruleKey()).thenReturn(RuleKey.of("squid", "Foo"));
+
+ // violation on class
+ assertThat(filter.accept(issue, chain)).isTrue();
+
+ // violation on lines
+ when(issue.line()).thenReturn(30);
+ assertThat(filter.accept(issue, chain)).isTrue();
+ when(issue.line()).thenReturn(31);
+ assertThat(filter.accept(issue, chain)).isFalse();
+ }
+
+ @Test
+ public void should_accept_violations_from_no_sonar_rules() {
+ // The "No Sonar" rule logs violations on the lines that are flagged with "NOSONAR" !!
+
+ Set<Integer> noSonarLines = new HashSet<>();
+ noSonarLines.add(31);
+ filter.addResource(javaFile, noSonarLines);
+
+ Issue issue = mock(Issue.class);
+ when(issue.componentKey()).thenReturn("struts:org.apache.Action");
+ when(issue.ruleKey()).thenReturn(RuleKey.of("squid", "NoSonarCheck"));
+
+ when(issue.line()).thenReturn(31);
+ assertThat(filter.accept(issue, chain)).isTrue();
+
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaFileTest.java
new file mode 100644
index 00000000000..017e6c4a34b
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaFileTest.java
@@ -0,0 +1,114 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+import org.junit.Test;
+
+import java.util.List;
+
+public class JavaFileTest {
+
+ JavaFile javaFile = new JavaFile();
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testConstructor() {
+ JavaFile javaClass = new JavaFile("", "");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testConstructor2() {
+ JavaFile javaClass = new JavaFile("", "", true);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testConstructor3() {
+ JavaFile javaClass = new JavaFile("");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testConstructor4() {
+ JavaFile javaClass = new JavaFile("", true);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetParent() {
+ javaFile.getParent();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetDescription() {
+ javaFile.getDescription();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetLanguage() {
+ javaFile.getLanguage();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetName() {
+ javaFile.getName();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetLongName() {
+ javaFile.getLongName();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetScope() {
+ javaFile.getScope();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetQualifier() {
+ javaFile.getQualifier();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testIsUnitTest() {
+ javaFile.isUnitTest();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testMathFilePattern() {
+ javaFile.matchFilePattern("");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void fromIoFile1() {
+ JavaFile.fromIOFile(null, (Project) null, true);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void fromIoFile2() {
+ JavaFile.fromIOFile(null, (List<java.io.File>) null, true);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void fromRelativePath() {
+ JavaFile.fromRelativePath("", false);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void fromAbsolutePath() {
+ JavaFile.fromAbsolutePath("", (List<java.io.File>) null, false);
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaPackageTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaPackageTest.java
new file mode 100644
index 00000000000..10479b91229
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaPackageTest.java
@@ -0,0 +1,78 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+import org.junit.Test;
+
+public class JavaPackageTest {
+
+ JavaPackage javaPackage = new JavaPackage();
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testConstructor() {
+ new JavaPackage("");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetParent() {
+ javaPackage.getParent();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetDescription() {
+ javaPackage.getDescription();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetLanguage() {
+ javaPackage.getLanguage();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetName() {
+ javaPackage.getName();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetLongName() {
+ javaPackage.getLongName();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetScope() {
+ javaPackage.getScope();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testGetQualifier() {
+ javaPackage.getQualifier();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testIsUnitTest() {
+ javaPackage.isDefault();
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testMathFilePattern() {
+ javaPackage.matchFilePattern("");
+ }
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaTest.java
new file mode 100644
index 00000000000..f77fba190b1
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/JavaTest.java
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class JavaTest {
+
+ @Test
+ public void test() {
+ Java language = new Java();
+ assertThat(language.getFileSuffixes()).isEqualTo(new String[] {".java", ".jav"});
+
+ assertThat(Java.isJavaFile(new java.io.File("Example.java"))).isTrue();
+ assertThat(Java.isJavaFile(new java.io.File("Example.JAVA"))).isTrue();
+ assertThat(Java.isJavaFile(new java.io.File("Example.jav"))).isTrue();
+ assertThat(Java.isJavaFile(new java.io.File("Example.Jav"))).isTrue();
+ assertThat(Java.isJavaFile(new java.io.File("Example.notjava"))).isFalse();
+ }
+
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/MethodTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/MethodTest.java
new file mode 100644
index 00000000000..8d8c7b66f80
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/MethodTest.java
@@ -0,0 +1,46 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.resources;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+public class MethodTest {
+
+ @Test
+ public void shouldAcceptOverridding() {
+ Method method = Method.createMethod("Foo.foo()", Java.INSTANCE);
+ Method fakeMethod = new FakeMethod("Foo.foo()");
+
+ assertThat(method.equals(fakeMethod), is(true));
+ assertThat(fakeMethod.equals(method), is(true));
+
+ assertThat(method.hashCode(), is(fakeMethod.hashCode()));
+ assertThat(fakeMethod.hashCode(), is(method.hashCode()));
+ }
+
+ static class FakeMethod extends Method {
+ protected FakeMethod(String key) {
+ super(key, Qualifiers.METHOD, Java.INSTANCE);
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/rules/AnnotationRuleParserTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/rules/AnnotationRuleParserTest.java
new file mode 100644
index 00000000000..6f5f7c9c9bd
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/rules/AnnotationRuleParserTest.java
@@ -0,0 +1,171 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.rules;
+
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.PropertyType;
+import org.sonar.api.utils.SonarException;
+import org.sonar.check.Priority;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AnnotationRuleParserTest {
+
+ @org.junit.Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+ @Test
+ public void rule_with_property() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithProperty.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo("foo");
+ assertThat(rule.getName()).isEqualTo("bar");
+ assertThat(rule.getDescription()).isEqualTo("Foo Bar");
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.BLOCKER);
+ assertThat(rule.getStatus()).isEqualTo(Rule.STATUS_READY);
+ assertThat(rule.getParams()).hasSize(1);
+
+ RuleParam prop = rule.getParam("property");
+ assertThat(prop.getKey()).isEqualTo("property");
+ assertThat(prop.getDescription()).isEqualTo("Ignore ?");
+ assertThat(prop.getDefaultValue()).isEqualTo("false");
+ assertThat(prop.getType()).isEqualTo(PropertyType.STRING.name());
+ }
+
+ @Test
+ public void rule_with_integer_property() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithIntegerProperty.class);
+
+ RuleParam prop = rules.get(0).getParam("property");
+ assertThat(prop.getDescription()).isEqualTo("Max");
+ assertThat(prop.getDefaultValue()).isEqualTo("12");
+ assertThat(prop.getType()).isEqualTo(PropertyType.INTEGER.name());
+ }
+
+ @Test
+ public void rule_with_text_property() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithTextProperty.class);
+
+ RuleParam prop = rules.get(0).getParam("property");
+ assertThat(prop.getDescription()).isEqualTo("text");
+ assertThat(prop.getDefaultValue()).isEqualTo("Long text");
+ assertThat(prop.getType()).isEqualTo(PropertyType.TEXT.name());
+ }
+
+ @Test
+ public void should_reject_invalid_property_types() {
+ exception.expect(SonarException.class);
+ exception.expectMessage("Invalid property type [INVALID]");
+
+ parseAnnotatedClass(RuleWithInvalidPropertyType.class);
+ }
+
+ @Test
+ public void should_recognize_type() {
+ assertThat(AnnotationRuleParser.guessType(Integer.class)).isEqualTo(PropertyType.INTEGER);
+ assertThat(AnnotationRuleParser.guessType(int.class)).isEqualTo(PropertyType.INTEGER);
+ assertThat(AnnotationRuleParser.guessType(Float.class)).isEqualTo(PropertyType.FLOAT);
+ assertThat(AnnotationRuleParser.guessType(float.class)).isEqualTo(PropertyType.FLOAT);
+ assertThat(AnnotationRuleParser.guessType(Boolean.class)).isEqualTo(PropertyType.BOOLEAN);
+ assertThat(AnnotationRuleParser.guessType(boolean.class)).isEqualTo(PropertyType.BOOLEAN);
+ assertThat(AnnotationRuleParser.guessType(String.class)).isEqualTo(PropertyType.STRING);
+ assertThat(AnnotationRuleParser.guessType(Object.class)).isEqualTo(PropertyType.STRING);
+ }
+
+ @Test
+ public void rule_without_name_nor_description() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithoutNameNorDescription.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo("foo");
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
+ assertThat(rule.getName()).isNull();
+ assertThat(rule.getDescription()).isNull();
+ }
+
+ @Test
+ public void rule_without_key() {
+ List<Rule> rules = parseAnnotatedClass(RuleWithoutKey.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo(RuleWithoutKey.class.getCanonicalName());
+ assertThat(rule.getName()).isEqualTo("foo");
+ assertThat(rule.getDescription()).isNull();
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
+ }
+
+ @Test
+ public void overridden_rule() {
+ List<Rule> rules = parseAnnotatedClass(OverridingRule.class);
+ assertThat(rules).hasSize(1);
+ Rule rule = rules.get(0);
+ assertThat(rule.getKey()).isEqualTo("overriding_foo");
+ assertThat(rule.getName()).isEqualTo("Overriding Foo");
+ assertThat(rule.getDescription()).isNull();
+ assertThat(rule.getSeverity()).isEqualTo(RulePriority.MAJOR);
+ assertThat(rule.getParams()).hasSize(2);
+ }
+
+ private List<Rule> parseAnnotatedClass(Class annotatedClass) {
+ return new AnnotationRuleParser().parse("repo", Collections.singleton(annotatedClass));
+ }
+
+ @org.sonar.check.Rule(name = "foo")
+ static class RuleWithoutKey {
+ }
+
+ @org.sonar.check.Rule(key = "foo")
+ static class RuleWithoutNameNorDescription {
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithProperty {
+ @org.sonar.check.RuleProperty(description = "Ignore ?", defaultValue = "false")
+ private String property;
+ }
+
+ @org.sonar.check.Rule(key = "overriding_foo", name = "Overriding Foo")
+ static class OverridingRule extends RuleWithProperty {
+ @org.sonar.check.RuleProperty
+ private String additionalProperty;
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithIntegerProperty {
+ @org.sonar.check.RuleProperty(description = "Max", defaultValue = "12")
+ private Integer property;
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithTextProperty {
+ @org.sonar.check.RuleProperty(description = "text", defaultValue = "Long text", type = "TEXT")
+ protected String property;
+ }
+
+ @org.sonar.check.Rule(key = "foo", name = "bar", description = "Foo Bar", status = Rule.STATUS_READY, priority = Priority.BLOCKER)
+ static class RuleWithInvalidPropertyType {
+ @org.sonar.check.RuleProperty(description = "text", defaultValue = "Long text", type = "INVALID")
+ public String property;
+ }
+}