aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/sonar-cpd-plugin/src
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2015-02-16 11:28:21 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2015-02-16 18:32:02 +0100
commit2660b61c7d0c0aee191ab719bf672f7902e78c5e (patch)
tree3fc4ecdca84ae66e2d4d623e1840f32e99b5e7d1 /plugins/sonar-cpd-plugin/src
parent1230b06fa26f9cc032c15d39f3563867d9d2914b (diff)
downloadsonarqube-2660b61c7d0c0aee191ab719bf672f7902e78c5e.tar.gz
sonarqube-2660b61c7d0c0aee191ab719bf672f7902e78c5e.zip
SONAR-6000 Merge cpd core plugin into the batch
Diffstat (limited to 'plugins/sonar-cpd-plugin/src')
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java49
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdMappings.java51
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java80
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java100
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java192
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java256
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecorator.java92
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecorator.java55
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/package-info.java25
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java137
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java90
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/SonarDuplicationsIndex.java83
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/package-info.java25
-rw-r--r--plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/package-info.java25
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdPluginTest.java32
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java85
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java109
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java164
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecoratorTest.java80
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecoratorTest.java70
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java85
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java175
22 files changed, 0 insertions, 2060 deletions
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java
deleted file mode 100644
index 2f2a7633f40..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java
+++ /dev/null
@@ -1,49 +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.plugins.cpd;
-
-import org.slf4j.Logger;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.batch.sensor.SensorContext;
-
-public abstract class CpdEngine implements BatchExtension {
-
- abstract boolean isLanguageSupported(String language);
-
- abstract void analyse(String language, SensorContext context);
-
- protected void logExclusions(String[] exclusions, Logger logger) {
- if (exclusions.length > 0) {
- StringBuilder message = new StringBuilder("Copy-paste detection exclusions:");
- for (String exclusion : exclusions) {
- message.append("\n ");
- message.append(exclusion);
- }
-
- logger.info(message.toString());
- }
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdMappings.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdMappings.java
deleted file mode 100644
index 3f0f9d83b8c..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdMappings.java
+++ /dev/null
@@ -1,51 +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.plugins.cpd;
-
-import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.CpdMapping;
-
-import javax.annotation.CheckForNull;
-
-public class CpdMappings implements BatchComponent {
-
- private final CpdMapping[] mappings;
-
- public CpdMappings(CpdMapping[] mappings) {
- this.mappings = mappings;
- }
-
- public CpdMappings() {
- this(new CpdMapping[0]);
- }
-
- @CheckForNull
- public CpdMapping getMapping(String language) {
- if (mappings != null) {
- for (CpdMapping cpdMapping : mappings) {
- if (cpdMapping.getLanguage().getKey().equals(language)) {
- return cpdMapping;
- }
- }
- }
- return null;
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java
deleted file mode 100644
index 2abed6cd61b..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java
+++ /dev/null
@@ -1,80 +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.plugins.cpd;
-
-import com.google.common.collect.ImmutableList;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.PropertyType;
-import org.sonar.api.SonarPlugin;
-import org.sonar.api.config.PropertyDefinition;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.plugins.cpd.decorators.DuplicationDensityDecorator;
-import org.sonar.plugins.cpd.decorators.SumDuplicationsDecorator;
-import org.sonar.plugins.cpd.index.IndexFactory;
-
-import java.util.List;
-
-public final class CpdPlugin extends SonarPlugin {
-
- @Override
- public List getExtensions() {
- return ImmutableList.of(
- PropertyDefinition.builder(CoreProperties.CPD_CROSS_PROJECT)
- .defaultValue(CoreProperties.CPD_CROSS_RPOJECT_DEFAULT_VALUE + "")
- .name("Cross project duplication detection")
- .description("By default, SonarQube detects duplications at sub-project level. This means that a block "
- + "duplicated on two sub-projects of the same project won't be reported. Setting this parameter to \"true\" "
- + "allows to detect duplicates across sub-projects and more generally across projects. Note that activating "
- + "this property will slightly increase each SonarQube analysis time.")
- .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE)
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DUPLICATIONS)
- .type(PropertyType.BOOLEAN)
- .build(),
- PropertyDefinition.builder(CoreProperties.CPD_SKIP_PROPERTY)
- .defaultValue("false")
- .name("Skip")
- .description("Disable detection of duplications")
- .hidden()
- .category(CoreProperties.CATEGORY_GENERAL)
- .subCategory(CoreProperties.SUBCATEGORY_DUPLICATIONS)
- .type(PropertyType.BOOLEAN)
- .build(),
- PropertyDefinition.builder(CoreProperties.CPD_EXCLUSIONS)
- .defaultValue("")
- .name("Duplication Exclusions")
- .description("Patterns used to exclude some source files from the duplication detection mechanism. " +
- "See below to know how to use wildcards to specify this property.")
- .onQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE)
- .category(CoreProperties.CATEGORY_EXCLUSIONS)
- .subCategory(CoreProperties.SUBCATEGORY_DUPLICATIONS_EXCLUSIONS)
- .multiValues(true)
- .build(),
-
- CpdSensor.class,
- CpdMappings.class,
- SumDuplicationsDecorator.class,
- DuplicationDensityDecorator.class,
- IndexFactory.class,
- JavaCpdEngine.class,
- DefaultCpdEngine.class);
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java
deleted file mode 100644
index 611658c26c2..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java
+++ /dev/null
@@ -1,100 +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.plugins.cpd;
-
-import com.google.common.annotations.VisibleForTesting;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.Phase;
-import org.sonar.api.batch.fs.FileSystem;
-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.config.Settings;
-
-@Phase(name = Phase.Name.POST)
-public class CpdSensor implements Sensor {
-
- private static final Logger LOG = LoggerFactory.getLogger(CpdSensor.class);
-
- private CpdEngine sonarEngine;
- private CpdEngine sonarBridgeEngine;
- private Settings settings;
- private FileSystem fs;
-
- public CpdSensor(JavaCpdEngine sonarEngine, DefaultCpdEngine sonarBridgeEngine, Settings settings, FileSystem fs) {
- this.sonarEngine = sonarEngine;
- this.sonarBridgeEngine = sonarBridgeEngine;
- this.settings = settings;
- this.fs = fs;
- }
-
- @Override
- public void describe(SensorDescriptor descriptor) {
- descriptor.name("CPD Sensor")
- .disabledInPreview();
- }
-
- @VisibleForTesting
- CpdEngine getEngine(String language) {
- if (sonarEngine.isLanguageSupported(language)) {
- return sonarEngine;
- }
- return sonarBridgeEngine;
- }
-
- @VisibleForTesting
- boolean isSkipped(String language) {
- String key = "sonar.cpd." + language + ".skip";
- if (settings.hasKey(key)) {
- return settings.getBoolean(key);
- }
- return settings.getBoolean(CoreProperties.CPD_SKIP_PROPERTY);
- }
-
- @Override
- public void execute(SensorContext context) {
- if (settings.hasKey(CoreProperties.CPD_SKIP_PROPERTY)) {
- LOG.warn("\"sonar.cpd.skip\" property is deprecated and will be removed. Please set \"sonar.cpd.exclusions=**\" instead to disable duplication mechanism.");
- }
-
- for (String language : fs.languages()) {
- if (settings.hasKey("sonar.cpd." + language + ".skip")) {
- LOG
- .warn("\"sonar.cpd." + language + ".skip\" property is deprecated and will be removed. Please set \"sonar.cpd.exclusions=**\" instead to disable duplication mechanism.");
- }
-
- if (isSkipped(language)) {
- LOG.info("Detection of duplicated code is skipped for {}", language);
- continue;
- }
-
- CpdEngine engine = getEngine(language);
- if (!engine.isLanguageSupported(language)) {
- LOG.debug("Detection of duplicated code is not supported for {}", language);
- continue;
- }
- LOG.info("{} is used for {}", engine, language);
- engine.analyse(language, context);
- }
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java
deleted file mode 100644
index deeb060b98f..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/DefaultCpdEngine.java
+++ /dev/null
@@ -1,192 +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.plugins.cpd;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.CpdMapping;
-import org.sonar.api.batch.fs.FilePredicates;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.duplication.BlockCache;
-import org.sonar.duplications.DuplicationPredicates;
-import org.sonar.duplications.block.Block;
-import org.sonar.duplications.block.FileBlocks;
-import org.sonar.duplications.index.CloneGroup;
-import org.sonar.duplications.internal.pmd.TokenizerBridge;
-import org.sonar.plugins.cpd.index.IndexFactory;
-import org.sonar.plugins.cpd.index.SonarDuplicationsIndex;
-
-import javax.annotation.Nullable;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-public class DefaultCpdEngine extends CpdEngine {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultCpdEngine.class);
-
- /**
- * Limit of time to analyse one file (in seconds).
- */
- private static final int TIMEOUT = 5 * 60;
-
- private final IndexFactory indexFactory;
- private final CpdMappings mappings;
- private final FileSystem fs;
- private final Settings settings;
- private final BlockCache blockCache;
- private final Project project;
-
- public DefaultCpdEngine(@Nullable Project project, IndexFactory indexFactory, CpdMappings mappings, FileSystem fs, Settings settings, BlockCache duplicationCache) {
- this.project = project;
- this.indexFactory = indexFactory;
- this.mappings = mappings;
- this.fs = fs;
- this.settings = settings;
- this.blockCache = duplicationCache;
- }
-
- public DefaultCpdEngine(IndexFactory indexFactory, CpdMappings mappings, FileSystem fs, Settings settings, BlockCache duplicationCache) {
- this(null, indexFactory, mappings, fs, settings, duplicationCache);
- }
-
- @Override
- public boolean isLanguageSupported(String language) {
- return true;
- }
-
- @Override
- public void analyse(String languageKey, SensorContext context) {
- String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS);
- logExclusions(cpdExclusions, LOG);
- FilePredicates p = fs.predicates();
- List<InputFile> sourceFiles = Lists.newArrayList(fs.inputFiles(p.and(
- p.hasType(InputFile.Type.MAIN),
- p.hasLanguage(languageKey),
- p.doesNotMatchPathPatterns(cpdExclusions)
- )));
- if (sourceFiles.isEmpty()) {
- return;
- }
-
- CpdMapping mapping = mappings.getMapping(languageKey);
-
- // Create index
- SonarDuplicationsIndex index = indexFactory.create(project, languageKey);
- populateIndex(languageKey, sourceFiles, mapping, index);
-
- // Detect
- Predicate<CloneGroup> minimumTokensPredicate = DuplicationPredicates.numberOfUnitsNotLessThan(getMinimumTokens(languageKey));
-
- ExecutorService executorService = Executors.newSingleThreadExecutor();
- try {
- for (InputFile inputFile : sourceFiles) {
- LOG.debug("Detection of duplications for {}", inputFile);
- String resourceEffectiveKey = ((DeprecatedDefaultInputFile) inputFile).key();
- Collection<Block> fileBlocks = index.getByInputFile(inputFile, resourceEffectiveKey);
-
- Iterable<CloneGroup> filtered;
- try {
- List<CloneGroup> duplications = executorService.submit(new JavaCpdEngine.Task(index, fileBlocks)).get(TIMEOUT, TimeUnit.SECONDS);
- filtered = Iterables.filter(duplications, minimumTokensPredicate);
- } catch (TimeoutException e) {
- filtered = null;
- LOG.warn("Timeout during detection of duplications for " + inputFile, e);
- } catch (InterruptedException e) {
- throw new SonarException("Fail during detection of duplication for " + inputFile, e);
- } catch (ExecutionException e) {
- throw new SonarException("Fail during detection of duplication for " + inputFile, e);
- }
-
- JavaCpdEngine.save(context, inputFile, filtered);
- }
- } finally {
- executorService.shutdown();
- }
- }
-
- 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 = blockCache.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");
- if (blockSize == 0) {
- blockSize = getDefaultBlockSize(languageKey);
- }
- return blockSize;
- }
-
- @VisibleForTesting
- static int getDefaultBlockSize(String languageKey) {
- if ("cobol".equals(languageKey)) {
- return 30;
- } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
- return 20;
- } else {
- return 10;
- }
- }
-
- @VisibleForTesting
- int getMinimumTokens(String languageKey) {
- int minimumTokens = settings.getInt("sonar.cpd." + languageKey + ".minimumTokens");
- if (minimumTokens == 0) {
- minimumTokens = settings.getInt(CoreProperties.CPD_MINIMUM_TOKENS_PROPERTY);
- }
- if (minimumTokens == 0) {
- minimumTokens = 100;
- }
-
- return minimumTokens;
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java
deleted file mode 100644
index cf74b2cab7f..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/JavaCpdEngine.java
+++ /dev/null
@@ -1,256 +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.plugins.cpd;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import org.apache.commons.io.IOUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.FilePredicates;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.config.Settings;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.utils.SonarException;
-import org.sonar.duplications.block.Block;
-import org.sonar.duplications.block.BlockChunker;
-import org.sonar.duplications.detector.suffixtree.SuffixTreeCloneDetectionAlgorithm;
-import org.sonar.duplications.index.CloneGroup;
-import org.sonar.duplications.index.CloneIndex;
-import org.sonar.duplications.index.ClonePart;
-import org.sonar.duplications.java.JavaStatementBuilder;
-import org.sonar.duplications.java.JavaTokenProducer;
-import org.sonar.duplications.statement.Statement;
-import org.sonar.duplications.statement.StatementChunker;
-import org.sonar.duplications.token.TokenChunker;
-import org.sonar.plugins.cpd.index.IndexFactory;
-import org.sonar.plugins.cpd.index.SonarDuplicationsIndex;
-
-import javax.annotation.Nullable;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.*;
-
-public class JavaCpdEngine extends CpdEngine {
-
- private static final Logger LOG = LoggerFactory.getLogger(JavaCpdEngine.class);
-
- private static final int BLOCK_SIZE = 10;
-
- /**
- * Limit of time to analyse one file (in seconds).
- */
- private static final int TIMEOUT = 5 * 60;
-
- private final IndexFactory indexFactory;
- private final FileSystem fs;
- private final Settings settings;
- private final Project project;
-
- public JavaCpdEngine(@Nullable Project project, IndexFactory indexFactory, FileSystem fs, Settings settings) {
- this.project = project;
- this.indexFactory = indexFactory;
- this.fs = fs;
- this.settings = settings;
- }
-
- public JavaCpdEngine(IndexFactory indexFactory, FileSystem fs, Settings settings) {
- this(null, indexFactory, fs, settings);
- }
-
- @Override
- public boolean isLanguageSupported(String language) {
- return "java".equals(language);
- }
-
- @Override
- public void analyse(String languageKey, SensorContext context) {
- String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS);
- logExclusions(cpdExclusions, LOG);
- FilePredicates p = fs.predicates();
- List<InputFile> sourceFiles = Lists.newArrayList(fs.inputFiles(p.and(
- p.hasType(InputFile.Type.MAIN),
- p.hasLanguage(languageKey),
- p.doesNotMatchPathPatterns(cpdExclusions)
- )));
- if (sourceFiles.isEmpty()) {
- return;
- }
- SonarDuplicationsIndex index = createIndex(project, languageKey, sourceFiles);
- detect(index, context, sourceFiles);
- }
-
- private SonarDuplicationsIndex createIndex(@Nullable Project project, String language, Iterable<InputFile> sourceFiles) {
- final SonarDuplicationsIndex index = indexFactory.create(project, language);
-
- TokenChunker tokenChunker = JavaTokenProducer.build();
- StatementChunker statementChunker = JavaStatementBuilder.build();
- BlockChunker blockChunker = new BlockChunker(BLOCK_SIZE);
-
- for (InputFile inputFile : sourceFiles) {
- LOG.debug("Populating index from {}", inputFile);
- String resourceEffectiveKey = ((DeprecatedDefaultInputFile) inputFile).key();
-
- List<Statement> statements;
-
- Reader reader = null;
- try {
- reader = new InputStreamReader(new FileInputStream(inputFile.file()), fs.encoding());
- statements = statementChunker.chunk(tokenChunker.chunk(reader));
- } catch (FileNotFoundException e) {
- throw new SonarException("Cannot find file " + inputFile.file(), e);
- } finally {
- IOUtils.closeQuietly(reader);
- }
-
- List<Block> blocks = blockChunker.chunk(resourceEffectiveKey, statements);
- index.insert(inputFile, blocks);
- }
-
- return index;
- }
-
- private void detect(SonarDuplicationsIndex index, org.sonar.api.batch.sensor.SensorContext context, List<InputFile> sourceFiles) {
- ExecutorService executorService = Executors.newSingleThreadExecutor();
- try {
- for (InputFile inputFile : sourceFiles) {
- LOG.debug("Detection of duplications for {}", inputFile);
- String resourceEffectiveKey = ((DeprecatedDefaultInputFile) inputFile).key();
-
- Collection<Block> fileBlocks = index.getByInputFile(inputFile, resourceEffectiveKey);
-
- List<CloneGroup> clones;
- try {
- clones = executorService.submit(new Task(index, fileBlocks)).get(TIMEOUT, TimeUnit.SECONDS);
- } catch (TimeoutException e) {
- clones = null;
- LOG.warn("Timeout during detection of duplications for " + inputFile, e);
- } catch (InterruptedException e) {
- throw new SonarException("Fail during detection of duplication for " + inputFile, e);
- } catch (ExecutionException e) {
- throw new SonarException("Fail during detection of duplication for " + inputFile, e);
- }
-
- save(context, inputFile, clones);
- }
- } finally {
- executorService.shutdown();
- }
- }
-
- static class Task implements Callable<List<CloneGroup>> {
- private final CloneIndex index;
- private final Collection<Block> fileBlocks;
-
- public Task(CloneIndex index, Collection<Block> fileBlocks) {
- this.index = index;
- this.fileBlocks = fileBlocks;
- }
-
- @Override
- public List<CloneGroup> call() {
- return SuffixTreeCloneDetectionAlgorithm.detect(index, fileBlocks);
- }
- }
-
- static void save(org.sonar.api.batch.sensor.SensorContext context, InputFile inputFile, @Nullable Iterable<CloneGroup> duplications) {
- if (duplications == null || Iterables.isEmpty(duplications)) {
- return;
- }
- Set<Integer> duplicatedLines = new HashSet<Integer>();
- int duplicatedBlocks = computeBlockAndLineCount(duplications, duplicatedLines);
- Map<Integer, Integer> duplicationByLine = new HashMap<Integer, Integer>();
- for (int i = 1; i <= inputFile.lines(); i++) {
- duplicationByLine.put(i, duplicatedLines.contains(i) ? 1 : 0);
- }
- ((DefaultMeasure<String>) context.<String>newMeasure()
- .forMetric(CoreMetrics.DUPLICATION_LINES_DATA)
- .onFile(inputFile)
- .withValue(KeyValueFormat.format(duplicationByLine)))
- .setFromCore()
- .save();
- // Save
- ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
- .forMetric(CoreMetrics.DUPLICATED_FILES)
- .onFile(inputFile)
- .withValue(1))
- .setFromCore()
- .save();
- ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
- .forMetric(CoreMetrics.DUPLICATED_LINES)
- .onFile(inputFile)
- .withValue(duplicatedLines.size()))
- .setFromCore()
- .save();
- ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
- .forMetric(CoreMetrics.DUPLICATED_BLOCKS)
- .onFile(inputFile)
- .withValue(duplicatedBlocks))
- .setFromCore()
- .save();
-
- DuplicationBuilder builder = context.duplicationBuilder(inputFile);
- for (CloneGroup duplication : duplications) {
- builder.originBlock(duplication.getOriginPart().getStartLine(), duplication.getOriginPart().getEndLine());
- for (ClonePart part : duplication.getCloneParts()) {
- if (!part.equals(duplication.getOriginPart())) {
- ((DefaultDuplicationBuilder) builder).isDuplicatedBy(part.getResourceId(), part.getStartLine(), part.getEndLine());
- }
- }
- }
- 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;
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecorator.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecorator.java
deleted file mode 100644
index c5208cf2a7f..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecorator.java
+++ /dev/null
@@ -1,92 +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.plugins.cpd.decorators;
-
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class DuplicationDensityDecorator implements Decorator {
-
- @DependsUpon
- public List<Metric> dependsUponMetrics() {
- return Arrays.<Metric>asList(
- CoreMetrics.NCLOC,
- CoreMetrics.COMMENT_LINES,
- CoreMetrics.DUPLICATED_LINES,
- CoreMetrics.LINES);
- }
-
- @DependedUpon
- public Metric generatesMetric() {
- return CoreMetrics.DUPLICATED_LINES_DENSITY;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @Override
- public void decorate(Resource resource, DecoratorContext context) {
- Measure nbDuplicatedLines = context.getMeasure(CoreMetrics.DUPLICATED_LINES);
- if (nbDuplicatedLines == null) {
- return;
- }
-
- Double divisor = getNbLinesFromLocOrNcloc(context);
- if (divisor != null && divisor > 0.0) {
- context.saveMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY, calculate(nbDuplicatedLines.getValue(), divisor));
- }
- }
-
- private Double getNbLinesFromLocOrNcloc(DecoratorContext context) {
- Measure nbLoc = context.getMeasure(CoreMetrics.LINES);
- if (nbLoc != null) {
- // TODO test this branch
- return nbLoc.getValue();
- }
- Measure nbNcloc = context.getMeasure(CoreMetrics.NCLOC);
- if (nbNcloc != null) {
- Measure nbComments = context.getMeasure(CoreMetrics.COMMENT_LINES);
- Double nbLines = nbNcloc.getValue();
- return nbComments != null ? nbLines + nbComments.getValue() : nbLines;
- }
- return null;
- }
-
- protected Double calculate(Double dividend, Double divisor) {
- Double result = 100.0 * dividend / divisor;
- if (result < 100.0) {
- return result;
- }
- return 100.0;
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecorator.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecorator.java
deleted file mode 100644
index 29110918beb..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecorator.java
+++ /dev/null
@@ -1,55 +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.plugins.cpd.decorators;
-
-import org.sonar.api.batch.AbstractSumChildrenDecorator;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class SumDuplicationsDecorator extends AbstractSumChildrenDecorator {
-
- @Override
- @DependedUpon
- public List<Metric> generatesMetrics() {
- return Arrays.<Metric>asList(CoreMetrics.DUPLICATED_BLOCKS, CoreMetrics.DUPLICATED_FILES, CoreMetrics.DUPLICATED_LINES);
- }
-
- @Override
- protected boolean shouldSaveZeroIfNoChildMeasures() {
- return true;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @Override
- public boolean shouldDecorateResource(Resource resource) {
- return !ResourceUtils.isUnitTestClass(resource);
- }
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/package-info.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/package-info.java
deleted file mode 100644
index 489cb4de835..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/decorators/package-info.java
+++ /dev/null
@@ -1,25 +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.
- */
-
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.cpd.decorators;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java
deleted file mode 100644
index d3258bfa7f6..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/DbDuplicationsIndex.java
+++ /dev/null
@@ -1,137 +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.plugins.cpd.index;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.index.ResourceCache;
-import org.sonar.core.duplication.DuplicationDao;
-import org.sonar.core.duplication.DuplicationUnitDto;
-import org.sonar.duplications.block.Block;
-import org.sonar.duplications.block.ByteArray;
-
-import javax.persistence.Query;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class DbDuplicationsIndex {
-
- private static final String RESOURCE_ID = "resourceId";
- private static final String LAST = "last";
-
- private final Map<ByteArray, Collection<Block>> cache = Maps.newHashMap();
-
- private final int currentProjectSnapshotId;
- private final Integer lastSnapshotId;
- private final String languageKey;
- private final DuplicationDao dao;
- private final DatabaseSession session;
- private final ResourceCache resourceCache;
-
- public DbDuplicationsIndex(Project currentProject, DuplicationDao dao,
- String language, DatabaseSession session, ResourceCache resourceCache) {
- this.dao = dao;
- this.session = session;
- this.resourceCache = resourceCache;
- Snapshot lastSnapshot = getLastSnapshot(currentProject.getId());
- this.currentProjectSnapshotId = resourceCache.get(currentProject.getEffectiveKey()).snapshotId();
- this.lastSnapshotId = lastSnapshot == null ? null : lastSnapshot.getId();
- this.languageKey = language;
- }
-
- private Snapshot getLastSnapshot(int resourceId) {
- String hql = "SELECT s FROM " + Snapshot.class.getSimpleName() + " s WHERE s.last=:last AND s.resourceId=:resourceId";
- Query query = session.createQuery(hql);
- query.setParameter(LAST, true);
- query.setParameter(RESOURCE_ID, resourceId);
- return session.getSingleResult(query, null);
- }
-
- int getSnapshotIdFor(InputFile inputFile) {
- return resourceCache.get(((DefaultInputFile) inputFile).key()).snapshotId();
- }
-
- public void prepareCache(InputFile inputFile) {
- int resourceSnapshotId = getSnapshotIdFor(inputFile);
- List<DuplicationUnitDto> units = dao.selectCandidates(resourceSnapshotId, lastSnapshotId, languageKey);
- cache.clear();
- // TODO Godin: maybe remove conversion of units to blocks?
- for (DuplicationUnitDto unit : units) {
- String hash = unit.getHash();
- String resourceKey = unit.getResourceKey();
- int indexInFile = unit.getIndexInFile();
- int startLine = unit.getStartLine();
- int endLine = unit.getEndLine();
-
- // TODO Godin: in fact we could work directly with id instead of key - this will allow to decrease memory consumption
- Block block = Block.builder()
- .setResourceId(resourceKey)
- .setBlockHash(new ByteArray(hash))
- .setIndexInFile(indexInFile)
- .setLines(startLine, endLine)
- .build();
-
- // Group blocks by hash
- Collection<Block> sameHash = cache.get(block.getBlockHash());
- if (sameHash == null) {
- sameHash = Lists.newArrayList();
- cache.put(block.getBlockHash(), sameHash);
- }
- sameHash.add(block);
- }
- }
-
- public Collection<Block> getByHash(ByteArray hash) {
- Collection<Block> result = cache.get(hash);
- if (result != null) {
- return result;
- } else {
- return Collections.emptyList();
- }
- }
-
- public void insert(InputFile inputFile, Collection<Block> blocks) {
- int resourceSnapshotId = getSnapshotIdFor(inputFile);
-
- // TODO Godin: maybe remove conversion of blocks to units?
- List<DuplicationUnitDto> units = Lists.newArrayList();
- for (Block block : blocks) {
- DuplicationUnitDto unit = new DuplicationUnitDto(
- currentProjectSnapshotId,
- resourceSnapshotId,
- block.getBlockHash().toString(),
- block.getIndexInFile(),
- block.getStartLine(),
- block.getEndLine());
- units.add(unit);
- }
-
- dao.insert(units);
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java
deleted file mode 100644
index 769e05bf2c3..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java
+++ /dev/null
@@ -1,90 +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.plugins.cpd.index;
-
-import com.google.common.annotations.VisibleForTesting;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.bootstrap.DefaultAnalysisMode;
-import org.sonar.batch.index.ResourceCache;
-import org.sonar.core.duplication.DuplicationDao;
-
-import javax.annotation.Nullable;
-
-public class IndexFactory implements BatchComponent {
-
- private static final Logger LOG = LoggerFactory.getLogger(IndexFactory.class);
-
- private final Settings settings;
- private final DuplicationDao dao;
- private final DefaultAnalysisMode mode;
- private final DatabaseSession session;
- private final ResourceCache resourceCache;
-
- public IndexFactory(DefaultAnalysisMode mode, Settings settings, @Nullable DuplicationDao dao, @Nullable DatabaseSession session, ResourceCache resourceCache) {
- this.mode = mode;
- this.settings = settings;
- this.dao = dao;
- this.session = session;
- this.resourceCache = resourceCache;
- }
-
- /**
- * Used by new sensor mode
- */
- public IndexFactory(DefaultAnalysisMode mode, Settings settings, ResourceCache resourceCache) {
- this(mode, settings, null, null, resourceCache);
- }
-
- public SonarDuplicationsIndex create(@Nullable Project project, String languageKey) {
- if (verifyCrossProject(project, LOG) && dao != null && session != null) {
- return new SonarDuplicationsIndex(new DbDuplicationsIndex(project, dao, languageKey, session, resourceCache));
- }
- return new SonarDuplicationsIndex();
- }
-
- @VisibleForTesting
- boolean verifyCrossProject(@Nullable Project project, Logger logger) {
- boolean crossProject = false;
-
- if (settings.getBoolean(CoreProperties.CPD_CROSS_PROJECT)) {
- if (mode.isPreview()) {
- logger.info("Cross-project analysis disabled. Not supported in preview mode.");
- } else if (StringUtils.isNotBlank(settings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY))) {
- logger.info("Cross-project analysis disabled. Not supported on project branches.");
- } else if (project == null) {
- // New sensor mode
- logger.info("Cross-project analysis disabled. Not supported in new sensor mode.");
- } else {
- logger.info("Cross-project analysis enabled");
- crossProject = true;
- }
- } else {
- logger.info("Cross-project analysis disabled");
- }
- return crossProject;
- }
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/SonarDuplicationsIndex.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/SonarDuplicationsIndex.java
deleted file mode 100644
index ad8ac293527..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/SonarDuplicationsIndex.java
+++ /dev/null
@@ -1,83 +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.plugins.cpd.index;
-
-import com.google.common.collect.Lists;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.duplications.block.Block;
-import org.sonar.duplications.block.ByteArray;
-import org.sonar.duplications.index.AbstractCloneIndex;
-import org.sonar.duplications.index.CloneIndex;
-import org.sonar.duplications.index.PackedMemoryCloneIndex;
-
-import java.util.Collection;
-import java.util.List;
-
-public class SonarDuplicationsIndex extends AbstractCloneIndex {
-
- private final CloneIndex mem = new PackedMemoryCloneIndex();
- private final DbDuplicationsIndex db;
-
- public SonarDuplicationsIndex() {
- this.db = null;
- }
-
- public SonarDuplicationsIndex(DbDuplicationsIndex db) {
- this.db = db;
- }
-
- public void insert(InputFile inputFile, Collection<Block> blocks) {
- for (Block block : blocks) {
- mem.insert(block);
- }
- if (db != null) {
- db.insert(inputFile, blocks);
- }
- }
-
- public Collection<Block> getByInputFile(InputFile inputFile, String resourceKey) {
- if (db != null) {
- db.prepareCache(inputFile);
- }
- return mem.getByResourceId(resourceKey);
- }
-
- @Override
- public Collection<Block> getBySequenceHash(ByteArray hash) {
- if (db == null) {
- return mem.getBySequenceHash(hash);
- } else {
- List<Block> result = Lists.newArrayList(mem.getBySequenceHash(hash));
- result.addAll(db.getByHash(hash));
- return result;
- }
- }
-
- @Override
- public Collection<Block> getByResourceId(String resourceId) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void insert(Block block) {
- throw new UnsupportedOperationException();
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/package-info.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/package-info.java
deleted file mode 100644
index 27f5b16ae24..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/package-info.java
+++ /dev/null
@@ -1,25 +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.
- */
-
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.cpd.index;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/package-info.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/package-info.java
deleted file mode 100644
index 90cdee73061..00000000000
--- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/package-info.java
+++ /dev/null
@@ -1,25 +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.
- */
-
-@ParametersAreNonnullByDefault
-package org.sonar.plugins.cpd;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdPluginTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdPluginTest.java
deleted file mode 100644
index 29308bf2e5f..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdPluginTest.java
+++ /dev/null
@@ -1,32 +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.plugins.cpd;
-
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CpdPluginTest {
-
- @Test
- public void getExtensions() {
- assertThat(new CpdPlugin().getExtensions()).hasSize(10);
- }
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java
deleted file mode 100644
index a4cfc381ae8..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java
+++ /dev/null
@@ -1,85 +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.plugins.cpd;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Java;
-import org.sonar.batch.duplication.BlockCache;
-import org.sonar.plugins.cpd.index.IndexFactory;
-
-import java.io.IOException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class CpdSensorTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- JavaCpdEngine sonarEngine;
- DefaultCpdEngine sonarBridgeEngine;
- CpdSensor sensor;
- Settings settings;
-
- @Before
- public void setUp() throws IOException {
- IndexFactory indexFactory = mock(IndexFactory.class);
- sonarEngine = new JavaCpdEngine(indexFactory, null, null);
- sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class));
- settings = new Settings(new PropertyDefinitions(CpdPlugin.class));
-
- DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder().toPath());
- sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, fs);
- }
-
- @Test
- public void test_global_skip() {
- settings.setProperty("sonar.cpd.skip", true);
- assertThat(sensor.isSkipped(Java.KEY)).isTrue();
- }
-
- @Test
- public void should_not_skip_by_default() {
- assertThat(sensor.isSkipped(Java.KEY)).isFalse();
- }
-
- @Test
- public void should_skip_by_language() {
- settings.setProperty("sonar.cpd.skip", false);
- settings.setProperty("sonar.cpd.php.skip", true);
-
- assertThat(sensor.isSkipped("php")).isTrue();
- assertThat(sensor.isSkipped(Java.KEY)).isFalse();
- }
-
- @Test
- public void test_engine() {
- assertThat(sensor.getEngine(Java.KEY)).isSameAs(sonarEngine);
- assertThat(sensor.getEngine("PHP")).isSameAs(sonarBridgeEngine);
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java
deleted file mode 100644
index 8ecac586a3b..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/DefaultCpdEngineTest.java
+++ /dev/null
@@ -1,109 +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.plugins.cpd;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.duplication.BlockCache;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-public class DefaultCpdEngineTest {
-
- private DefaultCpdEngine engine;
- private Settings settings;
-
- @Before
- public void init() {
- settings = new Settings();
- engine = new DefaultCpdEngine(null, null, null, settings, mock(BlockCache.class));
- }
-
- @Test
- public void shouldLogExclusions() {
- Logger logger = mock(Logger.class);
- engine.logExclusions(new String[0], logger);
- verify(logger, never()).info(anyString());
-
- logger = mock(Logger.class);
- engine.logExclusions(new String[] {"Foo*", "**/Bar*"}, logger);
-
- String message = "Copy-paste detection exclusions:"
- + "\n Foo*"
- + "\n **/Bar*";
- verify(logger, times(1)).info(message);
- }
-
- @Test
- public void shouldReturnDefaultBlockSize() {
- assertThat(DefaultCpdEngine.getDefaultBlockSize("cobol")).isEqualTo(30);
- assertThat(DefaultCpdEngine.getDefaultBlockSize("natur")).isEqualTo(20);
- assertThat(DefaultCpdEngine.getDefaultBlockSize("abap")).isEqualTo(20);
- assertThat(DefaultCpdEngine.getDefaultBlockSize("other")).isEqualTo(10);
- }
-
- @Test
- public void defaultBlockSize() {
-
- assertThat(engine.getBlockSize("java")).isEqualTo(10);
- }
-
- @Test
- public void blockSizeForCobol() {
- settings.setProperty("sonar.cpd.cobol.minimumLines", "42");
-
- assertThat(engine.getBlockSize("cobol")).isEqualTo(42);
- }
-
- @Test
- public void defaultMinimumTokens() {
- assertThat(engine.getMinimumTokens("java")).isEqualTo(100);
- }
-
- @Test
- public void generalMinimumTokens() {
- settings.setProperty("sonar.cpd.minimumTokens", 33);
-
- assertThat(engine.getMinimumTokens("java")).isEqualTo(33);
- }
-
- @Test
- public void minimumTokensByLanguage() {
- settings.setProperty("sonar.cpd.java.minimumTokens", "42");
- settings.setProperty("sonar.cpd.php.minimumTokens", "33");
- assertThat(engine.getMinimumTokens("java")).isEqualTo(42);
-
- settings.setProperty("sonar.cpd.java.minimumTokens", "42");
- settings.setProperty("sonar.cpd.php.minimumTokens", "33");
- assertThat(engine.getMinimumTokens("php")).isEqualTo(33);
- }
-
- private static Project newProject(String key) {
- return new Project(key).setAnalysisType(Project.AnalysisType.DYNAMIC);
- }
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java
deleted file mode 100644
index 182f57091d0..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java
+++ /dev/null
@@ -1,164 +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.plugins.cpd;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.InOrder;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.SensorStorage;
-import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
-import org.sonar.api.batch.sensor.measure.Measure;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.duplications.index.CloneGroup;
-import org.sonar.duplications.index.ClonePart;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class JavaCpdEngineTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- SensorContext context = mock(SensorContext.class);
- DeprecatedDefaultInputFile inputFile;
- private DefaultDuplicationBuilder duplicationBuilder;
- private SensorStorage storage = mock(SensorStorage.class);
-
- @Before
- public void before() throws IOException {
- when(context.newMeasure()).then(new Answer<Measure>() {
- @Override
- public Measure answer(InvocationOnMock invocation) throws Throwable {
- return new DefaultMeasure(storage);
- }
- });
- inputFile = new DeprecatedDefaultInputFile("foo", "src/main/java/Foo.java");
- duplicationBuilder = spy(new DefaultDuplicationBuilder(inputFile));
- when(context.duplicationBuilder(any(InputFile.class))).thenReturn(duplicationBuilder);
- inputFile.setModuleBaseDir(temp.newFolder().toPath());
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testNothingToSave() {
- JavaCpdEngine.save(context, inputFile, null);
- JavaCpdEngine.save(context, inputFile, Collections.EMPTY_LIST);
-
- verifyZeroInteractions(context);
- }
-
- @Test
- public void testOneSimpleDuplicationBetweenTwoFiles() {
- inputFile.setLines(5);
- List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 2, 4), new ClonePart("key2", 0, 15, 17)));
- JavaCpdEngine.save(context, inputFile, groups);
-
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(3));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATION_LINES_DATA).onFile(inputFile).withValue("1=0;2=1;3=1;4=1;5=0"));
-
- InOrder inOrder = Mockito.inOrder(duplicationBuilder);
- inOrder.verify(duplicationBuilder).originBlock(2, 4);
- inOrder.verify(duplicationBuilder).isDuplicatedBy("key2", 15, 17);
- inOrder.verify(duplicationBuilder).build();
- }
-
- @Test
- public void testDuplicationOnSameFile() throws Exception {
- List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key1", 0, 215, 414)));
- JavaCpdEngine.save(context, inputFile, groups);
-
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(400));
-
- InOrder inOrder = Mockito.inOrder(duplicationBuilder);
- inOrder.verify(duplicationBuilder).originBlock(5, 204);
- inOrder.verify(duplicationBuilder).isDuplicatedBy("key1", 215, 414);
- inOrder.verify(duplicationBuilder).build();
- }
-
- @Test
- public void testOneDuplicatedGroupInvolvingMoreThanTwoFiles() throws Exception {
- List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214), new ClonePart("key3", 0, 25, 224)));
- JavaCpdEngine.save(context, inputFile, groups);
-
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(200));
-
- InOrder inOrder = Mockito.inOrder(duplicationBuilder);
- inOrder.verify(duplicationBuilder).originBlock(5, 204);
- inOrder.verify(duplicationBuilder).isDuplicatedBy("key2", 15, 214);
- inOrder.verify(duplicationBuilder).isDuplicatedBy("key3", 25, 224);
- inOrder.verify(duplicationBuilder).build();
-
- verify(context).saveDuplications(inputFile, Arrays.asList(
- new DuplicationGroup(new DuplicationGroup.Block("foo:src/main/java/Foo.java", 5, 200))
- .addDuplicate(new DuplicationGroup.Block("key2", 15, 200))
- .addDuplicate(new DuplicationGroup.Block("key3", 25, 200))
- ));
- }
-
- @Test
- public void testTwoDuplicatedGroupsInvolvingThreeFiles() throws Exception {
- List<CloneGroup> groups = Arrays.asList(
- newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214)),
- newCloneGroup(new ClonePart("key1", 0, 15, 214), new ClonePart("key3", 0, 15, 214)));
- JavaCpdEngine.save(context, inputFile, groups);
-
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
- verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(210));
-
- InOrder inOrder = Mockito.inOrder(duplicationBuilder);
- inOrder.verify(duplicationBuilder).originBlock(5, 204);
- inOrder.verify(duplicationBuilder).isDuplicatedBy("key2", 15, 214);
- inOrder.verify(duplicationBuilder).originBlock(15, 214);
- inOrder.verify(duplicationBuilder).isDuplicatedBy("key3", 15, 214);
- inOrder.verify(duplicationBuilder).build();
- }
-
- private CloneGroup newCloneGroup(ClonePart... parts) {
- return CloneGroup.builder().setLength(0).setOrigin(parts[0]).setParts(Arrays.asList(parts)).build();
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecoratorTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecoratorTest.java
deleted file mode 100644
index d1a9835f104..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/DuplicationDensityDecoratorTest.java
+++ /dev/null
@@ -1,80 +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.plugins.cpd.decorators;
-
-import org.junit.Test;
-import static org.mockito.Mockito.*;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-
-public class DuplicationDensityDecoratorTest {
-
- @Test
- public void densityIsBalancedByNclocAndCommentLines() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 40.0));
- when(context.getMeasure(CoreMetrics.COMMENT_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 10.0));
- when(context.getMeasure(CoreMetrics.DUPLICATED_LINES)).thenReturn(new Measure(CoreMetrics.DUPLICATED_LINES, 10.0));
-
- DuplicationDensityDecorator decorator = new DuplicationDensityDecorator();
- decorator.decorate(null, context);
-
- verify(context).saveMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY, 20.0);
- }
-
-
- @Test
- public void densityEvenIfNoComments() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 40.0));
- when(context.getMeasure(CoreMetrics.DUPLICATED_LINES)).thenReturn(new Measure(CoreMetrics.DUPLICATED_LINES, 10.0));
-
- DuplicationDensityDecorator decorator = new DuplicationDensityDecorator();
- decorator.decorate(null, context);
-
- verify(context).saveMeasure(CoreMetrics.DUPLICATED_LINES_DENSITY, 25.0);
- }
-
- @Test
- public void noDensityIfNoDuplicationMeasure() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 45.0));
-
- DuplicationDensityDecorator decorator = new DuplicationDensityDecorator();
- decorator.decorate(null, context);
-
- verify(context, never()).saveMeasure(eq(CoreMetrics.DUPLICATED_LINES_DENSITY), anyDouble());
- }
-
- @Test
- public void noDensityWhenZeroNclocAndComments() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 0.0));
- when(context.getMeasure(CoreMetrics.DUPLICATED_LINES)).thenReturn(new Measure(CoreMetrics.COMMENT_LINES, 0.0));
- when(context.getMeasure(CoreMetrics.DUPLICATED_LINES)).thenReturn(new Measure(CoreMetrics.DUPLICATED_LINES, 10.0));
-
- DuplicationDensityDecorator decorator = new DuplicationDensityDecorator();
- decorator.decorate(null, context);
-
- verify(context, never()).saveMeasure(eq(CoreMetrics.DUPLICATED_LINES_DENSITY), anyDouble());
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecoratorTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecoratorTest.java
deleted file mode 100644
index de90865b0d0..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/decorators/SumDuplicationsDecoratorTest.java
+++ /dev/null
@@ -1,70 +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.plugins.cpd.decorators;
-
-import org.junit.Test;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.test.IsMeasure;
-
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-public class SumDuplicationsDecoratorTest {
-
- @Test
- public void parapets() {
- SumDuplicationsDecorator decorator = new SumDuplicationsDecorator();
- assertThat(decorator.generatesMetrics().size(), greaterThan(0));
- assertThat(decorator.shouldSaveZeroIfNoChildMeasures(), is(true));
- }
-
- @Test
- public void doNotSetDuplicationsOnUnitTests() {
- SumDuplicationsDecorator decorator = new SumDuplicationsDecorator();
- File unitTest = File.create("org/foo/BarTest.java");
- unitTest.setQualifier(Qualifiers.UNIT_TEST_FILE);
- DecoratorContext context = mock(DecoratorContext.class);
-
- decorator.decorate(unitTest, context);
-
- verify(context, never()).saveMeasure(any(Measure.class));
- }
-
- @Test
- public void saveZeroIfNoDuplications() {
- SumDuplicationsDecorator decorator = new SumDuplicationsDecorator();
- File file = File.create("org/foo/BarTest.java");
- DecoratorContext context = mock(DecoratorContext.class);
-
- decorator.decorate(file, context);
-
- verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DUPLICATED_LINES, 0.0)));
- }
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java
deleted file mode 100644
index b515d48e2cf..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java
+++ /dev/null
@@ -1,85 +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.plugins.cpd.index;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.bootstrap.DefaultAnalysisMode;
-import org.sonar.batch.index.ResourceCache;
-import org.sonar.core.duplication.DuplicationDao;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class IndexFactoryTest {
-
- Project project;
- Settings settings;
- IndexFactory factory;
- Logger logger;
- private DefaultAnalysisMode analysisMode;
-
- @Before
- public void setUp() {
- project = new Project("foo");
- settings = new Settings();
- analysisMode = mock(DefaultAnalysisMode.class);
- factory = new IndexFactory(analysisMode, settings, mock(DuplicationDao.class), mock(DatabaseSession.class), new ResourceCache());
- logger = mock(Logger.class);
- }
-
- @Test
- public void crossProjectEnabled() {
- settings.setProperty(CoreProperties.CPD_CROSS_PROJECT, "true");
- assertThat(factory.verifyCrossProject(project, logger)).isTrue();
- verify(logger).info("Cross-project analysis enabled");
- }
-
- @Test
- public void noCrossProjectWithBranch() {
- settings.setProperty(CoreProperties.CPD_CROSS_PROJECT, "true");
- settings.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "branch");
- assertThat(factory.verifyCrossProject(project, logger)).isFalse();
- verify(logger).info("Cross-project analysis disabled. Not supported on project branches.");
- }
-
- @Test
- public void cross_project_should_be_disabled_on_preview() {
- when(analysisMode.isPreview()).thenReturn(true);
- settings.setProperty(CoreProperties.CPD_CROSS_PROJECT, "true");
- assertThat(factory.verifyCrossProject(project, logger)).isFalse();
- verify(logger).info("Cross-project analysis disabled. Not supported in preview mode.");
- }
-
- @Test
- public void crossProjectDisabled() {
- settings.setProperty(CoreProperties.CPD_CROSS_PROJECT, "false");
- assertThat(factory.verifyCrossProject(project, logger)).isFalse();
- verify(logger).info("Cross-project analysis disabled");
- }
-
-}
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java
deleted file mode 100644
index 43043e35eea..00000000000
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java
+++ /dev/null
@@ -1,175 +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.plugins.cpd.medium;
-
-import com.google.common.collect.ImmutableMap;
-import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
-import org.sonar.batch.mediumtest.BatchMediumTester;
-import org.sonar.batch.mediumtest.TaskResult;
-import org.sonar.plugins.cpd.CpdPlugin;
-import org.sonar.xoo.XooPlugin;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CpdMediumTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- public BatchMediumTester tester = BatchMediumTester.builder()
- .registerPlugin("xoo", new XooPlugin())
- .registerPlugin("cpd", new CpdPlugin())
- .addDefaultQProfile("xoo", "Sonar Way")
- .build();
-
- private File baseDir;
-
- private ImmutableMap.Builder<String, String> builder;
-
- @Before
- public void prepare() throws IOException {
- tester.start();
-
- baseDir = temp.newFolder();
-
- builder = ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project");
- }
-
- @After
- public void stop() {
- tester.stop();
- }
-
- @Test
- public void testCrossFileDuplications() throws IOException {
- File srcDir = new File(baseDir, "src");
- srcDir.mkdir();
-
- String duplicatedStuff = "Sample xoo\ncontent\nfoo\nbar\ntoto\ntiti\nfoo\nbar\ntoto\ntiti\nbar\ntoto\ntiti\nfoo\nbar\ntoto\ntiti";
-
- File xooFile1 = new File(srcDir, "sample1.xoo");
- FileUtils.write(xooFile1, duplicatedStuff);
-
- File xooFile2 = new File(srcDir, "sample2.xoo");
- FileUtils.write(xooFile2, duplicatedStuff);
-
- TaskResult result = tester.newTask()
- .properties(builder
- .put("sonar.sources", "src")
- .put("sonar.cpd.xoo.minimumTokens", "10")
- .put("sonar.verbose", "true")
- .build())
- .start();
-
- assertThat(result.inputFiles()).hasSize(2);
-
- // 5 measures per file + quality profile measure
- assertThat(result.measures()).hasSize(11);
-
- InputFile inputFile1 = result.inputFile("src/sample1.xoo");
- InputFile inputFile2 = result.inputFile("src/sample2.xoo");
- // One clone group on each file
- List<DuplicationGroup> duplicationGroupsFile1 = result.duplicationsFor(inputFile1);
- assertThat(duplicationGroupsFile1).hasSize(1);
-
- DuplicationGroup cloneGroupFile1 = duplicationGroupsFile1.get(0);
- assertThat(cloneGroupFile1.duplicates()).hasSize(1);
- assertThat(cloneGroupFile1.originBlock().startLine()).isEqualTo(1);
- assertThat(cloneGroupFile1.originBlock().length()).isEqualTo(17);
- assertThat(cloneGroupFile1.originBlock().resourceKey()).isEqualTo(((DefaultInputFile) inputFile1).key());
- assertThat(cloneGroupFile1.duplicates()).hasSize(1);
- assertThat(cloneGroupFile1.duplicates().get(0).resourceKey()).isEqualTo(((DefaultInputFile) inputFile2).key());
-
- List<DuplicationGroup> duplicationGroupsFile2 = result.duplicationsFor(inputFile2);
- assertThat(duplicationGroupsFile2).hasSize(1);
-
- DuplicationGroup cloneGroupFile2 = duplicationGroupsFile2.get(0);
- assertThat(cloneGroupFile2.duplicates()).hasSize(1);
- assertThat(cloneGroupFile2.originBlock().startLine()).isEqualTo(1);
- assertThat(cloneGroupFile2.originBlock().length()).isEqualTo(17);
- assertThat(cloneGroupFile2.originBlock().resourceKey()).isEqualTo(((DefaultInputFile) inputFile2).key());
- assertThat(cloneGroupFile2.duplicates()).hasSize(1);
- assertThat(cloneGroupFile2.duplicates().get(0).resourceKey()).isEqualTo(((DefaultInputFile) inputFile1).key());
- }
-
- @Test
- public void testIntraFileDuplications() throws IOException {
- File srcDir = new File(baseDir, "src");
- srcDir.mkdir();
-
- String content = "Sample xoo\ncontent\nfoo\nbar\nSample xoo\ncontent\n";
-
- File xooFile = new File(srcDir, "sample.xoo");
- FileUtils.write(xooFile, content);
-
- TaskResult result = tester.newTask()
- .properties(builder
- .put("sonar.sources", "src")
- .put("sonar.cpd.xoo.minimumTokens", "2")
- .put("sonar.cpd.xoo.minimumLines", "2")
- .put("sonar.verbose", "true")
- .build())
- .start();
-
- // 5 measures per file + QP measure
- assertThat(result.measures()).hasSize(6);
-
- InputFile inputFile = result.inputFile("src/sample.xoo");
- // One clone group
- List<DuplicationGroup> duplicationGroups = result.duplicationsFor(inputFile);
- assertThat(duplicationGroups).hasSize(1);
-
- DuplicationGroup cloneGroup = duplicationGroups.get(0);
- assertThat(cloneGroup.duplicates()).hasSize(1);
- assertThat(cloneGroup.originBlock().startLine()).isEqualTo(1);
- assertThat(cloneGroup.originBlock().length()).isEqualTo(2);
- assertThat(cloneGroup.duplicates()).hasSize(1);
- assertThat(cloneGroup.duplicates().get(0).startLine()).isEqualTo(5);
- assertThat(cloneGroup.duplicates().get(0).length()).isEqualTo(2);
-
- // assertThat(result.measures()).contains(new DefaultMeasure<String>()
- // .forMetric(CoreMetrics.DUPLICATION_LINES_DATA)
- // .onFile(inputFile)
- // .withValue("1=1;2=1;3=0;4=0;5=1;6=1;7=0"));
- }
-
-}