diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2015-02-16 11:28:21 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2015-02-16 18:32:02 +0100 |
commit | 2660b61c7d0c0aee191ab719bf672f7902e78c5e (patch) | |
tree | 3fc4ecdca84ae66e2d4d623e1840f32e99b5e7d1 /plugins/sonar-cpd-plugin/src | |
parent | 1230b06fa26f9cc032c15d39f3563867d9d2914b (diff) | |
download | sonarqube-2660b61c7d0c0aee191ab719bf672f7902e78c5e.tar.gz sonarqube-2660b61c7d0c0aee191ab719bf672f7902e78c5e.zip |
SONAR-6000 Merge cpd core plugin into the batch
Diffstat (limited to 'plugins/sonar-cpd-plugin/src')
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")); - } - -} |