]> source.dussan.org Git - sonarqube.git/commitdiff
Issue exclusions patterns are now initialized prior to sensor phase
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 18 Feb 2014 14:00:19 +0000 (15:00 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 18 Feb 2014 14:02:05 +0000 (15:02 +0100)
72 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/EnforceIssuesFilter.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesConfiguration.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/package-info.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/AbstractPatternInitializer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/ExclusionPatternInitializer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/InclusionPatternInitializer.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/LineRange.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternDecoder.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/package-info.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScanner.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScanner.java [deleted file]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/package-info.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/EnforceIssuesFilterTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/ExclusionPatternInitializerTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/InclusionPatternInitializerTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePatternTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/LineRangeTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternDecoderTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest.java [deleted file]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScannerTest.java [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-mess.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-twice.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-unfinished.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-wrong-order.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-no-regexp.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt [deleted file]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-single-regexp.txt [deleted file]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/EnforceIssuesFilter.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilter.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IssueExclusionsConfiguration.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/package-info.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssuePattern.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/LineRange.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/PatternDecoder.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/PatternMatcher.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/package-info.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScanner.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/package-info.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/EnforceIssuesFilterTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilterTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssuePatternTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/LineRangeTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternDecoderTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternMatcherTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-mess.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-twice.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-unfinished.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-wrong-order.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-no-regexp.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt [new file with mode: 0644]

index 57f1b91037b063c9629bf5ff18cad00955a7f84a..0d2bd21ac5efcc08c6c48af545c20f420f0493db 100644 (file)
  */
 package org.sonar.plugins.core;
 
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+
 import com.google.common.collect.ImmutableList;
-import org.sonar.api.*;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
+import org.sonar.api.PropertyType;
+import org.sonar.api.SonarPlugin;
 import org.sonar.api.checks.NoSonarFilter;
 import org.sonar.api.config.PropertyDefinition;
 import org.sonar.api.resources.Qualifiers;
@@ -33,22 +39,92 @@ 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.colorizers.JavaColorizerFormat;
-import org.sonar.plugins.core.dashboards.*;
-import org.sonar.plugins.core.issue.*;
-import org.sonar.plugins.core.issue.ignore.IgnoreIssuesPlugin;
-import org.sonar.plugins.core.issue.notification.*;
+import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard;
+import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard;
+import org.sonar.plugins.core.dashboards.ProjectHotspotDashboard;
+import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard;
+import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard;
+import org.sonar.plugins.core.issue.CountFalsePositivesDecorator;
+import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator;
+import org.sonar.plugins.core.issue.InitialOpenIssuesSensor;
+import org.sonar.plugins.core.issue.InitialOpenIssuesStack;
+import org.sonar.plugins.core.issue.IssueHandlers;
+import org.sonar.plugins.core.issue.IssueTracking;
+import org.sonar.plugins.core.issue.IssueTrackingDecorator;
+import org.sonar.plugins.core.issue.IssuesDensityDecorator;
+import org.sonar.plugins.core.issue.WeightedIssuesDecorator;
+import org.sonar.plugins.core.issue.notification.ChangesOnMyIssueNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.IssueChangesEmailTemplate;
+import org.sonar.plugins.core.issue.notification.NewFalsePositiveNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.NewIssuesEmailTemplate;
+import org.sonar.plugins.core.issue.notification.NewIssuesNotificationDispatcher;
+import org.sonar.plugins.core.issue.notification.SendIssueNotificationsPostJob;
 import org.sonar.plugins.core.measurefilters.MyFavouritesFilter;
 import org.sonar.plugins.core.measurefilters.ProjectFilter;
 import org.sonar.plugins.core.notifications.alerts.NewAlerts;
 import org.sonar.plugins.core.security.ApplyProjectRolesDecorator;
-import org.sonar.plugins.core.sensors.*;
+import org.sonar.plugins.core.sensors.BranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.CheckAlertThresholds;
+import org.sonar.plugins.core.sensors.CommentDensityDecorator;
+import org.sonar.plugins.core.sensors.CoverageDecorator;
+import org.sonar.plugins.core.sensors.CoverageMeasurementFilter;
+import org.sonar.plugins.core.sensors.DirectoriesDecorator;
+import org.sonar.plugins.core.sensors.FileHashSensor;
+import org.sonar.plugins.core.sensors.FilesDecorator;
+import org.sonar.plugins.core.sensors.GenerateAlertEvents;
+import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.ItCoverageDecorator;
+import org.sonar.plugins.core.sensors.ItLineCoverageDecorator;
+import org.sonar.plugins.core.sensors.LineCoverageDecorator;
+import org.sonar.plugins.core.sensors.ManualMeasureDecorator;
+import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator;
+import org.sonar.plugins.core.sensors.OverallCoverageDecorator;
+import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator;
+import org.sonar.plugins.core.sensors.ProfileEventsSensor;
+import org.sonar.plugins.core.sensors.ProjectLinksSensor;
+import org.sonar.plugins.core.sensors.UnitTestDecorator;
+import org.sonar.plugins.core.sensors.VersionEventsSensor;
 import org.sonar.plugins.core.technicaldebt.NewTechnicalDebtDecorator;
 import org.sonar.plugins.core.technicaldebt.TechnicalDebtDecorator;
-import org.sonar.plugins.core.timemachine.*;
+import org.sonar.plugins.core.timemachine.NewCoverageAggregator;
+import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer;
+import org.sonar.plugins.core.timemachine.TendencyDecorator;
+import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister;
+import org.sonar.plugins.core.timemachine.VariationDecorator;
 import org.sonar.plugins.core.web.TestsViewer;
-import org.sonar.plugins.core.widgets.*;
-import org.sonar.plugins.core.widgets.issues.*;
-import org.sonar.plugins.core.widgets.measures.*;
+import org.sonar.plugins.core.widgets.AlertsWidget;
+import org.sonar.plugins.core.widgets.BubbleChartWidget;
+import org.sonar.plugins.core.widgets.ComplexityWidget;
+import org.sonar.plugins.core.widgets.CoverageWidget;
+import org.sonar.plugins.core.widgets.CustomMeasuresWidget;
+import org.sonar.plugins.core.widgets.DescriptionWidget;
+import org.sonar.plugins.core.widgets.DocumentationCommentsWidget;
+import org.sonar.plugins.core.widgets.DuplicationsWidget;
+import org.sonar.plugins.core.widgets.EventsWidget;
+import org.sonar.plugins.core.widgets.HotspotMetricWidget;
+import org.sonar.plugins.core.widgets.HotspotMostViolatedResourcesWidget;
+import org.sonar.plugins.core.widgets.HotspotMostViolatedRulesWidget;
+import org.sonar.plugins.core.widgets.ItCoverageWidget;
+import org.sonar.plugins.core.widgets.SizeWidget;
+import org.sonar.plugins.core.widgets.TechnicalDebtPyramidWidget;
+import org.sonar.plugins.core.widgets.TimeMachineWidget;
+import org.sonar.plugins.core.widgets.TimelineWidget;
+import org.sonar.plugins.core.widgets.TreemapWidget;
+import org.sonar.plugins.core.widgets.WelcomeWidget;
+import org.sonar.plugins.core.widgets.issues.ActionPlansWidget;
+import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget;
+import org.sonar.plugins.core.widgets.issues.IssueFilterWidget;
+import org.sonar.plugins.core.widgets.issues.IssuesWidget;
+import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget;
+import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget;
+import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesStatusesWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsBubbleChartWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsHistogramWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterAsPieChartWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterListWidget;
+import org.sonar.plugins.core.widgets.measures.MeasureFilterTreemapWidget;
 
 import java.util.Arrays;
 import java.util.List;
@@ -194,7 +270,8 @@ import java.util.List;
   @Property(
     key = CoreProperties.CORE_AUTHENTICATOR_LOCAL_USERS,
     name = "Local/technical users",
-    description = "Comma separated list of user logins that will always be authenticated using SonarQube database. When using the LDAP plugin, for these accounts, the user attributes (name, email, ...) are not re-synchronized",
+    description = "Comma separated list of user logins that will always be authenticated using SonarQube database. "
+      + "When using the LDAP plugin, for these accounts, the user attributes (name, email, ...) are not re-synchronized",
     project = false,
     global = false,
     defaultValue = "admin",
@@ -336,7 +413,7 @@ public final class CorePlugin extends SonarPlugin {
       NewAlerts.newMetadata());
 
     extensions.addAll(ExclusionProperties.definitions());
-    extensions.addAll(IgnoreIssuesPlugin.getExtensions());
+    extensions.addAll(IssueExclusionsConfiguration.getPropertyDefinitions());
     extensions.addAll(CoverageMeasurementFilter.getPropertyDefinitions());
     extensions.addAll(PastSnapshotFinder.getPropertyDefinitions());
     extensions.addAll(TechnicalDebtDecorator.definitions());
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/EnforceIssuesFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/EnforceIssuesFilter.java
deleted file mode 100644 (file)
index cd44317..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.plugins.core.issue.ignore;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.batch.IssueFilter;
-import org.sonar.api.issue.batch.IssueFilterChain;
-import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-
-public class EnforceIssuesFilter implements IssueFilter {
-
-  private InclusionPatternInitializer patternInitializer;
-
-  private static final Logger LOG = LoggerFactory.getLogger(EnforceIssuesFilter.class);
-
-  public EnforceIssuesFilter(InclusionPatternInitializer patternInitializer) {
-    this.patternInitializer = patternInitializer;
-  }
-
-  @Override
-  public boolean accept(Issue issue, IssueFilterChain chain) {
-    boolean atLeastOneRuleMatched = false;
-    boolean atLeastOnePatternFullyMatched = false;
-    IssuePattern matchingPattern = null;
-
-    for (IssuePattern pattern : patternInitializer.getMulticriteriaPatterns()) {
-      if (pattern.getRulePattern().match(issue.ruleKey().toString())) {
-        atLeastOneRuleMatched = true;
-        String pathForComponent = patternInitializer.getPathForComponent(issue.componentKey());
-        if (pathForComponent != null && pattern.getResourcePattern().match(pathForComponent)) {
-          atLeastOnePatternFullyMatched = true;
-          matchingPattern = pattern;
-        }
-      }
-    }
-
-    if (atLeastOneRuleMatched) {
-      if (atLeastOnePatternFullyMatched) {
-        LOG.debug("Issue {} enforced by pattern {}", issue, matchingPattern);
-      }
-      return atLeastOnePatternFullyMatched;
-    } else {
-      return chain.accept(issue);
-    }
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesConfiguration.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesConfiguration.java
deleted file mode 100644 (file)
index 2f85575..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.PropertyType;
-import org.sonar.api.config.PropertyDefinition;
-import org.sonar.api.config.PropertyFieldDefinition;
-import org.sonar.api.resources.Qualifiers;
-
-import java.util.List;
-
-public final class IgnoreIssuesConfiguration {
-
-  public static final String SUB_CATEGORY_IGNORE_ISSUES = "issues";
-
-  public static final String EXCLUSION_KEY_PREFIX = "sonar.issue.ignore";
-  public static final String INCLUSION_KEY_PREFIX = "sonar.issue.enforce";
-
-  public static final String MULTICRITERIA_SUFFIX = ".multicriteria";
-  public static final String PATTERNS_MULTICRITERIA_EXCLUSION_KEY = EXCLUSION_KEY_PREFIX + MULTICRITERIA_SUFFIX;
-  public static final String PATTERNS_MULTICRITERIA_INCLUSION_KEY = INCLUSION_KEY_PREFIX + MULTICRITERIA_SUFFIX;
-  public static final String RESOURCE_KEY = "resourceKey";
-  private static final String PROPERTY_FILE_PATH_PATTERN = "File Path Pattern";
-  public static final String RULE_KEY = "ruleKey";
-  private static final String PROPERTY_RULE_KEY_PATTERN = "Rule Key Pattern";
-
-  public static final String BLOCK_SUFFIX = ".block";
-  public static final String PATTERNS_BLOCK_KEY = EXCLUSION_KEY_PREFIX + BLOCK_SUFFIX;
-  public static final String BEGIN_BLOCK_REGEXP = "beginBlockRegexp";
-  public static final String END_BLOCK_REGEXP = "endBlockRegexp";
-
-  public static final String ALLFILE_SUFFIX = ".allfile";
-  public static final String PATTERNS_ALLFILE_KEY = EXCLUSION_KEY_PREFIX + ALLFILE_SUFFIX;
-  public static final String FILE_REGEXP = "fileRegexp";
-
-  static final int LARGE_SIZE = 40;
-  static final int SMALL_SIZE = 10;
-
-  private IgnoreIssuesConfiguration() {
-    // static configuration declaration only
-  }
-
-  public static List<PropertyDefinition> getPropertyDefinitions() {
-    return ImmutableList.of(
-      PropertyDefinition.builder(PATTERNS_MULTICRITERIA_EXCLUSION_KEY)
-        .category(CoreProperties.CATEGORY_EXCLUSIONS)
-        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
-        .name("Ignore Issues on Multiple Criteria")
-        .description("Patterns to ignore issues on certain components and for certain coding rules.")
-        .onQualifiers(Qualifiers.PROJECT)
-        .index(3)
-        .fields(
-          PropertyFieldDefinition.build(RULE_KEY)
-            .name(PROPERTY_RULE_KEY_PATTERN)
-            .description("Pattern to match rules which should be ignored.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build(),
-          PropertyFieldDefinition.build(RESOURCE_KEY)
-            .name(PROPERTY_FILE_PATH_PATTERN)
-            .description("Pattern to match files which should be ignored.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build())
-        .build(),
-      PropertyDefinition.builder(PATTERNS_BLOCK_KEY)
-        .category(CoreProperties.CATEGORY_EXCLUSIONS)
-        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
-        .name("Ignore Issues in Blocks")
-        .description("Patterns to ignore all issues on specific blocks of code, while continuing to scan and mark issues on the remainder of the file.")
-        .onQualifiers(Qualifiers.PROJECT)
-        .index(2)
-        .fields(
-          PropertyFieldDefinition.build(BEGIN_BLOCK_REGEXP)
-            .name("Regular Expression for Start of Block")
-            .description("If this regular expression is found in a file, then following lines are ignored until end of block.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build(),
-          PropertyFieldDefinition.build(END_BLOCK_REGEXP)
-            .name("Regular Expression for End of Block")
-            .description("If specified, this regular expression is used to determine the end of code blocks to ignore. If not, then block ends at the end of file.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build())
-        .build(),
-      PropertyDefinition.builder(PATTERNS_ALLFILE_KEY)
-        .category(CoreProperties.CATEGORY_EXCLUSIONS)
-        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
-        .name("Ignore Issues on Files")
-        .description("Patterns to ignore all issues on files that contain a block of code matching a given regular expression.")
-        .onQualifiers(Qualifiers.PROJECT)
-        .index(1)
-        .fields(
-          PropertyFieldDefinition.build(FILE_REGEXP)
-            .name("Regular Expression")
-            .description("If this regular expression is found in a file, then the whole file is ignored.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build())
-        .build(),
-      PropertyDefinition.builder(PATTERNS_MULTICRITERIA_INCLUSION_KEY)
-        .category(CoreProperties.CATEGORY_EXCLUSIONS)
-        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
-        .name("Restrict Scope of Coding Rules")
-        .description("Patterns to restrict the application of a rule to only certain components, ignoring all others.")
-        .onQualifiers(Qualifiers.PROJECT)
-        .index(4)
-        .fields(
-          PropertyFieldDefinition.build(RULE_KEY)
-            .name(PROPERTY_RULE_KEY_PATTERN)
-            .description("Pattern used to match rules which should be restricted.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build(),
-          PropertyFieldDefinition.build(RESOURCE_KEY)
-            .name(PROPERTY_FILE_PATH_PATTERN)
-            .description("Pattern used to match files to which the rules should be restricted.")
-            .type(PropertyType.STRING)
-            .indicativeSize(LARGE_SIZE)
-            .build())
-        .build());
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java
deleted file mode 100644 (file)
index d49369d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.plugins.core.issue.ignore;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.batch.IssueFilter;
-import org.sonar.api.issue.batch.IssueFilterChain;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
-
-public class IgnoreIssuesFilter implements IssueFilter {
-
-  private PatternMatcher patternMatcher;
-
-  private static final Logger LOG = LoggerFactory.getLogger(IgnoreIssuesFilter.class);
-
-  public IgnoreIssuesFilter(ExclusionPatternInitializer patternInitializer) {
-    this.patternMatcher = patternInitializer.getPatternMatcher();
-  }
-
-  @Override
-  public boolean accept(Issue issue, IssueFilterChain chain) {
-    if (hasMatchFor(issue)) {
-      return false;
-    } else {
-      return chain.accept(issue);
-    }
-  }
-
-  private boolean hasMatchFor(Issue issue) {
-    IssuePattern pattern = patternMatcher.getMatchingPattern(issue);
-    if (pattern != null) {
-      logExclusion(issue, pattern);
-      return true;
-    }
-    return false;
-  }
-
-  private void logExclusion(Issue issue, IssuePattern pattern) {
-    LOG.debug("Issue {} ignored by exclusion pattern {}", issue, pattern);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java
deleted file mode 100644 (file)
index c39060a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.scanner.IgnoreIssuesRegexpScanner;
-import org.sonar.plugins.core.issue.ignore.scanner.IgnoreIssuesSourceScanner;
-
-import java.util.List;
-
-public final class IgnoreIssuesPlugin {
-
-  private IgnoreIssuesPlugin() {
-    // static extension declaration only
-  }
-
-  public static List getExtensions() {
-    ImmutableList.Builder<Object> extensions = ImmutableList.builder();
-
-    extensions.addAll(IgnoreIssuesConfiguration.getPropertyDefinitions());
-    extensions.add(
-        InclusionPatternInitializer.class,
-        ExclusionPatternInitializer.class,
-        IgnoreIssuesRegexpScanner.class,
-        IgnoreIssuesSourceScanner.class,
-        EnforceIssuesFilter.class,
-        IgnoreIssuesFilter.class);
-
-    return extensions.build();
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/package-info.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/package-info.java
deleted file mode 100644 (file)
index bdadd24..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.core.issue.ignore;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/AbstractPatternInitializer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/AbstractPatternInitializer.java
deleted file mode 100644 (file)
index f8d2318..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.config.Settings;
-import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
-
-import java.util.List;
-
-import static com.google.common.base.Objects.firstNonNull;
-
-public abstract class AbstractPatternInitializer implements BatchExtension {
-
-  private Settings settings;
-
-  private List<IssuePattern> multicriteriaPatterns;
-
-  protected AbstractPatternInitializer(Settings settings) {
-    this.settings = settings;
-    initPatterns();
-  }
-
-  protected Settings getSettings() {
-    return settings;
-  }
-
-  public List<IssuePattern> getMulticriteriaPatterns() {
-    return multicriteriaPatterns;
-  }
-
-  public boolean hasConfiguredPatterns() {
-    return hasMulticriteriaPatterns();
-  }
-
-  public boolean hasMulticriteriaPatterns() {
-    return ! multicriteriaPatterns.isEmpty();
-  }
-
-  public abstract void initializePatternsForPath(String relativePath, String componentKey);
-
-  @VisibleForTesting
-  protected final void initPatterns() {
-    // Patterns Multicriteria
-    multicriteriaPatterns = Lists.newArrayList();
-    String patternConf = StringUtils.defaultIfBlank(settings.getString(getMulticriteriaConfigurationKey()), "");
-    for (String id : StringUtils.split(patternConf, ',')) {
-      String propPrefix = getMulticriteriaConfigurationKey() + "." + id + ".";
-      String resourceKeyPattern = settings.getString(propPrefix + IgnoreIssuesConfiguration.RESOURCE_KEY);
-      String ruleKeyPattern = settings.getString(propPrefix + IgnoreIssuesConfiguration.RULE_KEY);
-      String lineRange = "*";
-      String[] fields = new String[] { resourceKeyPattern, ruleKeyPattern, lineRange };
-      PatternDecoder.checkRegularLineConstraints(StringUtils.join(fields, ","), fields);
-      IssuePattern pattern = new IssuePattern(firstNonNull(resourceKeyPattern, "*"), firstNonNull(ruleKeyPattern, "*"));
-      PatternDecoder.decodeRangeOfLines(pattern, firstNonNull(lineRange, "*"));
-      multicriteriaPatterns.add(pattern);
-    }
-  }
-
-  protected abstract String getMulticriteriaConfigurationKey();
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/ExclusionPatternInitializer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/ExclusionPatternInitializer.java
deleted file mode 100644 (file)
index a20e8c3..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.config.Settings;
-import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
-
-import java.util.List;
-
-import static com.google.common.base.Strings.nullToEmpty;
-
-public class ExclusionPatternInitializer extends AbstractPatternInitializer {
-
-  private List<IssuePattern> blockPatterns;
-  private List<IssuePattern> allFilePatterns;
-  private PatternMatcher patternMatcher;
-
-  public ExclusionPatternInitializer(Settings settings) {
-    super(settings);
-    patternMatcher = new PatternMatcher();
-    loadFileContentPatterns();
-  }
-
-  @Override
-  protected String getMulticriteriaConfigurationKey() {
-    return IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY;
-  }
-
-  public PatternMatcher getPatternMatcher() {
-    return patternMatcher;
-  }
-
-  @Override
-  public void initializePatternsForPath(String relativePath, String componentKey) {
-    for (IssuePattern pattern: getMulticriteriaPatterns()) {
-      if (pattern.matchResource(relativePath)) {
-        getPatternMatcher().addPatternForComponent(componentKey, pattern);
-      }
-    }
-  }
-
-  @Override
-  public boolean hasConfiguredPatterns() {
-    return hasFileContentPattern() || hasMulticriteriaPatterns();
-  }
-
-  @VisibleForTesting
-  protected final void loadFileContentPatterns() {
-    // Patterns Block
-    blockPatterns = Lists.newArrayList();
-    String patternConf = StringUtils.defaultIfBlank(getSettings().getString(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY), "");
-    for (String id : StringUtils.split(patternConf, ',')) {
-      String propPrefix = IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + "." + id + ".";
-      String beginBlockRegexp = getSettings().getString(propPrefix + IgnoreIssuesConfiguration.BEGIN_BLOCK_REGEXP);
-      String endBlockRegexp = getSettings().getString(propPrefix + IgnoreIssuesConfiguration.END_BLOCK_REGEXP);
-      String[] fields = new String[] { beginBlockRegexp, endBlockRegexp };
-      PatternDecoder.checkDoubleRegexpLineConstraints(StringUtils.join(fields, ","), fields);
-      IssuePattern pattern = new IssuePattern().setBeginBlockRegexp(nullToEmpty(beginBlockRegexp)).setEndBlockRegexp(nullToEmpty(endBlockRegexp));
-      blockPatterns.add(pattern);
-    }
-
-    // Patterns All File
-    allFilePatterns = Lists.newArrayList();
-    patternConf = StringUtils.defaultIfBlank(getSettings().getString(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY), "");
-    for (String id : StringUtils.split(patternConf, ',')) {
-      String propPrefix = IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY + "." + id + ".";
-      String allFileRegexp = getSettings().getString(propPrefix + IgnoreIssuesConfiguration.FILE_REGEXP);
-      PatternDecoder.checkWholeFileRegexp(allFileRegexp);
-      IssuePattern pattern = new IssuePattern().setAllFileRegexp(nullToEmpty(allFileRegexp));
-      allFilePatterns.add(pattern);
-    }
-  }
-
-  public List<IssuePattern> getBlockPatterns() {
-    return blockPatterns;
-  }
-
-  public List<IssuePattern> getAllFilePatterns() {
-    return allFilePatterns;
-  }
-
-  public boolean hasFileContentPattern() {
-    return ! (blockPatterns.isEmpty() && allFilePatterns.isEmpty());
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/InclusionPatternInitializer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/InclusionPatternInitializer.java
deleted file mode 100644 (file)
index 57dd008..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.collect.Maps;
-import org.sonar.api.config.Settings;
-import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
-
-import java.util.Map;
-
-public class InclusionPatternInitializer extends AbstractPatternInitializer {
-
-  private Map<String, String> pathForComponent;
-
-  public InclusionPatternInitializer(Settings settings) {
-    super(settings);
-    pathForComponent = Maps.newHashMap();
-  }
-
-  @Override
-  protected String getMulticriteriaConfigurationKey() {
-    return IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY;
-  }
-
-  @Override
-  public void initializePatternsForPath(String relativePath, String componentKey) {
-    pathForComponent.put(componentKey, relativePath);
-  }
-
-  public String getPathForComponent(String componentKey) {
-    return pathForComponent.get(componentKey);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java
deleted file mode 100644 (file)
index 458292a..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.collect.Sets;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.WildcardPattern;
-
-import java.util.Set;
-
-public class IssuePattern {
-
-  private WildcardPattern resourcePattern;
-  private WildcardPattern rulePattern;
-  private Set<Integer> lines = Sets.newLinkedHashSet();
-  private Set<LineRange> lineRanges = Sets.newLinkedHashSet();
-  private String beginBlockRegexp;
-  private String endBlockRegexp;
-  private String allFileRegexp;
-  private boolean checkLines = true;
-
-  public IssuePattern() {
-  }
-
-  public IssuePattern(String resourcePattern, String rulePattern) {
-    this.resourcePattern = WildcardPattern.create(resourcePattern);
-    this.rulePattern = WildcardPattern.create(rulePattern);
-  }
-
-  public IssuePattern(String resourcePattern, String rulePattern, Set<LineRange> lineRanges) {
-    this(resourcePattern, rulePattern);
-    this.lineRanges = lineRanges;
-  }
-
-  public WildcardPattern getResourcePattern() {
-    return resourcePattern;
-  }
-
-  public WildcardPattern getRulePattern() {
-    return rulePattern;
-  }
-
-  public String getBeginBlockRegexp() {
-    return beginBlockRegexp;
-  }
-
-  public String getEndBlockRegexp() {
-    return endBlockRegexp;
-  }
-
-  public String getAllFileRegexp() {
-    return allFileRegexp;
-  }
-
-  IssuePattern addLineRange(int fromLineId, int toLineId) {
-    lineRanges.add(new LineRange(fromLineId, toLineId));
-    return this;
-  }
-
-  IssuePattern addLine(int lineId) {
-    lines.add(lineId);
-    return this;
-  }
-
-  boolean isCheckLines() {
-    return checkLines;
-  }
-
-  IssuePattern setCheckLines(boolean b) {
-    this.checkLines = b;
-    return this;
-  }
-
-  IssuePattern setBeginBlockRegexp(String beginBlockRegexp) {
-    this.beginBlockRegexp = beginBlockRegexp;
-    return this;
-  }
-
-  IssuePattern setEndBlockRegexp(String endBlockRegexp) {
-    this.endBlockRegexp = endBlockRegexp;
-    return this;
-  }
-
-  IssuePattern setAllFileRegexp(String allFileRegexp) {
-    this.allFileRegexp = allFileRegexp;
-    return this;
-  }
-
-  Set<Integer> getAllLines() {
-    Set<Integer> allLines = Sets.newLinkedHashSet(lines);
-    for (LineRange lineRange : lineRanges) {
-      allLines.addAll(lineRange.toLines());
-    }
-    return allLines;
-  }
-
-  public boolean match(Issue issue) {
-    boolean match = matchResource(issue.componentKey())
-      && matchRule(issue.ruleKey());
-    if (checkLines) {
-      Integer line = issue.line();
-      if (line == null) {
-        match = false;
-      } else {
-        match = match && matchLine(line);
-      }
-    }
-    return match;
-  }
-
-  boolean matchLine(int lineId) {
-    if (lines.contains(lineId)) {
-      return true;
-    }
-
-    for (LineRange range : lineRanges) {
-      if (range.in(lineId)) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  boolean matchRule(RuleKey rule) {
-    if (rule == null) {
-      return false;
-    }
-
-    String key = new StringBuilder().append(rule.repository()).append(':').append(rule.rule()).toString();
-    return rulePattern.match(key);
-  }
-
-  boolean matchResource(String resource) {
-    return resource != null && resourcePattern.match(resource);
-  }
-
-  public IssuePattern forResource(String resource) {
-    return new IssuePattern(resource, rulePattern.toString(), lineRanges).setCheckLines(isCheckLines());
-  }
-
-  @Override
-  public String toString() {
-    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/LineRange.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/LineRange.java
deleted file mode 100644 (file)
index 743533d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-public class LineRange {
-  private int from;
-  private int to;
-
-  public LineRange(int from, int to) {
-    Preconditions.checkArgument(from <= to, "Line range is not valid: %s must be greater than %s", from, to);
-
-    this.from = from;
-    this.to = to;
-  }
-
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-  @Override
-  public String toString() {
-    return "[" + from + "-" + to + "]";
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + from;
-    result = prime * result + to;
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
-    }
-    if (fieldsDiffer((LineRange) obj)) {
-      return false;
-    }
-    return true;
-  }
-
-  private boolean fieldsDiffer(LineRange other) {
-    if (from != other.from) {
-      return true;
-    }
-    if (to != other.to) {
-      return true;
-    }
-    return false;
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternDecoder.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternDecoder.java
deleted file mode 100644 (file)
index 7912ed1..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.utils.SonarException;
-
-import java.util.List;
-
-public class PatternDecoder {
-
-  private static final int THREE_FIELDS_PER_LINE = 3;
-  private static final String LINE_RANGE_REGEXP = "\\[((\\d+|\\d+-\\d+),?)*\\]";
-  private static final String CONFIG_FORMAT_ERROR_PREFIX = "Exclusions > Issues : Invalid format. ";
-
-  public List<IssuePattern> decode(String patternsList) {
-    List<IssuePattern> patterns = Lists.newLinkedList();
-    String[] patternsLines = StringUtils.split(patternsList, "\n");
-    for (String patternLine : patternsLines) {
-      IssuePattern pattern = decodeLine(patternLine.trim());
-      if (pattern != null) {
-        patterns.add(pattern);
-      }
-    }
-    return patterns;
-  }
-
-  /**
-   * Main method that decodes a line which defines a pattern
-   */
-  public IssuePattern decodeLine(String line) {
-    if (isBlankOrComment(line)) {
-      return null;
-    }
-
-    String[] fields = StringUtils.splitPreserveAllTokens(line, ';');
-    if (fields.length > THREE_FIELDS_PER_LINE) {
-      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The following line has more than 3 fields separated by comma: " + line);
-    }
-
-    IssuePattern pattern;
-    if (fields.length == THREE_FIELDS_PER_LINE) {
-      checkRegularLineConstraints(line, fields);
-      pattern = new IssuePattern(StringUtils.trim(fields[0]), StringUtils.trim(fields[1]));
-      decodeRangeOfLines(pattern, fields[2]);
-    } else if (fields.length == 2) {
-      checkDoubleRegexpLineConstraints(line, fields);
-      pattern = new IssuePattern().setBeginBlockRegexp(fields[0]).setEndBlockRegexp(fields[1]);
-    } else {
-      checkWholeFileRegexp(fields[0]);
-      pattern = new IssuePattern().setAllFileRegexp(fields[0]);
-    }
-
-    return pattern;
-  }
-
-  static void checkRegularLineConstraints(String line, String[] fields) {
-    if (!isResource(fields[0])) {
-      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a resource pattern: " + line);
-    }
-    if (!isRule(fields[1])) {
-      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The second field does not define a rule pattern: " + line);
-    }
-    if (!isLinesRange(fields[2])) {
-      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The third field does not define a range of lines: " + line);
-    }
-  }
-
-  static void checkDoubleRegexpLineConstraints(String line, String[] fields) {
-    if (!isRegexp(fields[0])) {
-      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a regular expression: " + line);
-    }
-    // As per configuration help, missing second field means: from start regexp to EOF
-  }
-
-  static void checkWholeFileRegexp(String regexp) {
-    if (!isRegexp(regexp)) {
-      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The field does not define a regular expression: " + regexp);
-    }
-  }
-
-  public static void decodeRangeOfLines(IssuePattern pattern, String field) {
-    if (StringUtils.equals(field, "*")) {
-      pattern.setCheckLines(false);
-    } else {
-      pattern.setCheckLines(true);
-      String s = StringUtils.substringBetween(StringUtils.trim(field), "[", "]");
-      String[] parts = StringUtils.split(s, ',');
-      for (String part : parts) {
-        if (StringUtils.contains(part, '-')) {
-          String[] range = StringUtils.split(part, '-');
-          pattern.addLineRange(Integer.valueOf(range[0]), Integer.valueOf(range[1]));
-        } else {
-          pattern.addLine(Integer.valueOf(part));
-        }
-      }
-    }
-  }
-
-  @VisibleForTesting
-  static boolean isLinesRange(String field) {
-    return StringUtils.equals(field, "*") || java.util.regex.Pattern.matches(LINE_RANGE_REGEXP, field);
-  }
-
-  @VisibleForTesting
-  static boolean isBlankOrComment(String line) {
-    return StringUtils.isBlank(line) ^ StringUtils.startsWith(line, "#");
-  }
-
-  @VisibleForTesting
-  static boolean isResource(String field) {
-    return StringUtils.isNotBlank(field);
-  }
-
-  @VisibleForTesting
-  static boolean isRule(String field) {
-    return StringUtils.isNotBlank(field);
-  }
-
-  @VisibleForTesting
-  static boolean isRegexp(String field) {
-    return StringUtils.isNotBlank(field);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java
deleted file mode 100644 (file)
index a01be7b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Multimap;
-import org.sonar.api.issue.Issue;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-
-public class PatternMatcher {
-
-  private Multimap<String, IssuePattern> patternByComponent = LinkedHashMultimap.create();
-
-  public IssuePattern getMatchingPattern(Issue issue) {
-    IssuePattern matchingPattern = null;
-    Iterator<IssuePattern> patternIterator = getPatternsForComponent(issue.componentKey()).iterator();
-    while(matchingPattern == null && patternIterator.hasNext()) {
-      IssuePattern nextPattern = patternIterator.next();
-      if (nextPattern.match(issue)) {
-        matchingPattern = nextPattern;
-      }
-    }
-    return matchingPattern;
-  }
-
-  public Collection<IssuePattern> getPatternsForComponent(String componentKey) {
-    return patternByComponent.get(componentKey);
-  }
-
-  public void addPatternForComponent(String component, IssuePattern pattern) {
-    patternByComponent.put(component, pattern.forResource(component));
-  }
-
-  public void addPatternToExcludeResource(String resource) {
-    addPatternForComponent(resource, new IssuePattern(resource, "*").setCheckLines(false));
-  }
-
-  public void addPatternToExcludeLines(String resource, Set<LineRange> lineRanges) {
-    addPatternForComponent(resource, new IssuePattern(resource, "*", lineRanges).setCheckLines(true));
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/package-info.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/package-info.java
deleted file mode 100644 (file)
index 55174cc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScanner.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScanner.java
deleted file mode 100644 (file)
index d6fa2d2..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.scanner;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchExtension;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-import org.sonar.plugins.core.issue.ignore.pattern.LineRange;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.Set;
-
-public class IgnoreIssuesRegexpScanner implements BatchExtension {
-
-  private static final Logger LOG = LoggerFactory.getLogger(IgnoreIssuesRegexpScanner.class);
-
-  private ExclusionPatternInitializer exclusionPatternInitializer;
-  private List<java.util.regex.Pattern> allFilePatterns;
-  private List<DoubleRegexpMatcher> blockMatchers;
-
-  // fields to be reset at every new scan
-  private DoubleRegexpMatcher currentMatcher;
-  private int fileLength;
-  private List<LineExclusion> lineExclusions;
-  private LineExclusion currentLineExclusion;
-
-  public IgnoreIssuesRegexpScanner(ExclusionPatternInitializer patternsInitializer) {
-    this.exclusionPatternInitializer = patternsInitializer;
-
-    lineExclusions = Lists.newArrayList();
-    allFilePatterns = Lists.newArrayList();
-    blockMatchers = Lists.newArrayList();
-
-    for (IssuePattern pattern : patternsInitializer.getAllFilePatterns()) {
-      allFilePatterns.add(java.util.regex.Pattern.compile(pattern.getAllFileRegexp()));
-    }
-    for (IssuePattern pattern : patternsInitializer.getBlockPatterns()) {
-      blockMatchers.add(new DoubleRegexpMatcher(
-          java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()),
-          java.util.regex.Pattern.compile(pattern.getEndBlockRegexp())));
-    }
-
-    init();
-  }
-
-  private void init() {
-    currentMatcher = null;
-    fileLength = 0;
-    lineExclusions.clear();
-    currentLineExclusion = null;
-  }
-
-  public void scan(String resource, File file, Charset sourcesEncoding) throws IOException {
-    LOG.debug("Scanning {}", resource);
-    init();
-
-    List<String> lines = FileUtils.readLines(file, sourcesEncoding.name());
-    int lineIndex = 0;
-    for (String line : lines) {
-      lineIndex++;
-      if (line.trim().length() == 0) {
-        continue;
-      }
-
-      // first check the single regexp patterns that can be used to totally exclude a file
-      for (java.util.regex.Pattern pattern : allFilePatterns) {
-        if (pattern.matcher(line).find()) {
-          exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeResource(resource);
-          // nothing more to do on this file
-          LOG.debug("- Exclusion pattern '{}': every violation in this file will be ignored.", pattern);
-          return;
-        }
-      }
-
-      // then check the double regexps if we're still here
-      checkDoubleRegexps(line, lineIndex);
-    }
-
-    if (currentMatcher != null && !currentMatcher.hasSecondPattern()) {
-      // this will happen when there is a start block regexp but no end block regexp
-      endExclusion(lineIndex + 1);
-    }
-
-    // now create the new line-based pattern for this file if there are exclusions
-    fileLength = lineIndex;
-    if (!lineExclusions.isEmpty()) {
-      Set<LineRange> lineRanges = convertLineExclusionsToLineRanges();
-      LOG.debug("- Line exclusions found: {}", lineRanges);
-      exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeLines(resource, lineRanges);
-    }
-  }
-
-  private Set<LineRange> convertLineExclusionsToLineRanges() {
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    for (LineExclusion lineExclusion : lineExclusions) {
-      lineRanges.add(lineExclusion.toLineRange());
-    }
-    return lineRanges;
-  }
-
-  private void checkDoubleRegexps(String line, int lineIndex) {
-    if (currentMatcher == null) {
-      for (DoubleRegexpMatcher matcher : blockMatchers) {
-        if (matcher.matchesFirstPattern(line)) {
-          startExclusion(lineIndex);
-          currentMatcher = matcher;
-          break;
-        }
-      }
-    } else {
-      if (currentMatcher.matchesSecondPattern(line)) {
-        endExclusion(lineIndex);
-        currentMatcher = null;
-      }
-    }
-  }
-
-  private void startExclusion(int lineIndex) {
-    currentLineExclusion = new LineExclusion(lineIndex);
-    lineExclusions.add(currentLineExclusion);
-  }
-
-  private void endExclusion(int lineIndex) {
-    currentLineExclusion.setEnd(lineIndex);
-    currentLineExclusion = null;
-  }
-
-  private class LineExclusion {
-
-    private int start;
-    private int end;
-
-    LineExclusion(int start) {
-      this.start = start;
-      this.end = -1;
-    }
-
-    void setEnd(int end) {
-      this.end = end;
-    }
-
-    public LineRange toLineRange() {
-      return new LineRange(start, end == -1 ? fileLength : end);
-    }
-
-  }
-
-  private static class DoubleRegexpMatcher {
-
-    private java.util.regex.Pattern firstPattern;
-    private java.util.regex.Pattern secondPattern;
-
-    DoubleRegexpMatcher(java.util.regex.Pattern firstPattern, java.util.regex.Pattern secondPattern) {
-      this.firstPattern = firstPattern;
-      this.secondPattern = secondPattern;
-    }
-
-    boolean matchesFirstPattern(String line) {
-      return firstPattern.matcher(line).find();
-    }
-
-    boolean matchesSecondPattern(String line) {
-      return hasSecondPattern() && secondPattern.matcher(line).find();
-    }
-
-    boolean hasSecondPattern() {
-      return StringUtils.isNotEmpty(secondPattern.toString());
-    }
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScanner.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScanner.java
deleted file mode 100644 (file)
index f88696d..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.scanner;
-
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.batch.Phase;
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.java.api.JavaUtils;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer;
-
-import java.nio.charset.Charset;
-
-@Phase(name = Phase.Name.PRE)
-// Issue Exclusions must be computed before JavaSquidSensor is executed and creates issues
-@DependedUpon(value = JavaUtils.BARRIER_BEFORE_SQUID)
-public final class IgnoreIssuesSourceScanner implements Sensor {
-
-  private final IgnoreIssuesRegexpScanner regexpScanner;
-  private final ExclusionPatternInitializer exclusionPatternInitializer;
-  private final InclusionPatternInitializer inclusionPatternInitializer;
-  private final DefaultModuleFileSystem fileSystem;
-
-  public IgnoreIssuesSourceScanner(IgnoreIssuesRegexpScanner regexpScanner, ExclusionPatternInitializer exclusionPatternInitializer, InclusionPatternInitializer inclusionPatternInitializer,
-    DefaultModuleFileSystem fileSystem) {
-    this.regexpScanner = regexpScanner;
-    this.exclusionPatternInitializer = exclusionPatternInitializer;
-    this.inclusionPatternInitializer = inclusionPatternInitializer;
-    this.fileSystem = fileSystem;
-  }
-
-  public boolean shouldExecuteOnProject(Project project) {
-    return inclusionPatternInitializer.hasConfiguredPatterns()
-      || exclusionPatternInitializer.hasConfiguredPatterns();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public void analyse(Project project, SensorContext context) {
-    Charset sourcesEncoding = fileSystem.sourceCharset();
-
-    for (InputFile inputFile : fileSystem.inputFiles(FileQuery.all())) {
-      try {
-        String componentEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
-        if (componentEffectiveKey != null) {
-          String path = inputFile.path();
-          inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
-          exclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
-          if (exclusionPatternInitializer.hasFileContentPattern()) {
-            regexpScanner.scan(componentEffectiveKey, inputFile.file(), sourcesEncoding);
-          }
-        }
-      } catch (Exception e) {
-        throw new SonarException("Unable to read the source file : '" + inputFile.absolutePath() + "' with the charset : '"
-          + sourcesEncoding.name() + "'.", e);
-      }
-    }
-  }
-
-  @Override
-  public String toString() {
-    return "Issues Exclusions - Source Scanner";
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/package-info.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/package-info.java
deleted file mode 100644 (file)
index 9471f4d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.core.issue.ignore.scanner;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/EnforceIssuesFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/EnforceIssuesFilterTest.java
deleted file mode 100644 (file)
index 3cba13d..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore;
-
-import com.google.common.collect.ImmutableList;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.batch.IssueFilterChain;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.WildcardPattern;
-import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class EnforceIssuesFilterTest {
-
-  private InclusionPatternInitializer exclusionPatternInitializer;
-  private EnforceIssuesFilter ignoreFilter;
-  private Issue issue;
-  private IssueFilterChain chain;
-
-  @Before
-  public void init() {
-    exclusionPatternInitializer = mock(InclusionPatternInitializer.class);
-    issue = mock(Issue.class);
-    chain = mock(IssueFilterChain.class);
-    when(chain.accept(issue)).thenReturn(true);
-
-    ignoreFilter = new EnforceIssuesFilter(exclusionPatternInitializer);
-  }
-
-  @Test
-  public void shouldPassToChainIfNoConfiguredPatterns() {
-    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
-    verify(chain).accept(issue);
-  }
-
-  @Test
-  public void shouldPassToChainIfRuleDoesNotMatch() {
-    String rule = "rule";
-    RuleKey ruleKey = mock(RuleKey.class);
-    when(ruleKey.toString()).thenReturn(rule);
-    when(issue.ruleKey()).thenReturn(ruleKey);
-
-    IssuePattern matching = mock(IssuePattern.class);
-    WildcardPattern rulePattern = mock(WildcardPattern.class);
-    when(matching.getRulePattern()).thenReturn(rulePattern);
-    when(rulePattern.match(rule)).thenReturn(false);
-    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
-
-    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
-    verify(chain).accept(issue);
-  }
-
-  @Test
-  public void shouldAcceptIssueIfFullyMatched() {
-    String rule = "rule";
-    String path = "org/sonar/api/Issue.java";
-    String componentKey = "org.sonar.api.Issue";
-    RuleKey ruleKey = mock(RuleKey.class);
-    when(ruleKey.toString()).thenReturn(rule);
-    when(issue.ruleKey()).thenReturn(ruleKey);
-    when(issue.componentKey()).thenReturn(componentKey);
-
-    IssuePattern matching = mock(IssuePattern.class);
-    WildcardPattern rulePattern = mock(WildcardPattern.class);
-    when(matching.getRulePattern()).thenReturn(rulePattern);
-    when(rulePattern.match(rule)).thenReturn(true);
-    WildcardPattern pathPattern = mock(WildcardPattern.class);
-    when(matching.getResourcePattern()).thenReturn(pathPattern);
-    when(pathPattern.match(path)).thenReturn(true);
-    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
-    when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path);
-
-    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
-    verifyZeroInteractions(chain);
-  }
-
-  @Test
-  public void shouldRefuseIssueIfRuleMatchesButNotPath() {
-    String rule = "rule";
-    String path = "org/sonar/api/Issue.java";
-    String componentKey = "org.sonar.api.Issue";
-    RuleKey ruleKey = mock(RuleKey.class);
-    when(ruleKey.toString()).thenReturn(rule);
-    when(issue.ruleKey()).thenReturn(ruleKey);
-    when(issue.componentKey()).thenReturn(componentKey);
-
-    IssuePattern matching = mock(IssuePattern.class);
-    WildcardPattern rulePattern = mock(WildcardPattern.class);
-    when(matching.getRulePattern()).thenReturn(rulePattern);
-    when(rulePattern.match(rule)).thenReturn(true);
-    WildcardPattern pathPattern = mock(WildcardPattern.class);
-    when(matching.getResourcePattern()).thenReturn(pathPattern);
-    when(pathPattern.match(path)).thenReturn(false);
-    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
-    when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path);
-
-    assertThat(ignoreFilter.accept(issue, chain)).isFalse();
-    verifyZeroInteractions(chain);
-  }
-
-  @Test
-  public void shouldRefuseIssueIfRuleMatchesAndPathUnknown() {
-    String rule = "rule";
-    String path = "org/sonar/api/Issue.java";
-    String componentKey = "org.sonar.api.Issue";
-    RuleKey ruleKey = mock(RuleKey.class);
-    when(ruleKey.toString()).thenReturn(rule);
-    when(issue.ruleKey()).thenReturn(ruleKey);
-    when(issue.componentKey()).thenReturn(componentKey);
-
-    IssuePattern matching = mock(IssuePattern.class);
-    WildcardPattern rulePattern = mock(WildcardPattern.class);
-    when(matching.getRulePattern()).thenReturn(rulePattern);
-    when(rulePattern.match(rule)).thenReturn(true);
-    WildcardPattern pathPattern = mock(WildcardPattern.class);
-    when(matching.getResourcePattern()).thenReturn(pathPattern);
-    when(pathPattern.match(path)).thenReturn(false);
-    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
-    when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(null);
-
-    assertThat(ignoreFilter.accept(issue, chain)).isFalse();
-    verifyZeroInteractions(chain);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java
deleted file mode 100644 (file)
index b582c10..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.batch.IssueFilterChain;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class IgnoreIssuesFilterTest {
-
-  private ExclusionPatternInitializer exclusionPatternInitializer;
-  private PatternMatcher exclusionPatternMatcher;
-  private IgnoreIssuesFilter ignoreFilter;
-  private Issue issue;
-  private IssueFilterChain chain;
-
-  @Before
-  public void init() {
-    exclusionPatternMatcher = mock(PatternMatcher.class);
-    exclusionPatternInitializer = mock(ExclusionPatternInitializer.class);
-    when(exclusionPatternInitializer.getPatternMatcher()).thenReturn(exclusionPatternMatcher);
-    issue = mock(Issue.class);
-    chain = mock(IssueFilterChain.class);
-    when(chain.accept(issue)).thenReturn(true);
-
-    ignoreFilter = new IgnoreIssuesFilter(exclusionPatternInitializer);
-  }
-
-  @Test
-  public void shouldPassToChainIfMatcherHasNoPatternForIssue() {
-    when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(null);
-
-    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
-  }
-
-  @Test
-  public void shouldAcceptOrRefuseIfMatcherHasPatternForIssue() {
-    when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(mock(IssuePattern.class));
-
-    assertThat(ignoreFilter.accept(issue, chain)).isFalse();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java
deleted file mode 100644 (file)
index 339ebee..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore;
-
-import org.junit.Test;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class IgnoreIssuesPluginTest {
-  @Test
-  public void justForCoverage() {
-    assertThat(IgnoreIssuesPlugin.getExtensions()).hasSize(4 /* properties */ + 6 /* extensions */);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/ExclusionPatternInitializerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/ExclusionPatternInitializerTest.java
deleted file mode 100644 (file)
index 0f9b649..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-import org.sonar.api.utils.SonarException;
-import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class ExclusionPatternInitializerTest {
-
-  private ExclusionPatternInitializer patternsInitializer;
-
-  private Settings settings;
-
-  @Before
-  public void init() {
-    settings = new Settings(new PropertyDefinitions(IgnoreIssuesConfiguration.getPropertyDefinitions()));
-    patternsInitializer = new ExclusionPatternInitializer(settings);
-  }
-
-  @Test
-  public void testNoConfiguration() {
-    patternsInitializer.initPatterns();
-    assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse();
-    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
-  }
-
-  @Test
-  public void shouldHavePatternsBasedOnMulticriteriaPattern() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1,2");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RESOURCE_KEY, "org/foo/Bar.java");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RULE_KEY, "*");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IgnoreIssuesConfiguration.RESOURCE_KEY, "org/foo/Hello.java");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IgnoreIssuesConfiguration.RULE_KEY, "checkstyle:MagicNumber");
-    patternsInitializer.initPatterns();
-
-    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
-    assertThat(patternsInitializer.hasFileContentPattern()).isFalse();
-    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue();
-    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2);
-    assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0);
-    assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0);
-
-    patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar");
-    patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz");
-    patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello");
-
-    assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Bar")).hasSize(1);
-    assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Baz")).hasSize(0);
-    assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Hello")).hasSize(1);
-
-  }
-
-  @Test(expected = SonarException.class)
-  public void shouldLogInvalidResourceKey() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RESOURCE_KEY, "");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RULE_KEY, "*");
-    patternsInitializer.initPatterns();
-  }
-
-  @Test(expected = SonarException.class)
-  public void shouldLogInvalidRuleKey() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RESOURCE_KEY, "*");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RULE_KEY, "");
-    patternsInitializer.initPatterns();
-  }
-
-  @Test
-  public void shouldReturnBlockPattern() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY, "1,2,3");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".1." + IgnoreIssuesConfiguration.BEGIN_BLOCK_REGEXP, "// SONAR-OFF");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".1." + IgnoreIssuesConfiguration.END_BLOCK_REGEXP, "// SONAR-ON");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".2." + IgnoreIssuesConfiguration.BEGIN_BLOCK_REGEXP, "// FOO-OFF");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".2." + IgnoreIssuesConfiguration.END_BLOCK_REGEXP, "// FOO-ON");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".3." + IgnoreIssuesConfiguration.BEGIN_BLOCK_REGEXP, "// IGNORE-TO-EOF");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".3." + IgnoreIssuesConfiguration.END_BLOCK_REGEXP, "");
-    patternsInitializer.loadFileContentPatterns();
-
-    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
-    assertThat(patternsInitializer.hasFileContentPattern()).isTrue();
-    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isFalse();
-    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
-    assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(3);
-    assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0);
-  }
-
-  @Test(expected = SonarException.class)
-  public void shouldLogInvalidStartBlockPattern() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY, "1");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".1." + IgnoreIssuesConfiguration.BEGIN_BLOCK_REGEXP, "");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_BLOCK_KEY + ".1." + IgnoreIssuesConfiguration.END_BLOCK_REGEXP, "// SONAR-ON");
-    patternsInitializer.loadFileContentPatterns();
-  }
-
-  @Test
-  public void shouldReturnAllFilePattern() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY, "1,2");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IgnoreIssuesConfiguration.FILE_REGEXP, "@SONAR-IGNORE-ALL");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY + ".2." + IgnoreIssuesConfiguration.FILE_REGEXP, "//FOO-IGNORE-ALL");
-    patternsInitializer.loadFileContentPatterns();
-
-    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
-    assertThat(patternsInitializer.hasFileContentPattern()).isTrue();
-    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isFalse();
-    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
-    assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0);
-    assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(2);
-  }
-
-  @Test(expected = SonarException.class)
-  public void shouldLogInvalidAllFilePattern() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY, "1");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IgnoreIssuesConfiguration.FILE_REGEXP, "");
-    patternsInitializer.loadFileContentPatterns();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/InclusionPatternInitializerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/InclusionPatternInitializerTest.java
deleted file mode 100644 (file)
index d277a2b..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class InclusionPatternInitializerTest {
-
-  private InclusionPatternInitializer patternsInitializer;
-
-  private Settings settings;
-
-  @Before
-  public void init() {
-    settings = new Settings(new PropertyDefinitions(IgnoreIssuesConfiguration.getPropertyDefinitions()));
-    patternsInitializer = new InclusionPatternInitializer(settings);
-  }
-
-  @Test
-  public void testNoConfiguration() {
-    patternsInitializer.initPatterns();
-    assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse();
-  }
-
-  @Test
-  public void shouldHavePatternsBasedOnMulticriteriaPattern() {
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY, "1,2");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RESOURCE_KEY, "org/foo/Bar.java");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IgnoreIssuesConfiguration.RULE_KEY, "*");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IgnoreIssuesConfiguration.RESOURCE_KEY, "org/foo/Hello.java");
-    settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IgnoreIssuesConfiguration.RULE_KEY, "checkstyle:MagicNumber");
-    patternsInitializer.initPatterns();
-
-    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
-    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue();
-    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2);
-
-    patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar");
-    patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz");
-    patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello");
-
-    assertThat(patternsInitializer.getPathForComponent("org.foo.Bar")).isEqualTo("org/foo/Bar.java");
-    assertThat(patternsInitializer.getPathForComponent("org.foo.Baz")).isEqualTo("org/foo/Baz.java");
-    assertThat(patternsInitializer.getPathForComponent("org.foo.Hello")).isEqualTo("org/foo/Hello.java");
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePatternTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePatternTest.java
deleted file mode 100644 (file)
index 9a069bb..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class IssuePatternTest {
-
-  @Test
-  public void shouldMatchLines() {
-    IssuePattern pattern = new IssuePattern("*", "*");
-    pattern.addLine(12).addLine(15).addLineRange(20, 25);
-
-    assertThat(pattern.matchLine(3)).isFalse();
-    assertThat(pattern.matchLine(12)).isTrue();
-    assertThat(pattern.matchLine(14)).isFalse();
-    assertThat(pattern.matchLine(21)).isTrue();
-    assertThat(pattern.matchLine(6599)).isFalse();
-  }
-
-  @Test
-  public void shouldMatchJavaFile() {
-    String javaFile = "org.foo.Bar";
-    assertThat(new IssuePattern("org.foo.Bar", "*").matchResource(javaFile)).isTrue();
-    assertThat(new IssuePattern("org.foo.*", "*").matchResource(javaFile)).isTrue();
-    assertThat(new IssuePattern("*Bar", "*").matchResource(javaFile)).isTrue();
-    assertThat(new IssuePattern("*", "*").matchResource(javaFile)).isTrue();
-    assertThat(new IssuePattern("org.*.?ar", "*").matchResource(javaFile)).isTrue();
-
-    assertThat(new IssuePattern("org.other.Hello", "*").matchResource(javaFile)).isFalse();
-    assertThat(new IssuePattern("org.foo.Hello", "*").matchResource(javaFile)).isFalse();
-    assertThat(new IssuePattern("org.*.??ar", "*").matchResource(javaFile)).isFalse();
-    assertThat(new IssuePattern("org.*.??ar", "*").matchResource(null)).isFalse();
-    assertThat(new IssuePattern("org.*.??ar", "*").matchResource("plop")).isFalse();
-  }
-
-  @Test
-  public void shouldMatchRule() {
-    RuleKey rule = Rule.create("checkstyle", "IllegalRegexp", "").ruleKey();
-    assertThat(new IssuePattern("*", "*").matchRule(rule)).isTrue();
-    assertThat(new IssuePattern("*", "checkstyle:*").matchRule(rule)).isTrue();
-    assertThat(new IssuePattern("*", "checkstyle:IllegalRegexp").matchRule(rule)).isTrue();
-    assertThat(new IssuePattern("*", "checkstyle:Illegal*").matchRule(rule)).isTrue();
-    assertThat(new IssuePattern("*", "*:*Illegal*").matchRule(rule)).isTrue();
-
-    assertThat(new IssuePattern("*", "pmd:IllegalRegexp").matchRule(rule)).isFalse();
-    assertThat(new IssuePattern("*", "pmd:*").matchRule(rule)).isFalse();
-    assertThat(new IssuePattern("*", "*:Foo*IllegalRegexp").matchRule(rule)).isFalse();
-  }
-
-  @Test
-  public void shouldMatchViolation() {
-    Rule rule = Rule.create("checkstyle", "IllegalRegexp", "");
-    String javaFile = "org.foo.Bar";
-
-    IssuePattern pattern = new IssuePattern("*", "*");
-    pattern.addLine(12);
-
-    assertThat(pattern.match(create(rule, javaFile, null))).isFalse();
-    assertThat(pattern.match(create(rule, javaFile, 12))).isTrue();
-    assertThat(pattern.match(create((Rule) null, javaFile, 5))).isFalse();
-    assertThat(pattern.match(create(rule, null, null))).isFalse();
-    assertThat(pattern.match(create((Rule) null, null, null))).isFalse();
-  }
-
-  private Issue create(Rule rule, String component, Integer line) {
-    Issue mockIssue = mock(Issue.class);
-    RuleKey ruleKey = null;
-    if (rule != null) {
-      ruleKey = rule.ruleKey();
-    }
-    when(mockIssue.ruleKey()).thenReturn(ruleKey);
-    when(mockIssue.componentKey()).thenReturn(component);
-    when(mockIssue.line()).thenReturn(line);
-    return mockIssue;
-  }
-
-  @Test
-  public void shouldNotMatchNullRule() {
-    assertThat(new IssuePattern("*", "*").matchRule(null)).isFalse();
-  }
-
-  @Test
-  public void shouldPrintPatternToString() {
-    IssuePattern pattern = new IssuePattern("*", "checkstyle:*");
-
-    assertThat(pattern.toString()).isEqualTo("IssuePattern[resourcePattern=*,rulePattern=checkstyle:*,lines=[],lineRanges=[],beginBlockRegexp=<null>,endBlockRegexp=<null>,allFileRegexp=<null>,checkLines=true]");
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/LineRangeTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/LineRangeTest.java
deleted file mode 100644 (file)
index 3c4c02a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import org.junit.Test;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class LineRangeTest {
-
-  @Test(expected = IllegalArgumentException.class)
-  public void lineRangeShouldBeOrdered() {
-    new LineRange(25, 12);
-  }
-
-  @Test
-  public void shouldConvertLineRangeToLines() {
-    LineRange range = new LineRange(12, 15);
-
-    assertThat(range.toLines()).containsOnly(12, 13, 14, 15);
-  }
-
-  @Test
-  public void shouldTestInclusionInRangeOfLines() {
-    LineRange range = new LineRange(12, 15);
-
-    assertThat(range.in(3)).isFalse();
-    assertThat(range.in(12)).isTrue();
-    assertThat(range.in(13)).isTrue();
-    assertThat(range.in(14)).isTrue();
-    assertThat(range.in(15)).isTrue();
-    assertThat(range.in(16)).isFalse();
-  }
-
-  @Test
-  public void testToString() throws Exception {
-    assertThat(new LineRange(12, 15).toString()).isEqualTo("[12-15]");
-  }
-
-  @Test
-  public void testEquals() throws Exception {
-    LineRange range = new LineRange(12, 15);
-    assertThat(range).isEqualTo(range);
-    assertThat(range).isEqualTo(new LineRange(12, 15));
-    assertThat(range).isNotEqualTo(new LineRange(12, 2000));
-    assertThat(range).isNotEqualTo(new LineRange(1000, 2000));
-    assertThat(range).isNotEqualTo(null);
-    assertThat(range).isNotEqualTo(new StringBuffer());
-  }
-
-  @Test
-  public void testHashCode() throws Exception {
-    assertThat(new LineRange(12, 15).hashCode()).isEqualTo(new LineRange(12, 15).hashCode());
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternDecoderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternDecoderTest.java
deleted file mode 100644 (file)
index 18e9e58..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.SonarException;
-
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class PatternDecoderTest {
-
-  private PatternDecoder decoder = new PatternDecoder();
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Test
-  public void shouldReadString() {
-    String patternsList = "# a comment followed by a blank line\n\n" +
-      "# suppress all violations\n" +
-      "*;*;*\n\n" +
-      "# exclude a Java file\n" +
-      "com.foo.Bar;*;*\n\n" +
-      "# exclude a Java package\n" +
-      "com.foo.*;*;*\n\n" +
-      "# exclude a specific rule\n" +
-      "*;checkstyle:IllegalRegexp;*\n\n" +
-      "# exclude a specific rule on a specific file\n" +
-      "com.foo.Bar;checkstyle:IllegalRegexp;*\n";
-    List<IssuePattern> patterns = decoder.decode(patternsList);
-
-    assertThat(patterns).hasSize(5);
-  }
-
-  @Test
-  public void shouldCheckFormatOfResource() {
-    assertThat(PatternDecoder.isResource("")).isFalse();
-    assertThat(PatternDecoder.isResource("*")).isTrue();
-    assertThat(PatternDecoder.isResource("com.foo.*")).isTrue();
-  }
-
-  @Test
-  public void shouldCheckFormatOfRule() {
-    assertThat(PatternDecoder.isRule("")).isFalse();
-    assertThat(PatternDecoder.isRule("*")).isTrue();
-    assertThat(PatternDecoder.isRule("com.foo.*")).isTrue();
-  }
-
-  @Test
-  public void shouldCheckFormatOfLinesRange() {
-    assertThat(PatternDecoder.isLinesRange("")).isFalse();
-    assertThat(PatternDecoder.isLinesRange("   ")).isFalse();
-    assertThat(PatternDecoder.isLinesRange("12")).isFalse();
-    assertThat(PatternDecoder.isLinesRange("12,212")).isFalse();
-
-    assertThat(PatternDecoder.isLinesRange("*")).isTrue();
-    assertThat(PatternDecoder.isLinesRange("[]")).isTrue();
-    assertThat(PatternDecoder.isLinesRange("[13]")).isTrue();
-    assertThat(PatternDecoder.isLinesRange("[13,24]")).isTrue();
-    assertThat(PatternDecoder.isLinesRange("[13,24,25-500]")).isTrue();
-    assertThat(PatternDecoder.isLinesRange("[24-65]")).isTrue();
-    assertThat(PatternDecoder.isLinesRange("[13,24-65,84-89,122]")).isTrue();
-  }
-
-  @Test
-  public void shouldReadStarPatterns() {
-    IssuePattern pattern = decoder.decodeLine("*;*;*");
-
-    assertThat(pattern.getResourcePattern().toString()).isEqualTo("*");
-    assertThat(pattern.getRulePattern().toString()).isEqualTo("*");
-    assertThat(pattern.isCheckLines()).isFalse();
-  }
-
-  @Test
-  public void shouldReadLineIds() {
-    IssuePattern pattern = decoder.decodeLine("*;*;[10,25,98]");
-
-    assertThat(pattern.isCheckLines()).isTrue();
-    assertThat(pattern.getAllLines()).containsOnly(10, 25, 98);
-  }
-
-  @Test
-  public void shouldReadRangeOfLineIds() {
-    IssuePattern pattern = decoder.decodeLine("*;*;[10-12,25,97-100]");
-
-    assertThat(pattern.isCheckLines()).isTrue();
-    assertThat(pattern.getAllLines()).containsOnly(10, 11, 12, 25, 97, 98, 99, 100);
-  }
-
-  @Test
-  public void shouldNotExcludeLines() {
-    // [] is different than *
-    // - all violations are excluded on *
-    // * no violations are excluded on []
-    IssuePattern pattern = decoder.decodeLine("*;*;[]");
-
-    assertThat(pattern.isCheckLines()).isTrue();
-    assertThat(pattern.getAllLines()).isEmpty();
-  }
-
-  @Test
-  public void shouldReadBlockPattern() {
-    IssuePattern pattern = decoder.decodeLine("SONAR-OFF;SONAR-ON");
-
-    assertThat(pattern.getResourcePattern()).isNull();
-    assertThat(pattern.getBeginBlockRegexp()).isEqualTo("SONAR-OFF");
-    assertThat(pattern.getEndBlockRegexp()).isEqualTo("SONAR-ON");
-  }
-
-  @Test
-  public void shouldReadAllFilePattern() {
-    IssuePattern pattern = decoder.decodeLine("SONAR-ALL-OFF");
-
-    assertThat(pattern.getResourcePattern()).isNull();
-    assertThat(pattern.getAllFileRegexp()).isEqualTo("SONAR-ALL-OFF");
-  }
-
-  @Test
-  public void shouldFailToReadUncorrectLine1() {
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("Exclusions > Issues : Invalid format. The following line has more than 3 fields separated by comma");
-
-    decoder.decode(";;;;");
-  }
-
-  @Test
-  public void shouldFailToReadUncorrectLine3() {
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a resource pattern");
-
-    decoder.decode(";*;*");
-  }
-
-  @Test
-  public void shouldFailToReadUncorrectLine4() {
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("Exclusions > Issues : Invalid format. The second field does not define a rule pattern");
-
-    decoder.decode("*;;*");
-  }
-
-  @Test
-  public void shouldFailToReadUncorrectLine5() {
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("Exclusions > Issues : Invalid format. The third field does not define a range of lines");
-
-    decoder.decode("*;*;blabla");
-  }
-
-  @Test
-  public void shouldFailToReadUncorrectLine6() {
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a regular expression");
-
-    decoder.decode(";ON");
-  }
-
-  @Test
-  public void shouldAcceptEmptyEndBlockRegexp() {
-    IssuePattern pattern = decoder.decodeLine("OFF;");
-
-    assertThat(pattern.getResourcePattern()).isNull();
-    assertThat(pattern.getBeginBlockRegexp()).isEqualTo("OFF");
-    assertThat(pattern.getEndBlockRegexp()).isEmpty();
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java
deleted file mode 100644 (file)
index af7f97e..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.plugins.core.issue.ignore.pattern;
-
-import com.google.common.collect.Sets;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-
-import java.io.IOException;
-import java.util.Set;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class PatternMatcherTest {
-
-  public static final Rule CHECKSTYLE_RULE = Rule.create("checkstyle", "MagicNumber", "");
-  public static final String JAVA_FILE = "org.foo.Hello";
-
-  private PatternMatcher patternMatcher;
-
-  @Before
-  public void setUp() {
-    patternMatcher = new PatternMatcher();
-  }
-
-  @Test
-  public void shouldReturnExtraPatternForResource() {
-    String file = "foo";
-    patternMatcher.addPatternToExcludeResource(file);
-
-    IssuePattern extraPattern = patternMatcher.getPatternsForComponent(file).iterator().next();
-    assertThat(extraPattern.matchResource(file)).isTrue();
-    assertThat(extraPattern.isCheckLines()).isFalse();
-  }
-
-  @Test
-  public void shouldReturnExtraPatternForLinesOfResource() {
-    String file = "foo";
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    lineRanges.add(new LineRange(25, 28));
-    patternMatcher.addPatternToExcludeLines(file, lineRanges);
-
-    IssuePattern extraPattern = patternMatcher.getPatternsForComponent(file).iterator().next();
-    assertThat(extraPattern.matchResource(file)).isTrue();
-    assertThat(extraPattern.getAllLines()).isEqualTo(Sets.newHashSet(25, 26, 27, 28));
-  }
-
-  @Test
-  public void shouldHaveNoMatcherIfNoneDefined() {
-    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, null))).isNull();
-  }
-
-  @Test
-  public void shouldMatchWithStandardPatterns() throws IOException {
-    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
-
-    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
-  }
-
-  @Test
-  public void shouldNotMatchWithStandardPatterns() throws IOException {
-    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
-
-    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
-  }
-
-  @Test
-  public void shouldMatchWithExtraPattern() throws IOException {
-    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
-
-    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
-  }
-
-  @Test
-  public void shouldNotMatchWithExtraPattern() throws IOException {
-    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
-
-    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
-  }
-
-  private Issue create(Rule rule, String component, Integer line) {
-    Issue mockIssue = mock(Issue.class);
-    RuleKey ruleKey = null;
-    if (rule != null) {
-      ruleKey = rule.ruleKey();
-    }
-    when(mockIssue.ruleKey()).thenReturn(ruleKey);
-    when(mockIssue.componentKey()).thenReturn(component);
-    when(mockIssue.line()).thenReturn(line);
-    return mockIssue;
-  }
-
-  private IssuePattern createPattern(String line) {
-    return new PatternDecoder().decode(line).get(0);
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest.java
deleted file mode 100644 (file)
index bfbe6c6..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.scanner;
-
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-import org.sonar.plugins.core.issue.ignore.pattern.LineRange;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
-import org.sonar.test.TestUtils;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Set;
-
-import static com.google.common.base.Charsets.UTF_8;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-public class IgnoreIssuesRegexpScannerTest {
-
-  private IgnoreIssuesRegexpScanner regexpScanner;
-
-  private String javaFile;
-  @Mock
-  private ExclusionPatternInitializer patternsInitializer;
-  @Mock
-  private PatternMatcher patternMatcher;
-  @Mock
-  private IssuePattern allFilePattern;
-  @Mock
-  private IssuePattern blockPattern1;
-  @Mock
-  private IssuePattern blockPattern2;
-
-  @Before
-  public void init() {
-    MockitoAnnotations.initMocks(this);
-
-    when(allFilePattern.getAllFileRegexp()).thenReturn("@SONAR-IGNORE-ALL");
-    when(blockPattern1.getBeginBlockRegexp()).thenReturn("// SONAR-OFF");
-    when(blockPattern1.getEndBlockRegexp()).thenReturn("// SONAR-ON");
-    when(blockPattern2.getBeginBlockRegexp()).thenReturn("// FOO-OFF");
-    when(blockPattern2.getEndBlockRegexp()).thenReturn("// FOO-ON");
-    when(patternsInitializer.getAllFilePatterns()).thenReturn(Arrays.asList(allFilePattern));
-    when(patternsInitializer.getBlockPatterns()).thenReturn(Arrays.asList(blockPattern1, blockPattern2));
-    when(patternsInitializer.getPatternMatcher()).thenReturn(patternMatcher);
-
-    regexpScanner = new IgnoreIssuesRegexpScanner(patternsInitializer);
-    verify(patternsInitializer, times(1)).getAllFilePatterns();
-    verify(patternsInitializer, times(1)).getBlockPatterns();
-
-    javaFile = "org.sonar.test.MyFile";
-  }
-
-  @Test
-  public void shouldDoNothing() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-no-regexp.txt"), UTF_8);
-
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeFile() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp.txt"), UTF_8);
-
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeFileEvenIfAlsoDoubleRegexps() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp-and-double-regexp.txt"), UTF_8);
-
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeLines() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp.txt"), UTF_8);
-
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    lineRanges.add(new LineRange(21, 25));
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeLinesTillTheEnd() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-unfinished.txt"), UTF_8);
-
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    lineRanges.add(new LineRange(21, 34));
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeSeveralLineRanges() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-twice.txt"), UTF_8);
-
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    lineRanges.add(new LineRange(21, 25));
-    lineRanges.add(new LineRange(29, 33));
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeLinesWithWrongOrder() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-wrong-order.txt"), UTF_8);
-
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    lineRanges.add(new LineRange(25, 35));
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-  @Test
-  public void shouldAddPatternToExcludeLinesWithMess() throws IOException {
-    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-mess.txt"), UTF_8);
-
-    Set<LineRange> lineRanges = Sets.newHashSet();
-    lineRanges.add(new LineRange(21, 29));
-    verify(patternsInitializer).getPatternMatcher();
-    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
-    verifyNoMoreInteractions(patternsInitializer);
-  }
-
-}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScannerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScannerTest.java
deleted file mode 100644 (file)
index 5fc3a27..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.plugins.core.issue.ignore.scanner;
-
-import com.google.common.base.Charsets;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-
-import static com.google.common.base.Charsets.UTF_8;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class IgnoreIssuesSourceScannerTest {
-
-  private IgnoreIssuesSourceScanner scanner;
-
-  @Mock
-  private IgnoreIssuesRegexpScanner regexpScanner;
-  @Mock
-  private InclusionPatternInitializer inclusionPatternInitializer;
-  @Mock
-  private ExclusionPatternInitializer exclusionPatternInitializer;
-  @Mock
-  private PatternMatcher patternMatcher;
-  @Mock
-  private DefaultModuleFileSystem fs;
-
-  private Project project;
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  private File baseDir;
-
-  @Before
-  public void init() throws IOException {
-    baseDir = temp.newFolder();
-    MockitoAnnotations.initMocks(this);
-
-    Project realProject = new Project("polop");
-    project = Mockito.spy(realProject);
-    Mockito.doReturn("java").when(project).getLanguageKey();
-    when(fs.sourceCharset()).thenReturn(UTF_8);
-
-    scanner = new IgnoreIssuesSourceScanner(regexpScanner, exclusionPatternInitializer, inclusionPatternInitializer, fs);
-  }
-
-  @Test
-  public void testToString() throws Exception {
-    assertThat(scanner.toString()).isEqualTo("Issues Exclusions - Source Scanner");
-  }
-
-  @Test
-  public void shouldExecute() throws IOException {
-    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
-    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
-    assertThat(scanner.shouldExecuteOnProject(null)).isTrue();
-
-    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
-    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
-    assertThat(scanner.shouldExecuteOnProject(null)).isTrue();
-
-    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
-    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
-    assertThat(scanner.shouldExecuteOnProject(null)).isTrue();
-
-    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
-    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
-    assertThat(scanner.shouldExecuteOnProject(null)).isFalse();
-
-  }
-
-  @Test
-  public void shouldAnalyseProject() throws IOException {
-    File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
-    File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
-    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java")
-        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java")
-        .build(),
-      new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java")
-        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java")
-        .build()));
-
-    when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
-
-    scanner.analyse(project, null);
-
-    verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
-    verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
-    verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
-    verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
-    verify(regexpScanner).scan("polop:src/main/java/Foo.java", javaFile1, UTF_8);
-    verify(regexpScanner).scan("polop:src/test/java/FooTest.java", javaTestFile1, UTF_8);
-  }
-
-  @Test
-  public void shouldAnalyseFilesOnlyWhenRegexConfigured() throws IOException {
-    File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
-    File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
-    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java")
-        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java")
-        .build(),
-      new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java")
-        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java")
-        .build()));
-
-    when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false);
-
-    scanner.analyse(project, null);
-
-    verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
-    verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
-    verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
-    verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
-    verifyZeroInteractions(regexpScanner);
-  }
-
-  @Test
-  public void shouldReportFailure() throws IOException {
-    File phpFile1 = new File(baseDir, "src/Foo.php");
-    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
-      new InputFileBuilder(phpFile1, Charsets.UTF_8, "src/Foo.php")
-        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/Foo.php")
-        .build()));
-
-    when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
-    doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8);
-
-    thrown.expect(SonarException.class);
-    thrown.expectMessage("Unable to read the source file");
-
-    scanner.analyse(project, null);
-  }
-}
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-mess.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-mess.txt
deleted file mode 100644 (file)
index 48d30c9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * 
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  // SONAR-OFF
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-  // FOO-OFF
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    // SONAR-ON
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    // FOO-ON
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-twice.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-twice.txt
deleted file mode 100644 (file)
index 9ae63dc..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * 
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  // SONAR-OFF
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-  // SONAR-ON
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    // FOO-OFF
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    // FOO-ON
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-unfinished.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-unfinished.txt
deleted file mode 100644 (file)
index dd76561..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * 
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  // SONAR-OFF
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-wrong-order.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp-wrong-order.txt
deleted file mode 100644 (file)
index 7cac0b9..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * 
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  // SONAR-ON
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-  // SONAR-OFF
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-double-regexp.txt
deleted file mode 100644 (file)
index 002169f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * 
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  // SONAR-OFF
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-  // SONAR-ON
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-no-regexp.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-no-regexp.txt
deleted file mode 100644 (file)
index f18fa5b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * 
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt
deleted file mode 100644 (file)
index e09ecd7..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-  // SONAR-OFF
-
-import java.util.Set;
-
-/**
- * @SONAR-IGNORE-ALL
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-  // SONAR-ON
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-single-regexp.txt b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest/file-with-single-regexp.txt
deleted file mode 100644 (file)
index ef135eb..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.sonar.plugins.switchoffviolations.pattern;
-
-import com.google.common.collect.Sets;
-
-import java.util.Set;
-
-/**
- * @SONAR-IGNORE-ALL
- */
-public class LineRange {
-  int from, to;
-
-  public LineRange(int from, int to) {
-    if (to < from) {
-      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
-    }
-    this.from = from;
-    this.to = to;
-  }
-
-  public boolean in(int lineId) {
-    return from <= lineId && lineId <= to;
-  }
-
-  public Set<Integer> toLines() {
-    Set<Integer> lines = Sets.newLinkedHashSet();
-    for (int index = from; index <= to; index++) {
-      lines.add(index);
-    }
-    return lines;
-  }
-
-}
\ No newline at end of file
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/EnforceIssuesFilter.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/EnforceIssuesFilter.java
new file mode 100644 (file)
index 0000000..7245d90
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.issue.ignore;
+
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.batch.IssueFilter;
+import org.sonar.api.issue.batch.IssueFilterChain;
+
+public class EnforceIssuesFilter implements IssueFilter {
+
+  private IssueInclusionPatternInitializer patternInitializer;
+
+  private static final Logger LOG = LoggerFactory.getLogger(EnforceIssuesFilter.class);
+
+  public EnforceIssuesFilter(IssueInclusionPatternInitializer patternInitializer) {
+    this.patternInitializer = patternInitializer;
+  }
+
+  @Override
+  public boolean accept(Issue issue, IssueFilterChain chain) {
+    boolean atLeastOneRuleMatched = false;
+    boolean atLeastOnePatternFullyMatched = false;
+    IssuePattern matchingPattern = null;
+
+    for (IssuePattern pattern : patternInitializer.getMulticriteriaPatterns()) {
+      if (pattern.getRulePattern().match(issue.ruleKey().toString())) {
+        atLeastOneRuleMatched = true;
+        String pathForComponent = patternInitializer.getPathForComponent(issue.componentKey());
+        if (pathForComponent != null && pattern.getResourcePattern().match(pathForComponent)) {
+          atLeastOnePatternFullyMatched = true;
+          matchingPattern = pattern;
+        }
+      }
+    }
+
+    if (atLeastOneRuleMatched) {
+      if (atLeastOnePatternFullyMatched) {
+        LOG.debug("Issue {} enforced by pattern {}", issue, matchingPattern);
+      }
+      return atLeastOnePatternFullyMatched;
+    } else {
+      return chain.accept(issue);
+    }
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilter.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilter.java
new file mode 100644 (file)
index 0000000..d880bf6
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.issue.ignore;
+
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.batch.IssueFilter;
+import org.sonar.api.issue.batch.IssueFilterChain;
+
+public class IgnoreIssuesFilter implements IssueFilter {
+
+  private PatternMatcher patternMatcher;
+
+  private static final Logger LOG = LoggerFactory.getLogger(IgnoreIssuesFilter.class);
+
+  public IgnoreIssuesFilter(IssueExclusionPatternInitializer patternInitializer) {
+    this.patternMatcher = patternInitializer.getPatternMatcher();
+  }
+
+  @Override
+  public boolean accept(Issue issue, IssueFilterChain chain) {
+    if (hasMatchFor(issue)) {
+      return false;
+    } else {
+      return chain.accept(issue);
+    }
+  }
+
+  private boolean hasMatchFor(Issue issue) {
+    IssuePattern pattern = patternMatcher.getMatchingPattern(issue);
+    if (pattern != null) {
+      logExclusion(issue, pattern);
+      return true;
+    }
+    return false;
+  }
+
+  private void logExclusion(Issue issue, IssuePattern pattern) {
+    LOG.debug("Issue {} ignored by exclusion pattern {}", issue, pattern);
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IssueExclusionsConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/IssueExclusionsConfiguration.java
new file mode 100644 (file)
index 0000000..441f08d
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore;
+
+import com.google.common.collect.ImmutableList;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.api.config.PropertyFieldDefinition;
+import org.sonar.api.resources.Qualifiers;
+
+import java.util.List;
+
+public final class IssueExclusionsConfiguration {
+
+  public static final String SUB_CATEGORY_IGNORE_ISSUES = "issues";
+
+  public static final String EXCLUSION_KEY_PREFIX = "sonar.issue.ignore";
+  public static final String INCLUSION_KEY_PREFIX = "sonar.issue.enforce";
+
+  public static final String MULTICRITERIA_SUFFIX = ".multicriteria";
+  public static final String PATTERNS_MULTICRITERIA_EXCLUSION_KEY = EXCLUSION_KEY_PREFIX + MULTICRITERIA_SUFFIX;
+  public static final String PATTERNS_MULTICRITERIA_INCLUSION_KEY = INCLUSION_KEY_PREFIX + MULTICRITERIA_SUFFIX;
+  public static final String RESOURCE_KEY = "resourceKey";
+  private static final String PROPERTY_FILE_PATH_PATTERN = "File Path Pattern";
+  public static final String RULE_KEY = "ruleKey";
+  private static final String PROPERTY_RULE_KEY_PATTERN = "Rule Key Pattern";
+
+  public static final String BLOCK_SUFFIX = ".block";
+  public static final String PATTERNS_BLOCK_KEY = EXCLUSION_KEY_PREFIX + BLOCK_SUFFIX;
+  public static final String BEGIN_BLOCK_REGEXP = "beginBlockRegexp";
+  public static final String END_BLOCK_REGEXP = "endBlockRegexp";
+
+  public static final String ALLFILE_SUFFIX = ".allfile";
+  public static final String PATTERNS_ALLFILE_KEY = EXCLUSION_KEY_PREFIX + ALLFILE_SUFFIX;
+  public static final String FILE_REGEXP = "fileRegexp";
+
+  static final int LARGE_SIZE = 40;
+  static final int SMALL_SIZE = 10;
+
+  private IssueExclusionsConfiguration() {
+    // static configuration declaration only
+  }
+
+  public static List<PropertyDefinition> getPropertyDefinitions() {
+    return ImmutableList.of(
+      PropertyDefinition.builder(PATTERNS_MULTICRITERIA_EXCLUSION_KEY)
+        .category(CoreProperties.CATEGORY_EXCLUSIONS)
+        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
+        .name("Ignore Issues on Multiple Criteria")
+        .description("Patterns to ignore issues on certain components and for certain coding rules.")
+        .onQualifiers(Qualifiers.PROJECT)
+        .index(3)
+        .fields(
+          PropertyFieldDefinition.build(RULE_KEY)
+            .name(PROPERTY_RULE_KEY_PATTERN)
+            .description("Pattern to match rules which should be ignored.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build(),
+          PropertyFieldDefinition.build(RESOURCE_KEY)
+            .name(PROPERTY_FILE_PATH_PATTERN)
+            .description("Pattern to match files which should be ignored.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build())
+        .build(),
+      PropertyDefinition.builder(PATTERNS_BLOCK_KEY)
+        .category(CoreProperties.CATEGORY_EXCLUSIONS)
+        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
+        .name("Ignore Issues in Blocks")
+        .description("Patterns to ignore all issues on specific blocks of code, while continuing to scan and mark issues on the remainder of the file.")
+        .onQualifiers(Qualifiers.PROJECT)
+        .index(2)
+        .fields(
+          PropertyFieldDefinition.build(BEGIN_BLOCK_REGEXP)
+            .name("Regular Expression for Start of Block")
+            .description("If this regular expression is found in a file, then following lines are ignored until end of block.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build(),
+          PropertyFieldDefinition.build(END_BLOCK_REGEXP)
+            .name("Regular Expression for End of Block")
+            .description("If specified, this regular expression is used to determine the end of code blocks to ignore. If not, then block ends at the end of file.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build())
+        .build(),
+      PropertyDefinition.builder(PATTERNS_ALLFILE_KEY)
+        .category(CoreProperties.CATEGORY_EXCLUSIONS)
+        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
+        .name("Ignore Issues on Files")
+        .description("Patterns to ignore all issues on files that contain a block of code matching a given regular expression.")
+        .onQualifiers(Qualifiers.PROJECT)
+        .index(1)
+        .fields(
+          PropertyFieldDefinition.build(FILE_REGEXP)
+            .name("Regular Expression")
+            .description("If this regular expression is found in a file, then the whole file is ignored.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build())
+        .build(),
+      PropertyDefinition.builder(PATTERNS_MULTICRITERIA_INCLUSION_KEY)
+        .category(CoreProperties.CATEGORY_EXCLUSIONS)
+        .subCategory(SUB_CATEGORY_IGNORE_ISSUES)
+        .name("Restrict Scope of Coding Rules")
+        .description("Patterns to restrict the application of a rule to only certain components, ignoring all others.")
+        .onQualifiers(Qualifiers.PROJECT)
+        .index(4)
+        .fields(
+          PropertyFieldDefinition.build(RULE_KEY)
+            .name(PROPERTY_RULE_KEY_PATTERN)
+            .description("Pattern used to match rules which should be restricted.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build(),
+          PropertyFieldDefinition.build(RESOURCE_KEY)
+            .name(PROPERTY_FILE_PATH_PATTERN)
+            .description("Pattern used to match files to which the rules should be restricted.")
+            .type(PropertyType.STRING)
+            .indicativeSize(LARGE_SIZE)
+            .build())
+        .build());
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/package-info.java
new file mode 100644 (file)
index 0000000..c25ccd3
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.issue.ignore;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/AbstractPatternInitializer.java
new file mode 100644 (file)
index 0000000..10d5e55
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.config.Settings;
+
+import java.util.List;
+
+import static com.google.common.base.Objects.firstNonNull;
+
+public abstract class AbstractPatternInitializer implements BatchExtension {
+
+  private Settings settings;
+
+  private List<IssuePattern> multicriteriaPatterns;
+
+  protected AbstractPatternInitializer(Settings settings) {
+    this.settings = settings;
+    initPatterns();
+  }
+
+  protected Settings getSettings() {
+    return settings;
+  }
+
+  public List<IssuePattern> getMulticriteriaPatterns() {
+    return multicriteriaPatterns;
+  }
+
+  public boolean hasConfiguredPatterns() {
+    return hasMulticriteriaPatterns();
+  }
+
+  public boolean hasMulticriteriaPatterns() {
+    return ! multicriteriaPatterns.isEmpty();
+  }
+
+  public abstract void initializePatternsForPath(String relativePath, String componentKey);
+
+  @VisibleForTesting
+  protected final void initPatterns() {
+    // Patterns Multicriteria
+    multicriteriaPatterns = Lists.newArrayList();
+    String patternConf = StringUtils.defaultIfBlank(settings.getString(getMulticriteriaConfigurationKey()), "");
+    for (String id : StringUtils.split(patternConf, ',')) {
+      String propPrefix = getMulticriteriaConfigurationKey() + "." + id + ".";
+      String resourceKeyPattern = settings.getString(propPrefix + IssueExclusionsConfiguration.RESOURCE_KEY);
+      String ruleKeyPattern = settings.getString(propPrefix + IssueExclusionsConfiguration.RULE_KEY);
+      String lineRange = "*";
+      String[] fields = new String[] { resourceKeyPattern, ruleKeyPattern, lineRange };
+      PatternDecoder.checkRegularLineConstraints(StringUtils.join(fields, ","), fields);
+      IssuePattern pattern = new IssuePattern(firstNonNull(resourceKeyPattern, "*"), firstNonNull(ruleKeyPattern, "*"));
+      PatternDecoder.decodeRangeOfLines(pattern, firstNonNull(lineRange, "*"));
+      multicriteriaPatterns.add(pattern);
+    }
+  }
+
+  protected abstract String getMulticriteriaConfigurationKey();
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializer.java
new file mode 100644 (file)
index 0000000..9cddda0
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.config.Settings;
+
+import java.util.List;
+
+import static com.google.common.base.Strings.nullToEmpty;
+
+public class IssueExclusionPatternInitializer extends AbstractPatternInitializer {
+
+  private List<IssuePattern> blockPatterns;
+  private List<IssuePattern> allFilePatterns;
+  private PatternMatcher patternMatcher;
+
+  public IssueExclusionPatternInitializer(Settings settings) {
+    super(settings);
+    patternMatcher = new PatternMatcher();
+    loadFileContentPatterns();
+  }
+
+  @Override
+  protected String getMulticriteriaConfigurationKey() {
+    return IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY;
+  }
+
+  public PatternMatcher getPatternMatcher() {
+    return patternMatcher;
+  }
+
+  @Override
+  public void initializePatternsForPath(String relativePath, String componentKey) {
+    for (IssuePattern pattern: getMulticriteriaPatterns()) {
+      if (pattern.matchResource(relativePath)) {
+        getPatternMatcher().addPatternForComponent(componentKey, pattern);
+      }
+    }
+  }
+
+  @Override
+  public boolean hasConfiguredPatterns() {
+    return hasFileContentPattern() || hasMulticriteriaPatterns();
+  }
+
+  @VisibleForTesting
+  protected final void loadFileContentPatterns() {
+    // Patterns Block
+    blockPatterns = Lists.newArrayList();
+    String patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY), "");
+    for (String id : StringUtils.split(patternConf, ',')) {
+      String propPrefix = IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + "." + id + ".";
+      String beginBlockRegexp = getSettings().getString(propPrefix + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP);
+      String endBlockRegexp = getSettings().getString(propPrefix + IssueExclusionsConfiguration.END_BLOCK_REGEXP);
+      String[] fields = new String[] { beginBlockRegexp, endBlockRegexp };
+      PatternDecoder.checkDoubleRegexpLineConstraints(StringUtils.join(fields, ","), fields);
+      IssuePattern pattern = new IssuePattern().setBeginBlockRegexp(nullToEmpty(beginBlockRegexp)).setEndBlockRegexp(nullToEmpty(endBlockRegexp));
+      blockPatterns.add(pattern);
+    }
+
+    // Patterns All File
+    allFilePatterns = Lists.newArrayList();
+    patternConf = StringUtils.defaultIfBlank(getSettings().getString(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY), "");
+    for (String id : StringUtils.split(patternConf, ',')) {
+      String propPrefix = IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + "." + id + ".";
+      String allFileRegexp = getSettings().getString(propPrefix + IssueExclusionsConfiguration.FILE_REGEXP);
+      PatternDecoder.checkWholeFileRegexp(allFileRegexp);
+      IssuePattern pattern = new IssuePattern().setAllFileRegexp(nullToEmpty(allFileRegexp));
+      allFilePatterns.add(pattern);
+    }
+  }
+
+  public List<IssuePattern> getBlockPatterns() {
+    return blockPatterns;
+  }
+
+  public List<IssuePattern> getAllFilePatterns() {
+    return allFilePatterns;
+  }
+
+  public boolean hasFileContentPattern() {
+    return ! (blockPatterns.isEmpty() && allFilePatterns.isEmpty());
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializer.java
new file mode 100644 (file)
index 0000000..08f7cca
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+
+import com.google.common.collect.Maps;
+import org.sonar.api.config.Settings;
+
+import java.util.Map;
+
+public class IssueInclusionPatternInitializer extends AbstractPatternInitializer {
+
+  private Map<String, String> pathForComponent;
+
+  public IssueInclusionPatternInitializer(Settings settings) {
+    super(settings);
+    pathForComponent = Maps.newHashMap();
+  }
+
+  @Override
+  protected String getMulticriteriaConfigurationKey() {
+    return IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY;
+  }
+
+  @Override
+  public void initializePatternsForPath(String relativePath, String componentKey) {
+    pathForComponent.put(componentKey, relativePath);
+  }
+
+  public String getPathForComponent(String componentKey) {
+    return pathForComponent.get(componentKey);
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssuePattern.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/IssuePattern.java
new file mode 100644 (file)
index 0000000..294afb6
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import com.google.common.collect.Sets;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.WildcardPattern;
+
+import java.util.Set;
+
+public class IssuePattern {
+
+  private WildcardPattern resourcePattern;
+  private WildcardPattern rulePattern;
+  private Set<Integer> lines = Sets.newLinkedHashSet();
+  private Set<LineRange> lineRanges = Sets.newLinkedHashSet();
+  private String beginBlockRegexp;
+  private String endBlockRegexp;
+  private String allFileRegexp;
+  private boolean checkLines = true;
+
+  public IssuePattern() {
+  }
+
+  public IssuePattern(String resourcePattern, String rulePattern) {
+    this.resourcePattern = WildcardPattern.create(resourcePattern);
+    this.rulePattern = WildcardPattern.create(rulePattern);
+  }
+
+  public IssuePattern(String resourcePattern, String rulePattern, Set<LineRange> lineRanges) {
+    this(resourcePattern, rulePattern);
+    this.lineRanges = lineRanges;
+  }
+
+  public WildcardPattern getResourcePattern() {
+    return resourcePattern;
+  }
+
+  public WildcardPattern getRulePattern() {
+    return rulePattern;
+  }
+
+  public String getBeginBlockRegexp() {
+    return beginBlockRegexp;
+  }
+
+  public String getEndBlockRegexp() {
+    return endBlockRegexp;
+  }
+
+  public String getAllFileRegexp() {
+    return allFileRegexp;
+  }
+
+  IssuePattern addLineRange(int fromLineId, int toLineId) {
+    lineRanges.add(new LineRange(fromLineId, toLineId));
+    return this;
+  }
+
+  IssuePattern addLine(int lineId) {
+    lines.add(lineId);
+    return this;
+  }
+
+  boolean isCheckLines() {
+    return checkLines;
+  }
+
+  IssuePattern setCheckLines(boolean b) {
+    this.checkLines = b;
+    return this;
+  }
+
+  IssuePattern setBeginBlockRegexp(String beginBlockRegexp) {
+    this.beginBlockRegexp = beginBlockRegexp;
+    return this;
+  }
+
+  IssuePattern setEndBlockRegexp(String endBlockRegexp) {
+    this.endBlockRegexp = endBlockRegexp;
+    return this;
+  }
+
+  IssuePattern setAllFileRegexp(String allFileRegexp) {
+    this.allFileRegexp = allFileRegexp;
+    return this;
+  }
+
+  Set<Integer> getAllLines() {
+    Set<Integer> allLines = Sets.newLinkedHashSet(lines);
+    for (LineRange lineRange : lineRanges) {
+      allLines.addAll(lineRange.toLines());
+    }
+    return allLines;
+  }
+
+  public boolean match(Issue issue) {
+    boolean match = matchResource(issue.componentKey())
+      && matchRule(issue.ruleKey());
+    if (checkLines) {
+      Integer line = issue.line();
+      if (line == null) {
+        match = false;
+      } else {
+        match = match && matchLine(line);
+      }
+    }
+    return match;
+  }
+
+  boolean matchLine(int lineId) {
+    if (lines.contains(lineId)) {
+      return true;
+    }
+
+    for (LineRange range : lineRanges) {
+      if (range.in(lineId)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  boolean matchRule(RuleKey rule) {
+    if (rule == null) {
+      return false;
+    }
+
+    String key = new StringBuilder().append(rule.repository()).append(':').append(rule.rule()).toString();
+    return rulePattern.match(key);
+  }
+
+  boolean matchResource(String resource) {
+    return resource != null && resourcePattern.match(resource);
+  }
+
+  public IssuePattern forResource(String resource) {
+    return new IssuePattern(resource, rulePattern.toString(), lineRanges).setCheckLines(isCheckLines());
+  }
+
+  @Override
+  public String toString() {
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/LineRange.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/LineRange.java
new file mode 100644 (file)
index 0000000..89433b8
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+public class LineRange {
+  private int from;
+  private int to;
+
+  public LineRange(int from, int to) {
+    Preconditions.checkArgument(from <= to, "Line range is not valid: %s must be greater than %s", from, to);
+
+    this.from = from;
+    this.to = to;
+  }
+
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+  @Override
+  public String toString() {
+    return "[" + from + "-" + to + "]";
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + from;
+    result = prime * result + to;
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    if (fieldsDiffer((LineRange) obj)) {
+      return false;
+    }
+    return true;
+  }
+
+  private boolean fieldsDiffer(LineRange other) {
+    if (from != other.from) {
+      return true;
+    }
+    if (to != other.to) {
+      return true;
+    }
+    return false;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/PatternDecoder.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/PatternDecoder.java
new file mode 100644 (file)
index 0000000..59f02ed
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.utils.SonarException;
+
+import java.util.List;
+
+public class PatternDecoder {
+
+  private static final int THREE_FIELDS_PER_LINE = 3;
+  private static final String LINE_RANGE_REGEXP = "\\[((\\d+|\\d+-\\d+),?)*\\]";
+  private static final String CONFIG_FORMAT_ERROR_PREFIX = "Exclusions > Issues : Invalid format. ";
+
+  public List<IssuePattern> decode(String patternsList) {
+    List<IssuePattern> patterns = Lists.newLinkedList();
+    String[] patternsLines = StringUtils.split(patternsList, "\n");
+    for (String patternLine : patternsLines) {
+      IssuePattern pattern = decodeLine(patternLine.trim());
+      if (pattern != null) {
+        patterns.add(pattern);
+      }
+    }
+    return patterns;
+  }
+
+  /**
+   * Main method that decodes a line which defines a pattern
+   */
+  public IssuePattern decodeLine(String line) {
+    if (isBlankOrComment(line)) {
+      return null;
+    }
+
+    String[] fields = StringUtils.splitPreserveAllTokens(line, ';');
+    if (fields.length > THREE_FIELDS_PER_LINE) {
+      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The following line has more than 3 fields separated by comma: " + line);
+    }
+
+    IssuePattern pattern;
+    if (fields.length == THREE_FIELDS_PER_LINE) {
+      checkRegularLineConstraints(line, fields);
+      pattern = new IssuePattern(StringUtils.trim(fields[0]), StringUtils.trim(fields[1]));
+      decodeRangeOfLines(pattern, fields[2]);
+    } else if (fields.length == 2) {
+      checkDoubleRegexpLineConstraints(line, fields);
+      pattern = new IssuePattern().setBeginBlockRegexp(fields[0]).setEndBlockRegexp(fields[1]);
+    } else {
+      checkWholeFileRegexp(fields[0]);
+      pattern = new IssuePattern().setAllFileRegexp(fields[0]);
+    }
+
+    return pattern;
+  }
+
+  static void checkRegularLineConstraints(String line, String[] fields) {
+    if (!isResource(fields[0])) {
+      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a resource pattern: " + line);
+    }
+    if (!isRule(fields[1])) {
+      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The second field does not define a rule pattern: " + line);
+    }
+    if (!isLinesRange(fields[2])) {
+      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The third field does not define a range of lines: " + line);
+    }
+  }
+
+  static void checkDoubleRegexpLineConstraints(String line, String[] fields) {
+    if (!isRegexp(fields[0])) {
+      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The first field does not define a regular expression: " + line);
+    }
+    // As per configuration help, missing second field means: from start regexp to EOF
+  }
+
+  static void checkWholeFileRegexp(String regexp) {
+    if (!isRegexp(regexp)) {
+      throw new SonarException(CONFIG_FORMAT_ERROR_PREFIX + "The field does not define a regular expression: " + regexp);
+    }
+  }
+
+  public static void decodeRangeOfLines(IssuePattern pattern, String field) {
+    if (StringUtils.equals(field, "*")) {
+      pattern.setCheckLines(false);
+    } else {
+      pattern.setCheckLines(true);
+      String s = StringUtils.substringBetween(StringUtils.trim(field), "[", "]");
+      String[] parts = StringUtils.split(s, ',');
+      for (String part : parts) {
+        if (StringUtils.contains(part, '-')) {
+          String[] range = StringUtils.split(part, '-');
+          pattern.addLineRange(Integer.valueOf(range[0]), Integer.valueOf(range[1]));
+        } else {
+          pattern.addLine(Integer.valueOf(part));
+        }
+      }
+    }
+  }
+
+  @VisibleForTesting
+  static boolean isLinesRange(String field) {
+    return StringUtils.equals(field, "*") || java.util.regex.Pattern.matches(LINE_RANGE_REGEXP, field);
+  }
+
+  @VisibleForTesting
+  static boolean isBlankOrComment(String line) {
+    return StringUtils.isBlank(line) ^ StringUtils.startsWith(line, "#");
+  }
+
+  @VisibleForTesting
+  static boolean isResource(String field) {
+    return StringUtils.isNotBlank(field);
+  }
+
+  @VisibleForTesting
+  static boolean isRule(String field) {
+    return StringUtils.isNotBlank(field);
+  }
+
+  @VisibleForTesting
+  static boolean isRegexp(String field) {
+    return StringUtils.isNotBlank(field);
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/PatternMatcher.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/PatternMatcher.java
new file mode 100644 (file)
index 0000000..5de14be
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.issue.ignore.pattern;
+
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import org.sonar.api.issue.Issue;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+public class PatternMatcher {
+
+  private Multimap<String, IssuePattern> patternByComponent = LinkedHashMultimap.create();
+
+  public IssuePattern getMatchingPattern(Issue issue) {
+    IssuePattern matchingPattern = null;
+    Iterator<IssuePattern> patternIterator = getPatternsForComponent(issue.componentKey()).iterator();
+    while(matchingPattern == null && patternIterator.hasNext()) {
+      IssuePattern nextPattern = patternIterator.next();
+      if (nextPattern.match(issue)) {
+        matchingPattern = nextPattern;
+      }
+    }
+    return matchingPattern;
+  }
+
+  public Collection<IssuePattern> getPatternsForComponent(String componentKey) {
+    return patternByComponent.get(componentKey);
+  }
+
+  public void addPatternForComponent(String component, IssuePattern pattern) {
+    patternByComponent.put(component, pattern.forResource(component));
+  }
+
+  public void addPatternToExcludeResource(String resource) {
+    addPatternForComponent(resource, new IssuePattern(resource, "*").setCheckLines(false));
+  }
+
+  public void addPatternToExcludeLines(String resource, Set<LineRange> lineRanges) {
+    addPatternForComponent(resource, new IssuePattern(resource, "*", lineRanges).setCheckLines(true));
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/pattern/package-info.java
new file mode 100644 (file)
index 0000000..d8d4906
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.issue.ignore.pattern;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java
new file mode 100644 (file)
index 0000000..fbe6142
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.scanner;
+
+import org.sonar.api.resources.Project;
+import org.sonar.api.scan.filesystem.FileQuery;
+import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+
+import java.nio.charset.Charset;
+
+public final class IssueExclusionsLoader {
+
+  private final IssueExclusionsRegexpScanner regexpScanner;
+  private final IssueExclusionPatternInitializer exclusionPatternInitializer;
+  private final IssueInclusionPatternInitializer inclusionPatternInitializer;
+  private final DefaultModuleFileSystem fileSystem;
+
+  public IssueExclusionsLoader(IssueExclusionsRegexpScanner regexpScanner, IssueExclusionPatternInitializer exclusionPatternInitializer,
+    IssueInclusionPatternInitializer inclusionPatternInitializer,
+    DefaultModuleFileSystem fileSystem) {
+    this.regexpScanner = regexpScanner;
+    this.exclusionPatternInitializer = exclusionPatternInitializer;
+    this.inclusionPatternInitializer = inclusionPatternInitializer;
+    this.fileSystem = fileSystem;
+  }
+
+  public boolean shouldExecuteOnProject(Project project) {
+    return inclusionPatternInitializer.hasConfiguredPatterns()
+      || exclusionPatternInitializer.hasConfiguredPatterns();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void execute() {
+    Charset sourcesEncoding = fileSystem.sourceCharset();
+
+    for (InputFile inputFile : fileSystem.inputFiles(FileQuery.all())) {
+      try {
+        String componentEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+        if (componentEffectiveKey != null) {
+          String path = inputFile.path();
+          inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
+          exclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
+          if (exclusionPatternInitializer.hasFileContentPattern()) {
+            regexpScanner.scan(componentEffectiveKey, inputFile.file(), sourcesEncoding);
+          }
+        }
+      } catch (Exception e) {
+        throw new SonarException("Unable to read the source file : '" + inputFile.absolutePath() + "' with the charset : '"
+          + sourcesEncoding.name() + "'.", e);
+      }
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "Issues Exclusions - Source Scanner";
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScanner.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScanner.java
new file mode 100644 (file)
index 0000000..3ddbbaf
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.scanner;
+
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+import org.sonar.batch.issue.ignore.pattern.LineRange;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchExtension;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Set;
+
+public class IssueExclusionsRegexpScanner implements BatchExtension {
+
+  private static final Logger LOG = LoggerFactory.getLogger(IssueExclusionsRegexpScanner.class);
+
+  private IssueExclusionPatternInitializer exclusionPatternInitializer;
+  private List<java.util.regex.Pattern> allFilePatterns;
+  private List<DoubleRegexpMatcher> blockMatchers;
+
+  // fields to be reset at every new scan
+  private DoubleRegexpMatcher currentMatcher;
+  private int fileLength;
+  private List<LineExclusion> lineExclusions;
+  private LineExclusion currentLineExclusion;
+
+  public IssueExclusionsRegexpScanner(IssueExclusionPatternInitializer patternsInitializer) {
+    this.exclusionPatternInitializer = patternsInitializer;
+
+    lineExclusions = Lists.newArrayList();
+    allFilePatterns = Lists.newArrayList();
+    blockMatchers = Lists.newArrayList();
+
+    for (IssuePattern pattern : patternsInitializer.getAllFilePatterns()) {
+      allFilePatterns.add(java.util.regex.Pattern.compile(pattern.getAllFileRegexp()));
+    }
+    for (IssuePattern pattern : patternsInitializer.getBlockPatterns()) {
+      blockMatchers.add(new DoubleRegexpMatcher(
+          java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()),
+          java.util.regex.Pattern.compile(pattern.getEndBlockRegexp())));
+    }
+
+    init();
+  }
+
+  private void init() {
+    currentMatcher = null;
+    fileLength = 0;
+    lineExclusions.clear();
+    currentLineExclusion = null;
+  }
+
+  public void scan(String resource, File file, Charset sourcesEncoding) throws IOException {
+    LOG.debug("Scanning {}", resource);
+    init();
+
+    List<String> lines = FileUtils.readLines(file, sourcesEncoding.name());
+    int lineIndex = 0;
+    for (String line : lines) {
+      lineIndex++;
+      if (line.trim().length() == 0) {
+        continue;
+      }
+
+      // first check the single regexp patterns that can be used to totally exclude a file
+      for (java.util.regex.Pattern pattern : allFilePatterns) {
+        if (pattern.matcher(line).find()) {
+          exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeResource(resource);
+          // nothing more to do on this file
+          LOG.debug("- Exclusion pattern '{}': every violation in this file will be ignored.", pattern);
+          return;
+        }
+      }
+
+      // then check the double regexps if we're still here
+      checkDoubleRegexps(line, lineIndex);
+    }
+
+    if (currentMatcher != null && !currentMatcher.hasSecondPattern()) {
+      // this will happen when there is a start block regexp but no end block regexp
+      endExclusion(lineIndex + 1);
+    }
+
+    // now create the new line-based pattern for this file if there are exclusions
+    fileLength = lineIndex;
+    if (!lineExclusions.isEmpty()) {
+      Set<LineRange> lineRanges = convertLineExclusionsToLineRanges();
+      LOG.debug("- Line exclusions found: {}", lineRanges);
+      exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeLines(resource, lineRanges);
+    }
+  }
+
+  private Set<LineRange> convertLineExclusionsToLineRanges() {
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    for (LineExclusion lineExclusion : lineExclusions) {
+      lineRanges.add(lineExclusion.toLineRange());
+    }
+    return lineRanges;
+  }
+
+  private void checkDoubleRegexps(String line, int lineIndex) {
+    if (currentMatcher == null) {
+      for (DoubleRegexpMatcher matcher : blockMatchers) {
+        if (matcher.matchesFirstPattern(line)) {
+          startExclusion(lineIndex);
+          currentMatcher = matcher;
+          break;
+        }
+      }
+    } else {
+      if (currentMatcher.matchesSecondPattern(line)) {
+        endExclusion(lineIndex);
+        currentMatcher = null;
+      }
+    }
+  }
+
+  private void startExclusion(int lineIndex) {
+    currentLineExclusion = new LineExclusion(lineIndex);
+    lineExclusions.add(currentLineExclusion);
+  }
+
+  private void endExclusion(int lineIndex) {
+    currentLineExclusion.setEnd(lineIndex);
+    currentLineExclusion = null;
+  }
+
+  private class LineExclusion {
+
+    private int start;
+    private int end;
+
+    LineExclusion(int start) {
+      this.start = start;
+      this.end = -1;
+    }
+
+    void setEnd(int end) {
+      this.end = end;
+    }
+
+    public LineRange toLineRange() {
+      return new LineRange(start, end == -1 ? fileLength : end);
+    }
+
+  }
+
+  private static class DoubleRegexpMatcher {
+
+    private java.util.regex.Pattern firstPattern;
+    private java.util.regex.Pattern secondPattern;
+
+    DoubleRegexpMatcher(java.util.regex.Pattern firstPattern, java.util.regex.Pattern secondPattern) {
+      this.firstPattern = firstPattern;
+      this.secondPattern = secondPattern;
+    }
+
+    boolean matchesFirstPattern(String line) {
+      return firstPattern.matcher(line).find();
+    }
+
+    boolean matchesSecondPattern(String line) {
+      return hasSecondPattern() && secondPattern.matcher(line).find();
+    }
+
+    boolean hasSecondPattern() {
+      return StringUtils.isNotEmpty(secondPattern.toString());
+    }
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/package-info.java
new file mode 100644 (file)
index 0000000..89e3708
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.issue.ignore.scanner;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index 8cc3ee7cee9852606354bd63858e3b29bacf404a..2043d7ee452685ad02369f6756dcf38fac77a672 100644 (file)
@@ -29,6 +29,7 @@ import org.sonar.batch.events.EventBus;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.batch.index.PersistenceManager;
 import org.sonar.batch.index.ScanPersister;
+import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
 import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
 import org.sonar.batch.scan.filesystem.FileSystemLogger;
 import org.sonar.batch.scan.maven.MavenPhaseExecutor;
@@ -65,13 +66,15 @@ public final class PhaseExecutor {
   private final JsonReport jsonReport;
   private final DefaultModuleFileSystem fs;
   private final ProfileLogger profileLogger;
+  private final IssueExclusionsLoader issueExclusionsLoader;
 
   public PhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
     MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
     PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
     PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
     EventBus eventBus, UpdateStatusJob updateStatusJob, ProjectInitializer pi,
-    ScanPersister[] persisters, FileSystemLogger fsLogger, JsonReport jsonReport, DefaultModuleFileSystem fs, ProfileLogger profileLogger) {
+    ScanPersister[] persisters, FileSystemLogger fsLogger, JsonReport jsonReport, DefaultModuleFileSystem fs, ProfileLogger profileLogger,
+    IssueExclusionsLoader issueExclusionsLoader) {
     this.phases = phases;
     this.decoratorsExecutor = decoratorsExecutor;
     this.mavenPhaseExecutor = mavenPhaseExecutor;
@@ -90,15 +93,17 @@ public final class PhaseExecutor {
     this.jsonReport = jsonReport;
     this.fs = fs;
     this.profileLogger = profileLogger;
+    this.issueExclusionsLoader = issueExclusionsLoader;
   }
 
   public PhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
     MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
     PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
     PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
-    EventBus eventBus, ProjectInitializer pi, ScanPersister[] persisters, FileSystemLogger fsLogger, JsonReport jsonReport, DefaultModuleFileSystem fs, ProfileLogger profileLogger) {
+    EventBus eventBus, ProjectInitializer pi, ScanPersister[] persisters, FileSystemLogger fsLogger, JsonReport jsonReport,
+    DefaultModuleFileSystem fs, ProfileLogger profileLogger, IssueExclusionsLoader issueExclusionsLoader) {
     this(phases, decoratorsExecutor, mavenPhaseExecutor, mavenPluginsConfigurator, initializersExecutor, postJobsExecutor,
-      sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, persisters, fsLogger, jsonReport, fs, profileLogger);
+      sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, persisters, fsLogger, jsonReport, fs, profileLogger, issueExclusionsLoader);
   }
 
   /**
@@ -122,6 +127,9 @@ public final class PhaseExecutor {
       // Log detected languages and their profiles after FS is indexed and languages detected
       profileLogger.execute();
 
+      // Initialize issue exclusions
+      issueExclusionsLoader.execute();
+
       sensorsExecutor.execute(sensorContext);
     }
 
index fbb5c6b94655c12fc16166c8209fa4526c691408..17c4182d137bed09d0fb34daa48329e401603d6f 100644 (file)
  */
 package org.sonar.batch.scan;
 
+import org.sonar.batch.issue.ignore.EnforceIssuesFilter;
+import org.sonar.batch.issue.ignore.IgnoreIssuesFilter;
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
+import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchExtension;
@@ -148,6 +155,14 @@ public class ModuleScanContainer extends ComponentContainer {
       IssuableFactory.class,
       ModuleIssues.class,
 
+      // issue exclusions
+      IssueInclusionPatternInitializer.class,
+      IssueExclusionPatternInitializer.class,
+      IssueExclusionsRegexpScanner.class,
+      IssueExclusionsLoader.class,
+      EnforceIssuesFilter.class,
+      IgnoreIssuesFilter.class,
+
       ScanPerspectives.class);
   }
 
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/EnforceIssuesFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/EnforceIssuesFilterTest.java
new file mode 100644 (file)
index 0000000..9c17310
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore;
+
+import org.sonar.batch.issue.ignore.EnforceIssuesFilter;
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.batch.IssueFilterChain;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.WildcardPattern;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class EnforceIssuesFilterTest {
+
+  private IssueInclusionPatternInitializer exclusionPatternInitializer;
+  private EnforceIssuesFilter ignoreFilter;
+  private Issue issue;
+  private IssueFilterChain chain;
+
+  @Before
+  public void init() {
+    exclusionPatternInitializer = mock(IssueInclusionPatternInitializer.class);
+    issue = mock(Issue.class);
+    chain = mock(IssueFilterChain.class);
+    when(chain.accept(issue)).thenReturn(true);
+
+    ignoreFilter = new EnforceIssuesFilter(exclusionPatternInitializer);
+  }
+
+  @Test
+  public void shouldPassToChainIfNoConfiguredPatterns() {
+    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
+    verify(chain).accept(issue);
+  }
+
+  @Test
+  public void shouldPassToChainIfRuleDoesNotMatch() {
+    String rule = "rule";
+    RuleKey ruleKey = mock(RuleKey.class);
+    when(ruleKey.toString()).thenReturn(rule);
+    when(issue.ruleKey()).thenReturn(ruleKey);
+
+    IssuePattern matching = mock(IssuePattern.class);
+    WildcardPattern rulePattern = mock(WildcardPattern.class);
+    when(matching.getRulePattern()).thenReturn(rulePattern);
+    when(rulePattern.match(rule)).thenReturn(false);
+    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
+
+    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
+    verify(chain).accept(issue);
+  }
+
+  @Test
+  public void shouldAcceptIssueIfFullyMatched() {
+    String rule = "rule";
+    String path = "org/sonar/api/Issue.java";
+    String componentKey = "org.sonar.api.Issue";
+    RuleKey ruleKey = mock(RuleKey.class);
+    when(ruleKey.toString()).thenReturn(rule);
+    when(issue.ruleKey()).thenReturn(ruleKey);
+    when(issue.componentKey()).thenReturn(componentKey);
+
+    IssuePattern matching = mock(IssuePattern.class);
+    WildcardPattern rulePattern = mock(WildcardPattern.class);
+    when(matching.getRulePattern()).thenReturn(rulePattern);
+    when(rulePattern.match(rule)).thenReturn(true);
+    WildcardPattern pathPattern = mock(WildcardPattern.class);
+    when(matching.getResourcePattern()).thenReturn(pathPattern);
+    when(pathPattern.match(path)).thenReturn(true);
+    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
+    when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path);
+
+    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
+    verifyZeroInteractions(chain);
+  }
+
+  @Test
+  public void shouldRefuseIssueIfRuleMatchesButNotPath() {
+    String rule = "rule";
+    String path = "org/sonar/api/Issue.java";
+    String componentKey = "org.sonar.api.Issue";
+    RuleKey ruleKey = mock(RuleKey.class);
+    when(ruleKey.toString()).thenReturn(rule);
+    when(issue.ruleKey()).thenReturn(ruleKey);
+    when(issue.componentKey()).thenReturn(componentKey);
+
+    IssuePattern matching = mock(IssuePattern.class);
+    WildcardPattern rulePattern = mock(WildcardPattern.class);
+    when(matching.getRulePattern()).thenReturn(rulePattern);
+    when(rulePattern.match(rule)).thenReturn(true);
+    WildcardPattern pathPattern = mock(WildcardPattern.class);
+    when(matching.getResourcePattern()).thenReturn(pathPattern);
+    when(pathPattern.match(path)).thenReturn(false);
+    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
+    when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path);
+
+    assertThat(ignoreFilter.accept(issue, chain)).isFalse();
+    verifyZeroInteractions(chain);
+  }
+
+  @Test
+  public void shouldRefuseIssueIfRuleMatchesAndPathUnknown() {
+    String rule = "rule";
+    String path = "org/sonar/api/Issue.java";
+    String componentKey = "org.sonar.api.Issue";
+    RuleKey ruleKey = mock(RuleKey.class);
+    when(ruleKey.toString()).thenReturn(rule);
+    when(issue.ruleKey()).thenReturn(ruleKey);
+    when(issue.componentKey()).thenReturn(componentKey);
+
+    IssuePattern matching = mock(IssuePattern.class);
+    WildcardPattern rulePattern = mock(WildcardPattern.class);
+    when(matching.getRulePattern()).thenReturn(rulePattern);
+    when(rulePattern.match(rule)).thenReturn(true);
+    WildcardPattern pathPattern = mock(WildcardPattern.class);
+    when(matching.getResourcePattern()).thenReturn(pathPattern);
+    when(pathPattern.match(path)).thenReturn(false);
+    when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching));
+    when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(null);
+
+    assertThat(ignoreFilter.accept(issue, chain)).isFalse();
+    verifyZeroInteractions(chain);
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilterTest.java
new file mode 100644 (file)
index 0000000..2dae552
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore;
+
+import org.sonar.batch.issue.ignore.IgnoreIssuesFilter;
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.batch.IssueFilterChain;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class IgnoreIssuesFilterTest {
+
+  private IssueExclusionPatternInitializer exclusionPatternInitializer;
+  private PatternMatcher exclusionPatternMatcher;
+  private IgnoreIssuesFilter ignoreFilter;
+  private Issue issue;
+  private IssueFilterChain chain;
+
+  @Before
+  public void init() {
+    exclusionPatternMatcher = mock(PatternMatcher.class);
+    exclusionPatternInitializer = mock(IssueExclusionPatternInitializer.class);
+    when(exclusionPatternInitializer.getPatternMatcher()).thenReturn(exclusionPatternMatcher);
+    issue = mock(Issue.class);
+    chain = mock(IssueFilterChain.class);
+    when(chain.accept(issue)).thenReturn(true);
+
+    ignoreFilter = new IgnoreIssuesFilter(exclusionPatternInitializer);
+  }
+
+  @Test
+  public void shouldPassToChainIfMatcherHasNoPatternForIssue() {
+    when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(null);
+
+    assertThat(ignoreFilter.accept(issue, chain)).isTrue();
+  }
+
+  @Test
+  public void shouldAcceptOrRefuseIfMatcherHasPatternForIssue() {
+    when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(mock(IssuePattern.class));
+
+    assertThat(ignoreFilter.accept(issue, chain)).isFalse();
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java
new file mode 100644 (file)
index 0000000..ef93bd8
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore;
+
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+
+import org.junit.Test;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssueExclusionsConfigurationTest {
+  @Test
+  public void justForCoverage() {
+    assertThat(IssueExclusionsConfiguration.getPropertyDefinitions()).hasSize(4);
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
new file mode 100644 (file)
index 0000000..fb769ec
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.SonarException;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssueExclusionPatternInitializerTest {
+
+  private IssueExclusionPatternInitializer patternsInitializer;
+
+  private Settings settings;
+
+  @Before
+  public void init() {
+    settings = new Settings(new PropertyDefinitions(IssueExclusionsConfiguration.getPropertyDefinitions()));
+    patternsInitializer = new IssueExclusionPatternInitializer(settings);
+  }
+
+  @Test
+  public void testNoConfiguration() {
+    patternsInitializer.initPatterns();
+    assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse();
+    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
+  }
+
+  @Test
+  public void shouldHavePatternsBasedOnMulticriteriaPattern() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1,2");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Bar.java");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Hello.java");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RULE_KEY, "checkstyle:MagicNumber");
+    patternsInitializer.initPatterns();
+
+    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
+    assertThat(patternsInitializer.hasFileContentPattern()).isFalse();
+    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue();
+    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2);
+    assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0);
+    assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0);
+
+    patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar");
+    patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz");
+    patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello");
+
+    assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Bar")).hasSize(1);
+    assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Baz")).hasSize(0);
+    assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Hello")).hasSize(1);
+
+  }
+
+  @Test(expected = SonarException.class)
+  public void shouldLogInvalidResourceKey() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*");
+    patternsInitializer.initPatterns();
+  }
+
+  @Test(expected = SonarException.class)
+  public void shouldLogInvalidRuleKey() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "*");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "");
+    patternsInitializer.initPatterns();
+  }
+
+  @Test
+  public void shouldReturnBlockPattern() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY, "1,2,3");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// SONAR-OFF");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// SONAR-ON");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// FOO-OFF");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// FOO-ON");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// IGNORE-TO-EOF");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "");
+    patternsInitializer.loadFileContentPatterns();
+
+    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
+    assertThat(patternsInitializer.hasFileContentPattern()).isTrue();
+    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isFalse();
+    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
+    assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(3);
+    assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0);
+  }
+
+  @Test(expected = SonarException.class)
+  public void shouldLogInvalidStartBlockPattern() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY, "1");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// SONAR-ON");
+    patternsInitializer.loadFileContentPatterns();
+  }
+
+  @Test
+  public void shouldReturnAllFilePattern() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY, "1,2");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionsConfiguration.FILE_REGEXP, "@SONAR-IGNORE-ALL");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".2." + IssueExclusionsConfiguration.FILE_REGEXP, "//FOO-IGNORE-ALL");
+    patternsInitializer.loadFileContentPatterns();
+
+    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
+    assertThat(patternsInitializer.hasFileContentPattern()).isTrue();
+    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isFalse();
+    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0);
+    assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0);
+    assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(2);
+  }
+
+  @Test(expected = SonarException.class)
+  public void shouldLogInvalidAllFilePattern() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY, "1");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionsConfiguration.FILE_REGEXP, "");
+    patternsInitializer.loadFileContentPatterns();
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
new file mode 100644 (file)
index 0000000..5954251
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration;
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssueInclusionPatternInitializerTest {
+
+  private IssueInclusionPatternInitializer patternsInitializer;
+
+  private Settings settings;
+
+  @Before
+  public void init() {
+    settings = new Settings(new PropertyDefinitions(IssueExclusionsConfiguration.getPropertyDefinitions()));
+    patternsInitializer = new IssueInclusionPatternInitializer(settings);
+  }
+
+  @Test
+  public void testNoConfiguration() {
+    patternsInitializer.initPatterns();
+    assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse();
+  }
+
+  @Test
+  public void shouldHavePatternsBasedOnMulticriteriaPattern() {
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY, "1,2");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Bar.java");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Hello.java");
+    settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RULE_KEY, "checkstyle:MagicNumber");
+    patternsInitializer.initPatterns();
+
+    assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue();
+    assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue();
+    assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2);
+
+    patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar");
+    patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz");
+    patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello");
+
+    assertThat(patternsInitializer.getPathForComponent("org.foo.Bar")).isEqualTo("org/foo/Bar.java");
+    assertThat(patternsInitializer.getPathForComponent("org.foo.Baz")).isEqualTo("org/foo/Baz.java");
+    assertThat(patternsInitializer.getPathForComponent("org.foo.Hello")).isEqualTo("org/foo/Hello.java");
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssuePatternTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssuePatternTest.java
new file mode 100644 (file)
index 0000000..3c9d43d
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+
+import org.junit.Test;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class IssuePatternTest {
+
+  @Test
+  public void shouldMatchLines() {
+    IssuePattern pattern = new IssuePattern("*", "*");
+    pattern.addLine(12).addLine(15).addLineRange(20, 25);
+
+    assertThat(pattern.matchLine(3)).isFalse();
+    assertThat(pattern.matchLine(12)).isTrue();
+    assertThat(pattern.matchLine(14)).isFalse();
+    assertThat(pattern.matchLine(21)).isTrue();
+    assertThat(pattern.matchLine(6599)).isFalse();
+  }
+
+  @Test
+  public void shouldMatchJavaFile() {
+    String javaFile = "org.foo.Bar";
+    assertThat(new IssuePattern("org.foo.Bar", "*").matchResource(javaFile)).isTrue();
+    assertThat(new IssuePattern("org.foo.*", "*").matchResource(javaFile)).isTrue();
+    assertThat(new IssuePattern("*Bar", "*").matchResource(javaFile)).isTrue();
+    assertThat(new IssuePattern("*", "*").matchResource(javaFile)).isTrue();
+    assertThat(new IssuePattern("org.*.?ar", "*").matchResource(javaFile)).isTrue();
+
+    assertThat(new IssuePattern("org.other.Hello", "*").matchResource(javaFile)).isFalse();
+    assertThat(new IssuePattern("org.foo.Hello", "*").matchResource(javaFile)).isFalse();
+    assertThat(new IssuePattern("org.*.??ar", "*").matchResource(javaFile)).isFalse();
+    assertThat(new IssuePattern("org.*.??ar", "*").matchResource(null)).isFalse();
+    assertThat(new IssuePattern("org.*.??ar", "*").matchResource("plop")).isFalse();
+  }
+
+  @Test
+  public void shouldMatchRule() {
+    RuleKey rule = Rule.create("checkstyle", "IllegalRegexp", "").ruleKey();
+    assertThat(new IssuePattern("*", "*").matchRule(rule)).isTrue();
+    assertThat(new IssuePattern("*", "checkstyle:*").matchRule(rule)).isTrue();
+    assertThat(new IssuePattern("*", "checkstyle:IllegalRegexp").matchRule(rule)).isTrue();
+    assertThat(new IssuePattern("*", "checkstyle:Illegal*").matchRule(rule)).isTrue();
+    assertThat(new IssuePattern("*", "*:*Illegal*").matchRule(rule)).isTrue();
+
+    assertThat(new IssuePattern("*", "pmd:IllegalRegexp").matchRule(rule)).isFalse();
+    assertThat(new IssuePattern("*", "pmd:*").matchRule(rule)).isFalse();
+    assertThat(new IssuePattern("*", "*:Foo*IllegalRegexp").matchRule(rule)).isFalse();
+  }
+
+  @Test
+  public void shouldMatchViolation() {
+    Rule rule = Rule.create("checkstyle", "IllegalRegexp", "");
+    String javaFile = "org.foo.Bar";
+
+    IssuePattern pattern = new IssuePattern("*", "*");
+    pattern.addLine(12);
+
+    assertThat(pattern.match(create(rule, javaFile, null))).isFalse();
+    assertThat(pattern.match(create(rule, javaFile, 12))).isTrue();
+    assertThat(pattern.match(create((Rule) null, javaFile, 5))).isFalse();
+    assertThat(pattern.match(create(rule, null, null))).isFalse();
+    assertThat(pattern.match(create((Rule) null, null, null))).isFalse();
+  }
+
+  private Issue create(Rule rule, String component, Integer line) {
+    Issue mockIssue = mock(Issue.class);
+    RuleKey ruleKey = null;
+    if (rule != null) {
+      ruleKey = rule.ruleKey();
+    }
+    when(mockIssue.ruleKey()).thenReturn(ruleKey);
+    when(mockIssue.componentKey()).thenReturn(component);
+    when(mockIssue.line()).thenReturn(line);
+    return mockIssue;
+  }
+
+  @Test
+  public void shouldNotMatchNullRule() {
+    assertThat(new IssuePattern("*", "*").matchRule(null)).isFalse();
+  }
+
+  @Test
+  public void shouldPrintPatternToString() {
+    IssuePattern pattern = new IssuePattern("*", "checkstyle:*");
+
+    assertThat(pattern.toString()).isEqualTo("IssuePattern[resourcePattern=*,rulePattern=checkstyle:*,lines=[],lineRanges=[],beginBlockRegexp=<null>,endBlockRegexp=<null>,allFileRegexp=<null>,checkLines=true]");
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/LineRangeTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/LineRangeTest.java
new file mode 100644 (file)
index 0000000..21df72b
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.pattern.LineRange;
+
+import org.junit.Test;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class LineRangeTest {
+
+  @Test(expected = IllegalArgumentException.class)
+  public void lineRangeShouldBeOrdered() {
+    new LineRange(25, 12);
+  }
+
+  @Test
+  public void shouldConvertLineRangeToLines() {
+    LineRange range = new LineRange(12, 15);
+
+    assertThat(range.toLines()).containsOnly(12, 13, 14, 15);
+  }
+
+  @Test
+  public void shouldTestInclusionInRangeOfLines() {
+    LineRange range = new LineRange(12, 15);
+
+    assertThat(range.in(3)).isFalse();
+    assertThat(range.in(12)).isTrue();
+    assertThat(range.in(13)).isTrue();
+    assertThat(range.in(14)).isTrue();
+    assertThat(range.in(15)).isTrue();
+    assertThat(range.in(16)).isFalse();
+  }
+
+  @Test
+  public void testToString() throws Exception {
+    assertThat(new LineRange(12, 15).toString()).isEqualTo("[12-15]");
+  }
+
+  @Test
+  public void testEquals() throws Exception {
+    LineRange range = new LineRange(12, 15);
+    assertThat(range).isEqualTo(range);
+    assertThat(range).isEqualTo(new LineRange(12, 15));
+    assertThat(range).isNotEqualTo(new LineRange(12, 2000));
+    assertThat(range).isNotEqualTo(new LineRange(1000, 2000));
+    assertThat(range).isNotEqualTo(null);
+    assertThat(range).isNotEqualTo(new StringBuffer());
+  }
+
+  @Test
+  public void testHashCode() throws Exception {
+    assertThat(new LineRange(12, 15).hashCode()).isEqualTo(new LineRange(12, 15).hashCode());
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternDecoderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternDecoderTest.java
new file mode 100644 (file)
index 0000000..b993e82
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+import org.sonar.batch.issue.ignore.pattern.PatternDecoder;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.SonarException;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PatternDecoderTest {
+
+  private PatternDecoder decoder = new PatternDecoder();
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void shouldReadString() {
+    String patternsList = "# a comment followed by a blank line\n\n" +
+      "# suppress all violations\n" +
+      "*;*;*\n\n" +
+      "# exclude a Java file\n" +
+      "com.foo.Bar;*;*\n\n" +
+      "# exclude a Java package\n" +
+      "com.foo.*;*;*\n\n" +
+      "# exclude a specific rule\n" +
+      "*;checkstyle:IllegalRegexp;*\n\n" +
+      "# exclude a specific rule on a specific file\n" +
+      "com.foo.Bar;checkstyle:IllegalRegexp;*\n";
+    List<IssuePattern> patterns = decoder.decode(patternsList);
+
+    assertThat(patterns).hasSize(5);
+  }
+
+  @Test
+  public void shouldCheckFormatOfResource() {
+    assertThat(PatternDecoder.isResource("")).isFalse();
+    assertThat(PatternDecoder.isResource("*")).isTrue();
+    assertThat(PatternDecoder.isResource("com.foo.*")).isTrue();
+  }
+
+  @Test
+  public void shouldCheckFormatOfRule() {
+    assertThat(PatternDecoder.isRule("")).isFalse();
+    assertThat(PatternDecoder.isRule("*")).isTrue();
+    assertThat(PatternDecoder.isRule("com.foo.*")).isTrue();
+  }
+
+  @Test
+  public void shouldCheckFormatOfLinesRange() {
+    assertThat(PatternDecoder.isLinesRange("")).isFalse();
+    assertThat(PatternDecoder.isLinesRange("   ")).isFalse();
+    assertThat(PatternDecoder.isLinesRange("12")).isFalse();
+    assertThat(PatternDecoder.isLinesRange("12,212")).isFalse();
+
+    assertThat(PatternDecoder.isLinesRange("*")).isTrue();
+    assertThat(PatternDecoder.isLinesRange("[]")).isTrue();
+    assertThat(PatternDecoder.isLinesRange("[13]")).isTrue();
+    assertThat(PatternDecoder.isLinesRange("[13,24]")).isTrue();
+    assertThat(PatternDecoder.isLinesRange("[13,24,25-500]")).isTrue();
+    assertThat(PatternDecoder.isLinesRange("[24-65]")).isTrue();
+    assertThat(PatternDecoder.isLinesRange("[13,24-65,84-89,122]")).isTrue();
+  }
+
+  @Test
+  public void shouldReadStarPatterns() {
+    IssuePattern pattern = decoder.decodeLine("*;*;*");
+
+    assertThat(pattern.getResourcePattern().toString()).isEqualTo("*");
+    assertThat(pattern.getRulePattern().toString()).isEqualTo("*");
+    assertThat(pattern.isCheckLines()).isFalse();
+  }
+
+  @Test
+  public void shouldReadLineIds() {
+    IssuePattern pattern = decoder.decodeLine("*;*;[10,25,98]");
+
+    assertThat(pattern.isCheckLines()).isTrue();
+    assertThat(pattern.getAllLines()).containsOnly(10, 25, 98);
+  }
+
+  @Test
+  public void shouldReadRangeOfLineIds() {
+    IssuePattern pattern = decoder.decodeLine("*;*;[10-12,25,97-100]");
+
+    assertThat(pattern.isCheckLines()).isTrue();
+    assertThat(pattern.getAllLines()).containsOnly(10, 11, 12, 25, 97, 98, 99, 100);
+  }
+
+  @Test
+  public void shouldNotExcludeLines() {
+    // [] is different than *
+    // - all violations are excluded on *
+    // * no violations are excluded on []
+    IssuePattern pattern = decoder.decodeLine("*;*;[]");
+
+    assertThat(pattern.isCheckLines()).isTrue();
+    assertThat(pattern.getAllLines()).isEmpty();
+  }
+
+  @Test
+  public void shouldReadBlockPattern() {
+    IssuePattern pattern = decoder.decodeLine("SONAR-OFF;SONAR-ON");
+
+    assertThat(pattern.getResourcePattern()).isNull();
+    assertThat(pattern.getBeginBlockRegexp()).isEqualTo("SONAR-OFF");
+    assertThat(pattern.getEndBlockRegexp()).isEqualTo("SONAR-ON");
+  }
+
+  @Test
+  public void shouldReadAllFilePattern() {
+    IssuePattern pattern = decoder.decodeLine("SONAR-ALL-OFF");
+
+    assertThat(pattern.getResourcePattern()).isNull();
+    assertThat(pattern.getAllFileRegexp()).isEqualTo("SONAR-ALL-OFF");
+  }
+
+  @Test
+  public void shouldFailToReadUncorrectLine1() {
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Exclusions > Issues : Invalid format. The following line has more than 3 fields separated by comma");
+
+    decoder.decode(";;;;");
+  }
+
+  @Test
+  public void shouldFailToReadUncorrectLine3() {
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a resource pattern");
+
+    decoder.decode(";*;*");
+  }
+
+  @Test
+  public void shouldFailToReadUncorrectLine4() {
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Exclusions > Issues : Invalid format. The second field does not define a rule pattern");
+
+    decoder.decode("*;;*");
+  }
+
+  @Test
+  public void shouldFailToReadUncorrectLine5() {
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Exclusions > Issues : Invalid format. The third field does not define a range of lines");
+
+    decoder.decode("*;*;blabla");
+  }
+
+  @Test
+  public void shouldFailToReadUncorrectLine6() {
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a regular expression");
+
+    decoder.decode(";ON");
+  }
+
+  @Test
+  public void shouldAcceptEmptyEndBlockRegexp() {
+    IssuePattern pattern = decoder.decodeLine("OFF;");
+
+    assertThat(pattern.getResourcePattern()).isNull();
+    assertThat(pattern.getBeginBlockRegexp()).isEqualTo("OFF");
+    assertThat(pattern.getEndBlockRegexp()).isEmpty();
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternMatcherTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternMatcherTest.java
new file mode 100644 (file)
index 0000000..a948aac
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.issue.ignore.pattern;
+
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+import org.sonar.batch.issue.ignore.pattern.LineRange;
+import org.sonar.batch.issue.ignore.pattern.PatternDecoder;
+import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+
+import java.io.IOException;
+import java.util.Set;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PatternMatcherTest {
+
+  public static final Rule CHECKSTYLE_RULE = Rule.create("checkstyle", "MagicNumber", "");
+  public static final String JAVA_FILE = "org.foo.Hello";
+
+  private PatternMatcher patternMatcher;
+
+  @Before
+  public void setUp() {
+    patternMatcher = new PatternMatcher();
+  }
+
+  @Test
+  public void shouldReturnExtraPatternForResource() {
+    String file = "foo";
+    patternMatcher.addPatternToExcludeResource(file);
+
+    IssuePattern extraPattern = patternMatcher.getPatternsForComponent(file).iterator().next();
+    assertThat(extraPattern.matchResource(file)).isTrue();
+    assertThat(extraPattern.isCheckLines()).isFalse();
+  }
+
+  @Test
+  public void shouldReturnExtraPatternForLinesOfResource() {
+    String file = "foo";
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    lineRanges.add(new LineRange(25, 28));
+    patternMatcher.addPatternToExcludeLines(file, lineRanges);
+
+    IssuePattern extraPattern = patternMatcher.getPatternsForComponent(file).iterator().next();
+    assertThat(extraPattern.matchResource(file)).isTrue();
+    assertThat(extraPattern.getAllLines()).isEqualTo(Sets.newHashSet(25, 26, 27, 28));
+  }
+
+  @Test
+  public void shouldHaveNoMatcherIfNoneDefined() {
+    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, null))).isNull();
+  }
+
+  @Test
+  public void shouldMatchWithStandardPatterns() throws IOException {
+    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+
+    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
+  }
+
+  @Test
+  public void shouldNotMatchWithStandardPatterns() throws IOException {
+    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+
+    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
+  }
+
+  @Test
+  public void shouldMatchWithExtraPattern() throws IOException {
+    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
+
+    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
+  }
+
+  @Test
+  public void shouldNotMatchWithExtraPattern() throws IOException {
+    patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
+
+    assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
+  }
+
+  private Issue create(Rule rule, String component, Integer line) {
+    Issue mockIssue = mock(Issue.class);
+    RuleKey ruleKey = null;
+    if (rule != null) {
+      ruleKey = rule.ruleKey();
+    }
+    when(mockIssue.ruleKey()).thenReturn(ruleKey);
+    when(mockIssue.componentKey()).thenReturn(component);
+    when(mockIssue.line()).thenReturn(line);
+    return mockIssue;
+  }
+
+  private IssuePattern createPattern(String line) {
+    return new PatternDecoder().decode(line).get(0);
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java
new file mode 100644 (file)
index 0000000..8f8eba5
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.scanner;
+
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
+import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
+import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
+
+import com.google.common.base.Charsets;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.sonar.api.scan.filesystem.FileQuery;
+import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class IssueExclusionsLoaderTest {
+
+  private IssueExclusionsLoader scanner;
+
+  @Mock
+  private IssueExclusionsRegexpScanner regexpScanner;
+  @Mock
+  private IssueInclusionPatternInitializer inclusionPatternInitializer;
+  @Mock
+  private IssueExclusionPatternInitializer exclusionPatternInitializer;
+  @Mock
+  private PatternMatcher patternMatcher;
+  @Mock
+  private DefaultModuleFileSystem fs;
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  private File baseDir;
+
+  @Before
+  public void init() throws IOException {
+    baseDir = temp.newFolder();
+    MockitoAnnotations.initMocks(this);
+
+    when(fs.sourceCharset()).thenReturn(UTF_8);
+
+    scanner = new IssueExclusionsLoader(regexpScanner, exclusionPatternInitializer, inclusionPatternInitializer, fs);
+  }
+
+  @Test
+  public void testToString() throws Exception {
+    assertThat(scanner.toString()).isEqualTo("Issues Exclusions - Source Scanner");
+  }
+
+  @Test
+  public void shouldExecute() throws IOException {
+    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
+    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
+    assertThat(scanner.shouldExecuteOnProject(null)).isTrue();
+
+    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
+    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
+    assertThat(scanner.shouldExecuteOnProject(null)).isTrue();
+
+    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
+    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true);
+    assertThat(scanner.shouldExecuteOnProject(null)).isTrue();
+
+    when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
+    when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false);
+    assertThat(scanner.shouldExecuteOnProject(null)).isFalse();
+
+  }
+
+  @Test
+  public void shouldAnalyseProject() throws IOException {
+    File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
+    File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java")
+        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java")
+        .build(),
+      new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java")
+        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java")
+        .build()));
+
+    when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
+
+    scanner.execute();
+
+    verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
+    verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
+    verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
+    verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
+    verify(regexpScanner).scan("polop:src/main/java/Foo.java", javaFile1, UTF_8);
+    verify(regexpScanner).scan("polop:src/test/java/FooTest.java", javaTestFile1, UTF_8);
+  }
+
+  @Test
+  public void shouldAnalyseFilesOnlyWhenRegexConfigured() throws IOException {
+    File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
+    File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java")
+        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java")
+        .build(),
+      new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java")
+        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java")
+        .build()));
+
+    when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false);
+
+    scanner.execute();
+
+    verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
+    verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
+    verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java");
+    verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java");
+    verifyZeroInteractions(regexpScanner);
+  }
+
+  @Test
+  public void shouldReportFailure() throws IOException {
+    File phpFile1 = new File(baseDir, "src/Foo.php");
+    when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
+      new InputFileBuilder(phpFile1, Charsets.UTF_8, "src/Foo.php")
+        .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/Foo.php")
+        .build()));
+
+    when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
+    doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8);
+
+    thrown.expect(SonarException.class);
+    thrown.expectMessage("Unable to read the source file");
+
+    scanner.execute();
+  }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
new file mode 100644 (file)
index 0000000..d50c377
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.issue.ignore.scanner;
+
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssuePattern;
+import org.sonar.batch.issue.ignore.pattern.LineRange;
+import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
+import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.sonar.test.TestUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Set;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class IssueExclusionsRegexpScannerTest {
+
+  private IssueExclusionsRegexpScanner regexpScanner;
+
+  private String javaFile;
+  @Mock
+  private IssueExclusionPatternInitializer patternsInitializer;
+  @Mock
+  private PatternMatcher patternMatcher;
+  @Mock
+  private IssuePattern allFilePattern;
+  @Mock
+  private IssuePattern blockPattern1;
+  @Mock
+  private IssuePattern blockPattern2;
+
+  @Before
+  public void init() {
+    MockitoAnnotations.initMocks(this);
+
+    when(allFilePattern.getAllFileRegexp()).thenReturn("@SONAR-IGNORE-ALL");
+    when(blockPattern1.getBeginBlockRegexp()).thenReturn("// SONAR-OFF");
+    when(blockPattern1.getEndBlockRegexp()).thenReturn("// SONAR-ON");
+    when(blockPattern2.getBeginBlockRegexp()).thenReturn("// FOO-OFF");
+    when(blockPattern2.getEndBlockRegexp()).thenReturn("// FOO-ON");
+    when(patternsInitializer.getAllFilePatterns()).thenReturn(Arrays.asList(allFilePattern));
+    when(patternsInitializer.getBlockPatterns()).thenReturn(Arrays.asList(blockPattern1, blockPattern2));
+    when(patternsInitializer.getPatternMatcher()).thenReturn(patternMatcher);
+
+    regexpScanner = new IssueExclusionsRegexpScanner(patternsInitializer);
+    verify(patternsInitializer, times(1)).getAllFilePatterns();
+    verify(patternsInitializer, times(1)).getBlockPatterns();
+
+    javaFile = "org.sonar.test.MyFile";
+  }
+
+  @Test
+  public void shouldDoNothing() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-no-regexp.txt"), UTF_8);
+
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeFile() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp.txt"), UTF_8);
+
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeFileEvenIfAlsoDoubleRegexps() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp-and-double-regexp.txt"), UTF_8);
+
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeLines() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp.txt"), UTF_8);
+
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    lineRanges.add(new LineRange(21, 25));
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeLinesTillTheEnd() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-unfinished.txt"), UTF_8);
+
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    lineRanges.add(new LineRange(21, 34));
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeSeveralLineRanges() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-twice.txt"), UTF_8);
+
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    lineRanges.add(new LineRange(21, 25));
+    lineRanges.add(new LineRange(29, 33));
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeLinesWithWrongOrder() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-wrong-order.txt"), UTF_8);
+
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    lineRanges.add(new LineRange(25, 35));
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+  @Test
+  public void shouldAddPatternToExcludeLinesWithMess() throws IOException {
+    regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-mess.txt"), UTF_8);
+
+    Set<LineRange> lineRanges = Sets.newHashSet();
+    lineRanges.add(new LineRange(21, 29));
+    verify(patternsInitializer).getPatternMatcher();
+    verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+    verifyNoMoreInteractions(patternsInitializer);
+  }
+
+}
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-mess.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-mess.txt
new file mode 100644 (file)
index 0000000..48d30c9
--- /dev/null
@@ -0,0 +1,37 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * 
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  // SONAR-OFF
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+  // FOO-OFF
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    // SONAR-ON
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    // FOO-ON
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-twice.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-twice.txt
new file mode 100644 (file)
index 0000000..9ae63dc
--- /dev/null
@@ -0,0 +1,37 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * 
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  // SONAR-OFF
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+  // SONAR-ON
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    // FOO-OFF
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    // FOO-ON
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-unfinished.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-unfinished.txt
new file mode 100644 (file)
index 0000000..dd76561
--- /dev/null
@@ -0,0 +1,34 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * 
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  // SONAR-OFF
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-wrong-order.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp-wrong-order.txt
new file mode 100644 (file)
index 0000000..7cac0b9
--- /dev/null
@@ -0,0 +1,35 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * 
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  // SONAR-ON
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+  // SONAR-OFF
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-double-regexp.txt
new file mode 100644 (file)
index 0000000..002169f
--- /dev/null
@@ -0,0 +1,35 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * 
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  // SONAR-OFF
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+  // SONAR-ON
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-no-regexp.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-no-regexp.txt
new file mode 100644 (file)
index 0000000..f18fa5b
--- /dev/null
@@ -0,0 +1,33 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * 
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp-and-double-regexp.txt
new file mode 100644 (file)
index 0000000..e09ecd7
--- /dev/null
@@ -0,0 +1,36 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+  // SONAR-OFF
+
+import java.util.Set;
+
+/**
+ * @SONAR-IGNORE-ALL
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+  // SONAR-ON
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+}
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest/file-with-single-regexp.txt
new file mode 100644 (file)
index 0000000..ef135eb
--- /dev/null
@@ -0,0 +1,33 @@
+package org.sonar.plugins.switchoffviolations.pattern;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+/**
+ * @SONAR-IGNORE-ALL
+ */
+public class LineRange {
+  int from, to;
+
+  public LineRange(int from, int to) {
+    if (to < from) {
+      throw new IllegalArgumentException("Line range is not valid: " + from + " must be greater than " + to);
+    }
+    this.from = from;
+    this.to = to;
+  }
+
+  public boolean in(int lineId) {
+    return from <= lineId && lineId <= to;
+  }
+
+  public Set<Integer> toLines() {
+    Set<Integer> lines = Sets.newLinkedHashSet();
+    for (int index = from; index <= to; index++) {
+      lines.add(index);
+    }
+    return lines;
+  }
+
+}
\ No newline at end of file