diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
commit | aeadc1f9129274949daaa57738c7c4550bdfbc7b (patch) | |
tree | 08dadf5ef7474fc41d1d48f74648f1ba8b55f34d /plugins/sonar-core-plugin | |
download | sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.tar.gz sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.zip |
SONAR-236 remove deprecated code from checkstyle plugin + display default value of rule parameters in Q profile console
Diffstat (limited to 'plugins/sonar-core-plugin')
194 files changed, 13023 insertions, 0 deletions
diff --git a/plugins/sonar-core-plugin/GWT-Clouds.sh b/plugins/sonar-core-plugin/GWT-Clouds.sh new file mode 100755 index 00000000000..a6746040a6f --- /dev/null +++ b/plugins/sonar-core-plugin/GWT-Clouds.sh @@ -0,0 +1 @@ +mvn gwt:run -DrunTarget=org.sonar.plugins.core.clouds.GwtClouds/test.html
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/GWT-CoverageViewer.sh b/plugins/sonar-core-plugin/GWT-CoverageViewer.sh new file mode 100755 index 00000000000..fccc7aa3f4a --- /dev/null +++ b/plugins/sonar-core-plugin/GWT-CoverageViewer.sh @@ -0,0 +1 @@ +mvn gwt:run -DrunTarget=org.sonar.plugins.core.coverageviewer.CoverageViewer/test.html
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/GWT-DefaultSourceViewer.sh b/plugins/sonar-core-plugin/GWT-DefaultSourceViewer.sh new file mode 100755 index 00000000000..a8f956909e1 --- /dev/null +++ b/plugins/sonar-core-plugin/GWT-DefaultSourceViewer.sh @@ -0,0 +1 @@ +mvn gwt:run -DrunTarget=org.sonar.plugins.core.defaultsourceviewer.GwtDefaultSourceViewer/test.html
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/GWT-DuplicationsViewer.sh b/plugins/sonar-core-plugin/GWT-DuplicationsViewer.sh new file mode 100755 index 00000000000..28d6abee29d --- /dev/null +++ b/plugins/sonar-core-plugin/GWT-DuplicationsViewer.sh @@ -0,0 +1 @@ +mvn gwt:run -DrunTarget=org.sonar.plugins.core.duplicationsviewer.DuplicationsViewer/test.html
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/GWT-Hotspots.sh b/plugins/sonar-core-plugin/GWT-Hotspots.sh new file mode 100755 index 00000000000..a659c47d15e --- /dev/null +++ b/plugins/sonar-core-plugin/GWT-Hotspots.sh @@ -0,0 +1 @@ +mvn gwt:run -DrunTarget=org.sonar.plugins.core.hotspots.GwtHotspots/test.html
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/GWT-TestsViewer.sh b/plugins/sonar-core-plugin/GWT-TestsViewer.sh new file mode 100755 index 00000000000..2ee40ce95a0 --- /dev/null +++ b/plugins/sonar-core-plugin/GWT-TestsViewer.sh @@ -0,0 +1 @@ +mvn gwt:run -DrunTarget=org.sonar.plugins.core.testdetailsviewer.TestsViewer/test.html
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/pom.xml b/plugins/sonar-core-plugin/pom.xml new file mode 100644 index 00000000000..d9aeef72496 --- /dev/null +++ b/plugins/sonar-core-plugin/pom.xml @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar</artifactId> + <version>2.3-SNAPSHOT</version> + <relativePath>../..</relativePath> + </parent> + <groupId>org.codehaus.sonar.plugins</groupId> + <artifactId>sonar-core-plugin</artifactId> + <packaging>sonar-plugin</packaging> + <name>Sonar :: Plugins :: Core</name> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-core</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-gwt-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.gwt</groupId> + <artifactId>gwt-user</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.google.gwt</groupId> + <artifactId>gwt-incubator</artifactId> + <scope>provided</scope> + </dependency> + + <!-- unit tests --> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-testing-harness</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <testResources> + <testResource> + <directory>${basedir}/src/main/resources</directory> + </testResource> + <testResource> + <directory>${basedir}/src/test/resources</directory> + </testResource> + </testResources> + + <plugins> + <plugin> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-packaging-maven-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <pluginKey>core</pluginKey> + <pluginName>Core</pluginName> + <pluginClass>org.sonar.plugins.core.CorePlugin</pluginClass> + </configuration> + </plugin> + <plugin> + <artifactId>maven-deploy-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <forkMode>always</forkMode> + </configuration> + </plugin> + <plugin> + <groupId>com.atlassian.maven.plugins</groupId> + <artifactId>maven-clover2-plugin</artifactId> + <configuration> + <excludes> + <!-- GWT classes --> + <exclude>**/client/**/*.java</exclude> + </excludes> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>gwt-maven-plugin</artifactId> + <executions> + <execution> + <configuration> + <modules> + <module>org.sonar.plugins.core.ui.pageselector.PageSelector</module> + <module>org.sonar.plugins.core.clouds.GwtClouds</module> + <module>org.sonar.plugins.core.violationsviewer.ViolationsViewer</module> + <module>org.sonar.plugins.core.coverageviewer.CoverageViewer</module> + <module>org.sonar.plugins.core.defaultsourceviewer.GwtDefaultSourceViewer</module> + <module>org.sonar.plugins.core.duplicationsviewer.DuplicationsViewer</module> + <module>org.sonar.plugins.core.testdetailsviewer.TestsViewer</module> + <module>org.sonar.plugins.core.hotspots.GwtHotspots</module> + </modules> + <skip>${skipGwt}</skip> + <webappDirectory>${project.build.directory}/classes</webappDirectory> + + <!-- do not break on two lines --> + <extraJvmArgs>-Xmx512m -Dgwt.jjs.permutationWorkerFactory=com.google.gwt.dev.ThreadedPermutationWorkerFactory</extraJvmArgs> + </configuration> + <goals> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java new file mode 100644 index 00000000000..d65ededd9a4 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -0,0 +1,191 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core; + +import org.sonar.api.*; +import org.sonar.api.checks.NoSonarFilter; +import org.sonar.api.resources.Java; +import org.sonar.plugins.core.batch.ExcludedResourceFilter; +import org.sonar.plugins.core.charts.DistributionAreaChart; +import org.sonar.plugins.core.charts.DistributionBarChart; +import org.sonar.plugins.core.charts.XradarChart; +import org.sonar.plugins.core.clouds.Clouds; +import org.sonar.plugins.core.colorizers.JavaColorizerFormat; +import org.sonar.plugins.core.coverageviewer.CoverageViewerDefinition; +import org.sonar.plugins.core.defaultsourceviewer.DefaultSourceViewer; +import org.sonar.plugins.core.duplicationsviewer.DuplicationsViewerDefinition; +import org.sonar.plugins.core.hotspots.Hotspots; +import org.sonar.plugins.core.metrics.UserManagedMetrics; +import org.sonar.plugins.core.purges.*; +import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; +import org.sonar.plugins.core.sensors.*; +import org.sonar.plugins.core.testdetailsviewer.TestsViewerDefinition; +import org.sonar.plugins.core.ui.pageselector.GwtPageSelector; +import org.sonar.plugins.core.violationsviewer.ViolationsViewerDefinition; + +import java.util.ArrayList; +import java.util.List; + +@Properties({ + @Property( + key = CoreProperties.CORE_COVERAGE_PLUGIN_PROPERTY, + defaultValue = "cobertura", + name = "Code coverage plugin", + description = "Key of the code coverage plugin to use.", + project = true, + global = true), + @Property( + key = CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, + defaultValue = "" + CoreProperties.CORE_IMPORT_SOURCES_DEFAULT_VALUE, + name = "Import sources", + description = "Set to false if sources should not be displayed, e.g. for security reasons.", + project = true, + module = true, + global = true), + @Property( + key = CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, + defaultValue = "" + CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE, + name = "Tendency period", + description = TendencyDecorator.PROP_DAYS_DESCRIPTION, + project = false, + global = true), + @Property( + key = CoreProperties.CORE_SKIPPED_MODULES_PROPERTY, + name = "Exclude modules", + description = "Maven artifact ids of modules to exclude (comma-separated).", + project = true, + global = false), + @Property( + key = CoreProperties.CORE_RULE_WEIGHTS_PROPERTY, + defaultValue = CoreProperties.CORE_RULE_WEIGHTS_DEFAULT_VALUE, + name = "Rules weight", + description = "A weight is associated to each priority to calculate the Rules Compliance Index.", + project = false, + global = true), + @Property( + key = CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY, + defaultValue = "" + CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE, + name = "Force user authentication", + description = "Forcing user authentication stops un-logged users to access Sonar.", + project = false, + global = true), + @Property( + key = CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_PROPERTY, + defaultValue = "" + CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_DEAULT_VALUE, + name = "Allow users to sign up online", + description = "Users can sign up online.", + project = false, + global = true), + @Property( + key = CoreProperties.CORE_DEFAULT_GROUP, + defaultValue = CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE, + name = "Default user group", + description = "Any new users will automatically join this group.", + project = false, + global = true + ) +}) +public class CorePlugin implements Plugin { + + public String getKey() { + return CoreProperties.CORE_PLUGIN; + } + + public String getName() { + return "General"; + } + + public String getDescription() { + return ""; + } + + public List getExtensions() { + List extensions = new ArrayList(); + + // languages + extensions.add(Java.class); + + // metrics + extensions.add(UserManagedMetrics.class); + + // pages + extensions.add(GwtPageSelector.class); + extensions.add(DefaultSourceViewer.class); + extensions.add(CoverageViewerDefinition.class); + extensions.add(ViolationsViewerDefinition.class); + extensions.add(DuplicationsViewerDefinition.class); + extensions.add(TestsViewerDefinition.class); + extensions.add(Clouds.class); + extensions.add(Hotspots.class); + + // chart + extensions.add(XradarChart.class); + extensions.add(DistributionBarChart.class); + extensions.add(DistributionAreaChart.class); + + // colorizers + extensions.add(JavaColorizerFormat.class); + + // batch + extensions.add(JavaSourceImporter.class); + extensions.add(ProfileSensor.class); + extensions.add(ProjectLinksSensor.class); + extensions.add(AsynchronousMeasuresSensor.class); + extensions.add(UnitTestDecorator.class); + extensions.add(VersionEventsSensor.class); + extensions.add(CheckAlertThresholds.class); + extensions.add(GenerateAlertEvents.class); + extensions.add(ViolationsDecorator.class); + extensions.add(WeightedViolationsDecorator.class); + extensions.add(ViolationsDensityDecorator.class); + extensions.add(TendencyDecorator.class); + extensions.add(LineCoverageDecorator.class); + extensions.add(CoverageDecorator.class); + extensions.add(BranchCoverageDecorator.class); + extensions.add(UncoveredComplexityDecorator.class); + extensions.add(ApplyProjectRolesDecorator.class); + extensions.add(ExcludedResourceFilter.class); + extensions.add(CommentDensityDecorator.class); + extensions.add(NoSonarFilter.class); + extensions.add(DirectoriesDecorator.class); + extensions.add(FilesDecorator.class); + + + // purges + extensions.add(PurgeOrphanResources.class); + extensions.add(PurgeEntities.class); + extensions.add(PurgeRuleMeasures.class); + extensions.add(PurgeUnprocessed.class); + extensions.add(PurgeDeletedResources.class); + extensions.add(PurgeDeprecatedLast.class); + extensions.add(UnflagLastDoublons.class); + extensions.add(PurgeDisabledResources.class); + extensions.add(PurgeResourceRoles.class); + extensions.add(PurgeEventOrphans.class); + extensions.add(PurgePropertyOrphans.class); + + return extensions; + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java new file mode 100644 index 00000000000..78365bce65c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java @@ -0,0 +1,55 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.batch; + +import org.sonar.api.batch.ResourceFilter; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +/** + * @since 1.12 + */ +public class ExcludedResourceFilter implements ResourceFilter { + + private String[] exclusionPatterns; + + public ExcludedResourceFilter(Project project) { + this(project.getExclusionPatterns()); + } + + protected ExcludedResourceFilter(String[] exclusionPatterns) { + this.exclusionPatterns = (exclusionPatterns==null ? new String[0] : exclusionPatterns); + } + + public boolean isIgnored(Resource resource) { + if (ResourceUtils.isUnitTestClass(resource)) { + // See SONAR-1115 Exclusion patterns do not apply to unit tests. + return false; + } + + for (String pattern : exclusionPatterns) { + if (resource.matchFilePattern(pattern)) { + return true; + } + } + return false; + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/DistributionAreaChart.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/DistributionAreaChart.java new file mode 100644 index 00000000000..a0f597ee7fc --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/DistributionAreaChart.java @@ -0,0 +1,83 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.charts; + +import org.apache.commons.lang.StringUtils; +import org.jfree.chart.axis.CategoryAxis; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.Plot; +import org.jfree.chart.renderer.category.AreaRenderer; +import org.jfree.data.category.DefaultCategoryDataset; +import org.sonar.api.charts.AbstractChart; +import org.sonar.api.charts.ChartParameters; + +import java.text.NumberFormat; + +public class DistributionAreaChart extends AbstractChart { + private static final String PARAM_COLORS = "c"; + + public String getKey() { + return "distarea"; + } + + @Override + protected Plot getPlot(ChartParameters params) { + DefaultCategoryDataset dataset = createDataset(params); + + CategoryAxis domainAxis = new CategoryAxis(); + domainAxis.setCategoryMargin(0.0); + domainAxis.setLowerMargin(0.0); + domainAxis.setUpperMargin(0.0); + + NumberAxis rangeAxis = new NumberAxis(); + rangeAxis.setNumberFormatOverride(NumberFormat.getIntegerInstance(params.getLocale())); + rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); + + AreaRenderer renderer = new AreaRenderer(); + CategoryPlot plot = new CategoryPlot(dataset, domainAxis, rangeAxis, renderer); + plot.setForegroundAlpha(0.5f); + plot.setDomainGridlinesVisible(true); + configureColors(dataset, plot, params.getValues(PARAM_COLORS, ",")); + return plot; + } + + private DefaultCategoryDataset createDataset(ChartParameters params) { + DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + + String[] series = params.getValues("v", "|", true); + int index = 0; + while (index < series.length) { + String[] pairs = StringUtils.split(series[index], ";"); + if (pairs.length == 0) { + dataset.addValue((Number)0.0, index, "0"); + + } else { + for (String pair : pairs) { + String[] keyValue = StringUtils.split(pair, "="); + double val = Double.parseDouble(keyValue[1]); + dataset.addValue((Number) val, index, keyValue[0]); + } + } + index++; + } + return dataset; + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/DistributionBarChart.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/DistributionBarChart.java new file mode 100644 index 00000000000..6820283e795 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/DistributionBarChart.java @@ -0,0 +1,129 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.charts; + +import org.apache.commons.lang.StringUtils; +import org.jfree.chart.axis.CategoryAxis; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.Plot; +import org.jfree.chart.renderer.category.BarRenderer; +import org.jfree.data.category.DefaultCategoryDataset; +import org.sonar.api.charts.AbstractChart; +import org.sonar.api.charts.ChartParameters; + +import java.awt.*; +import java.text.DecimalFormat; + +public class DistributionBarChart extends AbstractChart { + + + public static final String PARAM_VALUES = "v"; + public static final String PARAM_COLORS = "c"; + public static final String PARAM_Y_SUFFIX = "ysuf"; + public static final String PARAM_X_SUFFIX = "xsuf"; + public static final String PARAM_FONT_SIZE = "fs"; + + public String getKey() { + return "distbar"; + } + + @Override + public Plot getPlot(ChartParameters params) { + CategoryPlot plot = generateJFreeChart(params); + plot.setOutlinePaint(OUTLINE_COLOR); + plot.setDomainGridlinePaint(GRID_COLOR); + plot.setRangeGridlinePaint(GRID_COLOR); + return plot; + } + + private CategoryPlot generateJFreeChart(ChartParameters params) { + DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + CategoryPlot plot = new CategoryPlot(); + + Font font = getFont(params.getValue(PARAM_FONT_SIZE)); + configureDomainAxis(plot, font); + configureRangeAxis(plot, params.getValue(PARAM_Y_SUFFIX, "", true), font); + configureRenderer(plot); + configureValues(dataset, params.getValues(PARAM_VALUES, "|", true), params.getValue(PARAM_X_SUFFIX, "", true)); + configureColors(dataset, plot, params.getValues(PARAM_COLORS, ",")); + + plot.setDataset(dataset); + return plot; + } + + private void configureValues(DefaultCategoryDataset dataset, String[] series, String xSuffix) { + int index = 0; + while (index < series.length) { + String[] pairs = StringUtils.split(series[index], ";"); + if (pairs.length == 0) { + dataset.addValue((Number) 0.0, index, "0"); + + } else { + for (String pair : pairs) { + String[] keyValue = StringUtils.split(pair, "="); + double val = Double.parseDouble(keyValue[1]); + dataset.addValue((Number) val, index, keyValue[0] + xSuffix); + } + } + index++; + } + + } + + private void configureRenderer(CategoryPlot plot) { + BarRenderer renderer = new BarRenderer(); + renderer.setDrawBarOutline(true); + renderer.setSeriesItemLabelsVisible(0, true); + renderer.setItemMargin(0); + plot.setRenderer(renderer); + } + + private void configureDomainAxis(CategoryPlot plot, Font font) { + CategoryAxis categoryAxis = new CategoryAxis(); + categoryAxis.setTickMarksVisible(true); + categoryAxis.setTickLabelFont(font); + categoryAxis.setTickLabelPaint(OUTLINE_COLOR); + plot.setDomainAxis(categoryAxis); + plot.setDomainGridlinesVisible(false); + } + + private Font getFont(String fontSize) { + int size = FONT_SIZE; + if (!StringUtils.isBlank(fontSize)) { + size = Integer.parseInt(fontSize); + } + return new Font("SansSerif", Font.PLAIN, size); + } + + private void configureRangeAxis(CategoryPlot plot, String valueLabelSuffix, Font font) { + NumberAxis numberAxis = new NumberAxis(); + numberAxis.setUpperMargin(0.3); + numberAxis.setTickLabelFont(font); + numberAxis.setTickLabelPaint(OUTLINE_COLOR); + String suffix = ""; + if (valueLabelSuffix != null && !"".equals(valueLabelSuffix)) { + suffix = new StringBuilder().append("'").append(valueLabelSuffix).append("'").toString(); + } + numberAxis.setNumberFormatOverride(new DecimalFormat("0" + suffix)); + numberAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); + plot.setRangeAxis(numberAxis); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/XradarChart.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/XradarChart.java new file mode 100644 index 00000000000..52cfebd7d3b --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/charts/XradarChart.java @@ -0,0 +1,86 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.charts; + +import org.apache.commons.lang.StringUtils; +import org.jfree.chart.plot.Plot; +import org.jfree.chart.plot.SpiderWebPlot; +import org.jfree.data.category.CategoryDataset; +import org.jfree.data.category.DefaultCategoryDataset; +import org.sonar.api.charts.AbstractChart; +import org.sonar.api.charts.ChartParameters; + +import java.awt.*; + +public class XradarChart extends AbstractChart { + + /** + * see an example of complete URL in XradarChartTest + */ + + public static final String PARAM_COLOR = "c"; + public static final String PARAM_MAX_VALUE = "m"; + public static final String PARAM_INTERIOR_GAP = "g"; + public static final String PARAM_LABELS = "l"; + public static final String PARAM_VALUES = "v"; + + public String getKey() { + return "xradar"; + } + + @Override + protected Plot getPlot(ChartParameters params) { + SpiderWebPlot plot = new SpiderWebPlot(createDataset(params)); + plot.setStartAngle(0D); + plot.setOutlineVisible(false); + plot.setAxisLinePaint(Color.decode("0xCCCCCC")); + plot.setSeriesOutlineStroke(new BasicStroke(2f)); + + if (params.getValue(PARAM_INTERIOR_GAP) != null) { + plot.setInteriorGap(Double.parseDouble(params.getValue(PARAM_INTERIOR_GAP, "0.4", false))); + } + if (params.getValue(PARAM_MAX_VALUE) != null) { + plot.setMaxValue(Double.parseDouble(params.getValue(PARAM_MAX_VALUE, "100", false))); + } + configureColors(plot, params); + return plot; + } + + private void configureColors(SpiderWebPlot plot, ChartParameters params) { + String[] colors = params.getValues(PARAM_COLOR, "|"); + for (int i = 0; i < colors.length; i++) { + plot.setSeriesPaint(i, Color.decode("0x" + colors[i])); + } + } + + private CategoryDataset createDataset(ChartParameters params) { + String[] labels = params.getValues(PARAM_LABELS, ","); + String[] values = params.getValues(PARAM_VALUES, "|"); + + DefaultCategoryDataset set = new DefaultCategoryDataset(); + for (int indexValues = 0; indexValues < values.length; indexValues++) { + String[] fields = StringUtils.split(values[indexValues], ","); + for (int i = 0; i < fields.length; i++) { + set.addValue(Double.parseDouble(fields[i]), "" + indexValues, labels[i]); + } + } + return set; + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/Clouds.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/Clouds.java new file mode 100644 index 00000000000..f0b319604b2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/Clouds.java @@ -0,0 +1,42 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.clouds;
+
+import org.sonar.api.resources.Resource;
+import org.sonar.api.web.GwtPage;
+import org.sonar.api.web.NavigationSection;
+import org.sonar.api.web.ResourceScope;
+import org.sonar.api.web.UserRole;
+import org.sonar.plugins.core.clouds.client.GwtClouds;
+
+@NavigationSection(NavigationSection.RESOURCE)
+@ResourceScope({Resource.SCOPE_SET, Resource.SCOPE_SPACE})
+@UserRole(UserRole.USER)
+public class Clouds extends GwtPage {
+
+ public String getGwtId() {
+ return GwtClouds.GWT_ID;
+ }
+
+ public String getTitle() {
+ return "Clouds";
+ }
+
+}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/Calculator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/Calculator.java new file mode 100644 index 00000000000..5202b4feebc --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/Calculator.java @@ -0,0 +1,119 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.clouds.client;
+
+import org.sonar.plugins.core.clouds.client.model.Color;
+
+public class Calculator {
+
+ private Float minValue;
+ private Float maxValue;
+ private Float minPercent;
+ private Float maxPercent;
+
+ public Calculator(Float minPercent, Float maxPercent) {
+ this.minPercent = minPercent;
+ this.maxPercent = maxPercent;
+ }
+
+ public void updateMaxAndMin(Float value){
+ updateMaxValue(value);
+ updateMinValue(value);
+ }
+
+ public Integer getFontSizePercent(Integer value) {
+ float divisor = getMaxValue() - getMinValue();
+ float size = getMinPercent();
+ if (divisor != 0) {
+ float multiplier = (getMaxPercent() - getMinPercent()) / divisor;
+ size = getMinPercent() +
+ ((getMaxValue() - (getMaxValue() - (value - getMinValue()))) * multiplier);
+ }
+ return Float.valueOf(size).intValue();
+ }
+
+ public String getFontColor(float value) {
+ float interval = (getMaxPercent() - getMinPercent()) / 2f;
+ float mean = (getMinPercent() + getMaxPercent()) / 2f;
+
+ Color minColor = new Color(191/255f, 0f, 21/255f); // red
+ Color meanColor = new Color(77/255f, 5/255f, 177/255f); // purple
+ Color maxColor = new Color(23/255f, 96/255f, 191/255f); // blue
+
+ Color color;
+ if (value > mean) {
+ float valuePercent = ((value - mean) / interval) * 100f;
+ color = mixColorWith(maxColor, meanColor, valuePercent);
+ } else {
+ float valuePercent = ((mean - value) / interval) * 100f;
+ color = mixColorWith(minColor, meanColor, valuePercent);
+ }
+
+ int r = Float.valueOf(color.getRed()* 255f).intValue();
+ int g = Float.valueOf(color.getGreen() * 255f).intValue();
+ int b = Float.valueOf(color.getBlue() * 255f).intValue();
+
+ return ("rgb("+ r +","+ g +","+ b +")");
+ }
+
+ private Color mixColorWith(Color currentColor, Color mask, float value){
+ float opacity = value / 100f;
+
+ float r = (currentColor.getRed() * opacity) + (mask.getRed() * (1f - opacity));
+ float g = (currentColor.getGreen() * opacity) + (mask.getGreen() * (1f - opacity));
+ float b = (currentColor.getBlue() * opacity) + (mask.getBlue() * (1f - opacity));
+
+ return new Color(r, g, b);
+ }
+
+
+ private void updateMaxValue(Float value) {
+ if (maxValue == null) {
+ maxValue = value;
+ } else if (value > maxValue) {
+ maxValue = value;
+ }
+ }
+
+ private void updateMinValue(Float value) {
+ if (minValue == null) {
+ minValue = value;
+ } else if (value < minValue) {
+ minValue = value;
+ }
+ }
+
+
+ public Float getMinValue() {
+ return minValue;
+ }
+
+ public Float getMaxValue() {
+ return maxValue;
+ }
+
+ public Float getMinPercent() {
+ return minPercent;
+ }
+
+ public Float getMaxPercent() {
+ return maxPercent;
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/GwtClouds.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/GwtClouds.java new file mode 100644 index 00000000000..4770f3d64ba --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/GwtClouds.java @@ -0,0 +1,197 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.clouds.client; + +import com.google.gwt.core.client.JavaScriptException; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.user.client.ui.*; +import org.sonar.api.web.gwt.client.AbstractPage; +import org.sonar.api.web.gwt.client.ResourceDictionary; +import org.sonar.api.web.gwt.client.webservices.*; +import org.sonar.api.web.gwt.client.webservices.WSMetrics.Metric; +import org.sonar.api.web.gwt.client.webservices.WSMetrics.MetricsList; +import org.sonar.api.web.gwt.client.widgets.LoadingLabel; +import org.sonar.plugins.core.clouds.client.widget.ClassCloudsWidget; +import org.sonar.plugins.core.clouds.client.widget.TabWidget; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class GwtClouds extends AbstractPage { + + public static final String GWT_ID = "org.sonar.plugins.core.clouds.GwtClouds"; + + private Panel cloudsPanel; + private ListBox metricsListBox; + private Label sizeAndColorLabel; + private TabWidget sizeTabs; + private Resources resources; + + private final List<SizeMetric> SIZE_METRICS = Arrays.asList( + new SizeMetric("Quick Wins", WSMetrics.NCLOC), + new SizeMetric("Top risk", WSMetrics.FUNCTION_COMPLEXITY)); + + private final List<Metric> COLOR_METRICS = Arrays.asList(WSMetrics.COVERAGE, WSMetrics.VIOLATIONS_DENSITY); + + public void onModuleLoad() { + cloudsPanel = new FlowPanel(); + displayView(cloudsPanel); + loadClouds(); + } + + protected void loadClouds() { + String projectKey = ResourceDictionary.getResourceKey(); + final List<Metric> metricsToGet = new ArrayList<Metric>(); + for (SizeMetric size : SIZE_METRICS) { + metricsToGet.add(size.getSizeMetric()); + } + for (Metric color : COLOR_METRICS) { + metricsToGet.add(color); + } + if (projectKey != null) { + cloudsPanel.add(new LoadingLabel()); + + Query<Resources> resourcesQuery = ResourcesQuery.get(projectKey).setDepth(-1).setScopes(Resource.SCOPE_ENTITY).setMetrics(metricsToGet); + QueryCallBack<Resources> resourcesCb = new BaseQueryCallback<Resources>() { + public void onResponse(Resources response, JavaScriptObject jsonRawResponse) { + resources = response; + } + }; + Query<MetricsList> metrics = MetricsQuery.get().setUserManaged(false); + QueryCallBack<MetricsList> metricsCb = new BaseQueryCallback<MetricsList>() { + public void onResponse(MetricsList response, JavaScriptObject jsonRawResponse) { + // nothing to do WSMetrics.getUpdateMetricsFromServer will update the metrics labels + } + }; + metricsCb = WSMetrics.getUpdateMetricsFromServer(metricsCb); + + QueryCallBack<VoidResponse> updateCloudsCb = new BaseQueryCallback<VoidResponse>() { + public void onResponse(VoidResponse response, JavaScriptObject jsonRawResponse) { + updateClouds(resources); + } + }; + + SequentialQueries.get().add(resourcesQuery, resourcesCb).add(metrics, metricsCb).execute(updateCloudsCb); + } + } + + private void updateClouds(Resources resources) { + cloudsPanel.clear(); + Panel metricSelectPanel = getMetricColorSelectBox(resources); + sizeTabs = new TabWidget(new SelectionHandler<Integer>() { + public void onSelection(SelectionEvent<Integer> event) { + renderClassCloudsForCurrentMetric(); + } + }); + for (SizeMetric size : SIZE_METRICS) { + ClassCloudsWidget classCloudsTab = new ClassCloudsWidget(resources.getResources(), size.getSizeMetric()); + sizeTabs.addTab(classCloudsTab, size.getTabName(), size.getTabNameId()); + } + + cloudsPanel.add(metricSelectPanel); + cloudsPanel.add(sizeTabs); + } + + private Panel getMetricColorSelectBox(Resources resources) { + HTMLPanel metricSelectPanel = new HTMLPanel("<div id='select_metric' class='metricSelectBox small'> </div>"); + sizeAndColorLabel = new InlineLabel(); + sizeAndColorLabel.setStyleName("labelText gray"); + metricSelectPanel.add(sizeAndColorLabel, "select_metric"); + metricsListBox = new ListBox(false); + for (Metric color : COLOR_METRICS) { + if (resources.onceContainsMeasure(color)) { + metricsListBox.addItem(color.getName(), color.getKey()); + } + } + metricSelectPanel.add(metricsListBox, "select_metric"); + + metricsListBox.addChangeHandler(new ChangeHandler() { + public void onChange(ChangeEvent event) { + renderClassCloudsForCurrentMetric(); + } + }); + return metricSelectPanel; + } + + private void generateSizeAndColorLabel() { + sizeAndColorLabel.setText("Size : " + getCurrentSizeMetric().getName() + ", color : "); + } + + private void renderClassCloudsForCurrentMetric() { + Widget widget = sizeTabs.getSelectedWidget(); + if (widget instanceof ClassCloudsWidget) { + Metric current = getCurrentColorMetric(); + ClassCloudsWidget classCloudsWidget = (ClassCloudsWidget) widget; + classCloudsWidget.generateCloud(current); + generateSizeAndColorLabel(); + } + } + + private Metric getCurrentColorMetric() { + String metricKey = metricsListBox.getValue(metricsListBox.getSelectedIndex()); + for (Metric color : COLOR_METRICS) { + if (color.getKey().equals(metricKey)) { + return color; + } + } + throw new JavaScriptException("Unable to find metric " + metricKey); + } + + private Metric getCurrentSizeMetric() { + String selectedTabId = sizeTabs.getSelectedTabId(); + for (SizeMetric size : SIZE_METRICS) { + if (size.getTabNameId().equals(selectedTabId)) { + return size.sizeMetric; + } + } + throw new JavaScriptException("Unable to find metric for tab " + selectedTabId); + } + + + private class SizeMetric { + + private String tabName; + private Metric sizeMetric; + + public SizeMetric(String tabName, Metric sizeMetric) { + super(); + this.tabName = tabName; + this.sizeMetric = sizeMetric; + } + + public String getTabName() { + return tabName; + } + + public Metric getSizeMetric() { + return sizeMetric; + } + + public String getTabNameId() { + return tabName.toLowerCase().replace(' ', '_'); + } + } + +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/model/CloudElement.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/model/CloudElement.java new file mode 100644 index 00000000000..60f928d8f3e --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/model/CloudElement.java @@ -0,0 +1,53 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.clouds.client.model;
+
+import org.sonar.api.web.gwt.client.webservices.Resource;
+
+
+public class CloudElement implements Comparable<CloudElement> {
+
+ private Integer fontSize;
+ private Float fontColor;
+ private Resource resource;
+
+ public CloudElement(Resource resource, Integer fontSize, Float fontColor) {
+ this.resource = resource;
+ this.fontSize = fontSize;
+ this.fontColor = fontColor;
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ public Integer getFontSize() {
+ return fontSize;
+ }
+
+ public Float getFontColor() {
+ return fontColor;
+ }
+
+ public int compareTo(CloudElement cloudElement) {
+ return resource.getName().compareTo(cloudElement.getResource().getName());
+ }
+
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/model/Color.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/model/Color.java new file mode 100644 index 00000000000..598c470f207 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/model/Color.java @@ -0,0 +1,50 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.clouds.client.model;
+
+public class Color {
+
+ private float red;
+ private float green;
+ private float blue;
+
+ public Color(float red, float green, float blue) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ }
+
+ public float getRed() {
+ return red;
+ }
+
+ public float getGreen() {
+ return green;
+ }
+
+ public float getBlue() {
+ return blue;
+ }
+
+ @Override
+ public String toString() {
+ return ("red : "+ red + ", green : "+ green + ", blue : "+ blue );
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/widget/ClassCloudsWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/widget/ClassCloudsWidget.java new file mode 100644 index 00000000000..49c28d87656 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/widget/ClassCloudsWidget.java @@ -0,0 +1,146 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.clouds.client.widget;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.*;
+import org.sonar.api.web.gwt.client.Utils;
+import org.sonar.api.web.gwt.client.webservices.Measure;
+import org.sonar.api.web.gwt.client.webservices.Resource;
+import org.sonar.api.web.gwt.client.webservices.WSMetrics.Metric;
+import org.sonar.api.web.gwt.client.widgets.LoadingLabel;
+import org.sonar.plugins.core.clouds.client.Calculator;
+import org.sonar.plugins.core.clouds.client.GwtClouds;
+import org.sonar.plugins.core.clouds.client.model.CloudElement;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class ClassCloudsWidget extends Composite {
+
+ private Panel main;
+ private Metric sizeMetric;
+ private List<Resource> resources;
+ private float minSizePercent = 60f;
+ private float maxSizePercent = 240f;
+
+ private Calculator sizeCalculator = new Calculator(minSizePercent, maxSizePercent);
+ private Calculator colorCalculator = new Calculator(0f, 100f);
+
+ public ClassCloudsWidget(List<Resource> resources, Metric sizeMetric) {
+ this.sizeMetric = sizeMetric;
+ this.main = new FlowPanel();
+ this.resources = resources;
+ initWidget(main);
+ }
+
+ public Metric getSizeMetric() {
+ return sizeMetric;
+ }
+
+ public void generateCloud(Metric colorMetric) {
+ main.clear();
+ LoadingLabel loading = new LoadingLabel();
+ main.add(loading);
+ if (colorMetric.equals(colorMetric)) {
+ List<CloudElement> cloudElements = getCloudElements(resources, colorMetric);
+ createClouds(cloudElements, colorMetric);
+ }
+ main.remove(loading);
+ }
+
+ private List<CloudElement> getCloudElements(List<Resource> resources, Metric colorMetric) {
+ List<CloudElement> tagList = new ArrayList<CloudElement>();
+ for (Resource resource : resources) {
+ Measure sizeMeasure = getMeasure(resource, sizeMetric);
+ Measure colorMeasure = getMeasure(resource, colorMetric);
+
+ if (sizeMeasure != null && colorMeasure != null) {
+ Integer size = getMeasureValue(sizeMeasure.getValue());
+ float color = colorMeasure.getValue().floatValue();
+ tagList.add(new CloudElement(resource, size, color));
+ sizeCalculator.updateMaxAndMin(Float.valueOf(size.toString()));
+ }
+ }
+ Collections.sort(tagList);
+ return tagList;
+ }
+
+ private Integer getMeasureValue(Double value) {
+ Float floatValue = (value.floatValue() * 100.0f);
+ return floatValue.intValue();
+ }
+
+ private Measure getMeasure(Resource project, Metric metricToFind) {
+ return project.getMeasure(metricToFind);
+ }
+
+ private void createClouds(List<CloudElement> cloudElements, Metric colorMetric) {
+ for (CloudElement tag : cloudElements) {
+ HTML className = new HTML(
+ "<span style=\"font-size:" + Integer.toString(sizeCalculator.getFontSizePercent(tag.getFontSize())) +
+ "%; color:" + colorCalculator.getFontColor(tag.getFontColor()) + "\" >" +
+ tag.getResource().getName() + "</span>\n");
+ className.setStyleName("inline");
+
+ Hyperlink link = createLink(tag, colorMetric);
+ link.setHTML(className.getHTML());
+ main.add(link);
+ }
+ }
+
+ private Hyperlink createLink(CloudElement tag, final Metric colorMetric) {
+ Hyperlink link = new Hyperlink();
+ link.setStyleName("tag inline");
+ String tooltip = getTooltip(tag.getResource(), colorMetric);
+ link.getElement().setAttribute("title", tooltip);
+ link.getElement().setAttribute("rel", tooltip);
+
+ String sizeCss = Float.toString(maxSizePercent / 100f) + "em";
+ link.setHeight(sizeCss);
+ final Resource clickResource = tag.getResource();
+ link.addClickHandler(new ClickHandler() {
+ public void onClick(final ClickEvent event) {
+ if (clickResource.getCopy() != null) {
+ Window.Location.assign(Utils.getServerUrl() + "/plugins/resource/" + clickResource.getCopy() + "?page=" + GwtClouds.GWT_ID);
+ } else {
+ Utils.openResourcePopup(clickResource, colorMetric.getKey());
+ }
+ }
+ });
+
+ return link;
+ }
+
+ private String getTooltip(Resource resource, Metric colorMetric) {
+ Measure sizeMeasure = getMeasure(resource, sizeMetric);
+ String sizeMetricName = sizeMetric.getName();
+ String sizeMetricValue = sizeMeasure.getFormattedValue();
+
+ Measure colorMeasure = getMeasure(resource, colorMetric);
+ String colorMetricName = colorMetric.getName();
+ String colorMetricValue = colorMeasure.getFormattedValue();
+
+ return resource.getName(true) + ", " + sizeMetricName + " : " + sizeMetricValue + ", " + colorMetricName + " : " + colorMetricValue;
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/widget/TabWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/widget/TabWidget.java new file mode 100644 index 00000000000..7e9b571a4e0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/clouds/client/widget/TabWidget.java @@ -0,0 +1,77 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.clouds.client.widget;
+
+import com.google.gwt.event.logical.shared.SelectionEvent;
+import com.google.gwt.event.logical.shared.SelectionHandler;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.TabPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+public class TabWidget extends Composite {
+
+ private TabPanel tab = new TabPanel();
+
+ private Integer nbTab;
+ private final Integer defaultSelectedTabPosition = 0;
+ private String selectedTabId;
+ private int selectedIndex;
+
+ public TabWidget(final SelectionHandler<Integer> selectionListener) {
+ nbTab = 0;
+ initWidget(tab);
+ tab.setWidth("100%");
+
+ tab.addSelectionHandler(new SelectionHandler<Integer>() {
+ public void onSelection(SelectionEvent<Integer> event) {
+ selectedTabId = tab.getWidget(event.getSelectedItem()).getElement().getId().replace("_tab_content", "");
+ selectedIndex = event.getSelectedItem();
+ selectionListener.onSelection(event);
+ }
+ });
+
+ }
+
+ public String getSelectedTabId() {
+ return selectedTabId;
+ }
+
+ public Widget getSelectedWidget() {
+ return tab.getWidget(selectedIndex);
+ }
+
+ public void addTab(Widget widget, String tabName, String id) {
+ widget.getElement().setId(id + "_tab_content");
+ tab.add(widget, createTabLabel(tabName, id));
+ if (nbTab.equals(defaultSelectedTabPosition)) {
+ tab.selectTab(defaultSelectedTabPosition);
+ }
+ nbTab++;
+ }
+
+ private Label createTabLabel(String tabName, String id) {
+ Label tabLabel = new Label(tabName);
+ tabLabel.getElement().setId(id + "_tab_title");
+ tabLabel.addStyleName("tab_title");
+ return tabLabel;
+ }
+
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/colorizers/JavaColorizerFormat.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/colorizers/JavaColorizerFormat.java new file mode 100644 index 00000000000..45d6dc5d754 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/colorizers/JavaColorizerFormat.java @@ -0,0 +1,39 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.colorizers; + +import java.util.List; + +import org.sonar.api.resources.Java; +import org.sonar.api.web.CodeColorizerFormat; +import org.sonar.colorizer.CodeColorizer; +import org.sonar.colorizer.Tokenizer; + +public class JavaColorizerFormat extends CodeColorizerFormat{ + + public JavaColorizerFormat() { + super(Java.KEY); + } + + @Override + public List<Tokenizer> getTokenizers() { + return CodeColorizer.Format.JAVA.getTokenizers(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/CoverageViewerDefinition.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/CoverageViewerDefinition.java new file mode 100644 index 00000000000..ba9231e491d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/CoverageViewerDefinition.java @@ -0,0 +1,40 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.coverageviewer; + +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.resources.Resource; +import org.sonar.api.web.*; + +@ResourceQualifier(Resource.QUALIFIER_CLASS) +@NavigationSection(NavigationSection.RESOURCE_TAB) +@DefaultTab(metrics={CoreMetrics.COVERAGE_KEY, CoreMetrics.LINES_TO_COVER_KEY, CoreMetrics.UNCOVERED_LINES_KEY, CoreMetrics.LINE_COVERAGE_KEY, CoreMetrics.CONDITIONS_TO_COVER_KEY, CoreMetrics.UNCOVERED_CONDITIONS_KEY, CoreMetrics.BRANCH_COVERAGE_KEY}) +@UserRole(UserRole.CODEVIEWER) +public class CoverageViewerDefinition extends GwtPage { + + public String getTitle() { + return "Coverage"; + } + + public String getGwtId() { + return "org.sonar.plugins.core.coverageviewer.CoverageViewer"; + } +} + diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/client/CoveragePanel.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/client/CoveragePanel.java new file mode 100644 index 00000000000..fabda63343e --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/client/CoveragePanel.java @@ -0,0 +1,123 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.coverageviewer.client; + +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.SourcePanel; +import org.sonar.wsclient.gwt.AbstractCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CoveragePanel extends SourcePanel { + + private Map<Integer, String> hitsByLine = new HashMap<Integer, String>(); + private Map<Integer, String> branchHitsByLine = new HashMap<Integer, String>(); + + + public CoveragePanel(Resource resource) { + super(resource); + loadCoverageHits(resource); + } + + private void loadCoverageHits(Resource resource) { + ResourceQuery query = ResourceQuery.createForResource(resource, Metrics.COVERAGE_LINE_HITS_DATA, Metrics.BRANCH_COVERAGE_HITS_DATA); + Sonar.getInstance().find(query, new AbstractCallback<Resource>() { + + @Override + protected void doOnResponse(Resource resource) { + handleResponse(resource, Metrics.COVERAGE_LINE_HITS_DATA, hitsByLine); + handleResponse(resource, Metrics.BRANCH_COVERAGE_HITS_DATA, branchHitsByLine); + setStarted(); + } + }); + } + + private void handleResponse(Resource resource, String metric, Map<Integer, String> values) { + if (resource==null || resource.getMeasure(metric)==null) { + return; + } + + values.clear(); + String linesValue = resource.getMeasure(metric).getData(); + String[] lineWithValueArray; + if (linesValue.contains(",")) { + // deprecated - format before 1.9 + lineWithValueArray = linesValue.split(","); + } else { + lineWithValueArray = linesValue.split(";"); + } + for (String lineWithValue : lineWithValueArray) { + String[] elt = lineWithValue.split("="); + if (elt != null && elt.length == 2) { + values.put(Integer.parseInt(elt[0]), elt[1]); + } + } + } + + + @Override + protected boolean shouldDecorateLine(int index) { + return index > 0; + } + + @Override + protected List<Row> decorateLine(int index, String source) { + Row row = new Row().setLineIndex(index, ""); + + String hits = hitsByLine.get(index); + String branchHits = branchHitsByLine.get(index); + boolean hasLineCoverage = (null != hits); + boolean hasBranchCoverage = (null != branchHits); + boolean lineIsCovered = (hasLineCoverage && Integer.parseInt(hits) > 0); + boolean branchIsCovered = (hasBranchCoverage && "100%".equals(branchHits)); + + row.setSource(source, ""); + row.setValue(" ", ""); + row.setValue2(" ", ""); + + if (lineIsCovered) { + if (branchIsCovered) { + row.setValue(hits, "green"); + row.setValue2(branchHits, "green"); + } else if (hasBranchCoverage) { + row.setValue(hits, "orange"); + row.setValue2(branchHits, "orange"); + row.setSource(source, "orange"); + } else { + row.setValue(hits, "green"); + } + } else if (hasLineCoverage) { + row.setValue(hits, "red"); + row.setSource(source, "red"); + if (hasBranchCoverage) { + row.setValue2(branchHits, "red"); + } else { + row.setValue2(" ", "red"); + } + } + return Arrays.asList(row); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/client/CoverageViewer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/client/CoverageViewer.java new file mode 100644 index 00000000000..64752ddd7c0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/coverageviewer/client/CoverageViewer.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.coverageviewer.client; + +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Widget; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Page; +import org.sonar.gwt.ui.ViewerHeader; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; + +public class CoverageViewer extends Page { + @Override + protected Widget doOnResourceLoad(Resource resource) { + FlowPanel panel = new FlowPanel(); + panel.setWidth("100%"); + panel.add(new CoverageHeader(resource)); + panel.add(new CoveragePanel(resource)); + return panel; + } + + private static class CoverageHeader extends ViewerHeader { + public CoverageHeader(Resource resource) { + super(resource, new String[]{Metrics.COVERAGE, Metrics.LINE_COVERAGE, Metrics.UNCOVERED_LINES, Metrics.BRANCH_COVERAGE, Metrics.UNCOVERED_CONDITIONS}); + } + + @Override + protected void display(FlowPanel header, Resource resource) { + HorizontalPanel panel = new HorizontalPanel(); + header.add(panel); + + Measure measure = resource.getMeasure(Metrics.COVERAGE); + if (measure == null) { + addBigCell(panel, "-"); + } else { + addBigCell(panel, measure.getFormattedValue()); + } + + addCell(panel, resource.getMeasure(Metrics.LINE_COVERAGE)); + addCell(panel, resource.getMeasure(Metrics.UNCOVERED_LINES)); + addCell(panel, resource.getMeasure(Metrics.BRANCH_COVERAGE)); + addCell(panel, resource.getMeasure(Metrics.UNCOVERED_CONDITIONS)); + } + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/defaultsourceviewer/DefaultSourceViewer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/defaultsourceviewer/DefaultSourceViewer.java new file mode 100644 index 00000000000..f400727cc55 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/defaultsourceviewer/DefaultSourceViewer.java @@ -0,0 +1,39 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.defaultsourceviewer; + +import org.sonar.api.resources.Resource; +import org.sonar.api.web.*; +import org.sonar.plugins.core.defaultsourceviewer.client.GwtDefaultSourceViewer; + +@ResourceScope(Resource.SCOPE_ENTITY) +@NavigationSection(NavigationSection.RESOURCE_TAB) +@DefaultTab +@UserRole(UserRole.CODEVIEWER) +public class DefaultSourceViewer extends GwtPage { + public String getTitle() { + return "Sources"; + } + + public String getGwtId() { + return GwtDefaultSourceViewer.GWT_ID; + } + +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/defaultsourceviewer/client/GwtDefaultSourceViewer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/defaultsourceviewer/client/GwtDefaultSourceViewer.java new file mode 100644 index 00000000000..fd9a929ae58 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/defaultsourceviewer/client/GwtDefaultSourceViewer.java @@ -0,0 +1,113 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.defaultsourceviewer.client; + +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Widget; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.DefaultSourcePanel; +import org.sonar.gwt.ui.Page; +import org.sonar.gwt.ui.ViewerHeader; +import org.sonar.wsclient.services.Resource; + +public class GwtDefaultSourceViewer extends Page { + + public static final String GWT_ID = "org.sonar.plugins.core.defaultsourceviewer.GwtDefaultSourceViewer"; + + @Override + protected Widget doOnResourceLoad(Resource resource) { + FlowPanel panel = new FlowPanel(); + panel.setWidth("100%"); + panel.add(new SimpleHeader(resource)); + panel.add(new DefaultSourcePanel(resource)); + return panel; + } + + private static class SimpleHeader extends ViewerHeader { + public SimpleHeader(Resource resource) { + super(resource, new String[]{ + Metrics.LINES, + Metrics.NCLOC, + Metrics.FUNCTIONS, + Metrics.ACCESSORS, + Metrics.PARAGRAPHS, + + Metrics.STATEMENTS, + Metrics.COMPLEXITY, + Metrics.FUNCTION_COMPLEXITY, + Metrics.PARAGRAPH_COMPLEXITY, + + Metrics.COMMENT_LINES_DENSITY, + Metrics.COMMENT_LINES, + Metrics.COMMENTED_OUT_CODE_LINES, + Metrics.COMMENT_BLANK_LINES, + + Metrics.PUBLIC_DOCUMENTED_API_DENSITY, + Metrics.PUBLIC_UNDOCUMENTED_API, + Metrics.PUBLIC_API, + + Metrics.CLASSES, + Metrics.NUMBER_OF_CHILDREN, + Metrics.DEPTH_IN_TREE, + Metrics.RFC + } + ); + } + + @Override + protected void display(FlowPanel header, Resource resource) { + HorizontalPanel panel = new HorizontalPanel(); + addCell(panel, + resource.getMeasure(Metrics.LINES), + resource.getMeasure(Metrics.NCLOC), + resource.getMeasure(Metrics.FUNCTIONS), + resource.getMeasure(Metrics.ACCESSORS), + resource.getMeasure(Metrics.PARAGRAPHS)); + + addCell(panel, + resource.getMeasure(Metrics.STATEMENTS), + resource.getMeasure(Metrics.COMPLEXITY), + resource.getMeasure(Metrics.FUNCTION_COMPLEXITY), + resource.getMeasure(Metrics.PARAGRAPH_COMPLEXITY)); + + addCell(panel, + resource.getMeasure(Metrics.COMMENT_LINES_DENSITY), + resource.getMeasure(Metrics.COMMENT_LINES), + resource.getMeasure(Metrics.COMMENTED_OUT_CODE_LINES), + resource.getMeasure(Metrics.COMMENT_BLANK_LINES)); + + addCell(panel, + resource.getMeasure(Metrics.PUBLIC_DOCUMENTED_API_DENSITY), + resource.getMeasure(Metrics.PUBLIC_UNDOCUMENTED_API), + resource.getMeasure(Metrics.PUBLIC_API)); + + addCell(panel, + resource.getMeasure(Metrics.CLASSES), + resource.getMeasure(Metrics.NUMBER_OF_CHILDREN), + resource.getMeasure(Metrics.DEPTH_IN_TREE), + resource.getMeasure(Metrics.RFC)); + + if (panel.getWidgetCount() > 0) { + header.add(panel); + } + } + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/DuplicationsViewerDefinition.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/DuplicationsViewerDefinition.java new file mode 100644 index 00000000000..b679a144f76 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/DuplicationsViewerDefinition.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.duplicationsviewer; + +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.resources.Resource; +import org.sonar.api.web.*; +import org.sonar.plugins.core.duplicationsviewer.client.DuplicationsViewer; + +@ResourceQualifier({Resource.QUALIFIER_CLASS,Resource.QUALIFIER_FILE}) +@NavigationSection(NavigationSection.RESOURCE_TAB) +@DefaultTab(metrics={CoreMetrics.DUPLICATED_LINES_KEY, CoreMetrics.DUPLICATED_BLOCKS_KEY, CoreMetrics.DUPLICATED_FILES_KEY, CoreMetrics.DUPLICATED_LINES_DENSITY_KEY}) +@UserRole(UserRole.CODEVIEWER) +public class DuplicationsViewerDefinition extends GwtPage { + + public String getTitle() { + return "Duplications"; + } + + public String getGwtId() { + return DuplicationsViewer.GWT_ID; + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/client/DuplicationsPanel.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/client/DuplicationsPanel.java new file mode 100644 index 00000000000..17f34ffa94b --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/client/DuplicationsPanel.java @@ -0,0 +1,161 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.duplicationsviewer.client; + +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.DefaultSourcePanel; +import org.sonar.gwt.ui.ExpandCollapseLink; +import org.sonar.gwt.ui.Loading; +import org.sonar.gwt.ui.SourcePanel; + +import com.google.gwt.gen2.table.override.client.FlexTable; +import com.google.gwt.gen2.table.override.client.FlexTable.FlexCellFormatter; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.xml.client.Document; +import com.google.gwt.xml.client.Element; +import com.google.gwt.xml.client.NodeList; +import com.google.gwt.xml.client.XMLParser; +import org.sonar.wsclient.gwt.AbstractCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +public class DuplicationsPanel extends Composite { + + private final Panel panel; + private Loading loading; + + public DuplicationsPanel(Resource resource) { + panel = new VerticalPanel(); + loading = new Loading(); + panel.add(loading); + initWidget(panel); + setStyleName("gwt-DuplicationsPanel"); + getElement().setId("gwt-DuplicationsPanel"); + + loadDuplications(resource); + } + + public void loadDuplications(Resource resource) { + ResourceQuery query = ResourceQuery.createForResource(resource, Metrics.DUPLICATIONS_DATA); + Sonar.getInstance().find(query, new DuplicationCallback()); + } + + private class DuplicationCallback extends AbstractCallback<Resource> { + + public DuplicationCallback() { + super(loading); + } + + @Override + protected void doOnResponse(Resource resource) { + loading.removeFromParent(); + String duplications = null; + if (resource != null) { + Measure data = resource.getMeasure(Metrics.DUPLICATIONS_DATA); + if (data != null) { + duplications = data.getData(); + } + } + if (duplications != null) { + processDuplications(duplications, resource); + } + } + + private void processDuplications(String duplicationXMLData, Resource resource) { + Document parsed = XMLParser.parse(duplicationXMLData); + NodeList duplicationsXML = parsed.getElementsByTagName("duplication"); + + FlexTable table = getDuplicationsTable(); + + panel.add(table); + int rowCounter = 1; + for (int i = 0; i < duplicationsXML.getLength(); i++) { + Element duplicationXML = (Element) duplicationsXML.item(i); + String lines = duplicationXML.getAttribute("lines"); + String startLine = duplicationXML.getAttribute("start"); + String targetStartLine = duplicationXML.getAttribute("target-start"); + String targetResourceKey = duplicationXML.getAttribute("target-resource"); + renderDuplication(rowCounter, i, table, lines, startLine, targetStartLine, targetResourceKey, resource); + rowCounter+=2; + } + } + + private FlexTable getDuplicationsTable() { + FlexTable table = new FlexTable(); + table.setStylePrimaryName("duplicationsTable"); + table.setText(0, 0, ""); + table.setText(0, 1, "Nb lines"); + table.setText(0, 2, "From line"); + table.setText(0, 3, "File"); + table.setText(0, 4, "From line"); + + table.getCellFormatter().getElement(0, 0).setId("expandCollapseCol"); + table.getCellFormatter().getElement(0, 1).setId("nbLineCol"); + table.getCellFormatter().getElement(0, 2).setId("lineFromCol"); + table.getCellFormatter().getElement(0, 3).setId("fileCol"); + + setRowStyle(0, table, "header", false); + return table; + } + + private void renderDuplication(int row, int duplicationCounter, FlexTable table, String lines, String startLine, String targetStartLine, String targetResourceKey, final Resource resource) { + String style = (duplicationCounter % 2 == 0) ? "odd" : "even"; + + SourcePanel src = new DefaultSourcePanel(resource, new Integer(startLine), new Integer(lines)); + src.getElement().setId("source-panel-" + targetResourceKey.replace('.', '_')); + src.setVisible(false); + + ExpandCollapseLink link = new ExpandCollapseLink(src); + + table.setWidget(row, 0, link); + table.setText(row, 1, lines); + table.setText(row, 2, startLine); + if (targetResourceKey.equals(resource.getKey())) { + targetResourceKey = "Same file"; + } + if (targetResourceKey.contains(":")) { + targetResourceKey = targetResourceKey.substring(targetResourceKey.lastIndexOf(':') + 1); + } + table.setText(row, 3, targetResourceKey); + table.setText(row, 4, targetStartLine); + setRowStyle(row, table, style, false); + + FlexCellFormatter frmt = (FlexCellFormatter)table.getCellFormatter(); + frmt.setColSpan(row + 1, 1, 4); + table.setWidget(row + 1, 1, src); + setRowStyle(row + 1, table, style, true); + + } + + private void setRowStyle(int row, FlexTable table, String style, boolean isPanelRow) { + table.getCellFormatter().setStyleName(row, 0, style); + table.getCellFormatter().setStyleName(row, 1, style); + if (!isPanelRow) { + table.getCellFormatter().setStyleName(row, 2, style); + table.getCellFormatter().setStyleName(row, 3, style); + table.getCellFormatter().setStyleName(row, 4, style); + } + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/client/DuplicationsViewer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/client/DuplicationsViewer.java new file mode 100644 index 00000000000..742e0975dc7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/duplicationsviewer/client/DuplicationsViewer.java @@ -0,0 +1,79 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.duplicationsviewer.client; + +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.Widget; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Page; +import org.sonar.gwt.ui.ViewerHeader; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; + +public class DuplicationsViewer extends Page { + + public static final String GWT_ID = "org.sonar.plugins.core.duplicationsviewer.DuplicationsViewer"; + + @Override + protected Widget doOnResourceLoad(Resource resource) { + FlowPanel panel = new FlowPanel(); + panel.setWidth("100%"); + panel.add(new DuplicationsHeader(resource)); + panel.add(new DuplicationsPanel(resource)); + return panel; + } + + private static class DuplicationsHeader extends ViewerHeader { + public DuplicationsHeader(Resource resource) { + super(resource, new String[]{Metrics.DUPLICATED_LINES_DENSITY, Metrics.LINES, Metrics.DUPLICATED_LINES, Metrics.DUPLICATED_BLOCKS}); + } + + @Override + protected void display(FlowPanel header, Resource resource) { + Panel panel = new HorizontalPanel(); + header.add(panel); + + Measure measure = resource.getMeasure(Metrics.DUPLICATED_LINES_DENSITY); + if (measure == null) { + addBigCell(panel, "0"); + } else { + addBigCell(panel, measure.getFormattedValue()); + } + + addCell(panel, getDefaultMeasure(resource, Metrics.LINES, "lines")); + addCell(panel, getDefaultMeasure(resource, Metrics.DUPLICATED_LINES, "Duplicated lines")); + addCell(panel, getDefaultMeasure(resource, Metrics.DUPLICATED_BLOCKS, "Duplicated blocks")); + } + + private Measure getDefaultMeasure(Resource resource, String metric, String label) { + Measure measure = resource.getMeasure(metric); + if (measure == null || measure.getValue() == null) { + measure = new Measure(); + measure.setMetricName(label); + measure.setValue(0.0); + measure.setFormattedValue("0"); + } + return measure; + } + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java new file mode 100644 index 00000000000..35ec96f4e93 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/Hotspots.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots; + +import org.sonar.api.resources.Resource; +import org.sonar.api.web.GwtPage; +import org.sonar.api.web.NavigationSection; +import org.sonar.api.web.ResourceScope; +import org.sonar.api.web.UserRole; + +@NavigationSection(NavigationSection.RESOURCE) +@ResourceScope({Resource.SCOPE_SET, Resource.SCOPE_SPACE}) +@UserRole(UserRole.USER) +public class Hotspots extends GwtPage { + + public String getTitle() { + return "Hotspots"; + } + + public String getGwtId() { + return "org.sonar.plugins.core.hotspots.GwtHotspots"; + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java new file mode 100644 index 00000000000..5f9f3edae0c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/GwtHotspots.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client; + +import com.google.gwt.gen2.table.override.client.Grid; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Page; +import org.sonar.plugins.core.hotspots.client.widget.MetricHotspot; +import org.sonar.plugins.core.hotspots.client.widget.MostBadlyDesignedFiles; +import org.sonar.plugins.core.hotspots.client.widget.MostViolatedResources; +import org.sonar.plugins.core.hotspots.client.widget.MostViolatedRules; +import org.sonar.wsclient.services.Resource; + +public class GwtHotspots extends Page { + @Override + protected Widget doOnResourceLoad(Resource resource) { + Grid grid = new Grid(1, 2); + grid.setStylePrimaryName("gwt-Hotspots"); + loadHotspots(grid, resource); + return grid; + } + + + private void loadHotspots(Grid grid, Resource resource) { + VerticalPanel column1 = new VerticalPanel(); + column1.setStyleName("hotspotcol"); + VerticalPanel column2 = new VerticalPanel(); + column2.setStyleName("hotspotcol"); + + column1.add(new MostViolatedRules(resource)); + column1.add(new MetricHotspot(resource, Metrics.TEST_EXECUTION_TIME, I18nConstants.INSTANCE.titleLongestTests())); + column1.add(new MetricHotspot(resource, Metrics.COMPLEXITY, I18nConstants.INSTANCE.titleMostComplexResources())); + column1.add(new MetricHotspot(resource, Metrics.DUPLICATED_LINES, I18nConstants.INSTANCE.titleMostDuplicatedResources())); + column1.add(new MostBadlyDesignedFiles(resource)); + + column2.add(new MostViolatedResources(resource)); + column2.add(new MetricHotspot(resource, Metrics.UNCOVERED_LINES, I18nConstants.INSTANCE.titleLessTested())); + column2.add(new MetricHotspot(resource, Metrics.FUNCTION_COMPLEXITY, I18nConstants.INSTANCE.titleMostComplexMethods())); + column2.add(new MetricHotspot(resource, Metrics.PUBLIC_UNDOCUMENTED_API, I18nConstants.INSTANCE.titleMostUndocumentedAPI())); + + grid.setWidget(0, 0, column1); + grid.setWidget(0, 1, column2); + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/I18nConstants.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/I18nConstants.java new file mode 100644 index 00000000000..799b8267175 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/I18nConstants.java @@ -0,0 +1,69 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client; + +import com.google.gwt.core.client.GWT; + +public interface I18nConstants extends com.google.gwt.i18n.client.Constants { + + static I18nConstants INSTANCE = GWT.create(I18nConstants.class); + + @DefaultStringValue("Most violated rules") + String titleMostViolatedRules(); + + @DefaultStringValue("Most violated") + String titleMostViolatedResources(); + + @DefaultStringValue("Longest unit tests") + String titleLongestTests(); + + @DefaultStringValue("Highest complexity") + String titleMostComplexResources(); + + @DefaultStringValue("Highest duplications") + String titleMostDuplicatedResources(); + + @DefaultStringValue("Highest untested lines") + String titleLessTested(); + + @DefaultStringValue("Highest average method complexity") + String titleMostComplexMethods(); + + @DefaultStringValue("Most undocumented APIs") + String titleMostUndocumentedAPI(); + + @DefaultStringValue("No measures") + String noMeasures(); + + @DefaultStringValue("Any priority") + String anyPriority(); + + @DefaultStringValue("more") + String moreDetails(); + + @DefaultStringValue("Lack of Cohesion of Methods") + String lcom4(); + + @DefaultStringValue("Response for class") + String rfc(); + + @DefaultStringValue("Highest") + String designTitle(); +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java new file mode 100644 index 00000000000..f214e9f58d9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/AbstractHotspot.java @@ -0,0 +1,124 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client.widget; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Links; +import org.sonar.gwt.ui.Loading; +import org.sonar.plugins.core.hotspots.client.I18nConstants; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; + +public abstract class AbstractHotspot extends Composite { + + private Panel hotspot; + private Panel data; + private Resource resource; + + public static final int LIMIT = 5; + + protected AbstractHotspot(String id, Resource resource) { + this.resource = resource; + hotspot = new VerticalPanel(); + hotspot.getElement().setId(id); + hotspot.setStyleName("gwt-HotspotPanel"); + initWidget(hotspot); + } + + public Resource getResource() { + return resource; + } + + @Override + public void onLoad() { + hotspot.add(createHeader()); + data = new SimplePanel(); + hotspot.add(data); + loadData(); + } + + protected void loadData() { + data.clear(); + data.add(new Loading()); + doLoadData(); + } + + abstract Widget createHeader(); + + abstract void doLoadData(); + + protected void render(Widget widget) { + data.clear(); + data.add(widget); + } + + protected void renderEmptyResults() { + Grid grid = new Grid(1, 1); + grid.setWidget(0, 0, new HTML(I18nConstants.INSTANCE.noMeasures())); + grid.getCellFormatter().setStyleName(0, 0, getRowCssClass(0) + " emptyResultsCell"); + grid.setStyleName("gwt-Hotspot"); + render(grid); + } + + protected void renderNameCell(Grid hotspotGrid, final Resource resource, final String metricKey, int row, int column) { + Anchor link = new Anchor(resource.getName()); + link.getElement().setAttribute("title", resource.getName(true)); + link.getElement().setAttribute("rel", resource.getName(true)); + link.addClickHandler(new ClickHandler() { + public void onClick(final ClickEvent event) { + if (resource.getCopy() != null) { + Window.Location.assign(Links.baseUrl() + "/plugins/resource/" + resource.getCopy() + "?page=org.sonar.plugins.core.hotspots.GwtHotspots"); + } else { + Links.openMeasurePopup(resource.getKey(), metricKey); + } + } + }); + hotspotGrid.setWidget(row, column, link); + hotspotGrid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " resourceCell"); + } + + protected void renderValueCell(Grid hotspotGrid, Measure measure, int row, int column) { + hotspotGrid.setHTML(row, column, measure.getFormattedValue()); + hotspotGrid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " resultCell"); + } + + protected void renderGraphCell(Grid hotspotGrid, Measure measure, Measure firstMeasure, int row, int column) { + Double value = Double.valueOf(measure.getValue()); + Double upperValue = Double.valueOf(firstMeasure.getValue()); + Double percentPonderated = getPercentPonderatedValue(value, 0d, upperValue); + String graph = "<span style='width:100%'><ul class='hbar' style='float: right;'><li style='background-color: rgb(119, 119, 119); width: " + percentPonderated.intValue() + "%'> </li></ul></span>"; + hotspotGrid.setHTML(row, column, graph); + hotspotGrid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " graphCell"); + } + + protected String getRowCssClass(int row) { + return row % 2 == 0 ? "even" : "odd"; + } + + protected double getPercentPonderatedValue(Double value, Double lower, Double upper) { + if (value < lower) return 0; + if (value > upper) return 100; + double percentIncrement = (upper - lower) / 100d; + return (value - lower) / percentIncrement; + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java new file mode 100644 index 00000000000..688cca9a08a --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MetricHotspot.java @@ -0,0 +1,133 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client.widget; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Links; +import org.sonar.plugins.core.hotspots.client.I18nConstants; +import org.sonar.wsclient.gwt.AbstractListCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import java.util.ArrayList; +import java.util.List; + +public class MetricHotspot extends AbstractHotspot { + + private String metric; + private String title; + + public MetricHotspot(Resource resource, String metric, String title) { + super(metric + "-hotspot", resource); + this.metric = metric; + this.title = title; + } + + @Override + Widget createHeader() { + final Label label = new Label(title); + label.setStyleName("header"); + + final Anchor moreLink = new Anchor(I18nConstants.INSTANCE.moreDetails()); + moreLink.getElement().setId("more-" + metric); + moreLink.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + Window.Location.assign(Links.baseUrl() + "/drilldown/measures/" + getResource().getKey() + "?metric=" + metric); + } + }); + + final HorizontalPanel horizontal = new HorizontalPanel(); + horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); + horizontal.setWidth("98%"); + horizontal.add(label); + horizontal.add(moreLink); + horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); + horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); + + return horizontal; + } + + @Override + void doLoadData() { + final ResourceQuery query = getResourceQuery(); + Sonar.getInstance().findAll(query, new AbstractListCallback<Resource>() { + + @Override + protected void doOnResponse(List<Resource> resources) { + List<HotspotMeasure> measures = new ArrayList<HotspotMeasure>(); + for (Resource resource : resources) { + for (Measure measure : resource.getMeasures()) { + measures.add(new HotspotMeasure(resource, measure)); + } + } + + if (measures.isEmpty()) { + renderEmptyResults(); + + } else { + final Grid grid = new Grid(measures.size(), 3); + grid.setStyleName("gwt-Hotspot"); + int row = 0; + HotspotMeasure firstMeasure = measures.get(0); + for (HotspotMeasure measure : measures) { + renderNameCell(grid, measure.getResource(), metric, row, 0); + renderValueCell(grid, measure.getMeasure(), row, 1); + renderGraphCell(grid, measure.getMeasure(), firstMeasure.getMeasure(), row, 2); + row++; + } + + render(grid); + } + } + }); + } + + protected ResourceQuery getResourceQuery() { + return ResourceQuery.createForResource(getResource(), metric) + .setScopes(Resource.SCOPE_ENTITY) + .setDepth(ResourceQuery.DEPTH_UNLIMITED) + .setLimit(LIMIT); + } + + public static class HotspotMeasure { + private Resource resource; + private Measure measure; + + public HotspotMeasure(Resource resource, Measure measure) { + super(); + this.resource = resource; + this.measure = measure; + } + + public Resource getResource() { + return resource; + } + + public Measure getMeasure() { + return measure; + } + + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java new file mode 100644 index 00000000000..afbae117e5f --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostBadlyDesignedFiles.java @@ -0,0 +1,127 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client.widget; + +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Links; +import org.sonar.gwt.Metrics; +import org.sonar.plugins.core.hotspots.client.I18nConstants; +import org.sonar.wsclient.gwt.AbstractListCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import java.util.List; + +public class MostBadlyDesignedFiles extends AbstractHotspot { + + private ListBox metricSelectBox; + + public MostBadlyDesignedFiles(Resource resource) { + super("design-hotspot", resource); + } + + @Override + Widget createHeader() { + metricSelectBox = new ListBox(false); + metricSelectBox.addItem(I18nConstants.INSTANCE.lcom4(), "lcom4"); + metricSelectBox.addItem(I18nConstants.INSTANCE.rfc(), "rfc"); + metricSelectBox.setStyleName("small"); + metricSelectBox.addChangeHandler(new ChangeHandler() { + public void onChange(ChangeEvent event) { + loadData(); + } + }); + + final Label label = new Label(I18nConstants.INSTANCE.designTitle()); + label.setStyleName("header"); + + final Anchor moreLink = new Anchor(I18nConstants.INSTANCE.moreDetails()); + moreLink.getElement().setId("more-design"); + moreLink.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + final String metric = getSelectedMetric(); + Window.Location.assign(Links.baseUrl() + "/drilldown/measures/" + getResource().getId() + "?metric=" + metric); + } + }); + + final HorizontalPanel horizontal = new HorizontalPanel(); + horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); + horizontal.setWidth("98%"); + horizontal.add(label); + horizontal.add(metricSelectBox); + horizontal.add(moreLink); + horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); + horizontal.setCellHorizontalAlignment(metricSelectBox, HorizontalPanel.ALIGN_LEFT); + horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); + + return horizontal; + } + + @Override + void doLoadData() { + final ResourceQuery query = getResourceQuery(); + Sonar.getInstance().findAll(query, new AbstractListCallback<Resource>() { + + @Override + protected void doOnResponse(List<Resource> resources) { + final Grid grid = new Grid(resources.size(), 3); + grid.setStyleName("gwt-Hotspot"); + int row = 0; + Measure firstMeasure = null; + for (Resource resource : resources) { + if (resource.getMeasures().size() == 1) { + if (firstMeasure == null) { + firstMeasure = resource.getMeasures().get(0); + } + renderNameCell(grid, resource, firstMeasure.getMetricKey(), row, 0); + renderValueCell(grid, resource.getMeasures().get(0), row, 1); + renderGraphCell(grid, resource.getMeasures().get(0), firstMeasure, row, 2); + row++; + } + } + + if (firstMeasure == null) { + renderEmptyResults(); + } else { + render(grid); + } + } + }); + } + + public ResourceQuery getResourceQuery() { + return ResourceQuery.createForResource(getResource(), getSelectedMetric()) + .setDepth(-1) + .setQualifiers(Resource.QUALIFIER_CLASS) + .setLimit(LIMIT); + } + + private String getSelectedMetric() { + return metricSelectBox.getValue(metricSelectBox.getSelectedIndex()); + } +} + diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java new file mode 100644 index 00000000000..e79398ba063 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedResources.java @@ -0,0 +1,127 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client.widget; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Links; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Icons; +import org.sonar.plugins.core.hotspots.client.I18nConstants; +import org.sonar.wsclient.gwt.AbstractListCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import java.util.List; +import java.util.Map; + +public class MostViolatedResources extends AbstractHotspot { + + public MostViolatedResources(Resource resource) { + super("violated-files-hotspot", resource); + } + + @Override + Widget createHeader() { + final Label label = new Label(I18nConstants.INSTANCE.titleMostViolatedResources()); + label.setStyleName("header"); + + final Anchor moreLink = new Anchor(I18nConstants.INSTANCE.moreDetails()); + moreLink.getElement().setId("more-violated-resources"); + moreLink.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + Window.Location.assign(Links.baseUrl() + "/drilldown/measures/" + getResource().getId() + "?metric=" + Metrics.WEIGHTED_VIOLATIONS); + } + }); + + final HorizontalPanel horizontal = new HorizontalPanel(); + horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); + horizontal.setWidth("98%"); + horizontal.add(label); + horizontal.add(moreLink); + horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); + horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); + + return horizontal; + } + + @Override + void doLoadData() { + final ResourceQuery query = getResourceQuery(); + Sonar.getInstance().findAll(query, new AbstractListCallback<Resource>() { + + @Override + protected void doOnResponse(List<Resource> resources) { + Grid grid = new Grid(resources.size(), 11); + grid.setStyleName("gwt-Hotspot"); + int row = 0; + for (Resource resource : resources) { + if (resource.getMeasures().size() > 0) { + renderNameCell(grid, resource, Metrics.WEIGHTED_VIOLATIONS, row, 0); + renderPriorities(grid, resource, row); + row++; + } + } + if (row == 0) { + renderEmptyResults(); + } else { + render(grid); + } + } + }); + } + + + private void renderPriorities(Grid grid, Resource resource, int row) { + Measure debt = resource.getMeasures().get(0); + if (debt != null && debt.getData() != null) { + Map<String, String> map = debt.getDataAsMap(";"); + renderPriority(grid, row, map, 1, "BLOCKER"); + renderPriority(grid, row, map, 3, "CRITICAL"); + renderPriority(grid, row, map, 5, "MAJOR"); + renderPriority(grid, row, map, 7, "MINOR"); + renderPriority(grid, row, map, 9, "INFO"); + } + } + + private void renderPriority(Grid grid, int row, Map<String, String> map, int column, String priority) { + grid.setWidget(row, column, Icons.forPriority(priority).createImage()); + grid.getCellFormatter().setStyleName(row, column, getRowCssClass(row) + " small right"); + + if (map.containsKey(priority)) { + grid.setWidget(row, column + 1, new HTML(map.get(priority))); + } else { + grid.setWidget(row, column + 1, new HTML("0")); + } + grid.getCellFormatter().setStyleName(row, column + 1, getRowCssClass(row) + " small left"); + } + + private ResourceQuery getResourceQuery() { + return ResourceQuery.createForResource(getResource(), Metrics.WEIGHTED_VIOLATIONS) + .setScopes(Resource.SCOPE_ENTITY) + .setQualifiers(Resource.QUALIFIER_CLASS, Resource.QUALIFIER_FILE, Resource.QUALIFIER_PROJECT) + .setDepth(ResourceQuery.DEPTH_UNLIMITED) + .setLimit(LIMIT); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java new file mode 100644 index 00000000000..1255c1e5a63 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/hotspots/client/widget/MostViolatedRules.java @@ -0,0 +1,149 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.hotspots.client.widget; + +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Links; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Icons; +import org.sonar.plugins.core.hotspots.client.I18nConstants; +import org.sonar.wsclient.gwt.AbstractCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +public class MostViolatedRules extends AbstractHotspot { + + private ListBox priorities; + + public MostViolatedRules(Resource resource) { + super("rules-hotspot", resource); + } + + @Override + Widget createHeader() { + priorities = new ListBox(false); + priorities.addItem(I18nConstants.INSTANCE.anyPriority(), ""); + priorities.addItem("Blocker", "BLOCKER"); + priorities.addItem("Critical", "CRITICAL"); + priorities.addItem("Major", "MAJOR"); + priorities.addItem("Minor", "MINOR"); + priorities.addItem("Info", "INFO"); + priorities.setStyleName("small"); + priorities.addChangeHandler(new ChangeHandler() { + public void onChange(ChangeEvent event) { + loadData(); + } + }); + + final Label label = new Label(I18nConstants.INSTANCE.titleMostViolatedRules()); + label.setStyleName("header"); + + final Anchor moreLink = new Anchor(I18nConstants.INSTANCE.moreDetails()); + moreLink.getElement().setId("more-rules"); + moreLink.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + Window.Location.assign(Links.baseUrl() + "/drilldown/violations/" + getResource().getId()); + } + }); + + final HorizontalPanel horizontal = new HorizontalPanel(); + horizontal.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); + horizontal.setWidth("98%"); + horizontal.add(label); + horizontal.add(priorities); + horizontal.add(moreLink); + horizontal.setCellHorizontalAlignment(label, HorizontalPanel.ALIGN_LEFT); + horizontal.setCellHorizontalAlignment(priorities, HorizontalPanel.ALIGN_LEFT); + horizontal.setCellHorizontalAlignment(moreLink, HorizontalPanel.ALIGN_RIGHT); + + return horizontal; + } + + @Override + void doLoadData() { + final ResourceQuery query = getResourceQuery(); + Sonar.getInstance().find(query, new AbstractCallback<Resource>() { + + @Override + protected void doOnResponse(Resource resource) { + if (resource.getMeasures().isEmpty()) { + renderEmptyResults(); + } else { + renderGrid(resource); + } + } + }); + } + + private void renderGrid(Resource resource) { + final Grid grid = new Grid(resource.getMeasures().size(), 4); + grid.setStyleName("gwt-Hotspot"); + int row = 0; + Measure firstMeasure = resource.getMeasures().get(0); + for (Measure measure : resource.getMeasures()) { + renderRule(grid, measure, row); + renderValueCell(grid, measure, row, 2); + renderGraphCell(grid, measure, firstMeasure, row, 3); + row++; + } + render(grid); + } + + protected void renderRule(final Grid grid, final Measure measure, final int row) { + Anchor drillDown = new Anchor(measure.getRuleName()); + drillDown.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + Window.Location.assign(Links.baseUrl() + "/drilldown/violations/" + getResource().getId() + "?rule=" + measure.getRuleKey()); + } + }); + + grid.setWidget(row, 0, new HTML("<a id=\"rule" + row + "\" href=\"" + Links.urlForRule(measure.getRuleKey(), false) + "\" onclick=\"window.open(this.href,'rule','height=800,width=900,scrollbars=1,resizable=1');return false;\" title=\"" + measure.getRuleKey() + "\">" + Icons.forPriority(measure.getRulePriority()).getHTML() + "</a>")); + grid.setWidget(row, 1, drillDown); + grid.getCellFormatter().setStyleName(row, 0, getRowCssClass(row) + ""); + grid.getCellFormatter().setStyleName(row, 1, getRowCssClass(row) + " resourceCell"); + } + + public ResourceQuery getResourceQuery() { + ResourceQuery query = ResourceQuery.createForResource(getResource(), Metrics.VIOLATIONS) + .setDepth(0) + .setExcludeRules(false) + .setLimit(LIMIT); + String priority = getSelectedPriority(); + if (priority!=null) { + query.setRulePriorities(priority); + } + return query; + } + + private String getSelectedPriority() { + String priority = priorities.getValue(priorities.getSelectedIndex()); + if ("".equals(priority) || priority == null) { + return null; + } + return priority; + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/metrics/UserManagedMetrics.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/metrics/UserManagedMetrics.java new file mode 100644 index 00000000000..d6a2bfbbe3f --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/metrics/UserManagedMetrics.java @@ -0,0 +1,36 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.metrics; + +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; + +import java.util.Arrays; +import java.util.List; + +public class UserManagedMetrics implements Metrics { + public List<Metric> getMetrics() { + return Arrays.asList( + new Metric("burned_budget", "Burned budget", "The budget already used in the project", Metric.ValueType.FLOAT, 0, false, "Management", true), + new Metric("team_size", "Team size", "Size of the project team", Metric.ValueType.INT, 0, false, "Management", true), + new Metric("business_value", "Business value", "An indication on the value of the project for the business", Metric.ValueType.FLOAT, 1, true, "Management", true) + ); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDeletedResources.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDeletedResources.java new file mode 100644 index 00000000000..63136a6086b --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDeletedResources.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; + +import java.util.List; +import javax.persistence.Query; + +/** + * @since 1.11 + */ +public class PurgeDeletedResources extends AbstractPurge { + + public PurgeDeletedResources(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + + " s WHERE NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=s.resourceId)"); + final List<Integer> snapshotIds = query.getResultList(); + + deleteSnapshotData(snapshotIds); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDeprecatedLast.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDeprecatedLast.java new file mode 100644 index 00000000000..4e8c6a64c16 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDeprecatedLast.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; + +import javax.persistence.Query; +import java.util.List; + +/** + * @since 1.11 + */ +public class PurgeDeprecatedLast extends AbstractPurge { + + public PurgeDeprecatedLast(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + + " s WHERE s.last=true AND s.rootId IS NOT NULL AND NOT EXISTS(FROM " + Snapshot.class.getSimpleName() + " s2 WHERE s2.id=s.rootId AND s2.last=true)"); + List<Integer> snapshotIds = query.getResultList(); + + deleteSnapshotData(snapshotIds); + } +} + diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDisabledResources.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDisabledResources.java new file mode 100644 index 00000000000..bf1b571f469 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeDisabledResources.java @@ -0,0 +1,62 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; + +import java.util.List; +import javax.persistence.Query; + +/** + * @since 1.11 + */ +public class PurgeDisabledResources extends AbstractPurge { + + public PurgeDisabledResources(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + deleteSnapshotData(getSnapshotIds()); + deleteResources(); + } + + private void deleteResources() { + final List<Integer> resourceIds = getResourceIds(); + if (!resourceIds.isEmpty()) { + executeQuery(resourceIds, "delete from " + ResourceModel.class.getSimpleName() + " r where r.id in (:ids)"); + } + } + + private List<Integer> getResourceIds() { + Query query = getSession().createQuery("SELECT r.id FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.enabled=false"); + return (List<Integer>) query.getResultList(); + } + + private List<Integer> getSnapshotIds() { + Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + " s WHERE " + + " EXISTS (FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=s.resourceId AND r.enabled=false)"); + return (List<Integer>) query.getResultList(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeEntities.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeEntities.java new file mode 100644 index 00000000000..88b13381903 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeEntities.java @@ -0,0 +1,53 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.apache.commons.lang.time.DateUtils; +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Resource; + +import javax.persistence.Query; +import java.util.Date; +import java.util.List; + +/** + * @since 1.11 + */ +public class PurgeEntities extends AbstractPurge { + + private static final int MINIMUM_AGE_IN_HOURS = -12; + + public PurgeEntities(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + final Date beforeDate = DateUtils.addHours(new Date(), MINIMUM_AGE_IN_HOURS); + Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + " s WHERE s.last=false AND scope=:scope AND s.createdAt<:date"); + query.setParameter("scope", Resource.SCOPE_ENTITY); + query.setParameter("date", beforeDate); + List<Integer> snapshotIds = query.getResultList(); + + deleteSnapshotData(snapshotIds); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeEventOrphans.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeEventOrphans.java new file mode 100644 index 00000000000..d98c17effa9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeEventOrphans.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; + +import javax.persistence.Query; +import java.util.List; + +public class PurgeEventOrphans extends AbstractPurge { + + public PurgeEventOrphans(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + Query query = getSession().createQuery("SELECT e.id FROM " + Event.class.getSimpleName() + + " e WHERE e.resourceId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=e.resourceId)"); + final List<Integer> eventIds = query.getResultList(); + executeQuery(eventIds, "DELETE FROM " + Event.class.getSimpleName() + " WHERE id in (:ids)"); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeOrphanResources.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeOrphanResources.java new file mode 100644 index 00000000000..bc720f8fcf0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeOrphanResources.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; + +import javax.persistence.Query; +import java.util.List; + +/** + * @since 2.1 + */ +public class PurgeOrphanResources extends AbstractPurge { + + public PurgeOrphanResources(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + Query query = getSession().createQuery("SELECT r1.id FROM " + ResourceModel.class.getSimpleName() + + " r1 WHERE r1.rootId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r2 WHERE r1.rootId=r2.id)"); + List<Integer> idsToDelete = query.getResultList(); + if (idsToDelete.size() > 0) { + executeQuery(idsToDelete, "DELETE FROM " + ResourceModel.class.getSimpleName() + " WHERE id in (:ids)"); + } + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgePropertyOrphans.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgePropertyOrphans.java new file mode 100644 index 00000000000..e809dc2670c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgePropertyOrphans.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.configuration.Property; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.User; + +import javax.persistence.Query; +import java.util.List; + +/** + * @since 2.2 + */ +public class PurgePropertyOrphans extends AbstractPurge { + + public PurgePropertyOrphans(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + purgeResourceOrphans(); + purgeUserOrphans(); + } + + void purgeResourceOrphans() { + Query query = getSession().createQuery("SELECT p.id FROM " + Property.class.getSimpleName() + + " p WHERE p.resourceId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=p.resourceId)"); + List<Integer> idsToDelete = query.getResultList(); + if (idsToDelete.size() > 0) { + executeQuery(idsToDelete, "DELETE FROM " + Property.class.getSimpleName() + " WHERE id in (:ids)"); + } + } + + void purgeUserOrphans() { + Query query = getSession().createQuery("SELECT p.id FROM " + Property.class.getSimpleName() + + " p WHERE p.userId IS NOT NULL AND NOT EXISTS(FROM " + User.class.getSimpleName() + " u WHERE u.id=p.userId)"); + List<Integer> idsToDelete = query.getResultList(); + if (idsToDelete.size() > 0) { + executeQuery(idsToDelete, "DELETE FROM " + Property.class.getSimpleName() + " WHERE id in (:ids)"); + } + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeResourceRoles.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeResourceRoles.java new file mode 100644 index 00000000000..909301cc992 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeResourceRoles.java @@ -0,0 +1,54 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.security.GroupRole; +import org.sonar.api.security.UserRole; + +import javax.persistence.Query; +import java.util.List; + +/** + * @since 1.12 + */ +public class PurgeResourceRoles extends AbstractPurge { + + public PurgeResourceRoles(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + deleteRoles(UserRole.class.getSimpleName()); + deleteRoles(GroupRole.class.getSimpleName()); + } + + private void deleteRoles(String classname) { + Query query = getSession().createQuery("SELECT rol.id FROM " + classname + " rol " + + " WHERE rol.resourceId IS NOT NULL AND NOT EXISTS(FROM " + ResourceModel.class.getSimpleName() + " r WHERE r.id=rol.resourceId)"); + List<Integer> roleIds = (List<Integer>) query.getResultList(); + if (!roleIds.isEmpty()) { + executeQuery(roleIds, "delete from " + classname + " rol where rol.id in (:ids)"); + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeRuleMeasures.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeRuleMeasures.java new file mode 100644 index 00000000000..f2afd3b4b52 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeRuleMeasures.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; + +import javax.persistence.Query; +import java.util.List; + +/** + * see SONAR-522 + * + * @since 1.11 + */ +public class PurgeRuleMeasures extends AbstractPurge { + + public PurgeRuleMeasures(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + if (context.getPreviousSnapshotId() != null) { + purge(context.getPreviousSnapshotId()); + } + } + + private void purge(Integer sid) { + Query query = getSession().createQuery("SELECT m.id FROM " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s WHERE s.id = m.snapshotId and " + + "(s.rootId=:rootSid OR s.id=:rootSid) and (m.rule is not null or m.rulesCategoryId is not null or m.rulePriority is not null)"); + query.setParameter("rootSid", sid); + List<Integer> measureIds = query.getResultList(); + + deleteMeasuresById(measureIds); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeUnprocessed.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeUnprocessed.java new file mode 100644 index 00000000000..4f4a492f561 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/PurgeUnprocessed.java @@ -0,0 +1,52 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.apache.commons.lang.time.DateUtils; +import org.sonar.core.purge.AbstractPurge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; + +import javax.persistence.Query; +import java.util.Date; +import java.util.List; + +/** + * @since 1.11 + */ +public class PurgeUnprocessed extends AbstractPurge { + + private static final int MINIMUM_AGE_IN_HOURS = -12; + + public PurgeUnprocessed(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + final Date beforeDate = DateUtils.addHours(new Date(), MINIMUM_AGE_IN_HOURS); + Query query = getSession().createQuery("SELECT s.id FROM " + Snapshot.class.getSimpleName() + " s WHERE s.last=false AND status=:status AND s.createdAt<:date"); + query.setParameter("status", Snapshot.STATUS_UNPROCESSED); + query.setParameter("date", beforeDate); + List<Integer> snapshotIds = query.getResultList(); + + deleteSnapshotData(snapshotIds); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/UnflagLastDoublons.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/UnflagLastDoublons.java new file mode 100644 index 00000000000..da3c7a61202 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/purges/UnflagLastDoublons.java @@ -0,0 +1,48 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; +import org.sonar.core.purge.AbstractPurge; + +import javax.persistence.Query; +import java.util.List; + +/** + * @since 1.11 + */ +public class UnflagLastDoublons extends AbstractPurge { + + public UnflagLastDoublons(DatabaseSession session) { + super(session); + } + + public void purge(PurgeContext context) { + Query query = getSession().createQuery( + "SELECT olds.id FROM " + Snapshot.class.getSimpleName() + " olds " + + " where olds.last=true AND EXISTS (from " + Snapshot.class.getSimpleName() + " news WHERE news.last=true AND news.resourceId=olds.resourceId AND news.createdAt>olds.createdAt)"); + List<Integer> snapshotIds = query.getResultList(); + + executeQuery(snapshotIds, "UPDATE " + Snapshot.class.getSimpleName() + " SET last=false WHERE id in (:ids)"); + } +} + diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java new file mode 100644 index 00000000000..2f9f2e74779 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java @@ -0,0 +1,71 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.security; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +public class ApplyProjectRolesDecorator implements Decorator { + + private RoleManager roleManager; + + protected ApplyProjectRolesDecorator(RoleManager roleManager) { + this.roleManager = roleManager; + } + + public ApplyProjectRolesDecorator(DatabaseSession session) { + this.roleManager = new RoleManager(session); + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void decorate(Resource resource, DecoratorContext context) { + if (shouldDecorateResource(resource)) { + Project project = (Project) resource; + roleManager.affectDefaultRolesToResource(project.getId()); + } + } + + private boolean shouldDecorateResource(Resource resource) { + if (isProject(resource)) { + Project project = (Project) resource; + return project.getId() != null && countRoles(project.getId()) == 0; + } + return false; + } + + private boolean isProject(Resource resource) { + if (Resource.QUALIFIER_PROJECT.equals(resource.getQualifier()) || + Resource.QUALIFIER_VIEW.equals(resource.getQualifier()) || + Resource.QUALIFIER_SUBVIEW.equals(resource.getQualifier())) { + return resource instanceof Project; + } + return false; + } + + private int countRoles(int resourceId) { + return roleManager.getUserRoles(resourceId).size() + roleManager.getGroupRoles(resourceId).size(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/RoleManager.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/RoleManager.java new file mode 100644 index 00000000000..12bea9448a2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/RoleManager.java @@ -0,0 +1,89 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.security; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.security.GroupRole; +import org.sonar.api.security.UserRole; + +import javax.persistence.Query; +import java.util.List; + +/** + * @since 1.12 + */ +public class RoleManager { + + protected static final String DEFAULT_ROLE_PREFIX = "default-"; + private DatabaseSession session; + + public RoleManager(DatabaseSession session) { + this.session = session; + } + + public void affectDefaultRolesToResource(int resourceId) { + for (UserRole defaultRole : getDefaultUserRoles()) { + session.save(createResourceRoleFromDefault(defaultRole, resourceId)); + } + for (GroupRole defaultRole : getDefaultGroupRoles()) { + session.save(createResourceRoleFromDefault(defaultRole, resourceId)); + } + session.commit(); + } + + public List<UserRole> getUserRoles(int resourceId) { + return session.getResults(UserRole.class, "resourceId", resourceId); + } + + public List<GroupRole> getGroupRoles(int resourceId) { + return session.getResults(GroupRole.class, "resourceId", resourceId); + } + + protected List<UserRole> getDefaultUserRoles() { + final Query query = session.createQuery("from " + UserRole.class.getSimpleName() + " ur where ur.resourceId is null and ur.role like '" + DEFAULT_ROLE_PREFIX + "%'"); + return query.getResultList(); + } + + protected List<GroupRole> getDefaultGroupRoles() { + final Query query = session.createQuery("from " + GroupRole.class.getSimpleName() + " gr where gr.resourceId is null and gr.role like '" + DEFAULT_ROLE_PREFIX + "%'"); + return query.getResultList(); + } + + protected UserRole createResourceRoleFromDefault(UserRole defaultUserRole, int resourceId) { + final UserRole result = new UserRole(); + result.setRole(convertDefaultRoleName(defaultUserRole.getRole())); + result.setResourceId(resourceId); + result.setUserId(defaultUserRole.getUserId()); + return result; + } + + protected GroupRole createResourceRoleFromDefault(GroupRole defaultUserRole, int resourceId) { + final GroupRole result = new GroupRole(); + result.setRole(convertDefaultRoleName(defaultUserRole.getRole())); + result.setResourceId(resourceId); + result.setGroupId(defaultUserRole.getGroupId()); + return result; + } + + protected static String convertDefaultRoleName(String defaultRoleName) { + return StringUtils.substringAfter(defaultRoleName, DEFAULT_ROLE_PREFIX); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java new file mode 100644 index 00000000000..d6bc7c87828 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java @@ -0,0 +1,69 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +public abstract class AbstractCoverageDecorator implements Decorator { + + public boolean shouldExecuteOnProject(Project project) { + return project.getAnalysisType().isDynamic(true); + } + + @DependedUpon + public Metric generatesCoverage() { + return getTargetMetric(); + } + + public void decorate(final Resource resource, final DecoratorContext context) { + if (shouldDecorate(resource, context)) { + saveLineCoverage(context); + } + } + + protected boolean shouldDecorate(final Resource resource, final DecoratorContext context) { + return context.getMeasure(getTargetMetric()) == null && !ResourceUtils.isUnitTestClass(resource); + } + + private void saveLineCoverage(DecoratorContext context) { + Double elements = countElements(context); + Double coveredElements = countCoveredElements(context); + + if (elements != null && elements > 0.0 && coveredElements != null) { + context.saveMeasure(getTargetMetric(), calculateCoverage(coveredElements, elements)); + } + } + + private double calculateCoverage(final Double coveredLines, final Double lines) { + return (100.0 * coveredLines) / lines; + } + + protected abstract Metric getTargetMetric(); + + protected abstract Double countCoveredElements(DecoratorContext context); + + protected abstract Double countElements(DecoratorContext context); +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AlertUtils.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AlertUtils.java new file mode 100644 index 00000000000..a9741b43eb1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AlertUtils.java @@ -0,0 +1,104 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.lang.NotImplementedException; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.profiles.Alert; + +public final class AlertUtils { + private AlertUtils() { + } + + /** + * Get the matching alert level for the given measure + */ + public static Metric.Level getLevel(Alert alert, Measure measure) { + if (evaluateAlert(alert, measure, Metric.Level.ERROR)) { + return Metric.Level.ERROR; + } + if (evaluateAlert(alert, measure, Metric.Level.WARN)) { + return Metric.Level.WARN; + } + return Metric.Level.OK; + } + + private static boolean evaluateAlert(Alert alert, Measure measure, Metric.Level alertLevel) { + String valueToEval; + if (alertLevel.equals(Metric.Level.ERROR)) { + valueToEval = alert.getValueError(); + + } else if (alertLevel.equals(Metric.Level.WARN)) { + valueToEval = alert.getValueWarning(); + } else { + throw new IllegalStateException(alertLevel.toString()); + } + if (StringUtils.isEmpty(valueToEval)) { + return false; + } + + Comparable criteriaValue = getValueForComparison(alert.getMetric(), valueToEval); + Comparable metricValue = getMeasureValue(alert.getMetric(), measure); + + int comparison = metricValue.compareTo(criteriaValue); + if (alert.isNotEqualsOperator() && comparison == 0 || + alert.isGreaterOperator() && comparison != 1 || + alert.isSmallerOperator() && comparison != -1 || + alert.isEqualsOperator() && comparison != 0) { + return false; + } + return true; + } + + + private static Comparable<?> getValueForComparison(Metric metric, String value) { + if (metric.getType() == Metric.ValueType.FLOAT || + metric.getType() == Metric.ValueType.PERCENT) { + return Double.parseDouble(value); + } else if (metric.getType() == Metric.ValueType.INT || + metric.getType() == Metric.ValueType.MILLISEC) { + return value.contains(".") ? Integer.parseInt(value.substring(0, value.indexOf('.'))) : Integer.parseInt(value); + } else if (metric.getType() == Metric.ValueType.STRING || + metric.getType() == Metric.ValueType.LEVEL) { + return value; + } else if (metric.getType() == Metric.ValueType.BOOL) { + return Boolean.valueOf(value); + } + throw new NotImplementedException(metric.getType().toString()); + } + + private static Comparable<?> getMeasureValue(Metric metric, Measure measure) { + if (metric.getType() == Metric.ValueType.FLOAT || + metric.getType() == Metric.ValueType.PERCENT) { + return measure.getValue(); + } else if (metric.getType() == Metric.ValueType.INT || + metric.getType() == Metric.ValueType.MILLISEC) { + return measure.getValue().intValue(); + } else if (metric.getType() == Metric.ValueType.STRING || + metric.getType() == Metric.ValueType.LEVEL) { + return measure.getData(); + } else if (metric.getType() == Metric.ValueType.BOOL) { + return measure.getValue() == 0d ? Boolean.FALSE : Boolean.TRUE; + } + throw new NotImplementedException(metric.getType().toString()); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AsynchronousMeasuresSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AsynchronousMeasuresSensor.java new file mode 100644 index 00000000000..aef6430ae37 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AsynchronousMeasuresSensor.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Phase; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.jpa.dao.AsyncMeasuresService; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ResourceUtils; + +@Phase(name = Phase.Name.PRE) +public class AsynchronousMeasuresSensor implements Sensor { + + private AsyncMeasuresService reviewsService; + private Snapshot snapshot; + + public AsynchronousMeasuresSensor(AsyncMeasuresService reviewsService, Snapshot snapshot) { + this.reviewsService = reviewsService; + this.snapshot = snapshot; + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void analyse(Project project, SensorContext context) { + if (!ResourceUtils.isRootProject(project)) { + return; + } + reviewsService.refresh(snapshot); + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java new file mode 100644 index 00000000000..4102ec48e18 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java @@ -0,0 +1,54 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; + +import java.util.Arrays; +import java.util.List; + +public class BranchCoverageDecorator extends AbstractCoverageDecorator { + + @Override + protected Metric getTargetMetric() { + return CoreMetrics.BRANCH_COVERAGE; + } + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_TO_COVER); + } + + @Override + protected Double countCoveredElements(DecoratorContext context) { + double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0.0); + double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + return conditions - uncoveredConditions; + } + + @Override + protected Double countElements(DecoratorContext context) { + return MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java new file mode 100644 index 00000000000..8e55fa3890d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java @@ -0,0 +1,116 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.Phase; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.profiles.Alert; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.util.ArrayList; +import java.util.List; + +@Phase(name = Phase.Name.POST) +public class CheckAlertThresholds implements Decorator { + + private final RulesProfile profile; + + public CheckAlertThresholds(RulesProfile profile) { + this.profile = profile; + } + + @DependedUpon + public Metric generatesAlertStatus() { + return CoreMetrics.ALERT_STATUS; + } + + + public boolean shouldExecuteOnProject(Project project) { + return profile != null + && profile.getAlerts() != null + && profile.getAlerts().size() > 0 + && ResourceUtils.isRootProject(project); + } + + public void decorate(final Resource resource, final DecoratorContext context) { + if (shouldDecorateResource(resource)) { + decorateResource(context); + } + } + + private void decorateResource(DecoratorContext context) { + Metric.Level globalLevel = Metric.Level.OK; + List<String> labels = new ArrayList<String>(); + + for (final Alert alert : profile.getAlerts()) { + Measure measure = context.getMeasure(alert.getMetric()); + if (measure != null) { + Metric.Level level = AlertUtils.getLevel(alert, measure); + + measure.setAlertStatus(level); + String text = getText(alert, level); + if (!StringUtils.isBlank(text)) { + measure.setAlertText(text); + labels.add(text); + } + + context.saveMeasure(measure); + + if (Metric.Level.WARN == level && globalLevel != Metric.Level.ERROR) { + globalLevel = Metric.Level.WARN; + + } else if (Metric.Level.ERROR == level) { + globalLevel = Metric.Level.ERROR; + } + } + } + + Measure globalMeasure = new Measure(CoreMetrics.ALERT_STATUS, globalLevel); + globalMeasure.setAlertStatus(globalLevel); + globalMeasure.setAlertText(StringUtils.join(labels, ", ")); + context.saveMeasure(globalMeasure); + } + + private boolean shouldDecorateResource(final Resource resource) { + return ResourceUtils.isRootProject(resource); + } + + private String getText(Alert alert, Metric.Level level) { + if (level == Metric.Level.OK) { + return null; + } + return alert.getAlertLabel(level); + } + + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CommentDensityDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CommentDensityDecorator.java new file mode 100644 index 00000000000..0d9d579eb0c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CommentDensityDecorator.java @@ -0,0 +1,91 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import java.util.Arrays; +import java.util.List; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +public class CommentDensityDecorator implements Decorator { + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.NCLOC, CoreMetrics.COMMENT_LINES, CoreMetrics.PUBLIC_API, CoreMetrics.PUBLIC_UNDOCUMENTED_API); + } + + @DependedUpon + public List<Metric> generatesMetrics() { + return Arrays.asList(CoreMetrics.COMMENT_LINES_DENSITY, CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY); + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void decorate(Resource resource, DecoratorContext context) { + saveCommentsDensity(context); + savePublicApiDensity(context); + } + + private void saveCommentsDensity(DecoratorContext context) { + if (context.getMeasure(CoreMetrics.COMMENT_LINES_DENSITY) != null) { + return; + } + + Measure ncloc = context.getMeasure(CoreMetrics.NCLOC); + Measure comments = context.getMeasure(CoreMetrics.COMMENT_LINES); + if (MeasureUtils.hasValue(ncloc) && MeasureUtils.hasValue(comments)) { + if (comments.getValue() + ncloc.getValue() > 0) { + double val = 100.0 * (comments.getValue() / (comments.getValue() + ncloc.getValue())); + context.saveMeasure(new Measure(CoreMetrics.COMMENT_LINES_DENSITY, val)); + } + } + } + + private void savePublicApiDensity(DecoratorContext context) { + if (context.getMeasure(CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY) != null) { + return; + } + + Measure publicApi = context.getMeasure(CoreMetrics.PUBLIC_API); + Measure publicUndocApi = context.getMeasure(CoreMetrics.PUBLIC_UNDOCUMENTED_API); + + if (MeasureUtils.hasValue(publicApi) && MeasureUtils.hasValue(publicUndocApi) && publicApi.getValue() > 0) { + double documentedAPI = publicApi.getValue() - publicUndocApi.getValue(); + Double value = 100.0 * (documentedAPI / publicApi.getValue()); + context.saveMeasure(new Measure(CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY, value)); + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java new file mode 100644 index 00000000000..559d61e3c43 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java @@ -0,0 +1,58 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; + +import java.util.Arrays; +import java.util.List; + +public class CoverageDecorator extends AbstractCoverageDecorator { + + @Override + protected Metric getTargetMetric() { + return CoreMetrics.COVERAGE; + } + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS); + } + + @Override + protected Double countCoveredElements(DecoratorContext context) { + double uncoveredLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0.0); + double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); + double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0.0); + double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + return lines + conditions - uncoveredConditions - uncoveredLines; + } + + @Override + protected Double countElements(DecoratorContext context) { + double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); + double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + return lines + conditions; + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/DirectoriesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/DirectoriesDecorator.java new file mode 100644 index 00000000000..5df50ef6028 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/DirectoriesDecorator.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.util.Collection; + +/** + * @since 2.2 + */ +public final class DirectoriesDecorator implements Decorator { + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + @DependedUpon + public Metric generateDirectoriesMetric() { + return CoreMetrics.DIRECTORIES; + } + + /** + * {@inheritDoc} + */ + public void decorate(Resource resource, DecoratorContext context) { + if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.DIRECTORIES))) { + return; + } + + if (Resource.QUALIFIER_DIRECTORY.equals(resource.getQualifier())) { + context.saveMeasure(CoreMetrics.DIRECTORIES, 1.0); + + } else if (ResourceUtils.isSet(resource) || ResourceUtils.isView(resource) || ResourceUtils.isSubview(resource)) { + Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.DIRECTORIES); + Double sum = MeasureUtils.sum(false, childrenMeasures); + if (sum != null) { + context.saveMeasure(CoreMetrics.DIRECTORIES, sum); + } + } + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java new file mode 100644 index 00000000000..124690647e9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FilesDecorator.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +import java.util.Collection; + +/** + * @since 2.2 + */ +public final class FilesDecorator implements Decorator { + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + @DependedUpon + public Metric generateDirectoriesMetric() { + return CoreMetrics.FILES; + } + + public void decorate(Resource resource, DecoratorContext context) { + if (MeasureUtils.hasValue(context.getMeasure(CoreMetrics.FILES))) { + return; + } + + if (Resource.QUALIFIER_CLASS.equals(resource.getQualifier()) || Resource.QUALIFIER_FILE.equals(resource.getQualifier())) { + context.saveMeasure(CoreMetrics.FILES, 1.0); + + } else { + Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.FILES); + Double sum = MeasureUtils.sum(false, childrenMeasures); + if (sum != null) { + context.saveMeasure(CoreMetrics.FILES, sum); + } + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/GenerateAlertEvents.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/GenerateAlertEvents.java new file mode 100644 index 00000000000..f8af4708d3f --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/GenerateAlertEvents.java @@ -0,0 +1,92 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.*; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.util.List; + +@Phase(name = Phase.Name.POST) +public class GenerateAlertEvents implements Decorator { + + private final RulesProfile profile; + private final TimeMachine timeMachine; + + public GenerateAlertEvents(RulesProfile profile, TimeMachine timeMachine) { + this.profile = profile; + this.timeMachine = timeMachine; + } + + public boolean shouldExecuteOnProject(Project project) { + return profile != null && profile.getAlerts() != null && profile.getAlerts().size() > 0; + } + + + @DependsUpon + public Metric dependsUponAlertStatus() { + return CoreMetrics.ALERT_STATUS; + } + + public void decorate(Resource resource, DecoratorContext context) { + if (!shouldDecorateResource(resource)) { + return; + } + Measure currentStatus = context.getMeasure(CoreMetrics.ALERT_STATUS); + if (currentStatus == null) { + return; + } + + TimeMachineQuery query = new TimeMachineQuery(resource).setOnlyLastAnalysis(true).setMetrics(CoreMetrics.ALERT_STATUS); + List<Measure> measures = timeMachine.getMeasures(query); + + Measure pastStatus = (measures != null && measures.size() == 1 ? measures.get(0) : null); + if (pastStatus != null && pastStatus.getDataAsLevel() != currentStatus.getDataAsLevel()) { + createEvent(context, getName(pastStatus, currentStatus), currentStatus.getAlertText()); + + } else if (pastStatus == null && currentStatus.getDataAsLevel() != Metric.Level.OK) { + createEvent(context, getName(currentStatus), currentStatus.getAlertText()); + } + + } + + private boolean shouldDecorateResource(Resource resource) { + return ResourceUtils.isRootProject(resource); + } + + private String getName(Measure pastStatus, Measure currentStatus) { + return getName(currentStatus) + " (was " + getName(pastStatus) + ")"; + + } + + private String getName(Measure currentStatus) { + return currentStatus.getDataAsLevel().getColorName(); + } + + private void createEvent(DecoratorContext context, String name, String description) { + context.createEvent(name, description, Event.CATEGORY_ALERT, null); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/JavaSourceImporter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/JavaSourceImporter.java new file mode 100644 index 00000000000..b54a223fced --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/JavaSourceImporter.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.AbstractSourceImporter; +import org.sonar.api.batch.Phase; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.Resource; + +import java.io.File; +import java.util.List; + +@Phase(name = Phase.Name.PRE) +public class JavaSourceImporter extends AbstractSourceImporter { + + public JavaSourceImporter() { + super(Java.INSTANCE); + } + + @Override + protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) { + return (file != null && !file.getName().contains("$")) ? JavaFile.fromIOFile(file, sourceDirs, unitTest) : null; + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java new file mode 100644 index 00000000000..c97cc7784bf --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java @@ -0,0 +1,54 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; + +import java.util.Arrays; +import java.util.List; + +public class LineCoverageDecorator extends AbstractCoverageDecorator { + + @Override + protected Metric getTargetMetric() { + return CoreMetrics.LINE_COVERAGE; + } + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER); + } + + @Override + protected Double countCoveredElements(DecoratorContext context) { + double uncoveredLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0.0); + double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); + return lines - uncoveredLines; + } + + @Override + protected Double countElements(DecoratorContext context) { + return MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileSensor.java new file mode 100644 index 00000000000..661ea9f83d7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileSensor.java @@ -0,0 +1,55 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; + +public class ProfileSensor implements Sensor { + + private RulesProfile profile; + + public ProfileSensor(RulesProfile profile) { + this.profile = profile; + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void analyse(Project project, SensorContext context) { + if (profile != null) { + Measure measure = new Measure(CoreMetrics.PROFILE, profile.getName()); + if (profile.getId() != null) { + measure.setValue(profile.getId().doubleValue()); + } + context.saveMeasure(measure); + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java new file mode 100644 index 00000000000..32e1503a991 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java @@ -0,0 +1,81 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.lang.StringUtils; +import org.apache.maven.model.CiManagement; +import org.apache.maven.model.IssueManagement; +import org.apache.maven.model.Scm; +import org.apache.maven.project.MavenProject; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; + +public class ProjectLinksSensor implements Sensor { + + public static final String KEY_HOME = "homepage"; + public static final String KEY_CONTINUOUS_INTEGRATION = "ci"; + public static final String KEY_ISSUE_TRACKER = "issue"; + public static final String KEY_SCM = "scm"; + public static final String KEY_SCM_DEVELOPER_CONNECTION = "scm_dev"; + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void analyse(Project project, SensorContext context) { + MavenProject pom = project.getPom(); + updateLink(context, KEY_HOME, "Home", pom.getUrl()); + + Scm scm = pom.getScm(); + if (scm == null) { + scm = new Scm(); + } + updateLink(context, KEY_SCM, "Sources", scm.getUrl()); + updateLink(context, KEY_SCM_DEVELOPER_CONNECTION, "Developer connection", scm.getDeveloperConnection()); + + + CiManagement ci = pom.getCiManagement(); + if (ci == null) { + ci = new CiManagement(); + } + updateLink(context, KEY_CONTINUOUS_INTEGRATION, "Continuous integration", ci.getUrl()); + + IssueManagement issues = pom.getIssueManagement(); + if (issues == null) { + issues = new IssueManagement(); + } + updateLink(context, KEY_ISSUE_TRACKER, "Issues", issues.getUrl()); + } + + private void updateLink(SensorContext context, String key, String name, String url) { + if (StringUtils.isBlank(url)) { + context.deleteLink(key); + } else { + context.saveLink(new ProjectLink(key, name, url)); + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/TendencyAnalyser.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/TendencyAnalyser.java new file mode 100644 index 00000000000..0ffde81e912 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/TendencyAnalyser.java @@ -0,0 +1,191 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.sensors;
+
+import java.util.List;
+
+public class TendencyAnalyser {
+
+ public final static Integer TENDENCY_BIG_UP = 2;
+ public final static Integer TENDENCY_UP = 1;
+ public final static Integer TENDENCY_NEUTRAL = 0;
+ public final static Integer TENDENCY_DOWN = -1;
+ public final static Integer TENDENCY_BIG_DOWN = -2;
+
+ public Integer analyseLevel(List<Double> values) {
+ TendencyAnalyser.SlopeData slopeData = analyse(values);
+ if (slopeData != null) {
+ return slopeData.getLevel();
+ }
+ return null;
+ }
+
+ public SlopeData analyse(List<Double> values) {
+ double sumY = 0.0;
+ double sumX = 0.0;
+ double sumYPower2 = 0.0;
+ double sumXY = 0.0;
+ double sumXPower2 = 0.0;
+ int nbrPoints = 0;
+ boolean nullValuesYList = true;
+ int i = 0;
+ for (Double p : values) {
+ if (p != null) {
+ nullValuesYList = false;
+ //SumY calculation
+ sumY += p;
+ // sumYPower2 calculation
+ sumYPower2 += p * p;
+ //sumXY calculation
+ sumXY += p * (i + 1);
+ //SumX calculation
+ sumX += (i + 1);
+ //sumXPower2 calculation
+ sumXPower2 += (i + 1) * (i + 1);
+ //Point number calculation
+ nbrPoints++;
+ }
+ i++;
+ }
+ // no tendency if null values or only 1 value
+ if (nullValuesYList || nbrPoints == 1) {
+ return null;
+ }
+ double n0 = (((nbrPoints) * (sumXY)) - ((sumX) * (sumY)));
+ double d = (((nbrPoints) * (sumXPower2)) - ((sumX) * (sumX)));
+ double n1 = (((sumY) * (sumXPower2)) - ((sumX) * (sumXY)));
+
+ SlopeData result = new SlopeData();
+
+ //yIntercept Calculation the value when X equals zero
+ result.setYIntercept(n1 / d);
+ // Slope Calculation
+ if (n0 == 0d && d == 0d) {
+ result.setSlope(0.0);
+ } else {
+ Double slope = n0 / d;
+ if (Double.isNaN(slope) || Double.isInfinite(slope)) {
+ result.setSlope(null);
+ } else {
+ result.setSlope(slope);
+ }
+ }
+ result.setSumXPower2(sumXPower2);
+ result.setSumXY(sumXY);
+ result.setSumYPower2(sumYPower2);
+
+ if (sumXPower2 == 0 || sumYPower2 == 0) {
+ result.setCorrelationRate(0.0);
+ } else {
+ result.setCorrelationRate((sumXY) / (Math.sqrt(sumXPower2 * sumYPower2)));
+ }
+
+ return result;
+ }
+
+
+ static class SlopeData {
+ private double sumXPower2;
+ private double sumYPower2;
+ private double sumXY;
+ private double yIntercept; // not used today
+ private Double slope;
+ private Double correlationRate;
+
+ public double getSumXPower2() {
+ return sumXPower2;
+ }
+
+ public void setSumXPower2(double sumXPower2) {
+ this.sumXPower2 = sumXPower2;
+ }
+
+ public double getSumYPower2() {
+ return sumYPower2;
+ }
+
+ public void setSumYPower2(double sumYPower2) {
+ this.sumYPower2 = sumYPower2;
+ }
+
+ public double getSumXY() {
+ return sumXY;
+ }
+
+ public void setSumXY(double sumXY) {
+ this.sumXY = sumXY;
+ }
+
+ public double getYIntercept() {
+ return yIntercept;
+ }
+
+ public void setYIntercept(double yIntercept) {
+ this.yIntercept = yIntercept;
+ }
+
+ public Double getSlope() {
+ return slope;
+ }
+
+ public void setSlope(Double slope) {
+ this.slope = slope;
+ }
+
+ public Double getCorrelationRate() {
+ return correlationRate;
+ }
+
+ public void setCorrelationRate(Double correlationRate) {
+ this.correlationRate = correlationRate;
+ }
+
+ public Integer getLevel() {
+ double hSlope = 0.8;
+ double nSlope = 0.2;
+
+ double vHighCorcoef = 1.0;
+ double modCorcoef = 0.69;
+ Double correlationCoeff = getCorrelationRate();
+ Double slope = getSlope();
+ boolean vHCorCoefPos = (correlationCoeff > modCorcoef) && (correlationCoeff <= vHighCorcoef);
+ boolean vHCorCoefNeg = (correlationCoeff < -modCorcoef) && (correlationCoeff >= -vHighCorcoef);
+
+ if ((vHCorCoefPos || vHCorCoefNeg) && (slope >= hSlope)) {
+ return TENDENCY_BIG_UP;
+
+ } else if ((vHCorCoefPos || vHCorCoefNeg) && (slope <= -hSlope)) {
+ return TENDENCY_BIG_DOWN;
+
+ } else if ((vHCorCoefPos || vHCorCoefNeg) && ((slope >= nSlope) && (slope < hSlope))) {
+ return TENDENCY_UP;
+
+ } else if ((vHCorCoefPos || vHCorCoefNeg) && ((slope <= -nSlope) && (slope > -hSlope))) {
+ return TENDENCY_DOWN;
+
+ } else if ((vHCorCoefPos || vHCorCoefNeg) && ((slope < nSlope) || (slope > -nSlope))) {
+ return TENDENCY_NEUTRAL;
+ } else if (correlationCoeff == 0 && slope == 0 && !vHCorCoefPos && !vHCorCoefNeg) {
+ return TENDENCY_NEUTRAL;
+ }
+ return null;
+ }
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/TendencyDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/TendencyDecorator.java new file mode 100644 index 00000000000..dcc6c28bd33 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/TendencyDecorator.java @@ -0,0 +1,112 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import com.google.common.collect.ArrayListMultimap; +import org.apache.commons.lang.time.DateUtils; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.*; +import org.sonar.jpa.dao.MeasuresDao; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.util.ArrayList; +import java.util.List; + +@Phase(name = Phase.Name.POST) +public class TendencyDecorator implements Decorator { + + public static final String PROP_DAYS_DESCRIPTION = "Number of days the tendency should be calculated on."; + + private MeasuresDao measuresDao; + private TimeMachine timeMachine; + private TimeMachineQuery query; + private TendencyAnalyser analyser; + + public TendencyDecorator(TimeMachine timeMachine, MeasuresDao measuresDao) { + this.timeMachine = timeMachine; + this.measuresDao = measuresDao; + this.analyser = new TendencyAnalyser(); + } + + protected TendencyDecorator(TimeMachine timeMachine, TimeMachineQuery query, TendencyAnalyser analyser) { + this.timeMachine = timeMachine; + this.query = query; + this.analyser = analyser; + } + + protected TimeMachineQuery initQuery(Project project) { + int days = project.getConfiguration().getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE); + + List<Metric> metrics = new ArrayList<Metric>(); + for (Metric metric : measuresDao.getMetrics()) { + if (metric.isNumericType()) { + metrics.add(metric); + } + } + + query = new TimeMachineQuery(null) // resource is set after + .setFrom(DateUtils.addDays(project.getAnalysisDate(), -days)) + .setToCurrentAnalysis(true) + .setMetrics(metrics); + return query; + } + + protected TimeMachineQuery resetQuery(Project project, Resource resource) { + if (query == null) { + initQuery(project); + } + query.setResource(resource); + return query; + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void decorate(Resource resource, DecoratorContext context) { + if (shouldDecorateResource(resource)) { + resetQuery(context.getProject(), resource); + List<Object[]> fields = timeMachine.getMeasuresFields(query); + ArrayListMultimap<Metric, Double> valuesPerMetric = ArrayListMultimap.create(); + for (Object[] field : fields) { + valuesPerMetric.put((Metric) field[1], (Double) field[2]); + } + + for (Metric metric : query.getMetrics()) { + Measure measure = context.getMeasure(metric); + if (measure != null) { + List<Double> values = valuesPerMetric.get(metric); + values.add(measure.getValue()); + + measure.setTendency(analyser.analyseLevel(valuesPerMetric.get(metric))); + context.saveMeasure(measure); + } + } + } + } + + private boolean shouldDecorateResource(Resource resource) { + return ResourceUtils.isSet(resource) || ResourceUtils.isSpace(resource); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UncoveredComplexityDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UncoveredComplexityDecorator.java new file mode 100644 index 00000000000..2af5b2f3d08 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UncoveredComplexityDecorator.java @@ -0,0 +1,74 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.utils.KeyValueFormat; + +import java.util.Arrays; +import java.util.List; + +/** + * @deprecated the metric <code>CoreMetrics.UNCOVERED_COMPLEXITY_BY_TESTS</code> is deprecated since v.1.11. + * It's replaced by uncovered_line and uncovered_conditions + */ +@Deprecated +public class UncoveredComplexityDecorator implements Decorator { + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.COVERAGE, CoreMetrics.COMPLEXITY); + } + + @DependedUpon + public Metric generatesMetric() { + return CoreMetrics.UNCOVERED_COMPLEXITY_BY_TESTS; + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void decorate(Resource resource, DecoratorContext context) { + Measure coverage = context.getMeasure(CoreMetrics.COVERAGE); + Measure complexity = context.getMeasure(CoreMetrics.COMPLEXITY); + + if (MeasureUtils.haveValues(coverage, complexity)) { + double value = complexity.getValue() - (complexity.getValue() * (coverage.getValue() / 100.0)); + String data = KeyValueFormat.format("CMP", complexity.getValue().intValue(), "COV", coverage.getValue()); + context.saveMeasure(new Measure(CoreMetrics.UNCOVERED_COMPLEXITY_BY_TESTS, value, data)); + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} + diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UnitTestDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UnitTestDecorator.java new file mode 100644 index 00000000000..8bc670aec9d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/UnitTestDecorator.java @@ -0,0 +1,94 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasureUtils; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class UnitTestDecorator implements Decorator { + + @DependedUpon + public List<Metric> generatesMetrics() { + return Arrays.asList(CoreMetrics.TEST_EXECUTION_TIME, CoreMetrics.TESTS, CoreMetrics.TEST_ERRORS, CoreMetrics.TEST_FAILURES, CoreMetrics.TEST_SUCCESS_DENSITY); + } + + public boolean shouldExecuteOnProject(Project project) { + return !Project.AnalysisType.STATIC.equals(project.getAnalysisType()); + } + + public boolean shouldDecorateResource(Resource resource) { + return ResourceUtils.isUnitTestClass(resource) || !ResourceUtils.isEntity(resource); + } + + public void decorate(Resource resource, DecoratorContext context) { + if (shouldDecorateResource(resource)) { + sumChildren(context, CoreMetrics.TEST_EXECUTION_TIME); + sumChildren(context, CoreMetrics.SKIPPED_TESTS); + Double tests = sumChildren(context, CoreMetrics.TESTS); + Double errors = sumChildren(context, CoreMetrics.TEST_ERRORS); + Double failures = sumChildren(context, CoreMetrics.TEST_FAILURES); + + if (isPositive(tests, true) && isPositive(errors, false) && isPositive(failures, false)) { + Double errorsAndFailuresRatio = (errors + failures) * 100.0 / tests; + context.saveMeasure(CoreMetrics.TEST_SUCCESS_DENSITY, 100.0 - errorsAndFailuresRatio); + } + } + } + + private boolean isPositive(Double d, boolean strict) { + return d != null && (strict ? d > 0.0 : d >= 0.0); + } + + private Double sumChildren(DecoratorContext jobContext, Metric metric) { + Collection<Measure> childrenMeasures = jobContext.getChildrenMeasures(metric); + if (childrenMeasures != null && childrenMeasures.size() > 0) { + Double sum = 0.0; + boolean hasChildrenMeasures = false; + for (Measure measure : childrenMeasures) { + if (MeasureUtils.hasValue(measure)) { + sum += measure.getValue(); + hasChildrenMeasures = true; + } + } + if (hasChildrenMeasures) { + jobContext.saveMeasure(metric, sum); + return sum; + } + } + return null; + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/VersionEventsSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/VersionEventsSensor.java new file mode 100644 index 00000000000..97c572ed9f7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/VersionEventsSensor.java @@ -0,0 +1,74 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.time.DateUtils; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; + +import java.util.Iterator; + +public class VersionEventsSensor implements Sensor { + + private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void analyse(Project project, SensorContext context) { + if (StringUtils.isBlank(project.getAnalysisVersion())) { + return; + } + deleteDeprecatedEvents(project, context); + context.createEvent(project, project.getAnalysisVersion(), null, Event.CATEGORY_VERSION, null); + } + + private void deleteDeprecatedEvents(Project project, SensorContext context) { + String version = project.getAnalysisVersion(); + String snapshotVersionToDelete = (version.endsWith(SNAPSHOT_SUFFIX) ? "" : version + SNAPSHOT_SUFFIX); + for (Iterator<Event> it = context.getEvents(project).iterator(); it.hasNext();) { + Event event = it.next(); + if (event.isVersionCategory()) { + if (version.equals(event.getName()) || snapshotVersionToDelete.equals(event.getName())) { + it.remove(); + context.deleteEvent(event); + event = null; + } + } + + if (event != null && !event.isLinkedToSnapshot() && + event.getDate() != null && project.getAnalysisDate() != null && + DateUtils.isSameDay(event.getDate(), project.getAnalysisDate())) { + it.remove(); + context.deleteEvent(event); + context.createEvent(project, event.getName(), event.getDescription(), event.getCategory(), null); + } + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java new file mode 100644 index 00000000000..85febaa6e96 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java @@ -0,0 +1,160 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import org.sonar.api.batch.*; +import org.sonar.api.measures.*; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.rules.Violation; + +import java.util.*; + +@DependsUpon(classes = GeneratesViolations.class) +public class ViolationsDecorator implements Decorator { + + // temporary data for current resource + private Multiset<Rule> rules = HashMultiset.create(); + private Multiset<Integer> categories = HashMultiset.create(); + private Multiset<RulePriority> priorities = HashMultiset.create(); + private Map<Rule, RulePriority> ruleToLevel = new HashMap<Rule, RulePriority>(); + private int total = 0; + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + @DependedUpon + public List<Metric> generatesViolationsMetrics() { + return Arrays.asList(CoreMetrics.VIOLATIONS, + CoreMetrics.BLOCKER_VIOLATIONS, CoreMetrics.CRITICAL_VIOLATIONS, CoreMetrics.MAJOR_VIOLATIONS, CoreMetrics.MINOR_VIOLATIONS, CoreMetrics.INFO_VIOLATIONS, + CoreMetrics.USABILITY, CoreMetrics.MAINTAINABILITY, CoreMetrics.EFFICIENCY, CoreMetrics.PORTABILITY, CoreMetrics.RELIABILITY); + } + + public void decorate(Resource resource, DecoratorContext context) { + if (shouldDecorateResource(resource, context)) { + countViolations(context); + } + } + + private boolean shouldDecorateResource(Resource resource, DecoratorContext context) { + return !ResourceUtils.isUnitTestClass(resource) && context.getMeasure(CoreMetrics.VIOLATIONS) == null; + } + + private void resetCounters() { + rules.clear(); + categories.clear(); + priorities.clear(); + ruleToLevel.clear(); + total = 0; + } + + private void countViolations(DecoratorContext context) { + resetCounters(); + countCurrentResourceViolations(context); + saveTotalViolations(context); + saveViolationsByPriority(context); + saveViolationsByCategory(context); + saveViolationsByRule(context); + } + + private void saveViolationsByPriority(DecoratorContext context) { + for (RulePriority priority : RulePriority.values()) { + Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.rulePriority(CoreMetrics.VIOLATIONS, priority)); + double sum = MeasureUtils.sum(true, children) + priorities.count(priority); + context.saveMeasure(RuleMeasure.createForPriority(CoreMetrics.VIOLATIONS, priority, sum)); + context.saveMeasure(new Measure(getMetricForPriority(priority), sum)); + } + } + + private Metric getMetricForPriority(RulePriority priority) { + Metric metric = null; + if (priority.equals(RulePriority.BLOCKER)) { + metric = CoreMetrics.BLOCKER_VIOLATIONS; + } else if (priority.equals(RulePriority.CRITICAL)) { + metric = CoreMetrics.CRITICAL_VIOLATIONS; + } else if (priority.equals(RulePriority.MAJOR)) { + metric = CoreMetrics.MAJOR_VIOLATIONS; + } else if (priority.equals(RulePriority.MINOR)) { + metric = CoreMetrics.MINOR_VIOLATIONS; + } else if (priority.equals(RulePriority.INFO)) { + metric = CoreMetrics.INFO_VIOLATIONS; + } + return metric; + } + + private void saveViolationsByCategory(DecoratorContext context) { + Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.ruleCategories(CoreMetrics.VIOLATIONS)); + for (Measure childMeasure : children) { + RuleMeasure childCategMeasure = (RuleMeasure) childMeasure; + categories.add(childCategMeasure.getRuleCategory(), childCategMeasure.getValue().intValue()); + } + + for (Multiset.Entry<Integer> entry : categories.entrySet()) { + context.saveMeasure(RuleMeasure.createForCategory(CoreMetrics.VIOLATIONS, entry.getElement(), (double) entry.getCount())); + } + } + + private void saveViolationsByRule(DecoratorContext context) { + Collection<Measure> children = context.getChildrenMeasures(MeasuresFilters.rules(CoreMetrics.VIOLATIONS)); + for (Measure childMeasure : children) { + RuleMeasure childRuleMeasure = (RuleMeasure) childMeasure; + Rule rule = childRuleMeasure.getRule(); + if (rule != null && MeasureUtils.hasValue(childRuleMeasure)) { + rules.add(rule, childRuleMeasure.getValue().intValue()); + ruleToLevel.put(childRuleMeasure.getRule(), childRuleMeasure.getRulePriority()); + } + } + for (Multiset.Entry<Rule> entry : rules.entrySet()) { + Rule rule = entry.getElement(); + RuleMeasure measure = RuleMeasure.createForRule(CoreMetrics.VIOLATIONS, rule, (double) entry.getCount()); + measure.setRuleCategory(rule.getCategoryId()); + measure.setRulePriority(ruleToLevel.get(rule)); + context.saveMeasure(measure); + } + } + + private void saveTotalViolations(DecoratorContext context) { + Collection<Measure> childrenViolations = context.getChildrenMeasures(CoreMetrics.VIOLATIONS); + Double sum = MeasureUtils.sum(true, childrenViolations) + total; + context.saveMeasure(new Measure(CoreMetrics.VIOLATIONS, sum)); + } + + private void countCurrentResourceViolations(DecoratorContext context) { + List<Violation> violations = context.getViolations(); + for (Violation violation : violations) { + rules.add(violation.getRule()); + categories.add(violation.getRule().getCategoryId()); + priorities.add(violation.getPriority()); + ruleToLevel.put(violation.getRule(), violation.getPriority()); + } + total = violations.size(); + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDensityDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDensityDecorator.java new file mode 100644 index 00000000000..0f4e9714fd9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDensityDecorator.java @@ -0,0 +1,140 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; +import org.sonar.jpa.dao.RulesDao; +import org.sonar.api.measures.*; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; +import org.sonar.api.rules.Iso9126RulesCategories; +import org.sonar.api.rules.RulesCategory; + +import java.util.*; + +public class ViolationsDensityDecorator implements Decorator { + + private Map<Integer, Metric> metricByCategoryId; + + public ViolationsDensityDecorator(RulesDao rulesDao) { + metricByCategoryId = new HashMap<Integer, Metric>(); + for (RulesCategory category : rulesDao.getCategories()) { + if (category.equals(Iso9126RulesCategories.EFFICIENCY)) { + metricByCategoryId.put(category.getId(), CoreMetrics.EFFICIENCY); + + } else if (category.equals(Iso9126RulesCategories.MAINTAINABILITY)) { + metricByCategoryId.put(category.getId(), CoreMetrics.MAINTAINABILITY); + + } else if (category.equals(Iso9126RulesCategories.PORTABILITY)) { + metricByCategoryId.put(category.getId(), CoreMetrics.PORTABILITY); + + } else if (category.equals(Iso9126RulesCategories.RELIABILITY)) { + metricByCategoryId.put(category.getId(), CoreMetrics.RELIABILITY); + + } else if (category.equals(Iso9126RulesCategories.USABILITY)) { + metricByCategoryId.put(category.getId(), CoreMetrics.USABILITY); + } + } + } + + protected ViolationsDensityDecorator(Map<Integer, Metric> metricByCategoryId) { + this.metricByCategoryId = metricByCategoryId; + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + @DependsUpon + public List<Metric> dependsUponWeightedViolationsAndNcloc() { + return Arrays.asList(CoreMetrics.WEIGHTED_VIOLATIONS, CoreMetrics.NCLOC); + } + + @DependedUpon + public Metric generatesViolationsDensity() { + return CoreMetrics.VIOLATIONS_DENSITY; + } + + public void decorate(Resource resource, DecoratorContext context) { + if (shouldDecorateResource(context)) { + decorateDensity(resource, context); + } + } + + protected boolean shouldDecorateResource(DecoratorContext context) { + return context.getMeasure(CoreMetrics.VIOLATIONS_DENSITY) == null; + } + + private void decorateDensity(Resource resource, DecoratorContext context) { + Measure ncloc = context.getMeasure(CoreMetrics.NCLOC); + if (MeasureUtils.hasValue(ncloc) && ncloc.getValue() > 0.0) { + saveDensity(context, ncloc.getValue().intValue()); + if (ResourceUtils.isSpace(resource) || ResourceUtils.isSet(resource)) { + saveDensityByCategory(context, ncloc.getValue().intValue()); + } + } + } + + private void saveDensity(DecoratorContext context, int ncloc) { + Measure debt = context.getMeasure(CoreMetrics.WEIGHTED_VIOLATIONS); + Integer debtValue = 0; + if (MeasureUtils.hasValue(debt)) { + debtValue = debt.getValue().intValue(); + } + double density = calculate(debtValue, ncloc); + context.saveMeasure(CoreMetrics.VIOLATIONS_DENSITY, density); + } + + protected static double calculate(int debt, int ncloc) { + double rci = (1.0 - ((double) debt / (double) ncloc)) * 100.0; + rci = Math.max(rci, 0.0); + return rci; + } + + private void saveDensityByCategory(DecoratorContext context, int ncloc) { + Collection<RuleMeasure> categDebts = context.getMeasures(MeasuresFilters.ruleCategories(CoreMetrics.WEIGHTED_VIOLATIONS)); + Set<Integer> categIdsDone = new HashSet<Integer>(); + if (categDebts != null) { + for (RuleMeasure categDebt : categDebts) { + if (MeasureUtils.hasValue(categDebt)) { + double density = calculate(categDebt.getValue().intValue(), ncloc); + context.saveMeasure(RuleMeasure.createForCategory( + CoreMetrics.VIOLATIONS_DENSITY, categDebt.getRuleCategory(), density)); + context.saveMeasure(metricByCategoryId.get(categDebt.getRuleCategory()), density); + categIdsDone.add(categDebt.getRuleCategory()); + } + } + } + for (Map.Entry<Integer, Metric> entry : metricByCategoryId.entrySet()) { + if (!categIdsDone.contains(entry.getKey())) { + context.saveMeasure(entry.getValue(), 100.0); + } + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java new file mode 100644 index 00000000000..36c993e4d7d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/WeightedViolationsDecorator.java @@ -0,0 +1,111 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import com.google.common.collect.Multiset; +import com.google.common.collect.TreeMultiset; +import org.apache.commons.lang.ObjectUtils; +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.measures.*; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.rules.RuleUtils; +import org.sonar.api.utils.KeyValueFormat; + +import java.util.HashMap; +import java.util.Map; + +public class WeightedViolationsDecorator implements Decorator { + + private Map<RulePriority, Integer> weights; + + + @DependsUpon + public Metric dependsUponViolations() { + return CoreMetrics.VIOLATIONS; + } + + @DependedUpon + public Metric generatesWeightedViolations() { + return CoreMetrics.WEIGHTED_VIOLATIONS; + } + + public WeightedViolationsDecorator() { + } + + /** + * for unit tests + */ + protected WeightedViolationsDecorator(Map<RulePriority, Integer> weights) { + this.weights = weights; + } + + private void loadWeights(DecoratorContext context) { + if (weights == null && context != null) { + weights = RuleUtils.getPriorityWeights(context.getProject().getConfiguration()); + } + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + + public void decorate(Resource resource, DecoratorContext context) { + loadWeights(context); + + double debt = 0.0; + Multiset<RulePriority> violationsByPriority = TreeMultiset.create(); + Map<Integer, Double> categoryDebt = new HashMap<Integer, Double>(); + + for (RuleMeasure violations : context.getMeasures(MeasuresFilters.rules(CoreMetrics.VIOLATIONS))) { + if (MeasureUtils.hasValue(violations)) { + violationsByPriority.add(violations.getRulePriority(), violations.getValue().intValue()); + double add = (int) weights.get(violations.getRulePriority()) * violations.getValue(); + debt += add; + + Double categoryVal = (Double) ObjectUtils.defaultIfNull(categoryDebt.get(violations.getRuleCategory()), 0.0); + categoryDebt.put(violations.getRuleCategory(), categoryVal + add); + } + } + + Measure debtMeasure = new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, debt, KeyValueFormat.format(violationsByPriority)); + saveMeasure(context, debtMeasure); + + for (Map.Entry<Integer, Double> entry : categoryDebt.entrySet()) { + RuleMeasure categDebt = RuleMeasure.createForCategory(CoreMetrics.WEIGHTED_VIOLATIONS, entry.getKey(), entry.getValue()); + categDebt.setPersistenceMode(PersistenceMode.MEMORY); + saveMeasure(context, categDebt); + } + } + + private void saveMeasure(DecoratorContext context, Measure debtMeasure) { + if (debtMeasure.getValue() > 0.0) { + context.saveMeasure(debtMeasure); + } + } + + protected Map<RulePriority, Integer> getWeights() { + return weights; + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java new file mode 100644 index 00000000000..0cca72a7d7b --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/TestsViewerDefinition.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.testdetailsviewer; + +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.resources.Resource; +import org.sonar.api.web.*; +import org.sonar.plugins.core.testdetailsviewer.client.TestsViewer; + +@ResourceQualifier(Resource.QUALIFIER_UNIT_TEST_CLASS) +@NavigationSection(NavigationSection.RESOURCE_TAB) +@DefaultTab(metrics={CoreMetrics.TESTS_KEY, CoreMetrics.TEST_EXECUTION_TIME_KEY, CoreMetrics.TEST_SUCCESS_DENSITY_KEY, CoreMetrics.TEST_FAILURES_KEY, CoreMetrics.TEST_ERRORS_KEY, CoreMetrics.SKIPPED_TESTS_KEY}) +@UserRole(UserRole.CODEVIEWER) +public class TestsViewerDefinition extends GwtPage { + + public String getTitle() { + return "Tests"; + } + + public String getGwtId() { + return TestsViewer.GWT_ID; + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/client/TestsPanel.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/client/TestsPanel.java new file mode 100644 index 00000000000..ace2bb747a6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/client/TestsPanel.java @@ -0,0 +1,168 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.testdetailsviewer.client; + +import com.google.gwt.gen2.table.override.client.FlexTable; +import com.google.gwt.gen2.table.override.client.FlexTable.FlexCellFormatter; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.ui.*; +import com.google.gwt.xml.client.Document; +import com.google.gwt.xml.client.Element; +import com.google.gwt.xml.client.NodeList; +import com.google.gwt.xml.client.XMLParser; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.ExpandCollapseLink; +import org.sonar.gwt.ui.Loading; +import org.sonar.wsclient.gwt.AbstractCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +public class TestsPanel extends Composite { + + private final Panel panel; + private Loading loading; + + public TestsPanel(Resource resource) { + panel = new VerticalPanel(); + loading = new Loading(); + panel.add(loading); + initWidget(panel); + setStyleName("gwt-TestDetailsPanel"); + getElement().setId("gwt-TestDetailsPanel"); + loadData(resource); + } + + private void loadData(Resource resource) { + ResourceQuery query = ResourceQuery.createForResource(resource, Metrics.TEST_DATA); + Sonar.getInstance().find(query, new TestDetailsMeasureHandler()); + } + + private class TestDetailsMeasureHandler extends AbstractCallback<Resource> { + + public TestDetailsMeasureHandler() { + super(loading); + } + + @Override + protected void doOnResponse(Resource resource) { + loading.removeFromParent(); + if (resource != null) { + Measure measure = resource.getMeasure(Metrics.TEST_DATA); + processTestDetails(measure.getData()); + } + } + + private void processTestDetails(String testXMLData) { + Document parsed = XMLParser.parse(testXMLData); + NodeList testcasesXML = parsed.getElementsByTagName("testcase"); + + FlexTable table = new FlexTable(); + table.setStylePrimaryName("detailsTable"); + table.setText(0, 0, ""); + table.setText(0, 1, ""); + table.setText(0, 2, "Duration"); + table.setText(0, 3, "Unit test name"); + table.getCellFormatter().getElement(0, 1).setId("iCol"); + table.getCellFormatter().getElement(0, 2).setId("dCol"); + setRowStyle(0, table, "header", false); + + int rowCounter = 1; + for (int i = 0; i < testcasesXML.getLength(); i++) { + Element testcaseXML = (Element) testcasesXML.item(i); + String time = testcaseXML.getAttribute("time"); + String name = testcaseXML.getAttribute("name"); + String status = testcaseXML.getAttribute("status"); + Element error = getFirstElement("error", testcaseXML); + Element failure = getFirstElement("failure", testcaseXML); + Element stackTrace = status.equals("error") ? error : failure; + renderTestDetails(rowCounter, i, status, stackTrace, name, time, table); + rowCounter += 2; + } + panel.add(table); + } + + private Element getFirstElement(String elementName, Element node) { + NodeList elements = node.getElementsByTagName(elementName); + return elements.getLength() > 0 ? (Element) elements.item(0) : null; + } + + private void renderTestDetails(int row, int testCounter, String testCaseStatus, Element stackTrace, String name, String timeMS, FlexTable table) { + + HTML icon = new HTML(" "); + icon.setStyleName(testCaseStatus); + table.setWidget(row, 1, icon); + table.setText(row, 2, timeMS + " ms"); + + table.setText(row, 3, name); + String style = (testCounter % 2 == 0) ? "odd" : "even"; + setRowStyle(row, table, style, false); + + if (stackTrace != null) { + Panel stackPanel = new SimplePanel(); + stackPanel.setStyleName("stackPanel"); + stackPanel.getElement().setId("stack-panel" + name); + stackPanel.setVisible(false); + fillStackPanel(stackPanel, stackTrace); + + FlexCellFormatter frmt = (FlexCellFormatter) table.getCellFormatter(); + frmt.setColSpan(row + 1, 1, 3); + table.setWidget(row + 1, 1, stackPanel); + table.setWidget(row, 0, new ExpandCollapseLink(stackPanel)); + table.getCellFormatter().getElement(row, 0).setId("expandCollapseCol"); + setRowStyle(row + 1, table, style, true); + } + } + + private void setRowStyle(int row, FlexTable table, String style, boolean isPanelRow) { + table.getCellFormatter().setStyleName(row, 0, style); + table.getCellFormatter().setStyleName(row, 1, style); + if (!isPanelRow) { + table.getCellFormatter().setStyleName(row, 2, style); + table.getCellFormatter().setStyleName(row, 3, style); + } + table.getCellFormatter().getElement(row, 0).setId("noLinkExpandCollapseCol"); + } + } + + private void fillStackPanel(Panel p, Element stackElement) { + String message = stackElement.getAttribute("message"); + if (message.length() > 0) { + p.getElement().setInnerHTML(escapeHtml(message) + "<br/>" + stackLineBreaks(stackElement.getFirstChild().getNodeValue())); + } else { + p.getElement().setInnerHTML(stackLineBreaks(stackElement.getFirstChild().getNodeValue())); + } + } + + private String escapeHtml(String maybeHtml) { + com.google.gwt.dom.client.Element div = DOM.createDiv(); + div.setInnerText(maybeHtml); + return div.getInnerHTML(); + } + + private String stackLineBreaks(String s) { + StringBuilder stack = new StringBuilder(256); + for (String el : s.split("\n")) { + stack.append(el.trim()).append("<br/>"); + } + return stack.toString(); + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/client/TestsViewer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/client/TestsViewer.java new file mode 100644 index 00000000000..e6dfc2545e1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/testdetailsviewer/client/TestsViewer.java @@ -0,0 +1,87 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.testdetailsviewer.client; + +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Widget; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Page; +import org.sonar.gwt.ui.ViewerHeader; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; + +public class TestsViewer extends Page { + + public static final String GWT_ID = "org.sonar.plugins.core.testdetailsviewer.TestsViewer"; + + @Override + protected Widget doOnResourceLoad(Resource resource) { + FlowPanel flowPanel = new FlowPanel(); + flowPanel.add(new UnitTestsHeader(resource)); + flowPanel.add(new TestsPanel(resource)); + return flowPanel; + } + + private static class UnitTestsHeader extends ViewerHeader { + public UnitTestsHeader(Resource resource) { + + super(resource, new String[]{ + Metrics.TEST_ERRORS, + Metrics.TEST_FAILURES, + Metrics.TEST_SUCCESS_DENSITY, + Metrics.TESTS, + Metrics.SKIPPED_TESTS, + Metrics.TEST_EXECUTION_TIME} + ); + } + + @Override + protected void display(FlowPanel header, Resource resource) { + HorizontalPanel panel = new HorizontalPanel(); + header.add(panel); + + Measure measure = resource.getMeasure(Metrics.TEST_SUCCESS_DENSITY); + if (measure == null) { + addBigCell(panel, "100%"); // best value + } else { + addBigCell(panel, measure.getFormattedValue()); + } + + String skippedHtml = ""; + Measure skipped = resource.getMeasure(Metrics.SKIPPED_TESTS); + if (skipped != null && skipped.getValue() > 0.0) { + skippedHtml += " (+" + skipped.getFormattedValue() + " skipped)"; + } + addCell(panel, + "Tests: ", + resource.getMeasureFormattedValue(Metrics.TESTS, "-") + skippedHtml); + + addCell(panel, + "Failures/Errors: ", + resource.getMeasureFormattedValue(Metrics.TEST_FAILURES, "0") + "/" + resource.getMeasureFormattedValue(Metrics.TEST_ERRORS, "0")); + + addCell(panel, + "Duration: ", + resource.getMeasureFormattedValue(Metrics.TEST_EXECUTION_TIME, "-")); + } + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/GwtPageSelector.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/GwtPageSelector.java new file mode 100644 index 00000000000..ccebcbf588c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/GwtPageSelector.java @@ -0,0 +1,30 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.ui.pageselector; + +import org.sonar.api.web.GwtExtension; +import org.sonar.plugins.core.ui.pageselector.client.PageSelector; + +public class GwtPageSelector implements GwtExtension { + + public String getGwtId() { + return PageSelector.GWT_ID; + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/I18nConstants.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/I18nConstants.java new file mode 100644 index 00000000000..29e5d451445 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/I18nConstants.java @@ -0,0 +1,30 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.ui.pageselector.client; + +import com.google.gwt.core.client.GWT; + +public interface I18nConstants extends com.google.gwt.i18n.client.Constants { + + static I18nConstants INSTANCE = GWT.create(I18nConstants.class); + + @DefaultStringValue("New window") + String newWindow(); +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PageDef.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PageDef.java new file mode 100644 index 00000000000..fdaa9dbdeda --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PageDef.java @@ -0,0 +1,94 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.ui.pageselector.client; + +import com.google.gwt.core.client.JavaScriptObject; + +public class PageDef extends JavaScriptObject { + // Overlay types always have protected, zero-arg ctors + + protected PageDef() { + } + + public final native boolean isGwt() /*-{ return this.gwt; }-*/; + + public final native boolean isDefaultTab() /*-{ return this.d; }-*/; + + public final native String getId() /*-{ return this.id; }-*/; + + public final native String getUrl() /*-{ return this.url; }-*/; + + public final native String getName() /*-{ return this.name; }-*/; + + public final native StringArray getMetrics() /*-{ return this.m || []; }-*/; + + public final native StringArray getLanguages() /*-{ return this.l || []; }-*/; + + public final native StringArray getScopes() /*-{ return this.s || []; }-*/; + + public final native StringArray getQualifiers() /*-{ return this.q || []; }-*/; + + public final boolean acceptLanguage(String language) { + return hasValue(getLanguages(), language); + } + + public final boolean acceptScope(String scope) { + return hasValue(getScopes(), scope); + } + + public final boolean acceptQualifier(String qualifier) { + return hasValue(getQualifiers(), qualifier); + } + + public final boolean acceptMetric(String metric) { + StringArray metrics = getMetrics(); + for (int index = 0; index < metrics.length(); index++) { + if (metric.equals(metrics.get(index))) { + return true; + } + } + return false; + } + + + private boolean hasValue(StringArray array, String value) { + if (array == null || array.length() == 0) { + return true; + } + if (value != null) { + for (int index = 0; index < array.length(); index++) { + if (value.equals(array.get(index))) { + return true; + } + } + } + return false; + } + +} + +class StringArray extends JavaScriptObject { + protected StringArray() { + } + + public final native int length() /*-{ return this.length; }-*/; + + public final native String get(int i) /*-{ return this[i]; }-*/; +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PagePanel.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PagePanel.java new file mode 100644 index 00000000000..6c28f8c4d6c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PagePanel.java @@ -0,0 +1,156 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.ui.pageselector.client; + +import com.google.gwt.http.client.*; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.SimplePanel; +import org.sonar.api.web.gwt.client.Utils; +import org.sonar.gwt.Configuration; +import org.sonar.gwt.Links; +import org.sonar.gwt.ui.Loading; + +public class PagePanel extends SimplePanel { + + private PageDef def; + private String rootPanelId; + private String currentResourceId = null; + + public PagePanel(PageDef def) { + this.def = def; + rootPanelId = "gwtpage-" + def.getId(); + add(new HTML("<div id=\"" + rootPanelId + "\"> </div>")); + } + + public void display() { + String resourceId = Configuration.getResourceId(); + if (resourceId != null && !resourceId.equals(currentResourceId)) { + currentResourceId = resourceId; + if (def.isGwt()) { + loadGwt(Links.baseUrl(), Configuration.getSonarVersion(), def.getId()); + } else { + loadEmbeddedPage(resourceId); + } + } + } + + private native void loadGwt(final String serverUrl, final String sonarVersion, final String gwtId) /*-{ + if ($wnd.modules[gwtId]!=null) { + $wnd.modules[gwtId](); + return; + } + + // Create the script tag to be used for importing the GWT script loader. + var script = $doc.createElement('script'); + script.type = 'text/javascript'; + script.src = serverUrl + '/deploy/gwt/' + gwtId + '/' + gwtId + '.nocache.js?' + sonarVersion; + + // The default GWT script loader calls document.write() twice which prevents loading scripts + // on demand, after the document has been loaded. To overcome this we have to overwrite the document.write() + // method before the GWT script loader is executed and restore it after. + // NOTE: The GWT script loader uses document.write() to compute the URL from where it is loaded. + var counter = 0; + var limit = 2; + var oldWrite = $doc.write; + var newWrite = function(html) { + if (counter < limit) { + counter++; + // Fail silently if the script element hasn't been attached to the document. + if (!script.parentNode) { + return; + } + // Create a DIV and put the HTML inside. + var div = $doc.createElement('div'); + // We have to replace all the script tags because otherwise IE drops them. + div.innerHTML = html.replace(/<script\b([\s\S]*?)<\/script>/gi, "<pre script=\"script\"$1</pre>"); + // Move DIV contents after the GWT script loader. + var nextSibling = script.nextSibling; + while(div.firstChild) { + var child = div.firstChild; + // Recover the script tags. + if (child.nodeName.toLowerCase() == 'pre' && child.getAttribute('script') == 'script') { + var pre = child; + pre.removeAttribute('script'); + // Create the script tag. + child = $doc.createElement('script'); + // Copy all the attributes. + for (var i = 0; i < pre.attributes.length; i++) { + var attrNode = pre.attributes[i]; + // In case of IE we have to copy only the specified attributes. + if (typeof attrNode.specified == 'undefined' + || (typeof attrNode.specified == 'boolean' && attrNode.specified)) { + child.setAttribute(attrNode.nodeName, attrNode.nodeValue); + } + } + // Copy the script text. + child.text = typeof pre.innerText == 'undefined' ? pre.textContent : pre.innerText; + // Don't forget to remove the placeholder. + div.removeChild(pre); + } + if (nextSibling) { + script.parentNode.insertBefore(child, nextSibling); + } else { + script.parentNode.appendChild(child); + } + } + } + if (counter >= limit) { + $doc.write = oldWrite; + oldWrite = undefined; + script = undefined; + counter = undefined; + } + }; + + // Append the script tag to the head. + var heads = $doc.getElementsByTagName('head'); + if (heads.length > 0) { + $doc.write = newWrite; + heads[0].appendChild(script); + } + }-*/; + + private void loadEmbeddedPage(String resourceId) { + final RootPanel panel = RootPanel.get(rootPanelId); + panel.add(new Loading()); + String url = def.getUrl(); + if (url == null) { + url = "/plugins/resource/" + resourceId + "?page=" + def.getId() + "&layout=false&hd=false"; + } else { + url += resourceId; + } + RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(Links.baseUrl() + url)); + try { + builder.sendRequest(null, new RequestCallback() { + public void onError(Request request, Throwable exception) { + Utils.showError("Can not load the page " + request.toString()); + } + + public void onResponseReceived(Request request, Response response) { + panel.clear(); + panel.add(new HTML(response.getText())); + } + }); + } catch (RequestException e) { + Utils.showError("Can not connect to server: " + url); + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PageSelector.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PageSelector.java new file mode 100644 index 00000000000..76b6226fc58 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/ui/pageselector/client/PageSelector.java @@ -0,0 +1,224 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.ui.pageselector.client; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Configuration; +import org.sonar.gwt.Links; +import org.sonar.gwt.Utils; +import org.sonar.gwt.ui.Icons; +import org.sonar.gwt.ui.Loading; +import org.sonar.wsclient.gwt.Callback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import java.util.ArrayList; +import java.util.List; + +public class PageSelector implements EntryPoint { + + public static final String GWT_ID = "org.sonar.plugins.core.ui.pageselector.PageSelector"; + public static final String HTML_ROOT_ID = "pageselector"; + + private VerticalPanel container = null; + private String currentResourceId = null; + private PageDefs pageDefs = null; + + public void onModuleLoad() { + pageDefs = loadPageDefs(); + exportNativeJavascript(this); + if (Configuration.getResourceId() != null) { + selectResource(Configuration.getResourceId()); + } + } + + private VerticalPanel createContainer() { + if (container == null) { + container = new VerticalPanel(); + container.getElement().setId("rvs"); + RootPanel.get(HTML_ROOT_ID).add(container); + } + return container; + } + + public static native void exportNativeJavascript(Object obj) /*-{ + $wnd.sr=function(resourceIdOrKey) { + obj.@org.sonar.plugins.core.ui.pageselector.client.PageSelector::selectResource(Ljava/lang/String;)(resourceIdOrKey); + }; + }-*/; + + public void selectResource(final String resourceIdOrKey) { + createContainer().add(new Loading()); + currentResourceId = resourceIdOrKey; + Sonar.getInstance().find(new ResourceQuery(resourceIdOrKey), new Callback<Resource>() { + + public void onResponse(Resource resource, JavaScriptObject json) { + if (resourceIdOrKey != null && resourceIdOrKey.equals(currentResourceId)) { + if (resource == null) { + displayResourceNotFound(); + } else { + saveResource(resource.getId().toString(), json); + displayResource(resource); + } + } // else too late, user has selected another resource + } + + public void onTimeout() { + Utils.showError("Can not load data (timeout)"); + } + + public void onError(int errorCode, String errorMessage) { + Utils.showError("Can not load data: error " + errorCode + ", message: " + errorMessage); + } + }); + } + + private void displayResource(final Resource resource) { + List<PageDef> pages = selectPages(resource); + + PageDef selectedPage = selectPage(pages); + + Title title = new Title(resource); + final TabPanel tabs = new TabPanel(); + tabs.setWidth("100%"); + + int selectedTabIndex = -1; + for (int tabIndex = 0; tabIndex < pages.size(); tabIndex++) { + PageDef page = pages.get(tabIndex); + tabs.add(new PagePanel(page), page.getName()); + if (page == selectedPage) { + selectedTabIndex = tabIndex; + } + } + + container.clear(); // remove the loading icon + container.add(title); + container.add(tabs); + + tabs.addSelectionHandler(new SelectionHandler<Integer>() { + public void onSelection(SelectionEvent<Integer> tabId) { + ((PagePanel) tabs.getWidget(tabId.getSelectedItem())).display(); + } + }); + + if (selectedTabIndex > -1) { + tabs.selectTab(selectedTabIndex); + } + } + + private PageDef selectPage(List<PageDef> pages) { + String pageId = Configuration.getRequestParameter("page"); + if (pageId != null) { + for (PageDef page : pages) { + if (pageId.equals(page.getId())) { + return page; + } + } + } + String metric = Configuration.getParameter("metric"); + if (metric != null) { + for (PageDef page : pages) { + if (page.acceptMetric(metric)) { + return page; + } + } + } + + for (PageDef page : pages) { + if (page.isDefaultTab()) { + return page; + } + } + + return null; + } + + private native void saveResource(String resourceId, JavaScriptObject json) /*-{ + $wnd.config['resource_key']=resourceId; + $wnd.config['resource']=json; + }-*/; + + + /** + * Never return null. + */ + private List<PageDef> selectPages(final Resource resource) { + List<PageDef> pages = new ArrayList<PageDef>(); + for (int index = 0; index < pageDefs.length(); index++) { + PageDef page = pageDefs.get(index); + if (page.acceptLanguage(resource.getLanguage()) && + page.acceptQualifier(resource.getQualifier()) && + page.acceptScope(resource.getScope())) { + pages.add(page); + } + } + return pages; + } + + private void displayResourceNotFound() { + container.clear(); // remove the loading icon + } + + + static class Title extends Composite { + Title(final Resource resource) { + Grid grid = new Grid(1, 2); + grid.getElement().setId("rvstitle"); + grid.setHTML(0, 0, Icons.forQualifier(resource.getQualifier()).getHTML() + " <span class='name'>" + resource.getName(true) + "</span>"); + + if (!"true".equals(Configuration.getParameter("popup"))) { + Hyperlink newWindow = new Hyperlink(); + newWindow.setText(I18nConstants.INSTANCE.newWindow()); + newWindow.setStyleName("command"); + newWindow.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent clickEvent) { + Links.openMeasurePopup(resource.getKey(), Configuration.getParameter("metric")); + } + }); + grid.setWidget(0, 1, newWindow); + } + grid.getColumnFormatter().setStyleName(1, "right"); + initWidget(grid); + } + } + + + private native PageDefs loadPageDefs() /*-{ + return $wnd.pages; + }-*/; + + // An overlay type + + static class PageDefs extends JavaScriptObject { + protected PageDefs() { + } + + public final native int length() /*-{ return this.length; }-*/; + + public final native PageDef get(int i) /*-{ return this[i]; }-*/; + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/ViolationsViewerDefinition.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/ViolationsViewerDefinition.java new file mode 100644 index 00000000000..6b56ecc510c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/ViolationsViewerDefinition.java @@ -0,0 +1,41 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.violationsviewer; + +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.resources.Resource; +import org.sonar.api.web.*; +import org.sonar.plugins.core.violationsviewer.client.ViolationsViewer; + +@NavigationSection(NavigationSection.RESOURCE_TAB) +@DefaultTab(metrics={CoreMetrics.VIOLATIONS_DENSITY_KEY, CoreMetrics.WEIGHTED_VIOLATIONS_KEY, CoreMetrics.VIOLATIONS_KEY, CoreMetrics.BLOCKER_VIOLATIONS_KEY, CoreMetrics.CRITICAL_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, CoreMetrics.INFO_VIOLATIONS_KEY}) +@ResourceQualifier({Resource.QUALIFIER_CLASS,Resource.QUALIFIER_FILE}) +@UserRole(UserRole.CODEVIEWER) +public class ViolationsViewerDefinition extends GwtPage { + + public String getTitle() { + return "Violations"; + } + + public String getGwtId() { + return ViolationsViewer.GWT_ID; + } +} + diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/I18nConstants.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/I18nConstants.java new file mode 100644 index 00000000000..5a1767f0eb0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/I18nConstants.java @@ -0,0 +1,39 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.violationsviewer.client; + +import com.google.gwt.core.client.GWT; + +public interface I18nConstants extends com.google.gwt.i18n.client.Constants { + + static I18nConstants INSTANCE = GWT.create(I18nConstants.class); + + @DefaultStringValue("Filter:") + String filter(); + + @DefaultStringValue("No filters") + String noFilters(); + + @DefaultStringValue("Expand:") + String expand(); + + @DefaultStringValue("Loading...") + String loading(); +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/ViolationsPanel.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/ViolationsPanel.java new file mode 100644 index 00000000000..5554154532c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/ViolationsPanel.java @@ -0,0 +1,155 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.violationsviewer.client; + +import org.sonar.gwt.Links; +import org.sonar.gwt.Utils; +import org.sonar.gwt.ui.Icons; +import org.sonar.gwt.ui.SourcePanel; +import org.sonar.wsclient.gwt.AbstractListCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.Violation; +import org.sonar.wsclient.services.ViolationQuery; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ViolationsPanel extends SourcePanel { + private boolean expand = false; + private List<Violation> violations; + private Map<Integer, List<Violation>> filteredViolationsByLine = new HashMap<Integer, List<Violation>>(); + + public ViolationsPanel(Resource resource, String filter) { + super(resource); + loadViolations(resource, filter); + } + + protected void loadViolations(final Resource resource, final String filter) { + Sonar.getInstance().findAll(ViolationQuery.createForResource(resource), new AbstractListCallback<Violation>() { + + @Override + protected void doOnResponse(List<Violation> violations) { + ViolationsPanel.this.violations = violations; + filter(filter); + setStarted(); + } + }); + } + + public boolean isExpand() { + return expand; + } + + public void setExpand(boolean expand) { + this.expand = expand; + } + + public void filter(String filter) { + filteredViolationsByLine.clear(); + for (Violation violation : violations) { + if (filter == null || filter.equals("") || violation.getRuleKey().equals(filter) || violation.getPriority().equals(filter)) { + Integer line=0; + if (violation.getLine()!=null) { + line = violation.getLine(); + } + List<Violation> lineViolations = filteredViolationsByLine.get(line); + if (lineViolations == null) { + lineViolations = new ArrayList<Violation>(); + filteredViolationsByLine.put(line, lineViolations); + } + lineViolations.add(violation); + } + } + } + + @Override + public boolean shouldDecorateLine(int index) { + if (expand) { + return true; + } + for (int i = index - 5; i < index + 5; i++) { + if (hasViolations(i)) { + return true; + } + } + return false; + } + + @Override + protected List<Row> decorateLine(int index, String source) { + List<Row> rows = new ArrayList<Row>(); + List<Violation> lineViolations = filteredViolationsByLine.get(index); + boolean hasViolations = lineViolations != null && !lineViolations.isEmpty(); + + if (index > 0) { + String style = (hasViolations ? "red" : ""); + Row row = new Row().setLineIndex(index, style).unsetValue().setSource(source, style); + rows.add(row); + } + + if (hasViolations) { + for (Violation violation : lineViolations) { + rows.add(new ViolationRow(violation)); + } + } + return rows; + } + + + public static class ViolationRow extends Row { + private Violation violation; + + public ViolationRow(Violation violation) { + this.violation = violation; + } + + @Override + public String getColumn1() { + return "<div class=\"bigln\"> </div>"; + } + + @Override + public String getColumn2() { + return ""; + } + + @Override + public String getColumn3() { + return ""; + } + + @Override + public String getColumn4() { + return "<div class=\"warn\">" + Icons.forPriority(violation.getPriority()).getHTML() + "</img> " + + "<a href=\"" + Links.urlForRule(violation.getRuleKey(), false) + "\" onclick=\"window.open(this.href,'rule','height=800,width=900,scrollbars=1,resizable=1');return false;\" title=\"" + violation.getRuleKey() + "\"><b>" + Utils.escapeHtml(violation.getRuleName()) + "</b></a> : " + Utils.escapeHtml(violation.getMessage()) + "</div>"; + } + } + + private boolean hasViolations(int lineIndex) { + if (lineIndex < 0) { + return false; + } + List<Violation> list = filteredViolationsByLine.get(lineIndex); + return list != null && !list.isEmpty(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/ViolationsViewer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/ViolationsViewer.java new file mode 100644 index 00000000000..a79c243cf48 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/violationsviewer/client/ViolationsViewer.java @@ -0,0 +1,206 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.violationsviewer.client; + +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.gen2.table.override.client.Grid; +import com.google.gwt.user.client.ui.*; +import org.sonar.gwt.Configuration; +import org.sonar.gwt.Links; +import org.sonar.gwt.Metrics; +import org.sonar.gwt.ui.Icons; +import org.sonar.gwt.ui.Loading; +import org.sonar.gwt.ui.Page; +import org.sonar.wsclient.gwt.AbstractCallback; +import org.sonar.wsclient.gwt.Sonar; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class ViolationsViewer extends Page { + public static final String GWT_ID = "org.sonar.plugins.core.violationsviewer.ViolationsViewer"; + + private Resource resource; + private final Panel mainPanel = new VerticalPanel(); + private final Loading loading = new Loading(I18nConstants.INSTANCE.loading()); + + // header + private Grid header = null; + private ListBox filterBox = null; + private CheckBox expandCheckbox = null; + private String defaultFilter; + + // source + private ViolationsPanel sourcePanel; + + private boolean resourceHasViolations = false; + + @Override + protected Widget doOnResourceLoad(Resource resource) { + this.resource = resource; + mainPanel.clear(); + mainPanel.add(loading); + mainPanel.setWidth("100%"); + mainPanel.setStyleName("gwt-Violations"); + + header = new Grid(1, 5); + header.setWidth("100%"); + header.setStylePrimaryName("gwt-ViewerHeader"); + header.getCellFormatter().setStyleName(0, 0, "thin left"); + + initDefaultFilter(); + sourcePanel = new ViolationsPanel(resource, defaultFilter); + + header.setHTML(0, 1, "<div class='cell'><span class='note'>" + I18nConstants.INSTANCE.filter() + "</span></div>"); + header.getCellFormatter().setStyleName(0, 1, "right"); + + filterBox = new ListBox(); + filterBox.addItem(I18nConstants.INSTANCE.noFilters(), ""); + filterBox.setStyleName("small"); + + filterBox.addChangeHandler(new ChangeHandler() { + public void onChange(ChangeEvent event) { + String filter = filterBox.getValue(filterBox.getSelectedIndex()); + loadSources(); + sourcePanel.filter(filter); + sourcePanel.refresh(); + } + }); + + header.setWidget(0, 2, filterBox); + header.getCellFormatter().setStyleName(0, 2, "thin cell right"); + + header.setHTML(0, 3, "<div class='note'>" + I18nConstants.INSTANCE.expand() + "</div>"); + header.getCellFormatter().setStyleName(0, 3, "thin right"); + + expandCheckbox = new CheckBox(); + expandCheckbox.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + loadSources(); + sourcePanel.setExpand(expandCheckbox.getValue()); + sourcePanel.refresh(); + } + }); + header.setWidget(0, 4, expandCheckbox); + header.getCellFormatter().setStyleName(0, 4, "thin cell left"); + + loadRulePriorities(); + return mainPanel; + } + + private void initDefaultFilter() { + defaultFilter = Configuration.getRequestParameter("rule"); + if (defaultFilter == null) { + defaultFilter = Configuration.getRequestParameter("priority"); + } + } + + private void loadRulePriorities() { + final ResourceQuery query = ResourceQuery.createForResource(resource, Metrics.VIOLATIONS) + .setExcludeRulePriorities(false); + Sonar.getInstance().find(query, new AbstractCallback<Resource>(loading) { + @Override + protected void doOnResponse(Resource resource) { + setResourceHasViolations(resource); + displayRulePriorities(resource); + loadRules(resource); + } + }); + } + + private void displayRulePriorities(Resource resource) { + final Grid grid = new Grid(1, 10); + header.setWidget(0, 0, grid); + + List<Measure> measures = resource.getMeasures(); + displayRulePriority(grid, 0, "BLOCKER", measures); + displayRulePriority(grid, 2, "CRITICAL", measures); + displayRulePriority(grid, 4, "MAJOR", measures); + displayRulePriority(grid, 6, "MINOR", measures); + displayRulePriority(grid, 8, "INFO", measures); + } + + private void displayRulePriority(final Grid grid, final int column, final String priority, final List<Measure> measures) { + String value = "0"; + for (Measure measure : measures) { + if (priority.equals(measure.getRulePriority())) { + value = measure.getFormattedValue(); + filterBox.addItem(priority + " (" + value + ")", priority); + if (priority.equals(defaultFilter)) { + filterBox.setSelectedIndex(filterBox.getItemCount() - 1); + } + continue; + } + } + grid.setHTML(0, column, Icons.forPriority(priority).getHTML()); + grid.setHTML(0, column + 1, value); + grid.getCellFormatter().setStyleName(0, column, "thin metric right"); + grid.getCellFormatter().setStyleName(0, column + 1, "thin left value"); + } + + private void loadRules(Resource resource) { + final ResourceQuery query = ResourceQuery.createForResource(resource, Metrics.VIOLATIONS) + .setExcludeRules(false); + Sonar.getInstance().find(query, new AbstractCallback<Resource>(loading) { + + @Override + protected void doOnResponse(Resource resource) { + setResourceHasViolations(resource); + displayRules(resource); + loadSources(); + } + }); + } + + private void setResourceHasViolations(Resource resource) { + resourceHasViolations = resource != null && resource.getMeasure(Metrics.VIOLATIONS) != null; + } + + private void displayRules(Resource resource) { + Collections.sort(resource.getMeasures(), new Comparator<Measure>() { + public int compare(Measure m1, Measure m2) { + return m1.getRuleName().compareTo(m2.getRuleName()); + } + }); + filterBox.addItem("", ""); + for (Measure measure : resource.getMeasures()) { + filterBox.addItem(measure.getRuleName() + " (" + measure.getFormattedValue() + ")", measure.getRuleKey()); + if (measure.getRuleKey().equals(defaultFilter)) { + filterBox.setSelectedIndex(filterBox.getItemCount() - 1); + } + } + loading.removeFromParent(); + mainPanel.add(header); + } + + private void loadSources() { + mainPanel.remove(sourcePanel); + if (resourceHasViolations || expandCheckbox.getValue()) { + mainPanel.add(sourcePanel); + } + } +} diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/GwtClouds.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/GwtClouds.gwt.xml new file mode 100644 index 00000000000..cde524c0f66 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/GwtClouds.gwt.xml @@ -0,0 +1,11 @@ +<module> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.api.web.gwt.Sonar"/> + + <stylesheet src="clouds.css"/> + + <entry-point class="org.sonar.plugins.core.clouds.client.GwtClouds"/> + +</module> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/public/clouds.css b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/public/clouds.css new file mode 100644 index 00000000000..c2790c3c95c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/public/clouds.css @@ -0,0 +1,29 @@ +.tag {
+ padding: 0px;
+ cursor: pointer;
+}
+
+.inline{
+ display: inline;
+}
+
+a {
+ border-bottom: 0 none;
+}
+
+.tab_title {
+ white-space: nowrap;
+}
+
+.metricSelectBox {
+ float: right;
+}
+
+.metricSelectBox .labelText {
+ padding-top: 2px;
+ padding-right: 5px;
+
+}
+
+
+
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/public/test.html new file mode 100644 index 00000000000..c4292e18121 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/clouds/public/test.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Clouds xxx</title> + <link href="http://localhost:9000/dev/stylesheets/yui-2.6.0.css" media="all" rel="Stylesheet" type="text/css"/> + <link href="http://localhost:9000/dev/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> + <script src="http://localhost:9000/dev/javascripts/application.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/prototype.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/scriptaculous.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var config = { + "sonar_url": "http://localhost:9000/dev", + "resource_key" : "org.codehaus.sonar:sonar-plugin-api", + "permalink_url_base" : "http://localhost:9000/dev/views/project/org.codehaus.sonar:sonar/org.sonar.plugins.core.clouds.GwtClouds?foo=bar" + }; +</script> + +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" + onclick="javascript:$('error').hide();return false;">hide</a>] +</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" + onclick="javascript:$('warning').hide();return false;">hide</a>] +</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" + onclick="javascript:$('info').hide();return false;">hide</a>] +</div> + +<div id="gwtpage"> +</div> + +<script type="text/javascript" language="javascript" src="org.sonar.plugins.core.clouds.GwtClouds.nocache.js"></script> +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/coverageviewer/CoverageViewer.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/coverageviewer/CoverageViewer.gwt.xml new file mode 100644 index 00000000000..b14b0e2f735 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/coverageviewer/CoverageViewer.gwt.xml @@ -0,0 +1,10 @@ +<module> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.Sonar"/> + <inherits name="com.google.gwt.gen2.table.Table"/> + + <entry-point class="org.sonar.plugins.core.coverageviewer.client.CoverageViewer"/> + +</module> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/coverageviewer/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/coverageviewer/public/test.html new file mode 100644 index 00000000000..181a04a6a72 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/coverageviewer/public/test.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Code coverage</title> + <link href="http://localhost:9000/dev/stylesheets/yui-2.6.0.css" media="all" rel="Stylesheet" type="text/css"/> + <link href="http://localhost:9000/dev/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> + <script src="http://localhost:9000/dev/javascripts/application.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/prototype.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/scriptaculous.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var registeredTabs = []; + var config = { + "sonar_url": "http://localhost:9000/dev", + "viewer_resource_key": "org.apache.struts:struts-core:org.apache.struts.action.ActionServlet" + }; +</script> +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" + onclick="javascript:$('error').hide();return false;">hide</a>] +</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" + onclick="javascript:$('warning').hide();return false;">hide</a>] +</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" + onclick="javascript:$('info').hide();return false;">hide</a>] +</div> + +<div id="resource_viewers"> + <div id='loading'></div> +</div> +<script type="text/javascript" language="javascript" + src="org.sonar.plugins.core.coverageviewer.CoverageViewer.nocache.js"></script> + +<a href="#" onclick="load_org_sonar_plugins_core_coverageviewer_CoverageViewer();">load</a> +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/defaultsourceviewer/GwtDefaultSourceViewer.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/defaultsourceviewer/GwtDefaultSourceViewer.gwt.xml new file mode 100644 index 00000000000..be36aa7ef89 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/defaultsourceviewer/GwtDefaultSourceViewer.gwt.xml @@ -0,0 +1,10 @@ +<module> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.Sonar"/> + <inherits name="com.google.gwt.gen2.table.Table"/> + + <entry-point class="org.sonar.plugins.core.defaultsourceviewer.client.GwtDefaultSourceViewer"/> + +</module> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/defaultsourceviewer/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/defaultsourceviewer/public/test.html new file mode 100644 index 00000000000..02a9f684766 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/defaultsourceviewer/public/test.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Sources</title> + <link href="http://localhost:9000/stylesheets/sonar.css" media="all" rel="Stylesheet" type="text/css" /> + <script src="http://localhost:9000/javascripts/sonar.js" type="text/javascript"></script> +</head> + +<body> +<div id="gwtpage"></div> +<script type="text/javascript"> +var config = { + "sonar_url": "http://localhost:9000", + "resource":[{"id":97, "key":"org.apache.struts:struts-core:org.apache.struts.config.ConfigRuleSet","scope": "FIL", "qualifier": "CLA", "name": "Struts Core", "lang":"java"}] +}; +var modules = {}; +var rp = {}; + +</script> +<script type="text/javascript" language="javascript" src="org.sonar.plugins.core.defaultsourceviewer.GwtDefaultSourceViewer.nocache.js"></script> + +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/DuplicationsViewer.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/DuplicationsViewer.gwt.xml new file mode 100644 index 00000000000..b480cc0b418 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/DuplicationsViewer.gwt.xml @@ -0,0 +1,13 @@ +<module> + <inherits name="com.google.gwt.xml.XML"/> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.Sonar"/> + <inherits name="com.google.gwt.gen2.table.Table"/> + + <stylesheet src="DuplicationsViewer.css"/> + + <entry-point class="org.sonar.plugins.core.duplicationsviewer.client.DuplicationsViewer"/> + +</module> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/public/DuplicationsViewer.css b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/public/DuplicationsViewer.css new file mode 100644 index 00000000000..2cc0ced131c --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/public/DuplicationsViewer.css @@ -0,0 +1,48 @@ +.gwt-DuplicationsPanel { + width: 100%; +} + +.duplicationsTable { + border: 1px solid #C0C0C0; + width: 100%; + vertical-align: top; +} + +.duplicationsTable td { + vertical-align: top; + text-align: left; + padding: 3px; + white-space: nowrap; +} + +.duplicationsTable #expandCollapseCol { + width: 60px; +} + +.duplicationsTable #nbLineCol { + width: 80px; +} + +.duplicationsTable #lineFromCol { + width: 80px; +} + +.duplicationsTable #fileCol { + width: 80px; +} + +.duplicationsTable .header { + background-color: #EFEFEF; + font-weight: bold; + color: #333; + vertical-align: top; +} + +.expandCollapseLink { + margin-left: 5px; +} + +.gwt-SourcePanel table.sources td { + vertical-align: top; + padding: 0px; +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/public/test.html new file mode 100644 index 00000000000..37b1bb43253 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/duplicationsviewer/public/test.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Duplications</title> + <link href="http://localhost:9000/dev/stylesheets/yui-2.6.0.css" media="all" rel="Stylesheet" type="text/css"/> + <link href="http://localhost:9000/dev/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> + <script src="http://localhost:9000/dev/javascripts/application.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/prototype.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/scriptaculous.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var registeredTabs = []; + var config = { + "sonar_url": "http://localhost:9000/dev", + "viewer_resource_key" : "org.sonar.tests:reference:org.sonar.samples.duplicated_lines_within_same_class.DuplicatedLinesInSameClass" + }; + + +</script> +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" + onclick="javascript:$('error').hide();return false;">hide</a>] +</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" + onclick="javascript:$('warning').hide();return false;">hide</a>] +</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" + onclick="javascript:$('info').hide();return false;">hide</a>] +</div> + +<div id="resource_viewers"> + <div id='loading'></div> +</div> +<script type="text/javascript" language="javascript" + src="org.sonar.plugins.core.duplicationsviewer.DuplicationsViewer.nocache.js"></script> + +<a href="#" onclick="load_org_sonar_plugins_core_duplicationsviewer_DuplicationsViewer();">load</a> +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml new file mode 100644 index 00000000000..574aa03fedc --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/GwtHotspots.gwt.xml @@ -0,0 +1,15 @@ +<module> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.Sonar"/> + <inherits name="com.google.gwt.i18n.I18N"/> + + <stylesheet src="hotspots.css"/> + + <entry-point class="org.sonar.plugins.core.hotspots.client.GwtHotspots"/> + + <extend-property name="locale" values="en"/> + <extend-property name="locale" values="fr"/> + +</module>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/client/I18nConstants_fr.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/client/I18nConstants_fr.properties new file mode 100644 index 00000000000..efd8a8c42d6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/client/I18nConstants_fr.properties @@ -0,0 +1,16 @@ +# This file must use UTF-8 encoding + +titleMostViolatedRules=Règles les moins respectées +titleMostViolatedResources=Les moins respectueux des règles +titleLongestTests=Les plus long tests +titleMostComplexResources=Les plus complexes +titleMostDuplicatedResources=Les plus dupliqués +titleLessTested=Le plus de lignes non testées +titleMostComplexMethods=Avec les méthodes les plus complexes +titleMostUndocumentedAPI=Les API les moins documentées +noMeasures=Aucune mesure +anyPriority=Toutes les priorités +moreDetails=Détails +lcom4=Manque de cohésion entre méthodes +rfc=Response for class +designTitle=
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css new file mode 100644 index 00000000000..6ae0b1d2747 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/public/hotspots.css @@ -0,0 +1,102 @@ +.gwt-Hotspots { + width: 780px; +} + +.gwt-Hotspots td { + width: 380px; + vertical-align: top; +} + +.gwt-HotspotPanel { + width: 100%; +} + +.gwt-HotspotPanel .header { + color: #333; + font-size: 93%; + font-weight: bold; + padding: 3px 0px 3px 5px; + white-space: nowrap; +} +.hotspotcol { + vertical-align: top; +} + +.gwt-Hotspot { + border: 1px solid #ccc; + border-top-width: 2px; + border-bottom-width: 2px; + margin-left: 5px; + margin-right: 5px; + margin-bottom: 10px; + width: 390px; +} + +.gwt-Hotspot td { + padding: 3px 4px; + line-height: 18px; +} + +.gwt-Hotspot td.small { + padding: 3px 1px; +} + +.gwt-Hotspot .header { + color: #333; + font-size: 93%; + font-weight: bold; + padding: 4px 0 3px 9px; +} + +.gwt-Hotspot .resourceCell { + width: 99%; +} + +.gwt-Hotspot .ccResourceCell { + width: 60%; +} + +.gwt-Hotspot .resultCell { + width: 1%; + white-space: nowrap; + text-align: right; + border-right: none; +} + +.gwt-Hotspot .ccResultCell { + border-right: 1px solid #C0C0C0; + width: 1%; + white-space: nowrap; + text-align: right; +} + +.gwt-Hotspot .graphCell { + width: 1%; + white-space: nowrap; + text-align: right; + border-left: none; +} + +.gwt-Hotspot .header.ccHeaderResource { + width: 60%; +} + +.gwt-Hotspot .header.headerResource { + width: 70%; +} + +.gwt-Hotspot .header.headerEmptyResults { + width: 100%; +} + +.gwt-Hotspot .header.headerResult { + width: 20%; +} + +.gwt-Hotspot .header.ccHeaderResult { + width: 30%; +} + +.gwt-Hotspot .header.headerGraph { + width: 10%; +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html new file mode 100644 index 00000000000..d66011fb116 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/hotspots/public/test.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Hotspots</title> + <link href="http://localhost:9000/stylesheets/sonar.css" media="all" rel="Stylesheet" type="text/css"/> + <script src="http://localhost:9000/javascripts/sonar.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var config = { + "sonar_url": "http://localhost:9000", + "resource_key" : "org.apache.struts:struts-parent" + }; +</script> + +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" + onclick="javascript:$('error').hide();return false;">hide</a>] +</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" + onclick="javascript:$('warning').hide();return false;">hide</a>] +</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" + onclick="javascript:$('info').hide();return false;">hide</a>] +</div> + +<div id="gwtpage"> +</div> + +<script type="text/javascript" language="javascript" + src="org.sonar.plugins.core.hotspots.GwtHotspots.nocache.js"></script> +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/TestsViewer.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/TestsViewer.gwt.xml new file mode 100644 index 00000000000..c5e1c33bf6d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/TestsViewer.gwt.xml @@ -0,0 +1,13 @@ +<module> + <inherits name="com.google.gwt.xml.XML"/> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.Sonar"/> + <inherits name="com.google.gwt.gen2.table.Table"/> + + <stylesheet src="TestsViewer.css"/> + + <entry-point class="org.sonar.plugins.core.testdetailsviewer.client.TestsViewer"/> + +</module>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/TestsViewer.css b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/TestsViewer.css new file mode 100644 index 00000000000..0ce428402b6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/TestsViewer.css @@ -0,0 +1,88 @@ +.gwt-TestDetailsPanel { + width: 100%; +} + +.gwt-TestDetailsPanel .error { + background-image: url("images/error.png"); + background-position: 4px 2px; + background-repeat: no-repeat; + background-color: transparent; + border: none; + margin: 0 0 2px; + padding: 2px; + vertical-align: top; +} + +.gwt-TestDetailsPanel .failure { + background-image: url("images/failure.png"); + background-position: 4px 2px; + background-repeat: no-repeat; + margin: 0 0 2px; + padding: 2px; + vertical-align: top; +} + +.gwt-TestDetailsPanel .skipped { + background-image: url("images/skipped.png"); + background-position: 4px 2px; + background-repeat: no-repeat; + margin: 0 0 2px; + padding: 2px; + vertical-align: top; +} + +.gwt-TestDetailsPanel .ok { + background-image: url("images/ok.png"); + background-position: 4px 2px; + background-repeat: no-repeat; + margin: 0 0 2px; + padding: 2px; + vertical-align: top; +} + +.detailsTable { + border: 1px solid #C0C0C0; + width: 100%; + vertical-align: top; +} + +.detailsTable td { + vertical-align: top; + text-align: left; + padding: 3px; +} + +.detailsTable .header { + background-color: #EFEFEF; + font-weight: bold; + color: #333; + vertical-align: top; +} + +.detailsTable #iCol { + width: 25px; +} + +.detailsTable #dCol { + width: 70px; +} + +.detailsTable #expandCollapseCol { + width: 60px; + text-align: right; +} + +.detailsTable #noLinkExpandCollapseCol { + width: 0px; + padding: 0px; +} + +.stackPanel { + padding: 5px; + border: 1px solid #C0C0C0; +} + +.expandCollapseLink { + text-align: right; + margin-right: 5px; +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/error.png b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/error.png Binary files differnew file mode 100644 index 00000000000..c37bd062e60 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/error.png diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/failure.png b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/failure.png Binary files differnew file mode 100644 index 00000000000..628cf2dae3d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/failure.png diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/ok.png b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/ok.png Binary files differnew file mode 100644 index 00000000000..89c8129a490 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/ok.png diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/skipped.png b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/skipped.png Binary files differnew file mode 100644 index 00000000000..5c870176d4d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/images/skipped.png diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/test.html new file mode 100644 index 00000000000..6ec71b51686 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/testdetailsviewer/public/test.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>TestDetails</title> + <link href="http://localhost:9000/dev/stylesheets/yui-2.6.0.css" media="all" rel="Stylesheet" type="text/css"/> + <link href="http://localhost:9000/dev/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> + <script src="http://localhost:9000/dev/javascripts/application.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/prototype.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/scriptaculous.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var registeredTabs = []; + var config = { + "sonar_url": "http://localhost:9000/dev", + "viewer_resource_key" : "org.sonar.tests.test-failures:moduleA:ch.hortis.sonar.samples.testFailures.moduleA.FailTest" + }; +</script> +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" + onclick="javascript:$('error').hide();return false;">hide</a>] +</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" + onclick="javascript:$('warning').hide();return false;">hide</a>] +</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" + onclick="javascript:$('info').hide();return false;">hide</a>] +</div> + +<div id="resource_viewers"> + <div id='loading'></div> +</div> +<script type="text/javascript" language="javascript" + src="org.sonar.plugins.core.testdetailsviewer.TestsViewer.nocache.js"></script> + +<a href="#" onclick="load_org_sonar_plugins_core_testdetailsviewer_TestsViewer();">load</a> +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/PageSelector.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/PageSelector.gwt.xml new file mode 100644 index 00000000000..d7ec90cf690 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/PageSelector.gwt.xml @@ -0,0 +1,14 @@ +<module> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.api.web.gwt.Sonar"/> + <inherits name="org.sonar.Sonar"/> + <stylesheet src="pageselector.css" /> + + <entry-point class="org.sonar.plugins.core.ui.pageselector.client.PageSelector"/> + + <extend-property name="locale" values="en"/> + <extend-property name="locale" values="fr"/> + +</module>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/client/I18nConstants_fr.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/client/I18nConstants_fr.properties new file mode 100644 index 00000000000..067f7231c81 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/client/I18nConstants_fr.properties @@ -0,0 +1,2 @@ +# This file must use UTF-8 encoding +newWindow=Nouvelle fenêtre
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/public/pageselector.css b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/public/pageselector.css new file mode 100644 index 00000000000..367e5632efb --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/public/pageselector.css @@ -0,0 +1,25 @@ +/* #rvs is "resource viewer selector" */ +#rvs { + width: 100%; + margin-top: 10px; + border: 1px solid #CCC; +} +#rvstitle { + width: 100%; + margin: 5px; +} +#rvstitle .name { +} +#rvstitle .right { + float: none; + text-align: right; +} +#rvs .command { + text-align: right; + cursor: pointer; + margin-right: 15px; +} +#rvs .command a { + color: #444; + text-decoration: underline; +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/public/test.html new file mode 100644 index 00000000000..0f1e49dd8f9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/ui/pageselector/public/test.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Page selector</title> + <link href="http://localhost:9000/stylesheets/sonar.css" media="all" rel="Stylesheet" type="text/css" /> + <script src="http://localhost:9000/javascripts/sonar.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var config = { + "sonar_url": "http://localhost:9000", + "version": "2.0", + "metric": "ncloc", + "resource" : null + }; + var pages = [ + {"id": "org.sonar.plugins.foo.Foo", "gwt": false, "url": "http://localhost:9000/project/index/1", "metrics":[], "scopes":["PRJ"], "qualifiers": ["TRK", "BRC"], "langs": ["java"]}, + {"id": "org.sonar.plugins.core.clouds.GwtClouds", "gwt": true, "metrics":["lcom4","noc"], "scopes":["PRJ"], "qualifiers": ["TRK", "BRC"], "langs": ["java"]}, + {"id": "org.sonar.plugins.Overview", "gwt": true, "metrics":[], "scopes":[], "qualifiers": [], "langs": []}, + {"id": "org.sonar.plugins.Rails", "gwt": false, "metrics":["clirr"], "scopes":[], "qualifiers": ["FIL"], "langs": []} + + ]; + var entrypoints = {} + +</script> +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" onclick="javascript:$('error').hide();return false;">hide</a>]</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" onclick="javascript:$('warning').hide();return false;">hide</a>]</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" onclick="javascript:$('info').hide();return false;">hide</a>]</div> + +<a href="#" onclick="sr('org.apache.struts:struts-parent');">load struts</a> + +<div id="pageselector"> </div> + +<script type="text/javascript" language="javascript" src="org.sonar.plugins.core.ui.pageselector.PageSelector.nocache.js"></script> + +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/ViolationsViewer.gwt.xml b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/ViolationsViewer.gwt.xml new file mode 100644 index 00000000000..473ccebe360 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/ViolationsViewer.gwt.xml @@ -0,0 +1,13 @@ +<module> + <inherits name="com.google.gwt.user.User"/> + <inherits name="com.google.gwt.json.JSON"/> + <inherits name="com.google.gwt.http.HTTP"/> + <inherits name="org.sonar.Sonar"/> + <inherits name="com.google.gwt.gen2.table.Table"/> + <inherits name="com.google.gwt.i18n.I18N"/> + + <entry-point class="org.sonar.plugins.core.violationsviewer.client.ViolationsViewer"/> + + <extend-property name="locale" values="en"/> + <extend-property name="locale" values="fr"/> +</module> diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/client/I18nConstants_fr.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/client/I18nConstants_fr.properties new file mode 100644 index 00000000000..73a4d8909a0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/client/I18nConstants_fr.properties @@ -0,0 +1,5 @@ +# This file must use UTF-8 encoding +filter=Filtre: +noFilters=Aucun filtre +expand=Développer: +loading=En cours de chargement...
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/public/test.html b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/public/test.html new file mode 100644 index 00000000000..7c0a06d111e --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/violationsviewer/public/test.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Violations</title> + <link href="http://localhost:9000/dev/stylesheets/yui-2.6.0.css" media="all" rel="Stylesheet" type="text/css"/> + <link href="http://localhost:9000/dev/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/> + <script src="http://localhost:9000/dev/javascripts/application.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/prototype.js" type="text/javascript"></script> + <script src="http://localhost:9000/dev/javascripts/scriptaculous.js" type="text/javascript"></script> +</head> + +<body> +<script type="text/javascript"> + var registeredTabs = []; + var config = { + "sonar_url": "http://localhost:9000/dev", + "viewer_resource_key": "org.sonar.tests:reference:org.sonar.samples.PrivateClass" + }; + var request_parameters = {"priority": "BLOCKER"} +</script> +<div class="error" id="error" style="display:none"><span id="errormsg"></span> [<a href="#" + onclick="javascript:$('error').hide();return false;">hide</a>] +</div> +<div class="warning" id="warning" style="display:none"><span id="warningmsg"></span> [<a href="#" + onclick="javascript:$('warning').hide();return false;">hide</a>] +</div> +<div class="notice" id="info" style="display:none"><span id="infomsg"></span> [<a href="#" + onclick="javascript:$('info').hide();return false;">hide</a>] +</div> + +<div id="resource_viewers"> +</div> +<script type="text/javascript" language="javascript" + src="org.sonar.plugins.core.violationsviewer.ViolationsViewer.nocache.js"></script> + +<a href="#" onclick="load_org_sonar_plugins_core_violationsviewer_ViolationsViewer();">load</a> +</body> +</html>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/CorePluginTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/CorePluginTest.java new file mode 100644 index 00000000000..b9dd13aaa14 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/CorePluginTest.java @@ -0,0 +1,33 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core; + +import static org.hamcrest.number.OrderingComparisons.greaterThan; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class CorePluginTest { + + @Test + public void shouldDefineManyExtensions() { + assertThat(new CorePlugin().getExtensions().size(), greaterThan(10)); + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java new file mode 100644 index 00000000000..a6066489274 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java @@ -0,0 +1,69 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.batch; + +import org.junit.Test; +import org.sonar.api.resources.Resource; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ExcludedResourceFilterTest { + + @Test + public void doNotFailIfNoPatterns() { + ExcludedResourceFilter filter = new ExcludedResourceFilter((String[]) null); + assertThat(filter.isIgnored(mock(Resource.class)), is(false)); + } + + @Test + public void noPatternsMatch() { + ExcludedResourceFilter filter = new ExcludedResourceFilter(new String[]{"**/foo/*.java", "**/bar/*"}); + assertThat(filter.isIgnored(mock(Resource.class)), is(false)); + } + + /** + * See SONAR-1115 Exclusion patterns do not apply to unit tests. + */ + @Test + public void ignoreResourceIfMatchesPattern() { + ExcludedResourceFilter filter = new ExcludedResourceFilter(new String[]{"**/foo/*.java", "**/bar/*"}); + + Resource resource = mock(Resource.class); + when(resource.matchFilePattern("**/bar/*")).thenReturn(true); + + assertThat(filter.isIgnored(resource), is(true)); + } + + @Test + public void doNotExcludeUnitTestFiles() { + ExcludedResourceFilter filter = new ExcludedResourceFilter(new String[]{"**/foo/*.java", "**/bar/*"}); + + Resource unitTest = mock(Resource.class); + when(unitTest.getQualifier()).thenReturn(Resource.QUALIFIER_UNIT_TEST_CLASS); + + // match exclusion pattern + when(unitTest.matchFilePattern("**/bar/*")).thenReturn(true); + + assertThat(filter.isIgnored(unitTest), is(false)); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/DistributionAreaChartTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/DistributionAreaChartTest.java new file mode 100644 index 00000000000..3be2879ad12 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/DistributionAreaChartTest.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.charts; + +import org.junit.Test; +import org.sonar.api.charts.AbstractChartTest; +import org.sonar.api.charts.ChartParameters; + +import java.awt.image.BufferedImage; +import java.io.IOException; + +public class DistributionAreaChartTest extends AbstractChartTest { + + @Test + public void oneSerie() throws IOException { + DistributionAreaChart chart = new DistributionAreaChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionAreaChartTest/oneSerie.png"); + } + + @Test + public void manySeries() throws IOException { + DistributionAreaChart chart = new DistributionAreaChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2|0%3D7%3B1%3D15%3B2%3D4")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionAreaChartTest/manySeries.png"); + } + + @Test + public void manySeriesWithDifferentCategories() throws IOException { + DistributionAreaChart chart = new DistributionAreaChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2|2%3D7%3B4%3D15%3B9%3D4")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionAreaChartTest/manySeriesWithDifferentCategories.png"); + } + + @Test + public void manySeriesIncludingAnEmptySerie() throws IOException { + // the third serie should not have the second default color, but the third one ! + DistributionAreaChart chart = new DistributionAreaChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2||2%3D7%3B4%3D15%3B9%3D4")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionAreaChartTest/manySeriesIncludingAnEmptySerie.png"); + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/DistributionBarChartTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/DistributionBarChartTest.java new file mode 100644 index 00000000000..b83ed6f81ed --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/DistributionBarChartTest.java @@ -0,0 +1,97 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.charts; + +import org.junit.Test; +import org.sonar.api.charts.AbstractChartTest; +import org.sonar.api.charts.ChartParameters; + +import java.awt.image.BufferedImage; +import java.io.IOException; + +public class DistributionBarChartTest extends AbstractChartTest { + + @Test + public void simpleSample() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/simpleSample.png"); + } + + @Test + public void addXSuffix() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + // should suffix x labels with + + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2&xsuf=%2B")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/addXSuffix.png"); + } + + @Test + public void addYSuffix() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + // should suffix y labels with % + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2&ysuf=%25")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/addYSuffix.png"); + } + + @Test + public void manySeries() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2|0%3D7%3B1%3D15%3B2%3D4")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/manySeries.png"); + } + + @Test + public void manySeriesIncludingAnEmptySerie() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + // the third serie should not have the second default color, but the third one ! + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2||0%3D7%3B1%3D15%3B2%3D4")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/manySeriesIncludingAnEmptySerie.png"); + } + + @Test + public void overridenSize() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2|0%3D7%3B1%3D15%3B2%3D4&w=500&h=200")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/overridenSize.png"); + } + + @Test + public void changeColor() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2&c=777777&bgc=777777")); + assertChartSizeGreaterThan(image, 1000); + saveChart(image, "DistributionBarChartTest/changeColor.png"); + } + + @Test + public void smallSize() throws IOException { + DistributionBarChart chart = new DistributionBarChart(); + BufferedImage image = chart.generateImage(new ChartParameters("v=0%3D5%3B1%3D22%3B2%3D2%3B4%3D22%3B5%3D22%3B6%3D22&c=777777&w=120&h=80&fs=8")); + assertChartSizeGreaterThan(image, 500); + saveChart(image, "DistributionBarChartTest/smallSize.png"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/XradarChartTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/XradarChartTest.java new file mode 100644 index 00000000000..8f9cb7eb745 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/charts/XradarChartTest.java @@ -0,0 +1,50 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.charts; + +import org.junit.Test; +import org.sonar.api.charts.AbstractChartTest; +import org.sonar.api.charts.ChartParameters; + +import java.awt.image.BufferedImage; +import java.io.IOException; + +public class XradarChartTest extends AbstractChartTest { + + @Test + public void shouldGenerateXradar() throws IOException { + String url = "w=200&h=200&l=Usa.,Eff.,Rel.,Main.,Por.&g=0.25&m=100&v=90,80,70,60,50|40,30,20,10,10&c=CAE3F2|F8A036"; + XradarChart radar = new XradarChart(); + BufferedImage img = radar.generateImage(new ChartParameters(url)); + saveChart(img, "shouldGenerateXradar.png"); + assertChartSizeGreaterThan(img, 50); + } + + @Test + public void negativeValuesAreNotDisplayed() throws IOException { + String url = "w=200&h=200&l=Usa.,Eff.,Rel.,Main.,Por.&g=0.3&m=100&v=-90,-80,70,60,50&c=CAE3F2"; + XradarChart radar = new XradarChart(); + BufferedImage img = radar.generateImage(new ChartParameters(url)); + saveChart(img, "negativeValuesAreNotDisplayed.png"); + + // you have to check visually that it does not work ! Min value is 0. This is a limitation of JFreeChart. + assertChartSizeGreaterThan(img, 50); + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/metrics/UserManagedMetricsTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/metrics/UserManagedMetricsTest.java new file mode 100644 index 00000000000..72158fdbe88 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/metrics/UserManagedMetricsTest.java @@ -0,0 +1,33 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.metrics; + +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +public class UserManagedMetricsTest { + + @Test + public void checkDefinitions() { + UserManagedMetrics metrics = new UserManagedMetrics(); + assertThat(metrics.getMetrics().size(), greaterThan(2)); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest.java new file mode 100644 index 00000000000..b662d1e1cac --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest.java @@ -0,0 +1,44 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.Connection; +import java.sql.SQLException; + +public class PurgeDeletedResourcesTest extends AbstractDbUnitTestCase { + + @Test + public void purgeDeletedResources() throws SQLException { + setupData("sharedFixture", "purgeDeletedResources"); + + final Connection c = getConnection().getConnection(); + c.prepareStatement("SET REFERENTIAL_INTEGRITY FALSE; ").execute(); + c.prepareStatement("delete from projects where id=3").executeUpdate(); + c.commit(); + + final PurgeDeletedResources purge = new PurgeDeletedResources(getSession()); + purge.purge(null); + + checkTables("purgeDeletedResources", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest.java new file mode 100644 index 00000000000..c4b9f82ead9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest.java @@ -0,0 +1,37 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class PurgeDeprecatedLastTest extends AbstractDbUnitTestCase { + + @Test + public void purgeDeprecatedLast() throws SQLException { + setupData("sharedFixture", "purgeDeprecatedLast"); + + new PurgeDeprecatedLast(getSession()).purge(null); + + checkTables("purgeDeprecatedLast", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest.java new file mode 100644 index 00000000000..08138016e5f --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest.java @@ -0,0 +1,49 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class PurgeDisabledResourcesTest extends AbstractDbUnitTestCase { + + @Test + public void purgeDisabledModule() throws SQLException { + assertPurge("purgeDisabledModule"); + } + + @Test + public void purgeDisabledProject() throws SQLException { + assertPurge("purgeDisabledProject"); + } + + @Test + public void nothingToPurge() throws SQLException { + assertPurge("nothingToPurge"); + } + + private void assertPurge(String testName) { + setupData("sharedFixture", testName); + new PurgeDisabledResources(getSession()).purge(null); + checkTables(testName, "snapshots", "project_measures"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeEntitiesTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeEntitiesTest.java new file mode 100644 index 00000000000..aa354af823f --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeEntitiesTest.java @@ -0,0 +1,36 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +public class PurgeEntitiesTest extends AbstractDbUnitTestCase { + + @Test + public void purgeEntities() { + setupData("sharedFixture", "purgeEntities"); + + final PurgeEntities purge = new PurgeEntities(getSession()); + purge.purge(null); + + checkTables("purgeEntities", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeEventOrphansTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeEventOrphansTest.java new file mode 100644 index 00000000000..6712eb6f69e --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeEventOrphansTest.java @@ -0,0 +1,40 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class PurgeEventOrphansTest extends AbstractDbUnitTestCase { + + @Test + public void purgeEventOrphans() throws SQLException { + assertPurge("purgeEventOrphans"); + } + + private void assertPurge(String testName) { + setupData(testName); + new PurgeEventOrphans(getSession()).purge(null); + checkTables(testName, "events"); + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest.java new file mode 100644 index 00000000000..fdbb986d9d3 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest.java @@ -0,0 +1,38 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class PurgeOrphanResourcesTest extends AbstractDbUnitTestCase { + @Test + public void purgeOrphanResources() throws SQLException { + assertPurge("purgeOrphanResources"); + } + + private void assertPurge(String testName) { + setupData(testName); + new PurgeOrphanResources(getSession()).purge(null); + checkTables(testName, "projects"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgePropertyOrphansTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgePropertyOrphansTest.java new file mode 100644 index 00000000000..277fe317c61 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgePropertyOrphansTest.java @@ -0,0 +1,42 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class PurgePropertyOrphansTest extends AbstractDbUnitTestCase { + @Test + public void purgeResourceOrphans() throws SQLException { + setupData("purgeResourceOrphans"); + new PurgePropertyOrphans(getSession()).purgeResourceOrphans(); + checkTables("purgeResourceOrphans", "properties"); + } + + @Test + public void purgeUserOrphans() throws SQLException { + setupData("purgeUserOrphans"); + new PurgePropertyOrphans(getSession()).purgeUserOrphans(); + checkTables("purgeUserOrphans", "properties"); + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeResourceRolesTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeResourceRolesTest.java new file mode 100644 index 00000000000..041a888eca3 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeResourceRolesTest.java @@ -0,0 +1,38 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class PurgeResourceRolesTest extends AbstractDbUnitTestCase { + + @Test + public void purgeResourceRoles() throws SQLException { + setupData("purgeResourceRoles"); + + new PurgeResourceRoles(getSession()).purge(null); + + checkTables("purgeResourceRoles", "projects", "user_roles", "group_roles"); + } +} + diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest.java new file mode 100644 index 00000000000..76ae0121867 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.api.batch.PurgeContext; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +public class PurgeRuleMeasuresTest extends AbstractDbUnitTestCase { + + @Test + public void purgeRuleMeasures() { + setupData("sharedFixture", "purgeRuleMeasures"); + + new PurgeRuleMeasures(getSession()).purge(new PurgeContext(){ + public Integer getPreviousSnapshotId() { + return 1; + } + public Integer getLastSnapshotId() { + return 4; + } + }); + + checkTables("purgeRuleMeasures", "snapshots", "project_measures", "measure_data"); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeUnprocessedTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeUnprocessedTest.java new file mode 100644 index 00000000000..768098d6a00 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/PurgeUnprocessedTest.java @@ -0,0 +1,36 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +public class PurgeUnprocessedTest extends AbstractDbUnitTestCase { + + @Test + public void purgeUnprocessed() { + setupData("sharedFixture", "purgeUnprocessed"); + + new PurgeUnprocessed(getSession()).purge(null); + + checkTables("purgeUnprocessed", "snapshots", "project_measures", "measure_data", "rule_failures", "snapshot_sources"); + } +} + diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/UnflagLastDoublonsTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/UnflagLastDoublonsTest.java new file mode 100644 index 00000000000..e6633fc8d70 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/purges/UnflagLastDoublonsTest.java @@ -0,0 +1,38 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.purges; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.sql.SQLException; + +public class UnflagLastDoublonsTest extends AbstractDbUnitTestCase { + + @Test + public void unflagLastDoublons() throws SQLException { + setupData("sharedFixture", "unflagLastDoublons"); + + new UnflagLastDoublons(getSession()).purge(null); + + checkTables("unflagLastDoublons", "snapshots"); + } +} + diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java new file mode 100644 index 00000000000..51673cd37f0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/ApplyProjectRolesDecoratorTest.java @@ -0,0 +1,78 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.security; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.resources.Project; +import org.sonar.api.security.GroupRole; + +import java.util.ArrayList; +import java.util.Arrays; + +import static org.mockito.Mockito.*; + +public class ApplyProjectRolesDecoratorTest { + + private RoleManager roleManager; + private ApplyProjectRolesDecorator decorator; + + @Before + public void before() { + roleManager = mock(RoleManager.class); + decorator = new ApplyProjectRolesDecorator(roleManager); + } + + @Test + public void doNotApplySecurityWhenExistingRoles() { + Project project = new Project("project"); + project.setId(10); + when(roleManager.getGroupRoles(10)).thenReturn(Arrays.<GroupRole>asList(new GroupRole())); + + decorator.decorate(project, null); + + verify(roleManager, never()).affectDefaultRolesToResource(anyInt()); + } + + @Test + public void doNotApplySecurityOnModules() { + Project project = new Project("project"); + Project module = new Project("module").setParent(project); + module.setId(10); + + when(roleManager.getGroupRoles(10)).thenReturn(Arrays.<GroupRole>asList()); + + decorator.decorate(module, null); + + verify(roleManager, never()).affectDefaultRolesToResource(anyInt()); + } + + @Test + public void applySecurityWhenNoRoles() { + Project project = new Project("project"); + project.setId(10); + when(roleManager.getGroupRoles(10)).thenReturn(new ArrayList<GroupRole>()); + + decorator.decorate(project, null); + + verify(roleManager).affectDefaultRolesToResource(10); + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/RoleManagerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/RoleManagerTest.java new file mode 100644 index 00000000000..ad89b5611b7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/security/RoleManagerTest.java @@ -0,0 +1,55 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.security; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class RoleManagerTest extends AbstractDbUnitTestCase { + + @Test + public void affectDefaultRolesToResource() { + setupData("affectDefaultRolesToResource"); + new RoleManager(getSession()).affectDefaultRolesToResource(10); + checkTables("affectDefaultRolesToResource", "user_roles", "group_roles"); + } + + @Test + public void affectZeroDefaultRolesToResource() { + setupData("affectZeroDefaultRolesToResource"); + new RoleManager(getSession()).affectDefaultRolesToResource(10); + checkTables("affectZeroDefaultRolesToResource", "user_roles", "group_roles"); + } + + @Test + public void affectAnyoneDefaultRoleToResource() { + setupData("affectAnyoneDefaultRoleToResource"); + new RoleManager(getSession()).affectDefaultRolesToResource(10); + checkTables("affectAnyoneDefaultRoleToResource", "group_roles"); + } + + @Test + public void convertDefaultRoleName() { + assertThat(RoleManager.convertDefaultRoleName(RoleManager.DEFAULT_ROLE_PREFIX + "admin"), is("admin")); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/AlertUtilsTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/AlertUtilsTest.java new file mode 100644 index 00000000000..828ab46c4c9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/AlertUtilsTest.java @@ -0,0 +1,253 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.profiles.Alert; + +public class AlertUtilsTest { + private Metric metric; + private Measure measure; + private Metric metric2; + private Measure measure2; + private Alert alert; + + @Before + public void setup() { + metric = new Metric("test-metric"); + measure = new Measure(); + measure.setMetric(metric); + + metric2 = new Metric("test-metric2"); + measure2 = new Measure(); + measure2.setMetric(metric2); + + alert = new Alert(); + } + + @Test + public void testInputNumbers() { + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_SMALLER); + alert.setMetric(metric); + + try { + metric.setType(Metric.ValueType.FLOAT); + alert.setValueError("20"); + AlertUtils.getLevel(alert, measure); + } catch (NumberFormatException ex) { + Assert.fail(); + } + + try { + metric.setType(Metric.ValueType.INT); + alert.setValueError("20.1"); + AlertUtils.getLevel(alert, measure); + } catch (NumberFormatException ex) { + Assert.fail(); + } + + try { + metric.setType(Metric.ValueType.PERCENT); + alert.setValueError("20.1"); + AlertUtils.getLevel(alert, measure); + } catch (NumberFormatException ex) { + Assert.fail(); + } + } + + @Test + public void testEquals() { + + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError("10.2"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.1"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + metric.setType(Metric.ValueType.STRING); + measure.setData("TEST"); + measure.setValue(null); + + alert.setValueError("TEST"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("TEST2"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + } + + @Test + public void testNotEquals() { + + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_NOT_EQUALS); + alert.setMetric(metric); + + alert.setValueError("10.2"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.1"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + metric.setType(Metric.ValueType.STRING); + measure.setData("TEST"); + measure.setValue(null); + + alert.setValueError("TEST"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("TEST2"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + } + + @Test + public void testGreater() { + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_GREATER); + alert.setMetric(metric); + + alert.setValueError("10.1"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.3"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testSmaller() { + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_SMALLER); + alert.setMetric(metric); + + alert.setValueError("10.1"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.3"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testPercent() { + metric.setType(Metric.ValueType.PERCENT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError("10.2"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testFloat() { + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError("10.2"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testInteger() { + metric.setType(Metric.ValueType.INT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError("10"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.2"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testLevel() { + metric.setType(Metric.ValueType.LEVEL); + measure.setData(Metric.Level.ERROR.toString()); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError(Metric.Level.ERROR.toString()); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError(Metric.Level.OK.toString()); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + alert.setOperator(Alert.OPERATOR_NOT_EQUALS); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testBooleans() { + metric.setType(Metric.ValueType.BOOL); + measure.setValue(0d); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError("true"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("false"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setOperator(Alert.OPERATOR_NOT_EQUALS); + alert.setValueError("true"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("false"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + } + + @Test + public void testErrorAndWarningLevel() { + + metric.setType(Metric.ValueType.FLOAT); + measure.setValue(10.2d); + alert.setOperator(Alert.OPERATOR_EQUALS); + alert.setMetric(metric); + + alert.setValueError("10.2"); + Assert.assertEquals(Metric.Level.ERROR, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.1"); + Assert.assertEquals(Metric.Level.OK, AlertUtils.getLevel(alert, measure)); + + alert.setValueError("10.3"); + alert.setValueWarning("10.2"); + Assert.assertEquals(Metric.Level.WARN, AlertUtils.getLevel(alert, measure)); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java new file mode 100644 index 00000000000..69e3e06bd9e --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Test; +import static org.mockito.Matchers.anyDouble; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Project; + +public class BranchCoverageDecoratorTest { + + @Test + public void noBranchCoverageIfMissingConditions() { + Project resource = mock(Project.class); + when(resource.getScope()).thenReturn(Project.SCOPE_SET); + when(resource.getQualifier()).thenReturn(Project.QUALIFIER_SUBVIEW); + + DecoratorContext context = mockContext(null, null); + new BranchCoverageDecorator().decorate(resource, context); + + verify(context, never()).saveMeasure(eq(CoreMetrics.BRANCH_COVERAGE), anyDouble()); + } + + @Test + public void branchCoverage() { + Project resource = mock(Project.class); + when(resource.getScope()).thenReturn(Project.SCOPE_SET); + when(resource.getQualifier()).thenReturn(Project.QUALIFIER_PROJECT); + + DecoratorContext context = mockContext(20, 15); + + new BranchCoverageDecorator().decorate(resource, context); + verify(context).saveMeasure(CoreMetrics.BRANCH_COVERAGE, 25.0); + } + + + private DecoratorContext mockContext(Integer conditions, Integer uncoveredConditions) { + DecoratorContext context = mock(DecoratorContext.class); + if (conditions != null) { + when(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.CONDITIONS_TO_COVER, conditions.doubleValue())); + } + if (uncoveredConditions != null) { + when(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, uncoveredConditions.doubleValue())); + } + return context; + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CheckAlertThresholdsTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CheckAlertThresholdsTest.java new file mode 100644 index 00000000000..4354c4914c9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CheckAlertThresholdsTest.java @@ -0,0 +1,167 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.profiles.Alert; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.test.IsMeasure; + +import java.util.ArrayList; +import java.util.Arrays; + +import static org.junit.Assert.assertFalse; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.*; + +public class CheckAlertThresholdsTest { + private CheckAlertThresholds decorator; + private DecoratorContext context; + private RulesProfile profile; + private Measure measureClasses; + private Measure measureCoverage; + private Resource project; + + + @Before + public void setup() { + context = mock(DecoratorContext.class); + + measureClasses = new Measure(CoreMetrics.CLASSES, 20d); + measureCoverage = new Measure(CoreMetrics.COVERAGE, 35d); + + when(context.getMeasure(CoreMetrics.CLASSES)).thenReturn(measureClasses); + when(context.getMeasure(CoreMetrics.COVERAGE)).thenReturn(measureCoverage); + + profile = mock(RulesProfile.class); + decorator = new CheckAlertThresholds(profile); + project = mock(Resource.class); + when(project.getQualifier()).thenReturn(Project.QUALIFIER_PROJECT); + } + + @Test + public void shouldNotCreateAlertsWhenNoThresholds() { + when(profile.getAlerts()).thenReturn(new ArrayList<Alert>()); + assertFalse(decorator.shouldExecuteOnProject(new Project("key"))); + } + + @Test + public void shouldBeOkWhenNoAlerts() { + when(profile.getAlerts()).thenReturn(Arrays.asList( + new Alert(null, CoreMetrics.CLASSES, Alert.OPERATOR_GREATER, null, "20"), + new Alert(null, CoreMetrics.COVERAGE, Alert.OPERATOR_GREATER, null, "35.0"))); + + decorator.decorate(project, context); + + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.ALERT_STATUS, Metric.Level.OK.toString()))); + verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.OK))); + verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.OK))); + } + + @Test + public void checkRootProjectsOnly() { + when(project.getQualifier()).thenReturn(Project.QUALIFIER_FILE); + when(profile.getAlerts()).thenReturn(Arrays.asList( + new Alert(null, CoreMetrics.CLASSES, Alert.OPERATOR_GREATER, null, "20"), + new Alert(null, CoreMetrics.COVERAGE, Alert.OPERATOR_GREATER, null, "35.0"))); + + decorator.decorate(project, context); + + verify(context, never()).saveMeasure((Measure) anyObject()); + } + + @Test + public void shouldGenerateWarnings() { + when(profile.getAlerts()).thenReturn(Arrays.asList( + new Alert(null, CoreMetrics.CLASSES, Alert.OPERATOR_GREATER, null, "100"), + new Alert(null, CoreMetrics.COVERAGE, Alert.OPERATOR_SMALLER, null, "95.0"))); // generates warning because coverage 35% < 95% + + decorator.decorate(project, context); + + verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.WARN, null))); + + verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.OK))); + verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.WARN))); + + } + + @Test + public void globalStatusShouldBeErrorIfWarningsAndErrors() { + when(profile.getAlerts()).thenReturn(Arrays.asList( + new Alert(null, CoreMetrics.CLASSES, Alert.OPERATOR_SMALLER, null, "100"), // generates warning because classes 20 < 100 + new Alert(null, CoreMetrics.COVERAGE, Alert.OPERATOR_SMALLER, "50.0", "80.0"))); // generates error because coverage 35% < 50% + + decorator.decorate(project, context); + + verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.ERROR, null))); + + verify(context).saveMeasure(argThat(hasLevel(measureClasses, Metric.Level.WARN))); + verify(context).saveMeasure(argThat(hasLevel(measureCoverage, Metric.Level.ERROR))); + } + + @Test + public void globalLabelShouldAggregateAllLabels() { + Alert alert1 = mock(Alert.class); + when(alert1.getMetric()).thenReturn(CoreMetrics.CLASSES); + when(alert1.getValueError()).thenReturn("10000"); // there are 20 classes, error threshold is higher => alert + when(alert1.getAlertLabel(Metric.Level.ERROR)).thenReturn("error classes"); + + Alert alert2 = mock(Alert.class); + when(alert2.getMetric()).thenReturn(CoreMetrics.COVERAGE); + when(alert2.getValueWarning()).thenReturn("80"); // coverage is 35%, warning threshold is higher => alert + when(alert2.getAlertLabel(Metric.Level.WARN)).thenReturn("warning coverage"); + + when(profile.getAlerts()).thenReturn(Arrays.asList(alert1, alert2)); + decorator.decorate(project, context); + + verify(context).saveMeasure(argThat(matchesMetric(CoreMetrics.ALERT_STATUS, Metric.Level.ERROR, "error classes, warning coverage"))); + } + + private ArgumentMatcher<Measure> matchesMetric(final Metric metric, final Metric.Level alertStatus, final String alertText) { + return new ArgumentMatcher<Measure>() { + @Override + public boolean matches(Object arg) { + boolean result = ((Measure) arg).getMetric().equals(metric) && ((Measure) arg).getAlertStatus() == alertStatus; + if (result && alertText != null) { + result = alertText.equals(((Measure) arg).getAlertText()); + } + return result; + } + }; + } + + private ArgumentMatcher<Measure> hasLevel(final Measure measure, final Metric.Level alertStatus) { + return new ArgumentMatcher<Measure>() { + @Override + public boolean matches(Object arg) { + return arg == measure && ((Measure) arg).getAlertStatus().equals(alertStatus); + } + }; + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CommentDensityDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CommentDensityDecoratorTest.java new file mode 100644 index 00000000000..fd887e5df7a --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CommentDensityDecoratorTest.java @@ -0,0 +1,76 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.plugins.core.sensors; + +import org.junit.Test; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.test.IsMeasure; + +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class CommentDensityDecoratorTest { + + @Test + public void densityIsBalancedByNcloc() { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 300.0)); + when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 200.0)); + CommentDensityDecorator decorator = new CommentDensityDecorator(); + decorator.decorate(null, context); + // 200 / (200 + 300) = 40% + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY, 40.0))); + } + + @Test + public void noDensityIfUnknownComments() { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 300.0)); + CommentDensityDecorator decorator = new CommentDensityDecorator(); + decorator.decorate(null, context); + verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY))); + } + + @Test + public void noDensityIfZeroNcloc() { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 0.0)); + when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0)); + CommentDensityDecorator decorator = new CommentDensityDecorator(); + decorator.decorate(null, context); + verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY))); + } + + @Test + public void zeroDensityWhenZeroComments() { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 40.0)); + when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0)); + CommentDensityDecorator decorator = new CommentDensityDecorator(); + decorator.decorate(null, context); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.COMMENT_LINES_DENSITY, 0.0))); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageDecoratorTest.java new file mode 100644 index 00000000000..01a90d7afb0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageDecoratorTest.java @@ -0,0 +1,104 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Project; + +public class CoverageDecoratorTest { + + private Project project = null; + + @Before + public void before() { + project = mock(Project.class); + when(project.getScope()).thenReturn(Project.SCOPE_SET); + } + + @Test + public void noCoverageWhenStaticAnalysis() { + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.STATIC); + assertThat(new CoverageDecorator().shouldExecuteOnProject(project), is(false)); + + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.REUSE_REPORTS); + assertThat(new CoverageDecorator().shouldExecuteOnProject(project), is(true)); + + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC); + assertThat(new CoverageDecorator().shouldExecuteOnProject(project), is(true)); + } + + @Test + public void coverage() { + DecoratorContext context = mockContext(50, 40, 10, 8); + + new CoverageDecorator().decorate(project, context); + + // (50-40 covered lines + 10-8 covered conditions) / (50 lines + 10 conditions) + verify(context).saveMeasure(CoreMetrics.COVERAGE, 20.0); + } + + @Test + public void coverageCanBe0() { + DecoratorContext context = mockContext(50, 50, 5, 5); + new CoverageDecorator().decorate(project, context); + + verify(context).saveMeasure(CoreMetrics.COVERAGE, 0.0); + } + + @Test + public void coverageCanBe100() { + DecoratorContext context = mockContext(50, 0, 5, 0); + new CoverageDecorator().decorate(project, context); + + verify(context).saveMeasure(CoreMetrics.COVERAGE, 100.0); + } + + @Test + public void noCoverageIfNoElements() { + DecoratorContext context = mockContext(null, null, null, null); + new CoverageDecorator().decorate(project, context); + + verify(context, never()).saveMeasure(eq(CoreMetrics.COVERAGE), anyDouble()); + } + + private DecoratorContext mockContext(Integer lines, Integer uncoveredLines, Integer conditions, Integer uncoveredConditions) { + DecoratorContext context = mock(DecoratorContext.class); + if (lines != null) { + when(context.getMeasure(CoreMetrics.LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.LINES_TO_COVER, lines.doubleValue())); + } + if (uncoveredLines != null) { + when(context.getMeasure(CoreMetrics.UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.UNCOVERED_LINES, uncoveredLines.doubleValue())); + } + if (conditions != null) { + when(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER)).thenReturn(new Measure(CoreMetrics.CONDITIONS_TO_COVER, conditions.doubleValue())); + } + if (uncoveredConditions != null) { + when(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS)).thenReturn(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, uncoveredConditions.doubleValue())); + } + return context; + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/DirectoriesDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/DirectoriesDecoratorTest.java new file mode 100644 index 00000000000..b3b3720fb5f --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/DirectoriesDecoratorTest.java @@ -0,0 +1,94 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Test; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.*; + +import java.util.Arrays; +import java.util.Collections; + +import static org.mockito.Matchers.anyDouble; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +public class DirectoriesDecoratorTest { + + @Test + public void doNotInsertZeroOnFiles() { + DirectoriesDecorator decorator = new DirectoriesDecorator(); + Resource file = new File("foo.php"); + DecoratorContext context = mock(DecoratorContext.class); + + decorator.decorate(file, context); + + verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble()); + } + + @Test + public void directoryCountsForOne() { + DirectoriesDecorator decorator = new DirectoriesDecorator(); + Resource directory = new Directory("org/foo"); + DecoratorContext context = mock(DecoratorContext.class); + decorator.decorate(directory, context); + verify(context).saveMeasure(CoreMetrics.DIRECTORIES, 1.0); + } + + @Test + public void countProjectDirectories() { + DirectoriesDecorator decorator = new DirectoriesDecorator(); + Resource project = new Project("project"); + DecoratorContext context = mock(DecoratorContext.class); + + when(context.getChildrenMeasures(CoreMetrics.DIRECTORIES)).thenReturn(Arrays.<Measure>asList( + new Measure(CoreMetrics.DIRECTORIES, 1.0), + new Measure(CoreMetrics.DIRECTORIES, 1.0), + new Measure(CoreMetrics.DIRECTORIES, 1.0) + )); + decorator.decorate(project, context); + verify(context).saveMeasure(CoreMetrics.DIRECTORIES, 3.0); + } + + @Test + public void packagesAreIgnored() { + DirectoriesDecorator decorator = new DirectoriesDecorator(); + Resource pac = new JavaPackage("org.foo"); + DecoratorContext context = mock(DecoratorContext.class); + decorator.decorate(pac, context); + verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble()); + } + + @Test + public void noProjectValueWhenOnlyPackages() { + DirectoriesDecorator decorator = new DirectoriesDecorator(); + Resource project = new Project("project"); + DecoratorContext context = mock(DecoratorContext.class); + when(context.getChildrenMeasures(CoreMetrics.DIRECTORIES)).thenReturn(Collections.<Measure>emptyList()); + when(context.getChildrenMeasures(CoreMetrics.PACKAGES)).thenReturn(Arrays.<Measure>asList( + new Measure(CoreMetrics.PACKAGES, 1.0), + new Measure(CoreMetrics.PACKAGES, 1.0) + )); + decorator.decorate(project, context); + verify(context, never()).saveMeasure(eq(CoreMetrics.DIRECTORIES), anyDouble()); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/GenerateAlertEventsTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/GenerateAlertEventsTest.java new file mode 100644 index 00000000000..6a5732d76ae --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/GenerateAlertEventsTest.java @@ -0,0 +1,149 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.dbunit.dataset.DataSetException; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.TimeMachine; +import org.sonar.api.batch.TimeMachineQuery; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.profiles.Alert; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.test.ProjectTestBuilder; + +import java.util.Arrays; +import java.util.Date; + +public class GenerateAlertEventsTest { + private GenerateAlertEvents decorator; + private DecoratorContext context; + private RulesProfile profile; + private TimeMachine timeMachine; + private Project project; + + @Before + public void setup() { + context = mock(DecoratorContext.class); + timeMachine = mock(TimeMachine.class); + profile = mock(RulesProfile.class); + decorator = new GenerateAlertEvents(profile, timeMachine); + project = new ProjectTestBuilder().build(); + } + + @Test + public void doNotDecorateIfNoThresholds() { + assertThat(decorator.shouldExecuteOnProject(project), is(false)); + } + + @Test + public void shouldDecorateIfThresholds() { + when(profile.getAlerts()).thenReturn(Arrays.asList(new Alert())); + assertThat(decorator.shouldExecuteOnProject(project), is(true)); + } + + @Test + public void shouldCreateEventWhenNewErrorAlert() { + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.ERROR, "desc")); + decorator.decorate(project, context); + verify(context).createEvent(Metric.Level.ERROR.getColorName(), "desc", Event.CATEGORY_ALERT, null); + } + + @Test + public void shouldCreateEventWhenNewWarnAlert() { + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.WARN, "desc")); + decorator.decorate(project, context); + verify(context).createEvent(Metric.Level.WARN.getColorName(), "desc", Event.CATEGORY_ALERT, null); + } + + @Test + public void shouldCreateEventWhenWarnToError() { + when(timeMachine.getMeasures((TimeMachineQuery) anyObject())).thenReturn(Arrays.asList(newAlertStatus(Metric.Level.WARN, "desc"))); + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.ERROR, "desc")); + + decorator.decorate(project, context); + + verify(context).createEvent("Red (was Orange)", "desc", Event.CATEGORY_ALERT, null); + } + + @Test + public void shouldCreateEventWhenErrorToOk() { + when(timeMachine.getMeasures((TimeMachineQuery) anyObject())).thenReturn(Arrays.asList(newAlertStatus(Metric.Level.ERROR, "desc"))); + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.OK, null)); + + decorator.decorate(project, context); + + verify(context).createEvent("Green (was Red)", null, Event.CATEGORY_ALERT, null); + } + + @Test + public void shouldCreateEventWhenErrorToWarn() { + when(timeMachine.getMeasures((TimeMachineQuery) anyObject())).thenReturn(Arrays.asList(newAlertStatus(Metric.Level.ERROR, "desc"))); + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.WARN, "desc")); + + decorator.decorate(project, context); + + verify(context).createEvent("Orange (was Red)", "desc", Event.CATEGORY_ALERT, null); + } + + @Test + public void shouldNotCreateEventWhenNoAlertStatus() throws DataSetException { + decorator.decorate(project, context); + + verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + } + + @Test + public void shouldNotCreateEventWhenSameLevel() throws DataSetException { + when(timeMachine.getMeasures((TimeMachineQuery) anyObject())).thenReturn(Arrays.asList(newAlertStatus(Metric.Level.ERROR, "desc"))); + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.ERROR, "desc")); + + decorator.decorate(project, context); + + verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + } + + @Test + public void shouldNotCreateEventIfNoMoreAlertStatus() throws DataSetException { + when(timeMachine.getMeasures((TimeMachineQuery) anyObject())).thenReturn(Arrays.asList(newAlertStatus(Metric.Level.ERROR, "desc"))); + when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(null); + + decorator.decorate(project, context); + + verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull()); + } + + + private Measure newAlertStatus(Metric.Level level, String label) { + Measure measure = new Measure(CoreMetrics.ALERT_STATUS, level); + measure.setAlertStatus(level); + measure.setAlertText(label); + return measure; + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/JavaSourceImporterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/JavaSourceImporterTest.java new file mode 100644 index 00000000000..34927cfb1c7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/JavaSourceImporterTest.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.io.FileUtils; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import org.junit.Test; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.JavaPackage; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +public class JavaSourceImporterTest { + + @Test + public void shouldCreateResource() throws IOException { + JavaSourceImporter importer = new JavaSourceImporter(); + Resource clazz = importer.createResource(new File(newDir("source1"), "/MyClass.java"), Arrays.asList(newDir("source1")), false); + assertThat(clazz, is(JavaFile.class)); + assertThat(clazz.getKey(), is(JavaPackage.DEFAULT_PACKAGE_NAME + ".MyClass")); + assertThat(clazz.getName(), is("MyClass")); + } + + @Test + public void shouldCreateTestResource() throws IOException { + JavaSourceImporter importer = new JavaSourceImporter(); + Resource resource = importer.createResource(new File(newDir("tests"), "/MyClassTest.java"), Arrays.asList(newDir("tests")), true); + assertThat(resource, is(JavaFile.class)); + assertThat(ResourceUtils.isUnitTestClass(resource), is(true)); + } + + @Test + public void doNotSaveInnerClasses() throws IOException { + // example : https://svn.apache.org/repos/asf/geronimo/server/trunk/plugins/corba/geronimo-corba/src/test/java/org/apache/geronimo/corba/compiler/other/Generic$Interface.java + JavaSourceImporter importer = new JavaSourceImporter(); + Resource resource = importer.createResource(new File(newDir("tests"), "/Generic$Interface.java"), Arrays.asList(newDir("tests")), true); + assertThat(resource, nullValue()); + } + + private File newDir(String relativePath) throws IOException { + File target = new File("target", relativePath); + FileUtils.forceMkdir(target); + return target; + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java new file mode 100644 index 00000000000..018ac637503 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java @@ -0,0 +1,99 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Project; + +public class LineCoverageDecoratorTest { + + private Project project = null; + + @Before + public void before() { + project = mock(Project.class); + when(project.getScope()).thenReturn(Project.SCOPE_SET); + } + + @Test + public void noCoverageWhenStaticAnalysis() { + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.STATIC); + assertThat(new LineCoverageDecorator().shouldExecuteOnProject(project), is(false)); + + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.REUSE_REPORTS); + assertThat(new LineCoverageDecorator().shouldExecuteOnProject(project), is(true)); + + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC); + assertThat(new LineCoverageDecorator().shouldExecuteOnProject(project), is(true)); + } + + @Test + public void lineCoverage() { + DecoratorContext context = mockContext(50, 10); + new LineCoverageDecorator().decorate(project, context); + + // 50-10 covered lines / 50 lines + verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 80.0); + } + + + @Test + public void noLineCoverageIfNoLines() { + DecoratorContext context = mockContext(null, null); + new LineCoverageDecorator().decorate(project, context); + + verify(context, never()).saveMeasure(eq(CoreMetrics.LINE_COVERAGE), anyDouble()); + } + + @Test + public void zeroCoveredLines() { + DecoratorContext context = mockContext(50, 50); + new LineCoverageDecorator().decorate(project, context); + + verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 0.0); + } + + @Test + public void allCoveredLines() { + DecoratorContext context = mockContext(50, 00); + new LineCoverageDecorator().decorate(project, context); + + verify(context).saveMeasure(CoreMetrics.LINE_COVERAGE, 100.0); + } + + private DecoratorContext mockContext(Integer lines, Integer uncoveredLines) { + DecoratorContext context = mock(DecoratorContext.class); + if (lines != null) { + when(context.getMeasure(CoreMetrics.LINES_TO_COVER)).thenReturn(new Measure(CoreMetrics.LINES_TO_COVER, lines.doubleValue())); + } + if (uncoveredLines != null) { + when(context.getMeasure(CoreMetrics.UNCOVERED_LINES)).thenReturn(new Measure(CoreMetrics.UNCOVERED_LINES, uncoveredLines.doubleValue())); + } + return context; + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java new file mode 100644 index 00000000000..c0b94847950 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileSensorTest.java @@ -0,0 +1,44 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Test; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.test.IsMeasure; + +public class ProfileSensorTest { + + @Test + public void saveProfile() { + RulesProfile profile = mock(RulesProfile.class); + when(profile.getId()).thenReturn(22); + when(profile.getName()).thenReturn("fake"); + SensorContext context = mock(SensorContext.class); + + ProfileSensor sensor = new ProfileSensor(profile); + sensor.analyse(null, context); + + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.PROFILE, 22d))); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java new file mode 100644 index 00000000000..69b90dc466e --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java @@ -0,0 +1,89 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.lang.StringUtils; +import org.apache.maven.project.MavenProject; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Test; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; +import org.sonar.api.test.MavenTestUtils; + +public class ProjectLinksSensorTest { + + @Test + public void shouldSaveLinks() { + SensorContext context = mock(SensorContext.class); + MavenProject pom = MavenTestUtils.loadPom("/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml"); + Project project = mock(Project.class); + when(project.getPom()).thenReturn(pom); + + new ProjectLinksSensor().analyse(project, context); + + verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_HOME, "Home", "http://sonar.codehaus.org"))); + verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_ISSUE_TRACKER, "Issues", "http://jira.codehaus.org/browse/SONAR"))); + verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_CONTINUOUS_INTEGRATION, "Continuous integration", "http://bamboo.ci.codehaus.org/browse/SONAR/"))); + verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_SCM, "Sources", "http://svn.sonar.codehaus.org"))); + verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_SCM_DEVELOPER_CONNECTION, "Developer connection", "scm:svn:https://svn.codehaus.org/sonar/trunk"))); + } + + @Test + public void shouldDeleteMissingLinks() { + SensorContext context = mock(SensorContext.class); + MavenProject pom = MavenTestUtils.loadPom("/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml"); + Project project = mock(Project.class); + when(project.getPom()).thenReturn(pom); + + new ProjectLinksSensor().analyse(project, context); + + verify(context).deleteLink(ProjectLinksSensor.KEY_HOME); + verify(context).deleteLink(ProjectLinksSensor.KEY_ISSUE_TRACKER); + verify(context).deleteLink(ProjectLinksSensor.KEY_CONTINUOUS_INTEGRATION); + verify(context).deleteLink(ProjectLinksSensor.KEY_SCM); + verify(context).deleteLink(ProjectLinksSensor.KEY_SCM_DEVELOPER_CONNECTION); + } + + private class MatchLink extends BaseMatcher<ProjectLink> { + private String key; + private String name; + private String url; + + private MatchLink(String key, String name, String url) { + this.key = key; + this.name = name; + this.url = url; + } + + public boolean matches(Object o) { + ProjectLink link = (ProjectLink) o; + return StringUtils.equals(link.getHref(), url) && StringUtils.equals(link.getKey(), key) && StringUtils.equals(link.getName(), name); + } + + public void describeTo(Description description) { + + } + } + +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/TendencyAnalyserTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/TendencyAnalyserTest.java new file mode 100644 index 00000000000..2bab29d3f8b --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/TendencyAnalyserTest.java @@ -0,0 +1,131 @@ +/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2009 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.sensors;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class TendencyAnalyserTest {
+ private TendencyAnalyser analyser = new TendencyAnalyser();
+
+ private List<Double> getValues(Double[] array) {
+ return Arrays.asList(array);
+ }
+
+
+ protected void assertBetween(String typeLabel, Double value, Double min, Double max) {
+ assertTrue(typeLabel + " " + value + "<" + min, value >= min);
+ assertTrue(typeLabel + "=" + value + ">" + max, value <= max);
+ }
+
+ @Test
+ public void testNoData() {
+ assertThat(analyser.analyse(Collections.<Double>emptyList()), nullValue());
+ }
+
+ @Test
+ public void testNotEnoughData() {
+ assertThat(analyser.analyseLevel(Arrays.asList(10.0)), nullValue());
+ }
+
+ @Test
+ public void testTendencyOnThreeDays() {
+ Double[] doubles = new Double[]{10.0, null, 9.9};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), -0.5, 0.5);
+ assertEquals(TendencyAnalyser.TENDENCY_NEUTRAL, slopeData.getLevel());
+ }
+
+ @Test
+ public void testTendencyOnTwoZeroDays() {
+ Double[] doubles = new Double[]{0.0, 0.0};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), -0.0, 0.0);
+ assertEquals(TendencyAnalyser.TENDENCY_NEUTRAL, slopeData.getLevel());
+ }
+
+ @Test
+ public void testTendencyOnThreeZeroDays() {
+ Double[] doubles = new Double[]{0.0, 0.0, 0.0};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), -0.0, 0.0);
+ assertEquals(TendencyAnalyser.TENDENCY_NEUTRAL, slopeData.getLevel());
+ }
+
+ @Test
+ public void testBigDownOnThreeDays() {
+ Double[] doubles = new Double[]{90.0, 91.0, 50.0};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertTrue("slope", slopeData.getSlope() < -2.0);
+ assertEquals(TendencyAnalyser.TENDENCY_BIG_DOWN, slopeData.getLevel());
+ }
+
+ @Test
+ public void testFlatTendency() {
+ Double[] doubles = new Double[]{10.0, 10.2, 9.9};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), -0.5, 0.5);
+ assertEquals(TendencyAnalyser.TENDENCY_NEUTRAL, slopeData.getLevel());
+ }
+
+ @Test
+ public void testFlatTendencyWithPeak() {
+ Double[] doubles = new Double[]{10.0, 15.0, 10.0};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), -0.5, 0.5);
+ assertEquals(TendencyAnalyser.TENDENCY_NEUTRAL, slopeData.getLevel());
+ }
+
+ @Test
+ public void testBigUpTendencyOnThreeValues() {
+ Double[] doubles = new Double[]{10.0, 12.0, 15.5};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), 2.5, 3.0);
+ assertEquals(TendencyAnalyser.TENDENCY_BIG_UP, slopeData.getLevel());
+ }
+
+ @Test
+ public void testBigUpTendencyOnTenValues() {
+ Double[] doubles = new Double[]{45.0, 60.0, 57.0, 65.0, 58.0, 68.0, 59.0, 66.0, 76.0, 80.0};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), 2.5, 3.0);
+ assertEquals(TendencyAnalyser.TENDENCY_BIG_UP, slopeData.getLevel());
+ }
+
+ @Test
+ public void testMediumUpTendency() {
+ Double[] doubles = new Double[]{5.0, 4.5, 5.1, 5.5, 5.3, 6.4, 6.3, 6.6, 6.8, 6.5};
+ TendencyAnalyser.SlopeData slopeData = analyser.analyse(getValues(doubles));
+ assertBetween("slope", slopeData.getSlope(), 0.0, 1.0);
+ assertEquals(TendencyAnalyser.TENDENCY_UP, slopeData.getLevel());
+ }
+
+ @Test
+ public void testAsymetricAlgorithm() {
+ TendencyAnalyser.SlopeData slopeData1 = analyser.analyse(getValues(new Double[]{45.0, 47.0, 95.0}));
+ TendencyAnalyser.SlopeData slopeData2 = analyser.analyse(getValues(new Double[]{95.0, 45.0, 47.0}));
+ assertTrue(slopeData1.getSlope() != slopeData2.getSlope());
+ }
+}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/TendencyDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/TendencyDecoratorTest.java new file mode 100644 index 00000000000..7f7ddc3922d --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/TendencyDecoratorTest.java @@ -0,0 +1,114 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.Test; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.TimeMachine; +import org.sonar.api.batch.TimeMachineQuery; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.JavaPackage; +import org.sonar.api.resources.Project; +import org.sonar.jpa.dao.MeasuresDao; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.matchers.JUnitMatchers.hasItems; +import static org.mockito.Mockito.*; + +public class TendencyDecoratorTest { + + @Test + public void shouldExecuteOnAllProjects() { + assertThat(new TendencyDecorator(null, null, null).shouldExecuteOnProject(null), is(true)); + } + + @Test + public void initQuery() throws ParseException { + Project project = mock(Project.class); + when(project.getAnalysisDate()).thenReturn(date("2009-12-25")); + when(project.getConfiguration()).thenReturn(new PropertiesConfiguration()); + + MeasuresDao dao = mock(MeasuresDao.class); + when(dao.getMetrics()).thenReturn(Arrays.asList(CoreMetrics.LINES, CoreMetrics.COVERAGE, CoreMetrics.COVERAGE_LINE_HITS_DATA, CoreMetrics.PROFILE)); + + TendencyDecorator decorator = new TendencyDecorator(null, dao); + + TimeMachineQuery query = decorator.initQuery(project); + assertThat(query.getMetrics().size(), is(2)); + assertThat(query.getMetrics(), hasItems(CoreMetrics.LINES, CoreMetrics.COVERAGE)); + assertThat(query.getFrom(), is(date("2009-11-25"))); + assertThat(query.isToCurrentAnalysis(), is(true)); + } + + @Test + public void includeCurrentMeasures() throws ParseException { + TendencyAnalyser analyser = mock(TendencyAnalyser.class); + TimeMachineQuery query = new TimeMachineQuery(null).setMetrics(CoreMetrics.LINES, CoreMetrics.COVERAGE); + TimeMachine timeMachine = mock(TimeMachine.class); + + when(timeMachine.getMeasuresFields(query)).thenReturn(Arrays.<Object[]>asList( + new Object[]{date("2009-12-01"), CoreMetrics.LINES, 1200.0}, + new Object[]{date("2009-12-01"), CoreMetrics.COVERAGE, 80.5}, + new Object[]{date("2009-12-02"), CoreMetrics.LINES, 1300.0}, + new Object[]{date("2009-12-02"), CoreMetrics.COVERAGE, 79.6}, + new Object[]{date("2009-12-15"), CoreMetrics.LINES, 1150.0} + )); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.LINES)).thenReturn(new Measure(CoreMetrics.LINES, 1400.0)); + when(context.getMeasure(CoreMetrics.COVERAGE)).thenReturn(new Measure(CoreMetrics.LINES, 90.0)); + + TendencyDecorator decorator = new TendencyDecorator(timeMachine, query, analyser); + decorator.decorate(new JavaPackage("org.foo"), context); + + verify(analyser).analyseLevel(Arrays.asList(1200.0, 1300.0, 1150.0, 1400.0)); + verify(analyser).analyseLevel(Arrays.asList(80.5, 79.6, 90.0)); + } + + @Test + public void noTendencyIfNoCurrentMeasures() throws ParseException { + TendencyAnalyser analyser = mock(TendencyAnalyser.class); + TimeMachineQuery query = new TimeMachineQuery(null).setMetrics(CoreMetrics.LINES, CoreMetrics.COVERAGE); + TimeMachine timeMachine = mock(TimeMachine.class); + + when(timeMachine.getMeasuresFields(query)).thenReturn(Arrays.<Object[]>asList( + new Object[]{date("2009-12-01"), CoreMetrics.LINES, 1200.0}, + new Object[]{date("2009-12-02"), CoreMetrics.LINES, 1300.0} + )); + + DecoratorContext context = mock(DecoratorContext.class); + TendencyDecorator decorator = new TendencyDecorator(timeMachine, query, analyser); + decorator.decorate(new JavaPackage("org.foo"), context); + + verify(analyser, never()).analyseLevel(anyList()); + } + + private Date date(String date) throws ParseException { + return new SimpleDateFormat("yyyy-MM-dd").parse(date); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UncoveredComplexityDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UncoveredComplexityDecoratorTest.java new file mode 100644 index 00000000000..6c3c4f08049 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UncoveredComplexityDecoratorTest.java @@ -0,0 +1,63 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import static org.hamcrest.core.IsNot.not; +import static org.hamcrest.number.OrderingComparisons.greaterThan; +import static org.junit.Assert.assertThat; +import org.junit.Test; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.test.IsMeasure; + +public class UncoveredComplexityDecoratorTest { + + @Test + public void nothingWhenNoMeasures() { + DecoratorContext context = mock(DecoratorContext.class); + UncoveredComplexityDecorator decorator = new UncoveredComplexityDecorator(); + decorator.decorate(null, context); + + verify(context, never()).saveMeasure((Measure) anyObject()); + } + + @Test + public void quotientWhenMeasures() { + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.COMPLEXITY)).thenReturn(new Measure(CoreMetrics.COMPLEXITY, 1048.0)); + when(context.getMeasure(CoreMetrics.COVERAGE)).thenReturn(new Measure(CoreMetrics.COVERAGE, 32.5)); + + UncoveredComplexityDecorator decorator = new UncoveredComplexityDecorator(); + decorator.decorate(null, context); + + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.UNCOVERED_COMPLEXITY_BY_TESTS, 707.4))); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.UNCOVERED_COMPLEXITY_BY_TESTS, "CMP=1048;COV=32.5"))); + } + + @Test + public void declareDependencies() { + UncoveredComplexityDecorator decorator = new UncoveredComplexityDecorator(); + assertThat(decorator.dependsUponMetrics().size(), greaterThan(0)); + assertThat(decorator.generatesMetric(), not(isNull())); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UnitTestDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UnitTestDecoratorTest.java new file mode 100644 index 00000000000..2f837804bc0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/UnitTestDecoratorTest.java @@ -0,0 +1,45 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.sonar.api.resources.Project; + +public class UnitTestDecoratorTest { + + @Test + public void generatesMetrics() { + assertThat(new UnitTestDecorator().generatesMetrics().size(), is(5)); + } + + @Test + public void doNotDecorateStaticAnalysis() { + Project project = mock(Project.class); + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.STATIC); + assertThat(new UnitTestDecorator().shouldExecuteOnProject(project), is(false)); + + when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC); + assertThat(new UnitTestDecorator().shouldExecuteOnProject(project), is(true)); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/VersionEventsSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/VersionEventsSensorTest.java new file mode 100644 index 00000000000..ef6401e5578 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/VersionEventsSensorTest.java @@ -0,0 +1,142 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Test; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; + +public class VersionEventsSensorTest { + + private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); + private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMdd HH:mm"); + + + @Test + public void shouldDoNothingIfNoVersion() { + VersionEventsSensor sensor = new VersionEventsSensor(); + SensorContext context = mock(SensorContext.class); + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn(null); + + sensor.analyse(project, context); + + verify(context, never()).createEvent((Resource) anyObject(), anyString(), anyString(), anyString(), (Date) anyObject()); + verify(context, never()).deleteEvent((Event) anyObject()); + } + + @Test + public void shouldCreateVersionEvent() { + VersionEventsSensor sensor = new VersionEventsSensor(); + SensorContext context = mock(SensorContext.class); + + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); + + sensor.analyse(project, context); + + verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); + } + + @Test + public void shouldHaveOnlyOneEventByVersion() { + Event sameVersionEvent = mockVersionEvent("1.5-SNAPSHOT"); + Event otherEvent = mockVersionEvent("1.4"); + Event anotherEvent = mockVersionEvent("1.3-SNAPSHOT"); + + VersionEventsSensor sensor = new VersionEventsSensor(); + SensorContext context = mock(SensorContext.class); + + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); + + when(context.getEvents(project)).thenReturn(new ArrayList(Arrays.asList(sameVersionEvent, otherEvent, anotherEvent))); + + sensor.analyse(project, context); + + verify(context).deleteEvent(sameVersionEvent); + verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); + } + + @Test + public void shouldDeleteAssociatedSnapshotWhenReleasing() { + Event snapshotVersion = mockVersionEvent("1.5-SNAPSHOT"); + Event otherEvent = mockVersionEvent("1.4"); + + SensorContext context = mock(SensorContext.class); + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn("1.5"); + when(context.getEvents(project)).thenReturn(new ArrayList(Arrays.asList(snapshotVersion, otherEvent))); + + VersionEventsSensor sensor = new VersionEventsSensor(); + sensor.analyse(project, context); + + verify(context).deleteEvent(snapshotVersion); + verify(context).createEvent(eq(project), eq("1.5"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); + } + + @Test + public void shouldAssociateExistingEventsToSnapshot() throws ParseException { + Event christmas = mockEvent("christmas", "20081225"); + Event newYear = mockEvent("newYear", "20090101"); + Event valentine = mockEvent("valentine", "20090214"); + SensorContext context = mock(SensorContext.class); + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn("1.5"); + when(project.getAnalysisDate()).thenReturn(dateTimeFormat.parse("20090101 15:34")); + when(context.getEvents(project)).thenReturn(new ArrayList(Arrays.asList(christmas, newYear, valentine))); + + VersionEventsSensor sensor = new VersionEventsSensor(); + sensor.analyse(project, context); + + verify(context).deleteEvent(newYear); + verify(context).createEvent(eq(project), eq("newYear"), (String) isNull(), (String) isNull(), (Date) isNull()); + } + + + private Event mockVersionEvent(String version) { + Event event = mock(Event.class); + when(event.isVersionCategory()).thenReturn(true); + when(event.getName()).thenReturn(version); + return event; + } + + private Event mockEvent(String name, String yyyyMMdd) throws ParseException { + Event event = mock(Event.class); + when(event.isVersionCategory()).thenReturn(false); + when(event.isLinkedToSnapshot()).thenReturn(false); + when(event.getName()).thenReturn(name); + when(event.getDate()).thenReturn(dateFormat.parse(yyyyMMdd)); + return event; + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java new file mode 100644 index 00000000000..3ad15551926 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDecoratorTest.java @@ -0,0 +1,163 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Before; +import org.junit.Test; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.rules.RulesCategory; +import org.sonar.api.rules.Violation; +import org.sonar.api.test.IsMeasure; +import org.sonar.api.test.IsRuleMeasure; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ViolationsDecoratorTest { + private RulesCategory categA; + private RulesCategory categB; + private Rule ruleA1; + private Rule ruleA2; + private Rule ruleB1; + private ViolationsDecorator decorator; + private Resource resource; + private DecoratorContext context; + + @Before + public void before() { + categA = new RulesCategory("Maintainability"); + categA.setId(1); + + categB = new RulesCategory("Usability"); + categB.setId(2); + + ruleA1 = new Rule("ruleA1", "ruleA1", "nameA1", categA, null); + ruleA1.setId(1); + + ruleA2 = new Rule("ruleA2", "ruleA2", "nameA2", categA, null); + ruleA2.setId(2); + + ruleB1 = new Rule("ruleB1", "ruleB1", "nameB1", categB, null); + ruleB1.setId(3); + + decorator = new ViolationsDecorator(); + resource = mock(Resource.class); + context = mock(DecoratorContext.class); + when(context.getResource()).thenReturn(resource); + } + + @Test + public void countViolations() throws Exception { + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + when(context.getViolations()).thenReturn(createViolations()); + when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.<Measure>emptyList()); + + decorator.decorate(resource, context); + + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 4.0))); + } + + @Test + public void resetCountersAfterExecution() { + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + when(context.getViolations()).thenReturn(createViolations()); + when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.<Measure>emptyList()); + + decorator.decorate(resource, context); + decorator.decorate(resource, context); + + // we must not have 8 violations ! + verify(context, times(2)).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 4.0))); + verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 8.0))); + } + + @Test + public void saveZeroOnProjects() throws Exception { + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + when(context.getViolations()).thenReturn(Collections.<Violation>emptyList()); + when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.<Measure>emptyList()); + + decorator.decorate(resource, context); + + verify(context, atLeast(1)).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 0.0))); + } + + @Test + public void saveZeroOnDirectories() throws Exception { + when(resource.getScope()).thenReturn(Resource.SCOPE_SPACE); + when(context.getViolations()).thenReturn(Collections.<Violation>emptyList()); + when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.<Measure>emptyList()); + + decorator.decorate(resource, context); + + verify(context, atLeast(1)).saveMeasure(argThat(new IsMeasure(CoreMetrics.VIOLATIONS, 0.0))); + } + + @Test + public void priorityViolations() throws Exception { + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + when(context.getViolations()).thenReturn(createViolations()); + when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.<Measure>emptyList()); + + decorator.decorate(resource, context); + + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, null, RulePriority.BLOCKER, 0.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, null, RulePriority.CRITICAL, 2.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, null, RulePriority.MAJOR, 1.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, null, RulePriority.MINOR, 1.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, null, RulePriority.INFO, 0.0))); + + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.BLOCKER_VIOLATIONS, 0.0))); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.CRITICAL_VIOLATIONS, 2.0))); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.MAJOR_VIOLATIONS, 1.0))); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.MINOR_VIOLATIONS, 1.0))); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.INFO_VIOLATIONS, 0.0))); + } + + @Test + public void categoryViolations() throws Exception { + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + when(context.getViolations()).thenReturn(createViolations()); + when(context.getChildrenMeasures((MeasuresFilter) anyObject())).thenReturn(Collections.<Measure>emptyList()); + + decorator.decorate(resource, context); + + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, categA.getId(), null, 3.0))); + verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.VIOLATIONS, null, categB.getId(), null, 1.0))); + } + + + private List<Violation> createViolations() { + List<Violation> violations = new ArrayList<Violation>(); + violations.add(new Violation(ruleA1).setPriority(RulePriority.CRITICAL)); + violations.add(new Violation(ruleA1).setPriority(RulePriority.CRITICAL)); + violations.add(new Violation(ruleA2).setPriority(RulePriority.MAJOR)); + violations.add(new Violation(ruleB1).setPriority(RulePriority.MINOR)); + return violations; + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDensityDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDensityDecoratorTest.java new file mode 100644 index 00000000000..cf4bca69fc3 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ViolationsDensityDecoratorTest.java @@ -0,0 +1,173 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.*; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.Rule; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class ViolationsDensityDecoratorTest { + + @Test + public void calculateDensity() { + assertThat(ViolationsDensityDecorator.calculate(4000, 200), is(0.0)); + assertThat(ViolationsDensityDecorator.calculate(200, 200), is(0.0)); + assertThat(ViolationsDensityDecorator.calculate(50, 200), is(75.0)); + assertThat(ViolationsDensityDecorator.calculate(0, 200), is(100.0)); + } + + + @Test + public void decorateDensity() { + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 200.0)); + when(context.getMeasure(CoreMetrics.WEIGHTED_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, 50.0)); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(new HashMap()); + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.VIOLATIONS_DENSITY, 75.0); + } + + @Test + public void noDensityIfNoNcloc() { + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 0.0)); + when(context.getMeasure(CoreMetrics.WEIGHTED_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, 50.0)); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(new HashMap()); + decorator.decorate(resource, context); + + verify(context, never()).saveMeasure(eq(CoreMetrics.VIOLATIONS_DENSITY), anyDouble()); + } + + @Test + public void saveDensityIfValueIsZero() { + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 200.0)); + when(context.getMeasure(CoreMetrics.WEIGHTED_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, 5000.0)); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(new HashMap()); + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.VIOLATIONS_DENSITY, 0.0); + } + + @Test + public void densityIsHundredWhenNoDebt() { + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 200.0)); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(new HashMap()); + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.VIOLATIONS_DENSITY, 100.0); + } + + @Test + public void densityIsHundredWhenDebtIsZero() { + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 200.0)); + when(context.getMeasure(CoreMetrics.WEIGHTED_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, 0.0)); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(new HashMap()); + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.VIOLATIONS_DENSITY, 100.0); + } + + @Test + public void densityByCategory() { + Map<Integer, Metric> metricByCategoryId = new HashMap<Integer, Metric>(); + metricByCategoryId.put(3, CoreMetrics.USABILITY); + metricByCategoryId.put(5, CoreMetrics.EFFICIENCY); + metricByCategoryId.put(6, CoreMetrics.RELIABILITY); + + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_SET); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 200.0)); + when(context.getMeasures((MeasuresFilter) anyObject())) + .thenReturn(Arrays.asList( + new RuleMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, new Rule(), null, 3).setValue(50.0), + new RuleMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, new Rule(), null, 5).setValue(0.0))); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(metricByCategoryId); + decorator.decorate(resource, context); + + verify(context).saveMeasure(CoreMetrics.USABILITY, 75.0); + verify(context).saveMeasure(CoreMetrics.EFFICIENCY, 100.0); + verify(context).saveMeasure(CoreMetrics.RELIABILITY, 100.0); + } + + @Test + public void doNotCalculateDensityByCategoryOnEntities() { + Map<Integer, Metric> metricByCategoryId = new HashMap<Integer, Metric>(); + metricByCategoryId.put(3, CoreMetrics.USABILITY); + metricByCategoryId.put(5, CoreMetrics.EFFICIENCY); + metricByCategoryId.put(6, CoreMetrics.RELIABILITY); + + Resource resource = mock(Resource.class); + when(resource.getScope()).thenReturn(Resource.SCOPE_ENTITY); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 200.0)); + when(context.getMeasure(CoreMetrics.WEIGHTED_VIOLATIONS)).thenReturn(new Measure(CoreMetrics.WEIGHTED_VIOLATIONS, 50.0)); + when(context.getMeasures((MeasuresFilter) anyObject())) + .thenReturn(Arrays.asList( + new RuleMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, new Rule(), null, 3).setValue(50.0), + new RuleMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, new Rule(), null, 5).setValue(0.0))); + + ViolationsDensityDecorator decorator = new ViolationsDensityDecorator(metricByCategoryId); + decorator.decorate(resource, context); + + verify(context, never()).saveMeasure(eq(CoreMetrics.USABILITY), anyDouble()); + verify(context, never()).saveMeasure(eq(CoreMetrics.EFFICIENCY), anyDouble()); + verify(context, never()).saveMeasure(eq(CoreMetrics.RELIABILITY), anyDouble()); + verify(context, never()).saveMeasure(eq(CoreMetrics.MAINTAINABILITY), anyDouble()); + verify(context).saveMeasure(CoreMetrics.VIOLATIONS_DENSITY, 75.0); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java new file mode 100644 index 00000000000..f02934a6dbf --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/WeightedViolationsDecoratorTest.java @@ -0,0 +1,116 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.sensors; + +import org.junit.Test; +import static org.mockito.Mockito.*; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +import org.sonar.api.measures.RuleMeasure; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.test.IsMeasure; +import org.sonar.api.test.IsRuleMeasure; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class WeightedViolationsDecoratorTest { + + private List<RuleMeasure> createViolationsMeasures() { + return Arrays.asList( + // categ 3 + new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.INFO, 3).setValue(40.0), + new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.CRITICAL, 3).setValue(80.0), + new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.BLOCKER, 3).setValue(90.0), + + // categ 4 + new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.INFO, 4).setValue(10.0), + new RuleMeasure(CoreMetrics.VIOLATIONS, new Rule(), RulePriority.BLOCKER, 4).setValue(10.0) + ); + } + + private Map<RulePriority, Integer> createWeights() { + Map<RulePriority, Integer> weights = new HashMap(); + weights.put(RulePriority.BLOCKER, 10); + weights.put(RulePriority.CRITICAL, 5); + weights.put(RulePriority.MAJOR, 2); + weights.put(RulePriority.MINOR, 1); + weights.put(RulePriority.INFO, 0); + return weights; + } + + @Test + public void weightedViolations() { + Map<RulePriority, Integer> weights = createWeights(); + + WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(weights); + DecoratorContext context = mock(DecoratorContext.class); + + when(context.getMeasures((MeasuresFilter) anyObject())).thenReturn(createViolationsMeasures()); + + decorator.decorate(mock(Resource.class), context); + + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, (double) (100 * 10 + 80 * 5 + 50 * 0)))); + verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.WEIGHTED_VIOLATIONS, "INFO=50;CRITICAL=80;BLOCKER=100"))); + } + + @Test + public void doNotSaveZero() { + Map<RulePriority, Integer> weights = createWeights(); + + WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(weights); + DecoratorContext context = mock(DecoratorContext.class); + + when(context.getMeasures((MeasuresFilter) anyObject())).thenReturn(Arrays.asList()); + + decorator.decorate(mock(Resource.class), context); + + verify(context, never()).saveMeasure((Measure) anyObject()); + } + + @Test + public void weightedViolationsOnCategories() { + Map<RulePriority, Integer> weights = createWeights(); + + WeightedViolationsDecorator decorator = new WeightedViolationsDecorator(weights); + DecoratorContext context = mock(DecoratorContext.class); + + when(context.getMeasures((MeasuresFilter) anyObject())).thenReturn(createViolationsMeasures()); + + decorator.decorate(mock(Resource.class), context); + + // categ 3 + verify(context).saveMeasure(argThat(new IsRuleMeasure( + CoreMetrics.WEIGHTED_VIOLATIONS, null, 3, null, 40.0 * 0 + 80.0 * 5 + 90.0 * 10))); + + // categ 4 + verify(context).saveMeasure(argThat(new IsRuleMeasure( + CoreMetrics.WEIGHTED_VIOLATIONS, null, 4, null, 10.0 * 0 + 10.0 * 10))); + + } + +} diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/purgeDeletedResources-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/purgeDeletedResources-result.xml new file mode 100644 index 00000000000..acb67c7fca2 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/purgeDeletedResources-result.xml @@ -0,0 +1,68 @@ +<dataset> + + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <!--<snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="[null]"/>--> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <!--<SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/>--> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="4" DATA="foo"/> + + + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <!--<RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/>--> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <!--<measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/>--> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/purgeDeletedResources.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/purgeDeletedResources.xml new file mode 100644 index 00000000000..828e5275d7d --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/purgeDeletedResources.xml @@ -0,0 +1,68 @@ +<dataset> + + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="4" DATA="foo"/> + + + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/sharedFixture.xml new file mode 100644 index 00000000000..8d4d27778c7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeletedResourcesTest/sharedFixture.xml @@ -0,0 +1,33 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- file --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- project copy for views --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="TRK" kee="cp-mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="1"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/purgeDeprecatedLast-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/purgeDeprecatedLast-result.xml new file mode 100644 index 00000000000..daebf0a394a --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/purgeDeprecatedLast-result.xml @@ -0,0 +1,71 @@ +<dataset> + + <!-- old snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!-- last but project is not last --> + <!--<snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true"--> + <!--path="[null]"/>--> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <!--<SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/>--> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="4" DATA="foo"/> + + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <!--<RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/>--> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <!--<measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/>--> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/purgeDeprecatedLast.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/purgeDeprecatedLast.xml new file mode 100644 index 00000000000..29b9f3ada99 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/purgeDeprecatedLast.xml @@ -0,0 +1,71 @@ +<dataset> + + <!-- old snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!-- last but project is not last --> + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="4" DATA="foo"/> + + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/sharedFixture.xml new file mode 100644 index 00000000000..8d4d27778c7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDeprecatedLastTest/sharedFixture.xml @@ -0,0 +1,33 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- file --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- project copy for views --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="TRK" kee="cp-mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="1"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/nothingToPurge-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/nothingToPurge-result.xml new file mode 100644 index 00000000000..c7125729940 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/nothingToPurge-result.xml @@ -0,0 +1,89 @@ +<dataset> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- module --> + <projects long_name="[null]" id="2" scope="PRJ" qualifier="BRC" kee="mygroup:mymoduleartifact" name="module" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- class --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="Class1" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="1"/> + + <snapshots depth="0" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + <snapshots depth="1" id="2" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1."/> + + <snapshots depth="2" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2."/> + + <snapshots depth="3" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2.3."/> + + <snapshots depth="0" id="5" scope="PRJ" qualifier="TRK" created_at="2009-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/nothingToPurge.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/nothingToPurge.xml new file mode 100644 index 00000000000..c7125729940 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/nothingToPurge.xml @@ -0,0 +1,89 @@ +<dataset> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- module --> + <projects long_name="[null]" id="2" scope="PRJ" qualifier="BRC" kee="mygroup:mymoduleartifact" name="module" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- class --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="Class1" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="1"/> + + <snapshots depth="0" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + <snapshots depth="1" id="2" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1."/> + + <snapshots depth="2" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2."/> + + <snapshots depth="3" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2.3."/> + + <snapshots depth="0" id="5" scope="PRJ" qualifier="TRK" created_at="2009-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledModule-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledModule-result.xml new file mode 100644 index 00000000000..fbe36205e74 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledModule-result.xml @@ -0,0 +1,75 @@ +<dataset> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- disabled module --> + <!--<projects long_name="[null]" id="2" scope="PRJ" qualifier="BRC" kee="mygroup:mymoduleartifact" name="module" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="false" language="java" copy_resource_id="[null]"/>--> + + <!-- package --> + <!--<projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="[null]"/>--> + + <!-- class --> + <!--<projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" name="Class1" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="1"/>--> + + + <snapshots depth="0" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + <!--<snapshots depth="1" id="2" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="2"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="1."/>--> + + <!--<snapshots depth="2" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="1.2."/>--> + + <!--<snapshots depth="3" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="4"--> + <!--parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="1.2.3."/>--> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledModule.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledModule.xml new file mode 100644 index 00000000000..90abf33096c --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledModule.xml @@ -0,0 +1,78 @@ +<dataset> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- disabled module --> + <projects long_name="[null]" id="2" scope="PRJ" qualifier="BRC" kee="mygroup:mymoduleartifact" name="module" + root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]"/> + + <!-- class --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="Class1" root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="1"/> + + + <snapshots depth="0" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + <snapshots depth="1" id="2" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1."/> + + <snapshots depth="2" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2."/> + + <snapshots depth="3" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2.3."/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledProject-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledProject-result.xml new file mode 100644 index 00000000000..e99e5ca29af --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledProject-result.xml @@ -0,0 +1,106 @@ +<dataset> + + <!-- disabled project --> + <!--<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="false" language="java" copy_resource_id="[null]"/>--> + + <!-- disabled module --> + <!--<projects long_name="[null]" id="2" scope="PRJ" qualifier="BRC" kee="mygroup:mymoduleartifact" name="module" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="false" language="java" copy_resource_id="[null]"/>--> + + <!-- package --> + <!--<projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="[null]"/>--> + + <!-- class --> + <!--<projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" name="Class1" root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="1"/>--> + + + <!-- the same enabled project --> + <projects long_name="[null]" id="5" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + + <!--<snapshots depth="0" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="1"--> + <!--parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"--> + <!--path=""/>--> + + <!--<snapshots depth="1" id="2" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="2"--> + <!--parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="1."/>--> + + <!--<snapshots depth="2" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="1.2."/>--> + + <!--<snapshots depth="3" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="4"--> + <!--parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="1.2.3."/>--> + + <!--<snapshots depth="0" id="5" scope="PRJ" qualifier="TRK" created_at="2009-12-02 13:58:00.00" version="[null]"--> + <!--project_id="1"--> + <!--parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"--> + <!--path=""/>--> + + + <!-- enabled --> + <snapshots depth="0" id="6" scope="PRJ" qualifier="TRK" created_at="2009-02-14 13:58:00.00" version="[null]" + project_id="5" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path=""/> + + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledProject.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledProject.xml new file mode 100644 index 00000000000..884a048a5fb --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/purgeDisabledProject.xml @@ -0,0 +1,112 @@ +<dataset> + + <!-- disabled project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]"/> + + <!-- disabled module --> + <projects long_name="[null]" id="2" scope="PRJ" qualifier="BRC" kee="mygroup:mymoduleartifact" name="module" + root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="[null]"/> + + <!-- class --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="Class1" root_id="[null]" + description="[null]" + enabled="false" language="java" copy_resource_id="1"/> + + + <!-- the same enabled project --> + <projects long_name="[null]" id="5" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + + <!-- disabled --> + <snapshots depth="0" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + <snapshots depth="1" id="2" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1."/> + + <snapshots depth="2" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2."/> + + <snapshots depth="3" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="1.2.3."/> + + <snapshots depth="0" id="5" scope="PRJ" qualifier="TRK" created_at="2009-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path=""/> + + + <!-- enabled --> + <snapshots depth="0" id="6" scope="PRJ" qualifier="TRK" created_at="2009-02-14 13:58:00.00" version="[null]" + project_id="5" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path=""/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/sharedFixture.xml new file mode 100644 index 00000000000..eee1bfaad3c --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeDisabledResourcesTest/sharedFixture.xml @@ -0,0 +1,9 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/purgeEntities-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/purgeEntities-result.xml new file mode 100644 index 00000000000..3bdf1da2894 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/purgeEntities-result.xml @@ -0,0 +1,141 @@ +<dataset> + + <!-- old snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <!--<snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false"--> + <!--path="[null]"/>--> + + <!--<snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="4"--> + <!--parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false"--> + <!--path="[null]"/>--> + + + <!-- last snapshots --> + + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + + <!-- old source --> + <!--<SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/>--> + + <!-- last source --> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="7" DATA="foo"/> + + + <!-- old violations --> + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <!--<RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3"/>--> + <!--<RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4"/>--> + + + <!-- last violations --> + <RULE_FAILURES ID="5" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1"/> + <RULE_FAILURES ID="6" SNAPSHOT_ID="6" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2"/> + <RULE_FAILURES ID="7" SNAPSHOT_ID="7" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3"/> + <RULE_FAILURES ID="8" SNAPSHOT_ID="8" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4"/> + + <!-- old measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + + <!-- last measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="7" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="7" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="8" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="8" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- old measure data --> + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <!--<measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/>--> + <!--<measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/>--> + + <!-- last measure data --> + <measure_data id="5" measure_id="5" snapshot_id="5" data="[null]"/> + <measure_data id="6" measure_id="6" snapshot_id="6" data="[null]"/> + <measure_data id="7" measure_id="7" snapshot_id="7" data="[null]"/> + <measure_data id="8" measure_id="8" snapshot_id="8" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/purgeEntities.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/purgeEntities.xml new file mode 100644 index 00000000000..a93593ff164 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/purgeEntities.xml @@ -0,0 +1,141 @@ +<dataset> + + <!-- old snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <!-- last snapshots --> + + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + + <!-- old source --> + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/> + + <!-- last source --> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="7" DATA="foo"/> + + + <!-- old violations --> + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + + <!-- last violations --> + <RULE_FAILURES ID="5" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="6" SNAPSHOT_ID="6" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="7" SNAPSHOT_ID="7" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="8" SNAPSHOT_ID="8" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + <!-- old measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- last measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="7" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="7" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="8" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="8" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- old measure data --> + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + + <!-- last measure data --> + <measure_data id="5" measure_id="5" snapshot_id="5" data="[null]"/> + <measure_data id="6" measure_id="6" snapshot_id="6" data="[null]"/> + <measure_data id="7" measure_id="7" snapshot_id="7" data="[null]"/> + <measure_data id="8" measure_id="8" snapshot_id="8" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/sharedFixture.xml new file mode 100644 index 00000000000..8d4d27778c7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEntitiesTest/sharedFixture.xml @@ -0,0 +1,33 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- file --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- project copy for views --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="TRK" kee="cp-mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="1"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEventOrphansTest/purgeEventOrphans-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEventOrphansTest/purgeEventOrphans-result.xml new file mode 100644 index 00000000000..46bd9b39c93 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEventOrphansTest/purgeEventOrphans-result.xml @@ -0,0 +1,16 @@ +<dataset> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <!-- global event --> + <events id="1" name="Upgrade" resource_id="[null]" snapshot_id="[null]" category="SYSTEM" description="[null]" event_date="2008-12-02 13:58:00.00" CREATED_AT="[null]" data="[null]" /> + + <!-- project event --> + <events id="2" name="Version 1.0" resource_id="1" snapshot_id="[null]" category="VERSION" description="[null]" event_date="2008-12-02 13:58:00.00" CREATED_AT="[null]" data="[null]"/> + + <!-- orphan : the project does not exist--> + <!--<events id="3" name="Version 0.9" resource_id="5" snapshot_id="[null]" category="VERSION" description="[null]" event_date="2008-12-02 13:58:00.00" CREATED_AT="[null]" data="[null]"/> --> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEventOrphansTest/purgeEventOrphans.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEventOrphansTest/purgeEventOrphans.xml new file mode 100644 index 00000000000..6e462083c40 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeEventOrphansTest/purgeEventOrphans.xml @@ -0,0 +1,16 @@ +<dataset> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <!-- global event --> + <events id="1" name="Upgrade" resource_id="[null]" snapshot_id="[null]" category="SYSTEM" description="[null]" event_date="2008-12-02 13:58:00.00" CREATED_AT="[null]" data="[null]"/> + + <!-- project event --> + <events id="2" name="Version 1.0" resource_id="1" snapshot_id="[null]" category="VERSION" description="[null]" event_date="2008-12-02 13:58:00.00" CREATED_AT="[null]" data="[null]"/> + + <!-- orphan : the project does not exist--> + <events id="3" name="Version 0.9" resource_id="5" snapshot_id="[null]" category="VERSION" description="[null]" event_date="2008-12-02 13:58:00.00" CREATED_AT="[null]" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest/purgeOrphanResources-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest/purgeOrphanResources-result.xml new file mode 100644 index 00000000000..7b43ac967c3 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest/purgeOrphanResources-result.xml @@ -0,0 +1,23 @@ +<dataset> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="other-project" name="other-project" + root_id="[null]" profile_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- project1 has been removed from UI --> + <!--<projects long_name="[null]" id="2" scope="PRJ" qualifier="TRK" kee="project1" name="project1"--> + <!--root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="[null]"/>--> + + <!--<projects long_name="[null]" id="3" scope="PRJ" qualifier="BRC" kee="sub-project1" name="sub-project1"--> + <!--root_id="2"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="[null]"/>--> + + <!--<projects long_name="[null]" id="4" scope="DIR" qualifier="PAC" kee="package" name="package of sup-project1"--> + <!--root_id="2"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="[null]"/>--> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest/purgeOrphanResources.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest/purgeOrphanResources.xml new file mode 100644 index 00000000000..0be6420e8d1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeOrphanResourcesTest/purgeOrphanResources.xml @@ -0,0 +1,23 @@ +<dataset> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="other-project" name="other-project" + root_id="[null]" profile_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- project1 has been removed from UI --> + <!--<projects long_name="[null]" id="2" scope="PRJ" qualifier="TRK" kee="project1" name="project1"--> + <!--root_id="[null]"--> + <!--description="[null]"--> + <!--enabled="true" language="java" copy_resource_id="[null]"/>--> + + <projects long_name="[null]" id="3" scope="PRJ" qualifier="BRC" kee="sub-project1" name="sub-project1" + root_id="2" profile_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="4" scope="DIR" qualifier="PAC" kee="package" name="package of sup-project1" + root_id="2" profile_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeResourceOrphans-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeResourceOrphans-result.xml new file mode 100644 index 00000000000..e2cf33e7e40 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeResourceOrphans-result.xml @@ -0,0 +1,13 @@ +<dataset> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="other-project" name="other-project" + root_id="[null]" profile_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <properties id="1" prop_key="one" text_value="one" resource_id="[null]" user_id="[null]"/> + <properties id="2" prop_key="one" text_value="one" resource_id="1" user_id="[null]"/> + + <!-- resource 2 does not exist anymore --> + <!--<properties id="3" prop_key="one" text_value="one" resource_id="2" user_id="[null]"/>--> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeResourceOrphans.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeResourceOrphans.xml new file mode 100644 index 00000000000..35b75197444 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeResourceOrphans.xml @@ -0,0 +1,11 @@ +<dataset> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="other-project" name="other-project" + root_id="[null]" profile_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <properties id="1" prop_key="one" text_value="one" resource_id="[null]" user_id="[null]"/> + <properties id="2" prop_key="one" text_value="one" resource_id="1" user_id="[null]"/> + <properties id="3" prop_key="one" text_value="one" resource_id="2" user_id="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeUserOrphans-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeUserOrphans-result.xml new file mode 100644 index 00000000000..44ac13dd9d6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeUserOrphans-result.xml @@ -0,0 +1,10 @@ +<dataset> + <users id="1" login="me" name="Me" email="me@you.com" /> + + <properties id="1" prop_key="one" text_value="one" resource_id="[null]" user_id="[null]"/> + <properties id="2" prop_key="one" text_value="one" resource_id="[null]" user_id="1"/> + + <!-- user 2 has been deleted --> + <!--<properties id="3" prop_key="one" text_value="one" resource_id="[null]" user_id="2"/>--> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeUserOrphans.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeUserOrphans.xml new file mode 100644 index 00000000000..1b595f06123 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgePropertyOrphansTest/purgeUserOrphans.xml @@ -0,0 +1,8 @@ +<dataset> + <users id="1" login="me" name="Me" email="me@you.com" /> + + <properties id="1" prop_key="one" text_value="one" resource_id="[null]" user_id="[null]"/> + <properties id="2" prop_key="one" text_value="one" resource_id="[null]" user_id="1"/> + <properties id="3" prop_key="one" text_value="one" resource_id="[null]" user_id="2"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeResourceRolesTest/purgeResourceRoles-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeResourceRolesTest/purgeResourceRoles-result.xml new file mode 100644 index 00000000000..c4c0be5ed7a --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeResourceRolesTest/purgeResourceRoles-result.xml @@ -0,0 +1,27 @@ +<dataset> + + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]" /> + + <!-- existing project --> + <user_roles id="1" user_id="30" resource_id="1" role="admin" /> + <user_roles id="2" user_id="31" resource_id="1" role="user" /> + + <!-- deleted project --> + <!--<user_roles id="3" user_id="30" resource_id="90" role="admin" />--> + <!--<user_roles id="4" user_id="31" resource_id="90" role="user" />--> + + + <!-- existing project --> + <group_roles id="1" group_id="40" resource_id="1" role="admin" /> + <group_roles id="2" group_id="44" resource_id="1" role="user" /> + + <!-- deleted project --> + <!--<group_roles id="3" group_id="60" resource_id="90" role="admin" />--> + <!--<group_roles id="4" group_id="61" resource_id="90" role="user" />--> + + <!-- global roles --> + <group_roles id="5" group_id="60" resource_id="[null]" role="admin" /> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeResourceRolesTest/purgeResourceRoles.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeResourceRolesTest/purgeResourceRoles.xml new file mode 100644 index 00000000000..0678e9ec63b --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeResourceRolesTest/purgeResourceRoles.xml @@ -0,0 +1,27 @@ +<dataset> + + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <!-- existing project --> + <user_roles id="1" user_id="30" resource_id="1" role="admin" /> + <user_roles id="2" user_id="31" resource_id="1" role="user" /> + + <!-- deleted project --> + <user_roles id="3" user_id="30" resource_id="90" role="admin" /> + <user_roles id="4" user_id="31" resource_id="90" role="user" /> + + + <!-- existing project --> + <group_roles id="1" group_id="40" resource_id="1" role="admin" /> + <group_roles id="2" group_id="44" resource_id="1" role="user" /> + + <!-- deleted project --> + <group_roles id="3" group_id="60" resource_id="90" role="admin" /> + <group_roles id="4" group_id="61" resource_id="90" role="user" /> + + <!-- global roles --> + <group_roles id="5" group_id="60" resource_id="[null]" role="admin" /> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/purgeRuleMeasures-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/purgeRuleMeasures-result.xml new file mode 100644 index 00000000000..86dbc05aba1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/purgeRuleMeasures-result.xml @@ -0,0 +1,91 @@ +<dataset> + + <!-- old snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!-- last snapshots --> + + <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="5" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="4" root_project_id="[null]" root_snapshot_id="4" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="4" status="P" islast="true" + path="[null]"/> + + <!-- old measures --> + <project_measures characteristic_id="[null]" rule_priority="[null]" RULE_ID="[null]" RULES_CATEGORY_ID="[null]" + url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="4"--> + <!--alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]"--> + <!--RULE_ID="[null]"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + + <!-- last measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="4" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- old measure data --> + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <!--<measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/>--> + <!--<measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/>--> + + <!-- last measure data --> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + <measure_data id="5" measure_id="5" snapshot_id="5" data="[null]"/> + <measure_data id="6" measure_id="6" snapshot_id="6" data="[null]"/> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/purgeRuleMeasures.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/purgeRuleMeasures.xml new file mode 100644 index 00000000000..87f10a699e1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/purgeRuleMeasures.xml @@ -0,0 +1,92 @@ +<dataset> + + <!-- old snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!-- last snapshots --> + + <snapshots depth="[null]" id="4" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="5" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="4" root_project_id="[null]" root_snapshot_id="4" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="4" status="P" islast="true" + path="[null]"/> + + <!-- old measures --> + <project_measures characteristic_id="[null]" rule_priority="[null]" RULE_ID="[null]" RULES_CATEGORY_ID="[null]" + url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="4" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- last measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="4" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- old measure data --> + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + + <!-- last measure data --> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + <measure_data id="5" measure_id="5" snapshot_id="5" data="[null]"/> + <measure_data id="6" measure_id="6" snapshot_id="6" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/sharedFixture.xml new file mode 100644 index 00000000000..d4e59f25a41 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeRuleMeasuresTest/sharedFixture.xml @@ -0,0 +1,28 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- file --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/purgeUnprocessed-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/purgeUnprocessed-result.xml new file mode 100644 index 00000000000..a7a4c7d364d --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/purgeUnprocessed-result.xml @@ -0,0 +1,141 @@ +<dataset> + + <!-- valid snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <!-- unprocessed snapshots --> + + <!--<snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="1"--> + <!--parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false"--> + <!--path="[null]"/>--> + + <!--<snapshots depth="[null]" id="6" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="2"--> + <!--parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false"--> + <!--path="[null]"/>--> + + <!--<snapshots depth="[null]" id="7" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="3"--> + <!--parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false"--> + <!--path="[null]"/>--> + + <!--<snapshots depth="[null]" id="8" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]"--> + <!--project_id="4"--> + <!--parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false"--> + <!--path="[null]"/>--> + + + <!-- valid source --> + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/> + + <!-- unprocessed source --> + <!--<SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="7" DATA="foo"/>--> + + + <!-- valid violations --> + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + + <!-- unprocessed violations --> + <!--<RULE_FAILURES ID="5" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/>--> + <!--<RULE_FAILURES ID="6" SNAPSHOT_ID="6" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/>--> + <!--<RULE_FAILURES ID="7" SNAPSHOT_ID="7" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/>--> + <!--<RULE_FAILURES ID="8" SNAPSHOT_ID="8" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/>--> + + <!-- valid measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- unprocessed measures --> + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="7" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="7" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + <!--<project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"--> + <!--rule_priority="[null]"--> + <!--alert_text="[null]" ID="8" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="8" RULES_CATEGORY_ID="1"--> + <!--RULE_ID="1"--> + <!--text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"--> + <!--alert_status="[null]" description="[null]"/>--> + + + <!-- valid measure data --> + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + + <!-- unprocessed measure data --> + <!--<measure_data id="5" measure_id="5" snapshot_id="5" data="[null]"/>--> + <!--<measure_data id="6" measure_id="6" snapshot_id="6" data="[null]"/>--> + <!--<measure_data id="7" measure_id="7" snapshot_id="7" data="[null]"/>--> + <!--<measure_data id="8" measure_id="8" snapshot_id="8" data="[null]"/>--> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/purgeUnprocessed.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/purgeUnprocessed.xml new file mode 100644 index 00000000000..c99d66a31a0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/purgeUnprocessed.xml @@ -0,0 +1,141 @@ +<dataset> + + <!-- valid snapshots --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + + <!-- unprocessed snapshots --> + + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="FIL" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path="[null]"/> + + + <!-- valid source --> + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="3" DATA="foo"/> + + <!-- unprocessed source --> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="7" DATA="foo"/> + + + <!-- valid violations --> + <RULE_FAILURES ID="1" SNAPSHOT_ID="1" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="2" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="3" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + + <!-- unprocessed violations --> + <RULE_FAILURES ID="5" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1" LINE="[null]"/> + <RULE_FAILURES ID="6" SNAPSHOT_ID="6" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2" LINE="[null]"/> + <RULE_FAILURES ID="7" SNAPSHOT_ID="7" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3" LINE="[null]"/> + <RULE_FAILURES ID="8" SNAPSHOT_ID="8" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4" LINE="[null]"/> + + <!-- valid measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- unprocessed measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="6" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="7" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="7" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="8" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="8" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- valid measure data --> + <measure_data id="1" measure_id="1" snapshot_id="1" data="[null]"/> + <measure_data id="2" measure_id="2" snapshot_id="2" data="[null]"/> + <measure_data id="3" measure_id="3" snapshot_id="3" data="[null]"/> + <measure_data id="4" measure_id="4" snapshot_id="4" data="[null]"/> + + <!-- unprocessed measure data --> + <measure_data id="5" measure_id="5" snapshot_id="5" data="[null]"/> + <measure_data id="6" measure_id="6" snapshot_id="6" data="[null]"/> + <measure_data id="7" measure_id="7" snapshot_id="7" data="[null]"/> + <measure_data id="8" measure_id="8" snapshot_id="8" data="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/sharedFixture.xml new file mode 100644 index 00000000000..8d4d27778c7 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/PurgeUnprocessedTest/sharedFixture.xml @@ -0,0 +1,33 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- file --> + <projects long_name="[null]" id="3" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="class" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- project copy for views --> + <projects long_name="[null]" id="4" scope="FIL" qualifier="TRK" kee="cp-mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="1"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/sharedFixture.xml new file mode 100644 index 00000000000..ae4f6b24985 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/sharedFixture.xml @@ -0,0 +1,34 @@ +<!-- + ~ Sonar, open source software quality management tool. + ~ Copyright (C) 2009 SonarSource SA + ~ mailto:contact AT sonarsource DOT com + ~ + ~ Sonar is free software; you can redistribute it and/or + ~ modify it under the terms of the GNU Lesser General Public + ~ License as published by the Free Software Foundation; either + ~ version 3 of the License, or (at your option) any later version. + ~ + ~ Sonar is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ~ Lesser General Public License for more details. + ~ + ~ You should have received a copy of the GNU Lesser General Public + ~ License along with Sonar; if not, write to the Free Software + ~ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + --> +<dataset> + + <!-- project --> + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="project" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- package --> + <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="package" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/unflagLastDoublons-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/unflagLastDoublons-result.xml new file mode 100644 index 00000000000..e6a3e32080f --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/unflagLastDoublons-result.xml @@ -0,0 +1,68 @@ +<!-- + ~ Sonar, open source software quality management tool. + ~ Copyright (C) 2009 SonarSource SA + ~ mailto:contact AT sonarsource DOT com + ~ + ~ Sonar is free software; you can redistribute it and/or + ~ modify it under the terms of the GNU Lesser General Public + ~ License as published by the Free Software Foundation; either + ~ version 3 of the License, or (at your option) any later version. + ~ + ~ Sonar is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ~ Lesser General Public License for more details. + ~ + ~ You should have received a copy of the GNU Lesser General Public + ~ License along with Sonar; if not, write to the Free Software + ~ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + --> +<dataset> + + <!-- first analysis, not flagged as last --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!-- second analysis, flag islast => false --> + <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2009-02-14 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="DIR" qualifier="PAC" created_at="2009-02-14 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="3" status="P" islast="false" + path="[null]"/> + + <!-- third analysis, flag islast => false --> + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2009-04-01 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="DIR" qualifier="PAC" created_at="2009-04-01 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="P" islast="false" + path="[null]"/> + + + <!-- last analysis --> + <snapshots depth="[null]" id="7" scope="PRJ" qualifier="TRK" created_at="2009-05-18 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="DIR" qualifier="PAC" created_at="2009-05-18 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="7" root_project_id="[null]" root_snapshot_id="7" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/unflagLastDoublons.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/unflagLastDoublons.xml new file mode 100644 index 00000000000..e8a0a7f145d --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/purges/UnflagLastDoublonsTest/unflagLastDoublons.xml @@ -0,0 +1,68 @@ +<!-- + ~ Sonar, open source software quality management tool. + ~ Copyright (C) 2009 SonarSource SA + ~ mailto:contact AT sonarsource DOT com + ~ + ~ Sonar is free software; you can redistribute it and/or + ~ modify it under the terms of the GNU Lesser General Public + ~ License as published by the Free Software Foundation; either + ~ version 3 of the License, or (at your option) any later version. + ~ + ~ Sonar is distributed in the hope that it will be useful, + ~ but WITHOUT ANY WARRANTY; without even the implied warranty of + ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ~ Lesser General Public License for more details. + ~ + ~ You should have received a copy of the GNU Lesser General Public + ~ License along with Sonar; if not, write to the Free Software + ~ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + --> +<dataset> + + <!-- first analysis, not flagged as last --> + + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + + <!-- second analysis, crazy state : project not last, but package flagged as last --> + <snapshots depth="[null]" id="3" scope="PRJ" qualifier="TRK" created_at="2009-02-14 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="DIR" qualifier="PAC" created_at="2009-02-14 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="3" status="P" islast="true" + path="[null]"/> + + <!-- third analysis, flagged as last --> + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2009-04-01 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="DIR" qualifier="PAC" created_at="2009-04-01 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + + <!-- last analysis --> + <snapshots depth="[null]" id="7" scope="PRJ" qualifier="TRK" created_at="2009-05-18 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="DIR" qualifier="PAC" created_at="2009-05-18 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="7" root_project_id="[null]" root_snapshot_id="7" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource-result.xml new file mode 100644 index 00000000000..28a4c30bb5c --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource-result.xml @@ -0,0 +1,21 @@ +<dataset> + + <!-- GROUPS ***************** --> + <!-- global roles --> + <group_roles id="1" group_id="1" role="admin" resource_id="[null]" /> + <group_roles id="2" group_id="2" role="viewer" resource_id="[null]" /> + + <!-- default project roles --> + <group_roles id="3" group_id="[null]" role="default-admin" resource_id="[null]" /> + <group_roles id="4" group_id="[null]" role="default-viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <group_roles id="5" group_id="5" role="admin" resource_id="7" /> + + + + <!-- new project role : group 'Anyone' has admin and viewer --> + <group_roles id="6" group_id="[null]" role="admin" resource_id="10" /> + <group_roles id="7" group_id="[null]" role="viewer" resource_id="10" /> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource.xml new file mode 100644 index 00000000000..59af13b6b19 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectAnyoneDefaultRoleToResource.xml @@ -0,0 +1,16 @@ +<dataset> + + <!-- GROUPS ***************** --> + <!-- global roles --> + <group_roles id="1" group_id="1" role="admin" resource_id="[null]" /> + <group_roles id="2" group_id="2" role="viewer" resource_id="[null]" /> + + <!-- default project roles --> + <group_roles id="3" group_id="[null]" role="default-admin" resource_id="[null]" /> + <group_roles id="4" group_id="[null]" role="default-viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <group_roles id="5" group_id="5" role="admin" resource_id="7" /> + + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource-result.xml new file mode 100644 index 00000000000..ecb82d497a1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource-result.xml @@ -0,0 +1,39 @@ +<dataset> + + <!-- USERS ***************** --> + + <!-- global roles --> + <user_roles id="1" user_id="1" role="admin" resource_id="[null]" /> + <user_roles id="2" user_id="2" role="viewer" resource_id="[null]" /> + + <!-- default project roles --> + <user_roles id="3" user_id="1" role="default-admin" resource_id="[null]" /> + <user_roles id="4" user_id="1" role="default-viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <user_roles id="5" user_id="5" role="admin" resource_id="7" /> + + + <!-- new project role --> + <user_roles id="6" user_id="1" role="admin" resource_id="10" /> + <user_roles id="7" user_id="1" role="viewer" resource_id="10" /> + + + <!-- GROUPS ***************** --> + <!-- global roles --> + <group_roles id="1" group_id="1" role="admin" resource_id="[null]" /> + <group_roles id="2" group_id="2" role="viewer" resource_id="[null]" /> + + <!-- default project roles --> + <group_roles id="3" group_id="1" role="default-admin" resource_id="[null]" /> + <group_roles id="4" group_id="1" role="default-viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <group_roles id="5" group_id="5" role="admin" resource_id="7" /> + + <!-- new project roles --> + <group_roles id="6" group_id="1" role="admin" resource_id="10" /> + <group_roles id="7" group_id="1" role="viewer" resource_id="10" /> + + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource.xml new file mode 100644 index 00000000000..a6565eeea01 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectDefaultRolesToResource.xml @@ -0,0 +1,31 @@ +<dataset> + + <!-- USERS ***************** --> + + <!-- global roles --> + <user_roles id="1" user_id="1" role="admin" resource_id="[null]" /> + <user_roles id="2" user_id="2" role="viewer" resource_id="[null]" /> + + <!-- default project roles --> + <user_roles id="3" user_id="1" role="default-admin" resource_id="[null]" /> + <user_roles id="4" user_id="1" role="default-viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <user_roles id="5" user_id="5" role="admin" resource_id="7" /> + + + + <!-- GROUPS ***************** --> + <!-- global roles --> + <group_roles id="1" group_id="1" role="admin" resource_id="[null]" /> + <group_roles id="2" group_id="2" role="viewer" resource_id="[null]" /> + + <!-- default project roles --> + <group_roles id="3" group_id="1" role="default-admin" resource_id="[null]" /> + <group_roles id="4" group_id="1" role="default-viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <group_roles id="5" group_id="5" role="admin" resource_id="7" /> + + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource-result.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource-result.xml new file mode 100644 index 00000000000..30ce5f48597 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource-result.xml @@ -0,0 +1,27 @@ +<dataset> + + <!-- USERS ***************** --> + + <!-- global roles --> + <user_roles id="1" user_id="1" role="admin" resource_id="[null]" /> + <user_roles id="2" user_id="2" role="viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <user_roles id="5" user_id="5" role="admin" resource_id="7" /> + + <!-- no default project roles --> + + + + <!-- GROUPS ***************** --> + + <!-- global roles --> + <group_roles id="1" group_id="1" role="admin" resource_id="[null]" /> + <group_roles id="2" group_id="2" role="viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <group_roles id="5" group_id="5" role="admin" resource_id="7" /> + + <!-- no default project roles --> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource.xml new file mode 100644 index 00000000000..66f2aa19f2b --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/affectZeroDefaultRolesToResource.xml @@ -0,0 +1,27 @@ +<dataset> + + <!-- USERS ***************** --> + + <!-- global roles --> + <user_roles id="1" user_id="1" role="admin" resource_id="[null]" /> + <user_roles id="2" user_id="2" role="viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <user_roles id="5" user_id="5" role="admin" resource_id="7" /> + + <!-- no default project roles --> + + + + <!-- GROUPS ***************** --> + + <!-- global roles --> + <group_roles id="1" group_id="1" role="admin" resource_id="[null]" /> + <group_roles id="2" group_id="2" role="viewer" resource_id="[null]" /> + + <!-- existing project roles --> + <group_roles id="5" group_id="5" role="admin" resource_id="7" /> + + <!-- no default project roles --> + +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/sharedFixture.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/sharedFixture.xml new file mode 100644 index 00000000000..a9c48393d40 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/security/RoleManagerTest/sharedFixture.xml @@ -0,0 +1,7 @@ +<dataset> + <projects id="10" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" + long_name="[null]" /> +</dataset>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml new file mode 100644 index 00000000000..836bb4630e9 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar</artifactId> + <packaging>pom</packaging> + <version>1.8-SNAPSHOT</version> + +</project>
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml new file mode 100644 index 00000000000..a44ea429019 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar</artifactId> + <packaging>pom</packaging> + <version>1.8-SNAPSHOT</version> + <url>http://sonar.codehaus.org</url> + + <organization> + <name>SonarSource SA</name> + <url>http://www.sonarsource.com</url> + </organization> + <inceptionYear>2009</inceptionYear> + + <issueManagement> + <system>jira</system> + <url>http://jira.codehaus.org/browse/SONAR</url> + </issueManagement> + + <mailingLists> + <mailingList> + <name>Sonar users mailing list</name> + <subscribe>http://xircles.codehaus.org/projects/sonar/lists</subscribe> + <unsubscribe>http://xircles.codehaus.org/projects/sonar/lists</unsubscribe> + <post>user@sonar.codehaus.org</post> + <archive>http://www.nabble.com/Sonar-f30151.html</archive> + </mailingList> + </mailingLists> + + <scm> + <connection>scm:svn:http://svn.codehaus.org/sonar/trunk</connection> + <developerConnection>scm:svn:https://svn.codehaus.org/sonar/trunk</developerConnection> + <url>http://svn.sonar.codehaus.org</url> + </scm> + + <ciManagement> + <system>bamboo</system> + <url>http://bamboo.ci.codehaus.org/browse/SONAR/</url> + </ciManagement> + + <licenses> + <license> + <name>GNU Lesser General Public License (LGPL), v.3</name> + <url>http://www.gnu.org/licenses/lgpl.txt</url> + <distribution>repo</distribution> + </license> + </licenses> + +</project>
\ No newline at end of file |