]> source.dussan.org Git - sonarqube.git/commitdiff
Fix some quality flaws
authorJulien HENRY <julien.henry@sonarsource.com>
Mon, 1 Sep 2014 15:27:45 +0000 (17:27 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Mon, 1 Sep 2014 15:28:09 +0000 (17:28 +0200)
21 files changed:
plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java
plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java
plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java [deleted file]
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java
sonar-batch/src/main/java/org/sonar/batch/duplication/DefaultTokenBuilder.java
sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationGroupValueCoder.java
sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java
sonar-batch/src/main/java/org/sonar/batch/scan/measure/DeprecatedMetricFinder.java
sonar-batch/src/main/java/org/sonar/batch/scan2/CommonSensorContext.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
sonar-duplications/src/main/java/org/sonar/duplications/internal/pmd/PmdBlockChunker.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/DuplicationGroup.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueBuilder.java
sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java

index 887c886ac1e212834a6d68acce20f64ec82e0055..925ecb87638c08a9cc5b2979a8523168d6a4463d 100644 (file)
@@ -110,22 +110,7 @@ public class DefaultCpdEngine extends CpdEngine {
 
     // Create index
     SonarDuplicationsIndex index = indexFactory.create(project, languageKey);
-
-    TokenizerBridge bridge = null;
-    if (mapping != null) {
-      bridge = new TokenizerBridge(mapping.getTokenizer(), fs.encoding().name(), getBlockSize(languageKey));
-    }
-    for (InputFile inputFile : sourceFiles) {
-      LOG.debug("Populating index from {}", inputFile);
-      String resourceEffectiveKey = ((DeprecatedDefaultInputFile) inputFile).key();
-      FileBlocks fileBlocks = duplicationCache.byComponent(resourceEffectiveKey);
-      if (fileBlocks != null) {
-        index.insert(inputFile, fileBlocks.blocks());
-      } else if (bridge != null) {
-        List<Block> blocks2 = bridge.chunk(resourceEffectiveKey, inputFile.file());
-        index.insert(inputFile, blocks2);
-      }
-    }
+    populateIndex(languageKey, sourceFiles, mapping, index);
 
     // Detect
     Predicate<CloneGroup> minimumTokensPredicate = DuplicationPredicates.numberOfUnitsNotLessThan(getMinimumTokens(languageKey));
@@ -157,6 +142,24 @@ public class DefaultCpdEngine extends CpdEngine {
     }
   }
 
+  private void populateIndex(String languageKey, List<InputFile> sourceFiles, CpdMapping mapping, SonarDuplicationsIndex index) {
+    TokenizerBridge bridge = null;
+    if (mapping != null) {
+      bridge = new TokenizerBridge(mapping.getTokenizer(), fs.encoding().name(), getBlockSize(languageKey));
+    }
+    for (InputFile inputFile : sourceFiles) {
+      LOG.debug("Populating index from {}", inputFile);
+      String resourceEffectiveKey = ((DeprecatedDefaultInputFile) inputFile).key();
+      FileBlocks fileBlocks = duplicationCache.byComponent(resourceEffectiveKey);
+      if (fileBlocks != null) {
+        index.insert(inputFile, fileBlocks.blocks());
+      } else if (bridge != null) {
+        List<Block> blocks2 = bridge.chunk(resourceEffectiveKey, inputFile.file());
+        index.insert(inputFile, blocks2);
+      }
+    }
+  }
+
   @VisibleForTesting
   int getBlockSize(String languageKey) {
     int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
index 43585d4db4fe3dd37ca7721b0bddbdf19ec9c4db..a5770634444170fd9249829603a468c7c2ae2748 100644 (file)
@@ -198,20 +198,8 @@ public class JavaCpdEngine extends CpdEngine {
     if (duplications == null || Iterables.isEmpty(duplications)) {
       return;
     }
-    // Calculate number of lines and blocks
     Set<Integer> duplicatedLines = new HashSet<Integer>();
-    int duplicatedBlocks = 0;
-    for (CloneGroup clone : duplications) {
-      ClonePart origin = clone.getOriginPart();
-      for (ClonePart part : clone.getCloneParts()) {
-        if (part.getResourceId().equals(origin.getResourceId())) {
-          duplicatedBlocks++;
-          for (int duplicatedLine = part.getStartLine(); duplicatedLine < part.getStartLine() + part.getLines(); duplicatedLine++) {
-            duplicatedLines.add(duplicatedLine);
-          }
-        }
-      }
-    }
+    int duplicatedBlocks = computeBlockAndLineCount(duplications, duplicatedLines);
     FileLinesContext linesContext = contextFactory.createFor(inputFile);
     for (int i = 1; i <= inputFile.lines(); i++) {
       linesContext.setIntValue(CoreMetrics.DUPLICATION_LINES_DATA_KEY, i, duplicatedLines.contains(i) ? 1 : 0);
@@ -246,4 +234,20 @@ public class JavaCpdEngine extends CpdEngine {
     context.saveDuplications(inputFile, builder.build());
   }
 
+  private static int computeBlockAndLineCount(Iterable<CloneGroup> duplications, Set<Integer> duplicatedLines) {
+    int duplicatedBlocks = 0;
+    for (CloneGroup clone : duplications) {
+      ClonePart origin = clone.getOriginPart();
+      for (ClonePart part : clone.getCloneParts()) {
+        if (part.getResourceId().equals(origin.getResourceId())) {
+          duplicatedBlocks++;
+          for (int duplicatedLine = part.getStartLine(); duplicatedLine < part.getStartLine() + part.getLines(); duplicatedLine++) {
+            duplicatedLines.add(duplicatedLine);
+          }
+        }
+      }
+    }
+    return duplicatedBlocks;
+  }
+
 }
index 6d5a7f1201d5a776ea0918dc2141c9ac44ea61fe..9830f4b1dd085ad09831c15a975a5ba989642b75 100644 (file)
@@ -64,7 +64,7 @@ public class IndexFactory implements BatchComponent {
   }
 
   @VisibleForTesting
-  boolean verifyCrossProject(Project project, Logger logger) {
+  boolean verifyCrossProject(@Nullable Project project, Logger logger) {
     boolean crossProject = false;
 
     if (settings.getBoolean(CoreProperties.CPD_CROSS_PROJECT)) {
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooConstants.java
deleted file mode 100644 (file)
index 62f7d2b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.xoo;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public interface XooConstants {
-
-  String PLUGIN_KEY = "xoo";
-  String PLUGIN_NAME = "Xoo";
-
-  String REPOSITORY_KEY = PLUGIN_KEY;
-  String REPOSITORY_NAME = PLUGIN_NAME;
-
-  String[] FILE_SUFFIXES = {"xoo"};
-
-  Logger LOG = LoggerFactory.getLogger("xoo");
-}
index bc796808f1902e94c0ed6d2fa84da3b642824925..4ce85626d157182cb2a0557aaa6bfbe4da5f1899 100644 (file)
@@ -21,6 +21,8 @@ package org.sonar.xoo.lang;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.Sensor;
@@ -30,7 +32,6 @@ import org.sonar.api.batch.sensor.measure.Measure;
 import org.sonar.api.batch.sensor.measure.MeasureBuilder;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.xoo.Xoo;
-import org.sonar.xoo.XooConstants;
 
 import java.io.File;
 import java.io.IOException;
@@ -42,6 +43,8 @@ import java.util.List;
  */
 public class MeasureSensor implements Sensor {
 
+  private static final Logger LOG = LoggerFactory.getLogger(MeasureSensor.class);
+
   private static final String MEASURES_EXTENSION = ".measures";
 
   private MetricFinder metricFinder;
@@ -54,7 +57,7 @@ public class MeasureSensor implements Sensor {
     File ioFile = inputFile.file();
     File measureFile = new File(ioFile.getParentFile(), ioFile.getName() + MEASURES_EXTENSION);
     if (measureFile.exists()) {
-      XooConstants.LOG.debug("Processing " + measureFile.getAbsolutePath());
+      LOG.debug("Processing " + measureFile.getAbsolutePath());
       try {
         List<String> lines = FileUtils.readLines(measureFile, context.fileSystem().encoding().name());
         int lineNumber = 0;
@@ -81,7 +84,7 @@ public class MeasureSensor implements Sensor {
     }
   }
 
-  private Measure<?> createMeasure(SensorContext context, InputFile xooFile, String metricKey, String value) {
+  private Measure createMeasure(SensorContext context, InputFile xooFile, String metricKey, String value) {
     org.sonar.api.batch.measure.Metric<Serializable> metric = metricFinder.findByKey(metricKey);
     if (metric == null) {
       throw new IllegalStateException("Unknow metric with key: " + metricKey);
index 628ce6ece704f68930b9db5128b1fc07e36cbb49..c8232484a510304810eefa3b6968b7e5e633c974 100644 (file)
@@ -22,6 +22,8 @@ package org.sonar.xoo.lang;
 import com.google.common.base.Splitter;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.sensor.Sensor;
 import org.sonar.api.batch.sensor.SensorContext;
@@ -30,7 +32,6 @@ import org.sonar.api.batch.sensor.symbol.Symbol;
 import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.xoo.Xoo;
-import org.sonar.xoo.XooConstants;
 
 import java.io.File;
 import java.io.IOException;
@@ -42,41 +43,44 @@ import java.util.List;
  */
 public class SymbolReferencesSensor implements Sensor {
 
+  private static final Logger LOG = LoggerFactory.getLogger(SymbolReferencesSensor.class);
+
   private static final String SYMBOL_EXTENSION = ".symbol";
 
   private void processFileSymbol(InputFile inputFile, SensorContext context) {
     File ioFile = inputFile.file();
     File symbolFile = new File(ioFile.getParentFile(), ioFile.getName() + SYMBOL_EXTENSION);
     if (symbolFile.exists()) {
-      XooConstants.LOG.debug("Processing " + symbolFile.getAbsolutePath());
+      LOG.debug("Processing " + symbolFile.getAbsolutePath());
       try {
         List<String> lines = FileUtils.readLines(symbolFile, context.fileSystem().encoding().name());
         int lineNumber = 0;
         SymbolTableBuilder symbolTableBuilder = context.symbolTableBuilder(inputFile);
         for (String line : lines) {
           lineNumber++;
-          if (StringUtils.isBlank(line)) {
-            continue;
-          }
-          if (line.startsWith("#")) {
+          if (StringUtils.isBlank(line) || line.startsWith("#")) {
             continue;
           }
-          try {
-            Iterator<String> split = Splitter.on(",").split(line).iterator();
-            int startOffset = Integer.parseInt(split.next());
-            int endOffset = Integer.parseInt(split.next());
-            Symbol s = symbolTableBuilder.newSymbol(startOffset, endOffset);
-            while (split.hasNext()) {
-              symbolTableBuilder.newReference(s, Integer.parseInt(split.next()));
-            }
-          } catch (Exception e) {
-            throw new IllegalStateException("Error processing line " + lineNumber + " of file " + symbolFile.getAbsolutePath(), e);
-          }
+          processLine(symbolFile, lineNumber, symbolTableBuilder, line);
         }
         symbolTableBuilder.done();
       } catch (IOException e) {
-        throw new RuntimeException(e);
+        throw new IllegalStateException(e);
+      }
+    }
+  }
+
+  private void processLine(File symbolFile, int lineNumber, SymbolTableBuilder symbolTableBuilder, String line) {
+    try {
+      Iterator<String> split = Splitter.on(",").split(line).iterator();
+      int startOffset = Integer.parseInt(split.next());
+      int endOffset = Integer.parseInt(split.next());
+      Symbol s = symbolTableBuilder.newSymbol(startOffset, endOffset);
+      while (split.hasNext()) {
+        symbolTableBuilder.newReference(s, Integer.parseInt(split.next()));
       }
+    } catch (Exception e) {
+      throw new IllegalStateException("Error processing line " + lineNumber + " of file " + symbolFile.getAbsolutePath(), e);
     }
   }
 
index ca2f6b5e0ace2c042346c0c1ba311404900024b0..c9c9b8864061014c908b2aab327c71dc76d42ff3 100644 (file)
  */
 package org.sonar.xoo.lang;
 
-import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-
 import com.google.common.base.Splitter;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.sensor.Sensor;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.SensorDescriptor;
 import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.xoo.Xoo;
-import org.sonar.xoo.XooConstants;
 
 import java.io.File;
 import java.io.IOException;
@@ -43,42 +43,45 @@ import java.util.List;
  */
 public class SyntaxHighlightingSensor implements Sensor {
 
+  private static final Logger LOG = LoggerFactory.getLogger(SyntaxHighlightingSensor.class);
+
   private static final String HIGHLIGHTING_EXTENSION = ".highlighting";
 
   private void processFileHighlighting(InputFile inputFile, SensorContext context) {
     File ioFile = inputFile.file();
     File highlightingFile = new File(ioFile.getParentFile(), ioFile.getName() + HIGHLIGHTING_EXTENSION);
     if (highlightingFile.exists()) {
-      XooConstants.LOG.debug("Processing " + highlightingFile.getAbsolutePath());
+      LOG.debug("Processing " + highlightingFile.getAbsolutePath());
       try {
         List<String> lines = FileUtils.readLines(highlightingFile, context.fileSystem().encoding().name());
         int lineNumber = 0;
         HighlightingBuilder highlightingBuilder = context.highlightingBuilder(inputFile);
         for (String line : lines) {
           lineNumber++;
-          if (StringUtils.isBlank(line)) {
-            continue;
-          }
-          if (line.startsWith("#")) {
+          if (StringUtils.isBlank(line) || line.startsWith("#")) {
             continue;
           }
-          try {
-            Iterator<String> split = Splitter.on(":").split(line).iterator();
-            int startOffset = Integer.parseInt(split.next());
-            int endOffset = Integer.parseInt(split.next());
-            TypeOfText type = TypeOfText.forCssClass(split.next());
-            highlightingBuilder.highlight(startOffset, endOffset, type);
-          } catch (Exception e) {
-            throw new IllegalStateException("Error processing line " + lineNumber + " of file " + highlightingFile.getAbsolutePath(), e);
-          }
+          processLine(highlightingFile, lineNumber, highlightingBuilder, line);
         }
         highlightingBuilder.done();
       } catch (IOException e) {
-        throw new RuntimeException(e);
+        throw new IllegalStateException(e);
       }
     }
   }
 
+  private void processLine(File highlightingFile, int lineNumber, HighlightingBuilder highlightingBuilder, String line) {
+    try {
+      Iterator<String> split = Splitter.on(":").split(line).iterator();
+      int startOffset = Integer.parseInt(split.next());
+      int endOffset = Integer.parseInt(split.next());
+      TypeOfText type = TypeOfText.forCssClass(split.next());
+      highlightingBuilder.highlight(startOffset, endOffset, type);
+    } catch (Exception e) {
+      throw new IllegalStateException("Error processing line " + lineNumber + " of file " + highlightingFile.getAbsolutePath(), e);
+    }
+  }
+
   @Override
   public void describe(SensorDescriptor descriptor) {
     descriptor
index c3e7d2641e6df8a02da0ced69a92e5d15a5dc482..041bdd94efd6795027263d8db024c12db11b7fa7 100644 (file)
@@ -25,7 +25,6 @@ import org.sonar.api.batch.sensor.Sensor;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.SensorDescriptor;
 import org.sonar.xoo.Xoo;
-import org.sonar.xoo.XooConstants;
 
 public class CreateIssueByInternalKeySensor implements Sensor {
 
@@ -36,7 +35,7 @@ public class CreateIssueByInternalKeySensor implements Sensor {
     descriptor
       .name("CreateIssueByInternalKeySensor")
       .workOnLanguages(Xoo.KEY)
-      .createIssuesForRuleRepositories(XooConstants.REPOSITORY_KEY)
+      .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY)
       .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
   }
 
@@ -48,7 +47,7 @@ public class CreateIssueByInternalKeySensor implements Sensor {
   }
 
   private void createIssues(InputFile file, SensorContext context) {
-    ActiveRule rule = context.activeRules().findByInternalKey(XooConstants.REPOSITORY_KEY,
+    ActiveRule rule = context.activeRules().findByInternalKey(XooRulesDefinition.XOO_REPOSITORY,
       context.settings().getString(INTERNAL_KEY_PROPERTY));
     if (rule != null) {
       context.addIssue(context.issueBuilder()
index c247883097534a8f592e8005836fb0b1d879ed15..6763d0308c8ba462cd03955a0a96ef5904ea69aa 100644 (file)
@@ -26,7 +26,6 @@ import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.SensorDescriptor;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.xoo.Xoo;
-import org.sonar.xoo.XooConstants;
 
 public class OneIssueOnDirPerFileSensor implements Sensor {
 
@@ -37,7 +36,7 @@ public class OneIssueOnDirPerFileSensor implements Sensor {
     descriptor
       .name("One Issue On Dir Per File")
       .workOnLanguages(Xoo.KEY)
-      .createIssuesForRuleRepositories(XooConstants.REPOSITORY_KEY)
+      .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY)
       .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
   }
 
@@ -49,7 +48,7 @@ public class OneIssueOnDirPerFileSensor implements Sensor {
   }
 
   private void createIssues(InputFile file, SensorContext context) {
-    RuleKey ruleKey = RuleKey.of(XooConstants.REPOSITORY_KEY, RULE_KEY);
+    RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY);
     InputDir inputDir = context.fileSystem().inputDir(file.file().getParentFile());
     if (inputDir != null) {
       context.addIssue(context.issueBuilder()
index bc0697b64b4ddef407e707656a8718bc57111775..e65efa437188b22c2b596b25111f182f1b3d1f45 100644 (file)
@@ -29,7 +29,6 @@ import org.sonar.api.batch.sensor.measure.Measure;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.xoo.Xoo;
-import org.sonar.xoo.XooConstants;
 
 public class OneIssuePerLineSensor implements Sensor {
 
@@ -43,7 +42,7 @@ public class OneIssuePerLineSensor implements Sensor {
       .name("One Issue Per Line")
       .dependsOn(CoreMetrics.LINES)
       .workOnLanguages(Xoo.KEY)
-      .createIssuesForRuleRepositories(XooConstants.REPOSITORY_KEY)
+      .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY)
       .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
   }
 
@@ -55,7 +54,7 @@ public class OneIssuePerLineSensor implements Sensor {
   }
 
   private void createIssues(InputFile file, SensorContext context) {
-    RuleKey ruleKey = RuleKey.of(XooConstants.REPOSITORY_KEY, RULE_KEY);
+    RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY);
     Measure<Integer> linesMeasure = context.getMeasure(file, CoreMetrics.LINES);
     if (linesMeasure == null) {
       LoggerFactory.getLogger(getClass()).warn("Missing measure " + CoreMetrics.LINES_KEY + " on " + file);
index c05fe0e09768760c720c3289bbf7ad86b3ceff9a..0f37cefcb425eecd45c9dea396321f285fee6df0 100644 (file)
@@ -42,13 +42,13 @@ public class XooRulesDefinition implements RulesDefinition {
       .setName("No empty line")
       .setMarkdownDescription("Generate an issue on *empty* lines of Xoo source files")
 
-        // optional tags
+      // optional tags
       .setTags("style", "security")
 
-        // optional status. Default value is READY.
+      // optional status. Default value is READY.
       .setStatus(RuleStatus.BETA)
 
-        // default severity when the rule is activated on a Quality profile. Default value is MAJOR.
+      // default severity when the rule is activated on a Quality profile. Default value is MAJOR.
       .setSeverity(Severity.MINOR);
 
     // debt-related information
index b4af69174404a03b8bd0bf795d7915b6be478ac7..6add53318759463a072e6e6e879382eaf25d5a35 100644 (file)
@@ -21,8 +21,6 @@ package org.sonar.batch.duplication;
 
 import com.google.common.base.Preconditions;
 import net.sourceforge.pmd.cpd.TokenEntry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
@@ -37,8 +35,6 @@ import java.util.List;
 
 public class DefaultTokenBuilder implements DuplicationTokenBuilder {
 
-  private static final Logger LOG = LoggerFactory.getLogger(DefaultTokenBuilder.class);
-
   private final BlockCache cache;
   private final InputFile inputFile;
   private final List<TokenEntry> tokens = new ArrayList<TokenEntry>();
@@ -69,7 +65,7 @@ public class DefaultTokenBuilder implements DuplicationTokenBuilder {
     tokens.add(TokenEntry.getEOF());
     TokenEntry.clearImages();
     List<TokensLine> tokensLines = TokenizerBridge.convert(tokens);
-    ArrayList<Block> blocks = blockChunker.chunk(((DefaultInputFile) inputFile).key(), tokensLines);
+    List<Block> blocks = blockChunker.chunk(((DefaultInputFile) inputFile).key(), tokensLines);
 
     cache.put(((DefaultInputFile) inputFile).key(), new FileBlocks(((DefaultInputFile) inputFile).key(), blocks));
     tokens.clear();
index 5b6ed6d840159330a33167984f3db965dcad6a11..f53dfb4a569ffddc33bb293793559725ef902be4 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
 import org.sonar.api.batch.sensor.duplication.DuplicationGroup.Block;
 
 import java.util.ArrayList;
+import java.util.List;
 
 class DuplicationGroupValueCoder implements ValueCoder {
 
@@ -45,7 +46,7 @@ class DuplicationGroupValueCoder implements ValueCoder {
   public Object get(Value value, Class clazz, CoderContext context) {
     DuplicationGroup g = new DuplicationGroup((Block) blockCoder.get(value, DuplicationGroup.Block.class, context));
     int count = value.getInt();
-    ArrayList<DuplicationGroup.Block> blocks = new ArrayList<DuplicationGroup.Block>(count);
+    List<DuplicationGroup.Block> blocks = new ArrayList<DuplicationGroup.Block>(count);
     for (int i = 0; i < count; i++) {
       blocks.add((Block) blockCoder.get(value, DuplicationGroup.Block.class, context));
     }
index 1cf87b1d6d3e488039856615c05a3ef024bc1636..6a117d7ec6a64b91b0723a720efc944aefcf9926 100644 (file)
  */
 package org.sonar.batch.scan;
 
-import com.google.common.base.Preconditions;
+import org.sonar.api.batch.Sensor;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputDir;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputPath;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.measure.Metric;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
-import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
-import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
 import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.IssueBuilder;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
 import org.sonar.api.batch.sensor.measure.Measure;
-import org.sonar.api.batch.sensor.measure.MeasureBuilder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
-import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
 import org.sonar.api.component.ResourcePerspectives;
 import org.sonar.api.config.Settings;
 import org.sonar.api.issue.Issuable;
@@ -55,66 +44,32 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.duplication.BlockCache;
-import org.sonar.batch.duplication.DefaultTokenBuilder;
 import org.sonar.batch.duplication.DuplicationCache;
-import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
 import org.sonar.batch.index.ComponentDataCache;
-import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
-import org.sonar.duplications.internal.pmd.PmdBlockChunker;
+import org.sonar.batch.scan2.CommonSensorContext;
 
 import java.io.Serializable;
-import java.util.List;
 
 /**
  * Implements {@link SensorContext} but forward everything to {@link org.sonar.api.batch.SensorContext} for backward compatibility.
+ * Will be dropped once old {@link Sensor} API is dropped.
  *
  */
-public class SensorContextAdaptor implements SensorContext {
+public class SensorContextAdaptor extends CommonSensorContext {
 
   private final org.sonar.api.batch.SensorContext sensorContext;
   private final MetricFinder metricFinder;
   private final Project project;
   private final ResourcePerspectives perspectives;
-  private final Settings settings;
-  private final FileSystem fs;
-  private final ActiveRules activeRules;
-  private final ComponentDataCache componentDataCache;
-  private final BlockCache blockCache;
-  private final DuplicationCache duplicationCache;
 
   public SensorContextAdaptor(org.sonar.api.batch.SensorContext sensorContext, MetricFinder metricFinder, Project project, ResourcePerspectives perspectives,
     Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, BlockCache blockCache,
     DuplicationCache duplicationCache) {
+    super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache);
     this.sensorContext = sensorContext;
     this.metricFinder = metricFinder;
     this.project = project;
     this.perspectives = perspectives;
-    this.settings = settings;
-    this.fs = fs;
-    this.activeRules = activeRules;
-    this.componentDataCache = componentDataCache;
-    this.blockCache = blockCache;
-    this.duplicationCache = duplicationCache;
-  }
-
-  @Override
-  public Settings settings() {
-    return settings;
-  }
-
-  @Override
-  public FileSystem fileSystem() {
-    return fs;
-  }
-
-  @Override
-  public ActiveRules activeRules() {
-    return activeRules;
-  }
-
-  @Override
-  public <G extends Serializable> MeasureBuilder<G> measureBuilder() {
-    return new DefaultMeasureBuilder<G>();
   }
 
   @Override
@@ -143,7 +98,7 @@ public class SensorContextAdaptor implements SensorContext {
     return getMeasure(file, m);
   }
 
-  private Metric<?> findMetricOrFail(String metricKey) {
+  private Metric findMetricOrFail(String metricKey) {
     Metric<?> m = metricFinder.findByKey(metricKey);
     if (m == null) {
       throw new IllegalStateException("Unknow metric with key: " + metricKey);
@@ -222,11 +177,6 @@ public class SensorContextAdaptor implements SensorContext {
     }
   }
 
-  @Override
-  public IssueBuilder issueBuilder() {
-    return new DefaultIssueBuilder();
-  }
-
   @Override
   public boolean addIssue(Issue issue) {
     Resource r;
@@ -259,53 +209,4 @@ public class SensorContextAdaptor implements SensorContext {
       .build();
   }
 
-  @Override
-  public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
-    return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
-  }
-
-  @Override
-  public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
-    return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
-  }
-
-  @Override
-  public DuplicationTokenBuilder duplicationTokenBuilder(InputFile inputFile) {
-    PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
-    return new DefaultTokenBuilder(inputFile, blockCache, blockChunker);
-  }
-
-  @Override
-  public DuplicationBuilder duplicationBuilder(InputFile inputFile) {
-    return new DefaultDuplicationBuilder(inputFile);
-  }
-
-  @Override
-  public void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications) {
-    Preconditions.checkState(duplications.size() > 0, "Empty duplications");
-    String effectiveKey = ((DefaultInputFile) inputFile).key();
-    for (DuplicationGroup duplicationGroup : duplications) {
-      Preconditions.checkState(effectiveKey.equals(duplicationGroup.originBlock().resourceKey()), "Invalid duplication group");
-    }
-    duplicationCache.put(effectiveKey, duplications);
-  }
-
-  private int getBlockSize(String languageKey) {
-    int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
-    if (blockSize == 0) {
-      blockSize = getDefaultBlockSize(languageKey);
-    }
-    return blockSize;
-  }
-
-  private static int getDefaultBlockSize(String languageKey) {
-    if ("cobol".equals(languageKey)) {
-      return 30;
-    } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
-      return 20;
-    } else {
-      return 10;
-    }
-  }
-
 }
index 7242f61c8ad73c0bca3c71b2142d424ff1ed7545..761d0a74001b55d5d0d09bae00aff82bee150245 100644 (file)
@@ -37,13 +37,12 @@ public final class DeprecatedMetricFinder implements MetricFinder {
 
   public DeprecatedMetricFinder(GlobalReferentials globalReferentials) {
     for (org.sonar.batch.protocol.input.Metric metric : globalReferentials.metrics()) {
-      Metric hibernateMetric = new org.sonar.api.measures.Metric.Builder(metric.key(), metric.key(), ValueType.valueOf(metric.valueType()))
+      Metric hibernateMetric = new org.sonar.api.measures.Metric.Builder(metric.key(), metric.name(), ValueType.valueOf(metric.valueType()))
         .create()
         .setDirection(metric.direction())
         .setQualitative(metric.isQualitative())
         .setUserManaged(metric.isUserManaged())
         .setDescription(metric.description())
-        .setName(metric.name())
         .setOptimizedBestValue(metric.isOptimizedBestValue())
         .setBestValue(metric.bestValue())
         .setWorstValue(metric.worstValue())
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/CommonSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/CommonSensorContext.java
new file mode 100644 (file)
index 0000000..6c3ed89
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.scan2;
+
+import com.google.common.base.Preconditions;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
+import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
+import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
+import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.batch.sensor.issue.IssueBuilder;
+import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
+import org.sonar.api.batch.sensor.measure.MeasureBuilder;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.api.config.Settings;
+import org.sonar.batch.duplication.BlockCache;
+import org.sonar.batch.duplication.DefaultTokenBuilder;
+import org.sonar.batch.duplication.DuplicationCache;
+import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.batch.scan.SensorContextAdaptor;
+import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
+import org.sonar.duplications.internal.pmd.PmdBlockChunker;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Common bits between {@link DefaultSensorContext} and {@link SensorContextAdaptor}
+ * @author julien
+ *
+ */
+public abstract class CommonSensorContext implements SensorContext {
+
+  private final Settings settings;
+  private final FileSystem fs;
+  private final ActiveRules activeRules;
+  private final ComponentDataCache componentDataCache;
+  private final BlockCache blockCache;
+  private final DuplicationCache duplicationCache;
+
+  protected CommonSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache,
+    BlockCache blockCache, DuplicationCache duplicationCache) {
+    this.settings = settings;
+    this.fs = fs;
+    this.activeRules = activeRules;
+    this.componentDataCache = componentDataCache;
+    this.blockCache = blockCache;
+    this.duplicationCache = duplicationCache;
+  }
+
+  @Override
+  public Settings settings() {
+    return settings;
+  }
+
+  @Override
+  public FileSystem fileSystem() {
+    return fs;
+  }
+
+  @Override
+  public ActiveRules activeRules() {
+    return activeRules;
+  }
+
+  @Override
+  public <G extends Serializable> MeasureBuilder<G> measureBuilder() {
+    return new DefaultMeasureBuilder<G>();
+  }
+
+  @Override
+  public IssueBuilder issueBuilder() {
+    return new DefaultIssueBuilder();
+  }
+
+  @Override
+  public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
+    return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+  }
+
+  @Override
+  public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
+    return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+  }
+
+  @Override
+  public DuplicationTokenBuilder duplicationTokenBuilder(InputFile inputFile) {
+    PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
+
+    return new DefaultTokenBuilder(inputFile, blockCache, blockChunker);
+  }
+
+  @Override
+  public DuplicationBuilder duplicationBuilder(InputFile inputFile) {
+    return new DefaultDuplicationBuilder(inputFile);
+  }
+
+  @Override
+  public void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications) {
+    Preconditions.checkState(!duplications.isEmpty(), "Empty duplications");
+    String effectiveKey = ((DefaultInputFile) inputFile).key();
+    for (DuplicationGroup duplicationGroup : duplications) {
+      Preconditions.checkState(effectiveKey.equals(duplicationGroup.originBlock().resourceKey()), "Invalid duplication group");
+    }
+    duplicationCache.put(effectiveKey, duplications);
+  }
+
+  private int getBlockSize(String languageKey) {
+    int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
+    if (blockSize == 0) {
+      blockSize = getDefaultBlockSize(languageKey);
+    }
+    return blockSize;
+  }
+
+  private static int getDefaultBlockSize(String languageKey) {
+    if ("cobol".equals(languageKey)) {
+      return 30;
+    } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
+      return 20;
+    } else {
+      return 10;
+    }
+  }
+
+}
index 74b13c2e43e6ca52b2a2553f283ae4cb8ded0872..6350622c72fa69bf2272dfa2fd61d847832634de 100644 (file)
  */
 package org.sonar.batch.scan2;
 
-import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.measure.Metric;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.DefaultActiveRule;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
-import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
-import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
-import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
 import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.IssueBuilder;
 import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
 import org.sonar.api.batch.sensor.measure.Measure;
-import org.sonar.api.batch.sensor.measure.MeasureBuilder;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
-import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
 import org.sonar.api.config.Settings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.MessageException;
 import org.sonar.batch.duplication.BlockCache;
-import org.sonar.batch.duplication.DefaultTokenBuilder;
 import org.sonar.batch.duplication.DuplicationCache;
-import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
 import org.sonar.batch.index.ComponentDataCache;
 import org.sonar.batch.issue.IssueFilters;
 import org.sonar.batch.scan.SensorContextAdaptor;
-import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
 import org.sonar.core.component.ComponentKeys;
-import org.sonar.duplications.internal.pmd.PmdBlockChunker;
 
 import java.io.Serializable;
-import java.util.List;
 
-public class DefaultSensorContext implements SensorContext {
+public class DefaultSensorContext extends CommonSensorContext {
 
   private final AnalyzerMeasureCache measureCache;
   private final AnalyzerIssueCache issueCache;
   private final ProjectDefinition def;
-  private final Settings settings;
-  private final FileSystem fs;
   private final ActiveRules activeRules;
   private final IssueFilters issueFilters;
-  private final ComponentDataCache componentDataCache;
-  private final BlockCache blockCache;
-  private final DuplicationCache duplicationCache;
 
   public DefaultSensorContext(ProjectDefinition def, AnalyzerMeasureCache measureCache, AnalyzerIssueCache issueCache,
     Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache,
     BlockCache blockCache, DuplicationCache duplicationCache) {
+    super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache);
     this.def = def;
     this.measureCache = measureCache;
     this.issueCache = issueCache;
-    this.settings = settings;
-    this.fs = fs;
     this.activeRules = activeRules;
     this.issueFilters = issueFilters;
-    this.componentDataCache = componentDataCache;
-    this.blockCache = blockCache;
-    this.duplicationCache = duplicationCache;
-  }
-
-  @Override
-  public Settings settings() {
-    return settings;
-  }
-
-  @Override
-  public FileSystem fileSystem() {
-    return fs;
-  }
-
-  @Override
-  public ActiveRules activeRules() {
-    return activeRules;
-  }
-
-  @Override
-  public <G extends Serializable> MeasureBuilder<G> measureBuilder() {
-    return new DefaultMeasureBuilder<G>();
   }
 
   @Override
@@ -138,11 +91,6 @@ public class DefaultSensorContext implements SensorContext {
     }
   }
 
-  @Override
-  public IssueBuilder issueBuilder() {
-    return new DefaultIssueBuilder();
-  }
-
   @Override
   public boolean addIssue(Issue issue) {
     String resourceKey;
@@ -181,54 +129,4 @@ public class DefaultSensorContext implements SensorContext {
     }
   }
 
-  @Override
-  public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
-    return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
-  }
-
-  @Override
-  public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
-    return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
-  }
-
-  @Override
-  public DuplicationTokenBuilder duplicationTokenBuilder(InputFile inputFile) {
-    PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
-
-    return new DefaultTokenBuilder(inputFile, blockCache, blockChunker);
-  }
-
-  @Override
-  public DuplicationBuilder duplicationBuilder(InputFile inputFile) {
-    return new DefaultDuplicationBuilder(inputFile);
-  }
-
-  @Override
-  public void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications) {
-    Preconditions.checkState(duplications.size() > 0, "Empty duplications");
-    String effectiveKey = ((DefaultInputFile) inputFile).key();
-    for (DuplicationGroup duplicationGroup : duplications) {
-      Preconditions.checkState(effectiveKey.equals(duplicationGroup.originBlock().resourceKey()), "Invalid duplication group");
-    }
-    duplicationCache.put(effectiveKey, duplications);
-  }
-
-  private int getBlockSize(String languageKey) {
-    int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
-    if (blockSize == 0) {
-      blockSize = getDefaultBlockSize(languageKey);
-    }
-    return blockSize;
-  }
-
-  private static int getDefaultBlockSize(String languageKey) {
-    if ("cobol".equals(languageKey)) {
-      return 30;
-    } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
-      return 20;
-    } else {
-      return 10;
-    }
-  }
-
 }
index b0ae419332a0f50f3727dcc70a813ef6bea01026..c2e42cad0a160ee880ec3f2ff7fd078d0414da76 100644 (file)
@@ -51,7 +51,7 @@ public class PmdBlockChunker {
   /**
    * @return ArrayList as we need a serializable object
    */
-  public ArrayList<Block> chunk(String resourceId, List<TokensLine> fragments) {
+  public List<Block> chunk(String resourceId, List<TokensLine> fragments) {
     List<TokensLine> filtered = Lists.newArrayList();
     int i = 0;
     while (i < fragments.size()) {
index 28e1e7d2041841a81c9c002f67ad99c8ba2a0f16..710ab81c652ba62bd28b98f928acc3db35edf40f 100644 (file)
@@ -79,6 +79,14 @@ public class DuplicationGroup {
         .append(length, rhs.length).isEquals();
     }
 
+    @Override
+    public int hashCode() {
+      return new HashCodeBuilder(13, 43)
+        .append(resourceKey)
+        .append(startLine)
+        .append(length).toHashCode();
+    }
+
     @Override
     public String toString() {
       return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
index fefbfb1e4c83f5f1b4a316328afbbc49ca20f395..10c0c71f5be2999fc20bdd95f7cdf00e14a3d3cd 100644 (file)
@@ -31,6 +31,10 @@ import javax.annotation.Nullable;
 
 public class DefaultIssueBuilder implements IssueBuilder {
 
+  private static final String INPUT_DIR_SHOULD_BE_NON_NULL = "InputDir should be non null";
+  private static final String INPUT_FILE_SHOULD_BE_NON_NULL = "InputFile should be non null";
+  private static final String ON_FILE_OR_ON_DIR_ALREADY_CALLED = "onFile or onDir already called";
+  private static final String ON_PROJECT_ALREADY_CALLED = "onProject already called";
   String key;
   boolean onProject = false;
   InputPath path;
@@ -48,26 +52,26 @@ public class DefaultIssueBuilder implements IssueBuilder {
 
   @Override
   public DefaultIssueBuilder onFile(InputFile file) {
-    Preconditions.checkState(!this.onProject, "onProject already called");
-    Preconditions.checkState(this.path == null, "onFile or onDir already called");
-    Preconditions.checkNotNull(file, "InputFile should be non null");
+    Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
+    Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
+    Preconditions.checkNotNull(file, INPUT_FILE_SHOULD_BE_NON_NULL);
     this.path = file;
     return this;
   }
 
   @Override
   public DefaultIssueBuilder onDir(InputDir dir) {
-    Preconditions.checkState(!this.onProject, "onProject already called");
-    Preconditions.checkState(this.path == null, "onFile or onDir already called");
-    Preconditions.checkNotNull(dir, "InputDir should be non null");
+    Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
+    Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
+    Preconditions.checkNotNull(dir, INPUT_DIR_SHOULD_BE_NON_NULL);
     this.path = dir;
     return this;
   }
 
   @Override
   public DefaultIssueBuilder onProject() {
-    Preconditions.checkState(!this.onProject, "onProject already called");
-    Preconditions.checkState(this.path == null, "onFile or onDir already called");
+    Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
+    Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
     this.onProject = true;
     return this;
   }
index 5e16b420c2ebb7a6a5c283b117cf70518aa2113c..af8af470cd1b9ebb0dad55cfedc9fe8c0e71564e 100644 (file)
@@ -341,6 +341,7 @@ public class Metric<G extends Serializable> implements ServerExtension, BatchExt
   /**
    * @return the metric description
    */
+  @CheckForNull
   public String getDescription() {
     return description;
   }
@@ -351,7 +352,7 @@ public class Metric<G extends Serializable> implements ServerExtension, BatchExt
    * @param description the description
    * @return this
    */
-  public Metric setDescription(String description) {
+  public Metric setDescription(@Nullable String description) {
     this.description = description;
     return this;
   }