From ec02a8faea5132013a21349ef75872bbb888a8f4 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Mon, 6 Feb 2012 12:43:18 +0400 Subject: [PATCH] Fix some quality flaws --- .../sonar/plugins/cpd/SonarBridgeEngine.java | 8 +--- .../org/sonar/plugins/cpd/SonarEngine.java | 36 +++++++++----- .../duplications/DuplicationPredicates.java | 48 +++++++++++++++++++ .../DuplicationPredicatesTest.java | 39 +++++++++++++++ 4 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 sonar-duplications/src/main/java/org/sonar/duplications/DuplicationPredicates.java create mode 100644 sonar-duplications/src/test/java/org/sonar/duplications/DuplicationPredicatesTest.java diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarBridgeEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarBridgeEngine.java index 2e736acde3f..cd53e73f14e 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarBridgeEngine.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarBridgeEngine.java @@ -24,6 +24,7 @@ import com.google.common.collect.Iterables; import org.sonar.api.batch.CpdMapping; import org.sonar.api.batch.SensorContext; import org.sonar.api.resources.*; +import org.sonar.duplications.DuplicationPredicates; import org.sonar.duplications.block.Block; import org.sonar.duplications.detector.suffixtree.SuffixTreeCloneDetectionAlgorithm; import org.sonar.duplications.index.CloneGroup; @@ -75,12 +76,7 @@ public class SonarBridgeEngine extends CpdEngine { } // Detect - final int minimumTokens = PmdEngine.getMinimumTokens(project); - Predicate minimumTokensPredicate = new Predicate() { - public boolean apply(CloneGroup input) { - return input.getLengthInUnits() >= minimumTokens; - } - }; + Predicate minimumTokensPredicate = DuplicationPredicates.numberOfUnitsNotLessThan(PmdEngine.getMinimumTokens(project)); for (InputFile inputFile : inputFiles) { Resource resource = mapping.createResource(inputFile.getFile(), fileSystem.getSourceDirs()); diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java index 7fe2852931f..2fbdde1ed4d 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java @@ -19,6 +19,7 @@ */ package org.sonar.plugins.cpd; +import com.google.common.collect.Iterables; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,8 +89,11 @@ public class SonarEngine extends CpdEngine { if (inputFiles.isEmpty()) { return; } + SonarDuplicationsIndex index = createIndex(project, inputFiles); + detect(index, context, project, inputFiles); + } - // Create index + private SonarDuplicationsIndex createIndex(Project project, List inputFiles) { final SonarDuplicationsIndex index = indexFactory.create(project); TokenChunker tokenChunker = JavaTokenProducer.build(); @@ -117,7 +121,10 @@ public class SonarEngine extends CpdEngine { index.insert(resource, blocks); } - // Detect + return index; + } + + private void detect(SonarDuplicationsIndex index, SensorContext context, Project project, List inputFiles) { ExecutorService executorService = Executors.newSingleThreadExecutor(); try { for (InputFile inputFile : inputFiles) { @@ -164,14 +171,14 @@ public class SonarEngine extends CpdEngine { return JavaFile.fromRelativePath(inputFile.getRelativePath(), false); } - static void save(SensorContext context, Resource resource, Iterable clones) { - if (clones == null || !clones.iterator().hasNext()) { + static void save(SensorContext context, Resource resource, Iterable duplications) { + if (Iterables.isEmpty(duplications)) { return; } // Calculate number of lines and blocks Set duplicatedLines = new HashSet(); double duplicatedBlocks = 0; - for (CloneGroup clone : clones) { + for (CloneGroup clone : duplications) { ClonePart origin = clone.getOriginPart(); for (ClonePart part : clone.getCloneParts()) { if (part.getResourceId().equals(origin.getResourceId())) { @@ -182,12 +189,19 @@ public class SonarEngine extends CpdEngine { } } } - // Build XML + // Save + context.saveMeasure(resource, CoreMetrics.DUPLICATED_FILES, 1.0); + context.saveMeasure(resource, CoreMetrics.DUPLICATED_LINES, (double) duplicatedLines.size()); + context.saveMeasure(resource, CoreMetrics.DUPLICATED_BLOCKS, duplicatedBlocks); + context.saveMeasure(resource, new Measure(CoreMetrics.DUPLICATIONS_DATA, toXml(duplications))); + } + + private static String toXml(Iterable duplications) { StringBuilder xml = new StringBuilder(); xml.append(""); - for (CloneGroup clone : clones) { + for (CloneGroup duplication : duplications) { xml.append(""); - for (ClonePart part : clone.getCloneParts()) { + for (ClonePart part : duplication.getCloneParts()) { xml.append(""); } xml.append(""); - // Save - context.saveMeasure(resource, CoreMetrics.DUPLICATED_FILES, 1d); - context.saveMeasure(resource, CoreMetrics.DUPLICATED_LINES, (double) duplicatedLines.size()); - context.saveMeasure(resource, CoreMetrics.DUPLICATED_BLOCKS, duplicatedBlocks); - context.saveMeasure(resource, new Measure(CoreMetrics.DUPLICATIONS_DATA, xml.toString())); + return xml.toString(); } } diff --git a/sonar-duplications/src/main/java/org/sonar/duplications/DuplicationPredicates.java b/sonar-duplications/src/main/java/org/sonar/duplications/DuplicationPredicates.java new file mode 100644 index 00000000000..a6e05179fae --- /dev/null +++ b/sonar-duplications/src/main/java/org/sonar/duplications/DuplicationPredicates.java @@ -0,0 +1,48 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.duplications; + +import com.google.common.annotations.Beta; +import com.google.common.base.Predicate; +import org.sonar.duplications.index.CloneGroup; + +@Beta +public final class DuplicationPredicates { + + private DuplicationPredicates() { + } + + public static Predicate numberOfUnitsNotLessThan(int min) { + return new NumberOfUnitsNotLessThan(min); + } + + private static class NumberOfUnitsNotLessThan implements Predicate { + private final int min; + + public NumberOfUnitsNotLessThan(int min) { + this.min = min; + } + + public boolean apply(CloneGroup input) { + return input.getLengthInUnits() >= min; + } + } + +} diff --git a/sonar-duplications/src/test/java/org/sonar/duplications/DuplicationPredicatesTest.java b/sonar-duplications/src/test/java/org/sonar/duplications/DuplicationPredicatesTest.java new file mode 100644 index 00000000000..11bd94a5f8a --- /dev/null +++ b/sonar-duplications/src/test/java/org/sonar/duplications/DuplicationPredicatesTest.java @@ -0,0 +1,39 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.duplications; + +import com.google.common.base.Predicate; +import org.junit.Test; +import org.sonar.duplications.index.CloneGroup; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class DuplicationPredicatesTest { + + @Test + public void testNumberOfUnitsNotLessThan() { + Predicate predicate = DuplicationPredicates.numberOfUnitsNotLessThan(5); + assertThat(predicate.apply(CloneGroup.builder().setLengthInUnits(6).build()), is(true)); + assertThat(predicate.apply(CloneGroup.builder().setLengthInUnits(5).build()), is(true)); + assertThat(predicate.apply(CloneGroup.builder().setLengthInUnits(4).build()), is(false)); + } + +} -- 2.39.5