]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6933 Drop newDuplication() beta API 663/head
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 1 Dec 2015 10:26:45 +0000 (11:26 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 1 Dec 2015 15:38:08 +0000 (16:38 +0100)
27 files changed:
sonar-batch/src/main/java/org/sonar/batch/cpd/AbstractCpdEngine.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/cpd/DefaultCpdEngine.java
sonar-batch/src/main/java/org/sonar/batch/cpd/JavaCpdEngine.java
sonar-batch/src/main/java/org/sonar/batch/duplication/DefaultDuplicationValueCoder.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationBlockValueCoder.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationCache.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/duplication/package-info.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/report/DuplicationsPublisher.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
sonar-batch/src/test/java/org/sonar/batch/cpd/AbstractCpdEngineTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/cpd/JavaCpdEngineTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/duplication/DuplicationCacheTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/report/DuplicationsPublisherTest.java [deleted file]
sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/Duplication.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/NewDuplication.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplication.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/internal/package-info.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/package-info.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/DuplicationTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplicationTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java

diff --git a/sonar-batch/src/main/java/org/sonar/batch/cpd/AbstractCpdEngine.java b/sonar-batch/src/main/java/org/sonar/batch/cpd/AbstractCpdEngine.java
new file mode 100644 (file)
index 0000000..8905bf5
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.batch.cpd;
+
+import com.google.common.base.Function;
+import java.util.List;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.batch.index.BatchComponent;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReport.Duplicate;
+import org.sonar.batch.protocol.output.BatchReport.Duplication;
+import org.sonar.batch.report.ReportPublisher;
+import org.sonar.duplications.index.CloneGroup;
+import org.sonar.duplications.index.ClonePart;
+
+import static com.google.common.collect.FluentIterable.from;
+
+public abstract class AbstractCpdEngine extends CpdEngine {
+
+  private static final Logger LOG = Loggers.get(AbstractCpdEngine.class);
+
+  static final int MAX_CLONE_GROUP_PER_FILE = 100;
+  static final int MAX_CLONE_PART_PER_GROUP = 100;
+
+  private final ReportPublisher publisher;
+  private final BatchComponentCache batchComponentCache;
+
+  public AbstractCpdEngine(ReportPublisher publisher, BatchComponentCache batchComponentCache) {
+    this.publisher = publisher;
+    this.batchComponentCache = batchComponentCache;
+  }
+
+  protected final void saveDuplications(final InputFile inputFile, List<CloneGroup> duplications) {
+    if (duplications.size() > MAX_CLONE_GROUP_PER_FILE) {
+      LOG.warn("Too many duplication groups on file " + inputFile.relativePath() + ". Keep only the first " + MAX_CLONE_GROUP_PER_FILE + " groups.");
+    }
+    final BatchComponent component = batchComponentCache.get(inputFile);
+    Iterable<org.sonar.batch.protocol.output.BatchReport.Duplication> reportDuplications = from(duplications)
+      .limit(MAX_CLONE_GROUP_PER_FILE)
+      .transform(
+        new Function<CloneGroup, BatchReport.Duplication>() {
+          private final BatchReport.Duplication.Builder dupBuilder = BatchReport.Duplication.newBuilder();
+          private final BatchReport.Duplicate.Builder blockBuilder = BatchReport.Duplicate.newBuilder();
+
+          @Override
+          public BatchReport.Duplication apply(CloneGroup input) {
+            return toReportDuplication(component, inputFile, dupBuilder, blockBuilder, input);
+          }
+
+        });
+    publisher.getWriter().writeComponentDuplications(component.batchId(), reportDuplications);
+  }
+
+  private Duplication toReportDuplication(BatchComponent component, InputFile inputFile, Duplication.Builder dupBuilder, Duplicate.Builder blockBuilder, CloneGroup input) {
+    dupBuilder.clear();
+    ClonePart originBlock = input.getOriginPart();
+    blockBuilder.clear();
+    dupBuilder.setOriginPosition(BatchReport.TextRange.newBuilder()
+      .setStartLine(originBlock.getStartLine())
+      .setEndLine(originBlock.getEndLine())
+      .build());
+    int clonePartCount = 0;
+    for (ClonePart duplicate : input.getCloneParts()) {
+      if (!duplicate.equals(originBlock)) {
+        clonePartCount++;
+        if (clonePartCount > MAX_CLONE_PART_PER_GROUP) {
+          LOG.warn("Too many duplication references on file " + inputFile.relativePath() + " for block at line " + originBlock.getStartLine() + ". Keep only the first "
+            + MAX_CLONE_PART_PER_GROUP + " references.");
+          break;
+        }
+        blockBuilder.clear();
+        String componentKey = duplicate.getResourceId();
+        if (!component.key().equals(componentKey)) {
+          BatchComponent sameProjectComponent = batchComponentCache.get(componentKey);
+          blockBuilder.setOtherFileRef(sameProjectComponent.batchId());
+        }
+        dupBuilder.addDuplicate(blockBuilder
+          .setRange(BatchReport.TextRange.newBuilder()
+            .setStartLine(duplicate.getStartLine())
+            .setEndLine(duplicate.getEndLine())
+            .build())
+          .build());
+      }
+    }
+    return dupBuilder.build();
+  }
+
+}
index a63b04f00065e5393f7e5d48fe27873d71332663..2eb64fcc73d3a8126b49ba9b5fc63608441f9a7b 100644 (file)
@@ -21,9 +21,9 @@ package org.sonar.batch.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 java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -47,7 +47,9 @@ import org.sonar.duplications.block.Block;
 import org.sonar.duplications.index.CloneGroup;
 import org.sonar.duplications.internal.pmd.TokenizerBridge;
 
-public class DefaultCpdEngine extends CpdEngine {
+import static com.google.common.collect.FluentIterable.from;
+
+public class DefaultCpdEngine extends AbstractCpdEngine {
 
   private static final Logger LOG = LoggerFactory.getLogger(DefaultCpdEngine.class);
 
@@ -63,6 +65,7 @@ public class DefaultCpdEngine extends CpdEngine {
   private final BatchComponentCache batchComponentCache;
 
   public DefaultCpdEngine(CpdMappings mappings, FileSystem fs, Settings settings, ReportPublisher publisher, BatchComponentCache batchComponentCache) {
+    super(publisher, batchComponentCache);
     this.mappings = mappings;
     this.fs = fs;
     this.settings = settings;
@@ -112,18 +115,20 @@ public class DefaultCpdEngine extends CpdEngine {
         String resourceEffectiveKey = ((DefaultInputFile) inputFile).key();
         Collection<Block> fileBlocks = index.getByInputFile(inputFile, resourceEffectiveKey);
 
-        Iterable<CloneGroup> filtered;
+        List<CloneGroup> filtered;
         try {
           List<CloneGroup> duplications = executorService.submit(new JavaCpdEngine.Task(index, fileBlocks)).get(TIMEOUT, TimeUnit.SECONDS);
-          filtered = Iterables.filter(duplications, minimumTokensPredicate);
+          filtered = from(duplications)
+            .filter(minimumTokensPredicate)
+            .toList();
         } catch (TimeoutException e) {
-          filtered = null;
+          filtered = Collections.emptyList();
           LOG.warn("Timeout during detection of duplications for " + inputFile, e);
         } catch (InterruptedException | ExecutionException e) {
           throw new IllegalStateException("Fail during detection of duplication for " + inputFile, e);
         }
 
-        JavaCpdEngine.save(context, inputFile, filtered);
+        saveDuplications(inputFile, filtered);
       }
     } finally {
       executorService.shutdown();
index 21bec46e794ec931dcfb5911996ee2a87eac9d5c..d83e049a45a1aa144cb0e76f9dbeb9af92fc14d9 100644 (file)
 
 package org.sonar.batch.cpd;
 
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -34,7 +34,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import javax.annotation.Nullable;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,8 +43,6 @@ import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.duplication.NewDuplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
 import org.sonar.api.config.Settings;
 import org.sonar.batch.cpd.index.SonarDuplicationsIndex;
 import org.sonar.batch.index.BatchComponentCache;
@@ -55,14 +52,13 @@ 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;
 
-public class JavaCpdEngine extends CpdEngine {
+public class JavaCpdEngine extends AbstractCpdEngine {
 
   private static final Logger LOG = LoggerFactory.getLogger(JavaCpdEngine.class);
 
@@ -73,15 +69,13 @@ public class JavaCpdEngine extends CpdEngine {
    */
   private static final int TIMEOUT = 5 * 60;
 
-  private static final int MAX_CLONE_GROUP_PER_FILE = 100;
-  private static final int MAX_CLONE_PART_PER_GROUP = 100;
-
   private final FileSystem fs;
   private final Settings settings;
   private final ReportPublisher publisher;
   private final BatchComponentCache batchComponentCache;
 
   public JavaCpdEngine(FileSystem fs, Settings settings, ReportPublisher publisher, BatchComponentCache batchComponentCache) {
+    super(publisher, batchComponentCache);
     this.fs = fs;
     this.settings = settings;
     this.publisher = publisher;
@@ -152,13 +146,13 @@ public class JavaCpdEngine extends CpdEngine {
         try {
           clones = executorService.submit(new Task(index, fileBlocks)).get(TIMEOUT, TimeUnit.SECONDS);
         } catch (TimeoutException e) {
-          clones = null;
+          clones = Collections.emptyList();
           LOG.warn("Timeout during detection of duplications for " + inputFile, e);
         } catch (InterruptedException | ExecutionException e) {
           throw new IllegalStateException("Fail during detection of duplication for " + inputFile, e);
         }
 
-        save(context, inputFile, clones);
+        saveDuplications(inputFile, clones);
       }
     } finally {
       executorService.shutdown();
@@ -180,39 +174,4 @@ public class JavaCpdEngine extends CpdEngine {
     }
   }
 
-  static void save(org.sonar.api.batch.sensor.SensorContext context, InputFile inputFile, @Nullable Iterable<CloneGroup> duplications) {
-    if (duplications == null || Iterables.isEmpty(duplications)) {
-      return;
-    }
-
-    saveDuplications(context, inputFile, duplications);
-  }
-
-  private static void saveDuplications(org.sonar.api.batch.sensor.SensorContext context, InputFile inputFile, Iterable<CloneGroup> duplications) {
-    int cloneGroupCount = 0;
-    for (CloneGroup duplication : duplications) {
-      cloneGroupCount++;
-      if (cloneGroupCount > MAX_CLONE_GROUP_PER_FILE) {
-        LOG.warn("Too many duplication groups on file " + inputFile.relativePath() + ". Keep only the first " + MAX_CLONE_GROUP_PER_FILE + " groups.");
-        break;
-      }
-      NewDuplication builder = context.newDuplication();
-      ClonePart originPart = duplication.getOriginPart();
-      builder.originBlock(inputFile, originPart.getStartLine(), originPart.getEndLine());
-      int clonePartCount = 0;
-      for (ClonePart part : duplication.getCloneParts()) {
-        if (!part.equals(originPart)) {
-          clonePartCount++;
-          if (clonePartCount > MAX_CLONE_PART_PER_GROUP) {
-            LOG.warn("Too many duplication references on file " + inputFile.relativePath() + " for block at line " + originPart.getStartLine() + ". Keep only the first "
-              + MAX_CLONE_PART_PER_GROUP + " references.");
-            break;
-          }
-          ((DefaultDuplication) builder).isDuplicatedBy(part.getResourceId(), part.getStartLine(), part.getEndLine());
-        }
-      }
-      builder.save();
-    }
-  }
-
 }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/duplication/DefaultDuplicationValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/duplication/DefaultDuplicationValueCoder.java
deleted file mode 100644 (file)
index 1ab206e..0000000
+++ /dev/null
@@ -1,53 +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.batch.duplication;
-
-import com.persistit.Value;
-import com.persistit.encoding.CoderContext;
-import com.persistit.encoding.ValueCoder;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-import org.sonar.api.batch.sensor.duplication.Duplication.Block;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-
-class DefaultDuplicationValueCoder implements ValueCoder {
-
-  private DuplicationBlockValueCoder blockCoder = new DuplicationBlockValueCoder();
-
-  @Override
-  public void put(Value value, Object object, CoderContext context) {
-    DefaultDuplication c = (DefaultDuplication) object;
-    blockCoder.put(value, c.originBlock(), context);
-    value.put(c.duplicates().size());
-    for (Duplication.Block block : c.duplicates()) {
-      blockCoder.put(value, block, context);
-    }
-  }
-
-  @Override
-  public Object get(Value value, Class clazz, CoderContext context) {
-    DefaultDuplication g = new DefaultDuplication();
-    g.setOriginBlock((Block) blockCoder.get(value, Duplication.Block.class, context));
-    int count = value.getInt();
-    for (int i = 0; i < count; i++) {
-      g.duplicates().add((Block) blockCoder.get(value, Duplication.Block.class, context));
-    }
-    return g;
-  }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationBlockValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationBlockValueCoder.java
deleted file mode 100644 (file)
index 50dbd31..0000000
+++ /dev/null
@@ -1,44 +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.batch.duplication;
-
-import com.persistit.Value;
-import com.persistit.encoding.CoderContext;
-import com.persistit.encoding.ValueCoder;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-
-class DuplicationBlockValueCoder implements ValueCoder {
-
-  @Override
-  public void put(Value value, Object object, CoderContext context) {
-    Duplication.Block b = (Duplication.Block) object;
-    value.putUTF(b.resourceKey());
-    value.put(b.startLine());
-    value.put(b.length());
-  }
-
-  @Override
-  public Object get(Value value, Class clazz, CoderContext context) {
-    String resourceKey = value.getString();
-    int startLine = value.getInt();
-    int length = value.getInt();
-    return new Duplication.Block(resourceKey, startLine, length);
-  }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationCache.java b/sonar-batch/src/main/java/org/sonar/batch/duplication/DuplicationCache.java
deleted file mode 100644 (file)
index cfc091d..0000000
+++ /dev/null
@@ -1,62 +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.batch.duplication;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import org.sonar.api.batch.BatchSide;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import org.sonar.batch.index.Cache;
-import org.sonar.batch.index.Caches;
-
-/**
- * Cache of duplication blocks. This cache is shared amongst all project modules.
- */
-@BatchSide
-public class DuplicationCache {
-
-  private final Cache<DefaultDuplication> cache;
-  private int sequence = 1;
-
-  public DuplicationCache(Caches caches) {
-    caches.registerValueCoder(DefaultDuplication.class, new DefaultDuplicationValueCoder());
-    cache = caches.createCache("duplications");
-  }
-
-  public Iterable<String> componentKeys() {
-    return Iterables.transform(cache.keySet(), new Function<Object, String>() {
-      @Override
-      public String apply(Object input) {
-        return input.toString();
-      }
-    });
-  }
-
-  public Iterable<DefaultDuplication> byComponent(String effectiveKey) {
-    return cache.values(effectiveKey);
-  }
-
-  public DuplicationCache put(String effectiveKey, DefaultDuplication duplication) {
-    cache.put(effectiveKey, sequence, duplication);
-    sequence++;
-    return this;
-  }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/duplication/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/duplication/package-info.java
deleted file mode 100644 (file)
index 103e90a..0000000
+++ /dev/null
@@ -1,23 +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.batch.duplication;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/DuplicationsPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/DuplicationsPublisher.java
deleted file mode 100644 (file)
index 068cb1c..0000000
+++ /dev/null
@@ -1,98 +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.batch.report;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import org.sonar.api.batch.sensor.duplication.Duplication.Block;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import org.sonar.batch.duplication.DuplicationCache;
-import org.sonar.batch.index.BatchComponent;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReport.Duplicate;
-import org.sonar.batch.protocol.output.BatchReport.Duplication;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-
-public class DuplicationsPublisher implements ReportPublisherStep {
-
-  private final BatchComponentCache resourceCache;
-  private final DuplicationCache duplicationCache;
-
-  public DuplicationsPublisher(BatchComponentCache resourceCache, DuplicationCache duplicationCache) {
-    this.resourceCache = resourceCache;
-    this.duplicationCache = duplicationCache;
-  }
-
-  @Override
-  public void publish(BatchReportWriter writer) {
-    for (final BatchComponent resource : resourceCache.all()) {
-      if (!resource.isFile()) {
-        continue;
-      }
-      Iterable<DefaultDuplication> dups = duplicationCache.byComponent(resource.resource().getEffectiveKey());
-      if (dups.iterator().hasNext()) {
-        Iterable<org.sonar.batch.protocol.output.BatchReport.Duplication> reportDuplications = Iterables.transform(dups,
-          new Function<DefaultDuplication, BatchReport.Duplication>() {
-            private final BatchReport.Duplication.Builder dupBuilder = BatchReport.Duplication.newBuilder();
-            private final BatchReport.Duplicate.Builder blockBuilder = BatchReport.Duplicate.newBuilder();
-
-            @Override
-            public BatchReport.Duplication apply(DefaultDuplication input) {
-              return toReportDuplication(resource.key(), dupBuilder, blockBuilder, input);
-            }
-
-          });
-        writer.writeComponentDuplications(resource.batchId(), reportDuplications);
-      }
-    }
-  }
-
-  private Duplication toReportDuplication(String currentComponentKey, Duplication.Builder dupBuilder, Duplicate.Builder blockBuilder, DefaultDuplication input) {
-    dupBuilder.clear();
-    Block originBlock = input.originBlock();
-    blockBuilder.clear();
-    dupBuilder.setOriginPosition(BatchReport.TextRange.newBuilder()
-      .setStartLine(originBlock.startLine())
-      .setEndLine(originBlock.startLine() + originBlock.length() - 1)
-      .build());
-    for (Block duplicate : input.duplicates()) {
-      blockBuilder.clear();
-      String componentKey = duplicate.resourceKey();
-      if (!currentComponentKey.equals(componentKey)) {
-        BatchComponent sameProjectComponent = resourceCache.get(componentKey);
-        if (sameProjectComponent != null) {
-          blockBuilder.setOtherFileRef(sameProjectComponent.batchId());
-        } else {
-          // Should never happens
-          throw new IllegalStateException("No cross project duplication supported on batch side: " + componentKey);
-        }
-      }
-      dupBuilder.addDuplicate(blockBuilder
-        .setRange(BatchReport.TextRange.newBuilder()
-          .setStartLine(duplicate.startLine())
-          .setEndLine(duplicate.startLine() + duplicate.length() - 1)
-          .build())
-        .build());
-    }
-    return dupBuilder.build();
-  }
-
-}
index b694beb38cf0fea059641f30f2d94e999d4dae3c..7c5e87050f999ba3b2c2894b50f228f00974312f 100644 (file)
@@ -41,7 +41,6 @@ import org.sonar.batch.bootstrap.ExtensionMatcher;
 import org.sonar.batch.bootstrap.ExtensionUtils;
 import org.sonar.batch.bootstrap.MetricProvider;
 import org.sonar.batch.cache.ProjectPersistentCacheProvider;
-import org.sonar.batch.duplication.DuplicationCache;
 import org.sonar.batch.events.EventBus;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.index.Caches;
@@ -61,7 +60,6 @@ import org.sonar.batch.report.ActiveRulesPublisher;
 import org.sonar.batch.report.AnalysisContextReportPublisher;
 import org.sonar.batch.report.ComponentsPublisher;
 import org.sonar.batch.report.CoveragePublisher;
-import org.sonar.batch.report.DuplicationsPublisher;
 import org.sonar.batch.report.MeasuresPublisher;
 import org.sonar.batch.report.MetadataPublisher;
 import org.sonar.batch.report.ReportPublisher;
@@ -179,9 +177,6 @@ public class ProjectScanContainer extends ComponentContainer {
       // Measures
       MeasureCache.class,
 
-      // Duplications
-      DuplicationCache.class,
-
       ProjectSettings.class,
 
       // Report
@@ -191,7 +186,6 @@ public class ProjectScanContainer extends ComponentContainer {
       ActiveRulesPublisher.class,
       ComponentsPublisher.class,
       MeasuresPublisher.class,
-      DuplicationsPublisher.class,
       CoveragePublisher.class,
       SourcePublisher.class,
       TestExecutionAndCoveragePublisher.class,
index cb58332f96cdd4d9771de32480b1d6d088c591c1..f6d30a2ae02c1e3d195a0d7d1ffcd83c9eab1b7d 100644 (file)
@@ -27,8 +27,6 @@ import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.coverage.NewCoverage;
 import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
-import org.sonar.api.batch.sensor.duplication.NewDuplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
 import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
@@ -114,11 +112,6 @@ public class DefaultSensorContext implements SensorContext {
     return new DefaultHighlighting(sensorStorage);
   }
 
-  @Override
-  public NewDuplication newDuplication() {
-    return new DefaultDuplication(sensorStorage);
-  }
-
   @Override
   public NewCoverage newCoverage() {
     return new DefaultCoverage(sensorStorage);
index bcb38b4958aa8e8cbee5d48dde1100a3c7a5b221..1c25a98091b5b3525caabc89bb3843dde66d1184 100644 (file)
@@ -37,8 +37,6 @@ import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.coverage.CoverageType;
 import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
@@ -53,7 +51,6 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.source.Symbol;
 import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.api.utils.SonarException;
-import org.sonar.batch.duplication.DuplicationCache;
 import org.sonar.batch.index.BatchComponent;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.issue.ModuleIssues;
@@ -94,18 +91,16 @@ public class DefaultSensorStorage implements SensorStorage {
   private final MetricFinder metricFinder;
   private final ModuleIssues moduleIssues;
   private final CoverageExclusions coverageExclusions;
-  private final DuplicationCache duplicationCache;
   private final BatchComponentCache componentCache;
   private final ReportPublisher reportPublisher;
   private final MeasureCache measureCache;
 
   public DefaultSensorStorage(MetricFinder metricFinder, ModuleIssues moduleIssues,
-    Settings settings, FileSystem fs, ActiveRules activeRules, DuplicationCache duplicationCache,
+    Settings settings, FileSystem fs, ActiveRules activeRules,
     CoverageExclusions coverageExclusions, BatchComponentCache componentCache, ReportPublisher reportPublisher, MeasureCache measureCache) {
     this.metricFinder = metricFinder;
     this.moduleIssues = moduleIssues;
     this.coverageExclusions = coverageExclusions;
-    this.duplicationCache = duplicationCache;
     this.componentCache = componentCache;
     this.reportPublisher = reportPublisher;
     this.measureCache = measureCache;
@@ -190,11 +185,6 @@ public class DefaultSensorStorage implements SensorStorage {
     return (File) r.resource();
   }
 
-  @Override
-  public void store(Duplication duplication) {
-    duplicationCache.put(duplication.originBlock().resourceKey(), (DefaultDuplication) duplication);
-  }
-
   @Override
   public void store(DefaultHighlighting highlighting) {
     BatchReportWriter writer = reportPublisher.getWriter();
diff --git a/sonar-batch/src/test/java/org/sonar/batch/cpd/AbstractCpdEngineTest.java b/sonar-batch/src/test/java/org/sonar/batch/cpd/AbstractCpdEngineTest.java
new file mode 100644 (file)
index 0000000..1f843d8
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.batch.cpd;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.batch.index.BatchComponent;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.protocol.output.BatchReport.Duplication;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.batch.report.ReportPublisher;
+import org.sonar.core.util.CloseableIterator;
+import org.sonar.duplications.index.CloneGroup;
+import org.sonar.duplications.index.ClonePart;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AbstractCpdEngineTest {
+
+  @Rule
+  public LogTester logTester = new LogTester();
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  private AbstractCpdEngine engine;
+
+  private BatchReportReader reader;
+  private DefaultInputFile inputFile1;
+  private BatchComponent batchComponent1;
+  private BatchComponent batchComponent2;
+  private BatchComponent batchComponent3;
+
+  @Before
+  public void before() throws IOException {
+    File outputDir = temp.newFolder();
+    ReportPublisher reportPublisher = mock(ReportPublisher.class);
+    when(reportPublisher.getWriter()).thenReturn(new BatchReportWriter(outputDir));
+    reader = new BatchReportReader(outputDir);
+    BatchComponentCache componentCache = new BatchComponentCache();
+    Project p = new Project("foo");
+    componentCache.add(p, null).setInputComponent(new DefaultInputModule("foo"));
+    org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
+    inputFile1 = new DefaultInputFile("foo", "src/Foo.php").setLines(5);
+    batchComponent1 = componentCache.add(sampleFile, null).setInputComponent(inputFile1);
+    org.sonar.api.resources.Resource sampleFile2 = org.sonar.api.resources.File.create("src/Foo2.php").setEffectiveKey("foo:src/Foo2.php");
+    batchComponent2 = componentCache.add(sampleFile2, null).setInputComponent(new DefaultInputFile("foo", "src/Foo2.php").setLines(5));
+    org.sonar.api.resources.Resource sampleFile3 = org.sonar.api.resources.File.create("src/Foo3.php").setEffectiveKey("foo:src/Foo3.php");
+    batchComponent3 = componentCache.add(sampleFile3, null).setInputComponent(new DefaultInputFile("foo", "src/Foo3.php").setLines(5));
+    engine = new AbstractCpdEngine(reportPublisher, componentCache) {
+
+      @Override
+      boolean isLanguageSupported(String language) {
+        return false;
+      }
+
+      @Override
+      void analyse(String language, SensorContext context) {
+      }
+    };
+  }
+
+  @Test
+  public void testNothingToSave() {
+    engine.saveDuplications(inputFile1, Collections.EMPTY_LIST);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(0);
+  }
+
+  @Test
+  public void testOneSimpleDuplicationBetweenTwoFiles() {
+    List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart(batchComponent1.key(), 0, 2, 4), new ClonePart(batchComponent2.key(), 0, 15, 17)));
+    engine.saveDuplications(inputFile1, groups);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(1);
+    CloseableIterator<Duplication> dups = reader.readComponentDuplications(batchComponent1.batchId());
+    Duplication duplication = dups.next();
+    dups.close();
+    assertThat(duplication.getOriginPosition().getStartLine()).isEqualTo(2);
+    assertThat(duplication.getOriginPosition().getEndLine()).isEqualTo(4);
+    assertThat(duplication.getDuplicateList()).hasSize(1);
+    assertThat(duplication.getDuplicate(0).getOtherFileRef()).isEqualTo(batchComponent2.batchId());
+    assertThat(duplication.getDuplicate(0).getRange().getStartLine()).isEqualTo(15);
+    assertThat(duplication.getDuplicate(0).getRange().getEndLine()).isEqualTo(17);
+  }
+
+  @Test
+  public void testDuplicationOnSameFile() throws Exception {
+    List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart(batchComponent1.key(), 0, 5, 204), new ClonePart(batchComponent1.key(), 0, 215, 414)));
+    engine.saveDuplications(inputFile1, groups);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(1);
+    CloseableIterator<Duplication> dups = reader.readComponentDuplications(batchComponent1.batchId());
+    Duplication duplication = dups.next();
+    dups.close();
+    assertThat(duplication.getOriginPosition().getStartLine()).isEqualTo(5);
+    assertThat(duplication.getOriginPosition().getEndLine()).isEqualTo(204);
+    assertThat(duplication.getDuplicateList()).hasSize(1);
+    assertThat(duplication.getDuplicate(0).hasOtherFileRef()).isFalse();
+    assertThat(duplication.getDuplicate(0).getRange().getStartLine()).isEqualTo(215);
+    assertThat(duplication.getDuplicate(0).getRange().getEndLine()).isEqualTo(414);
+  }
+
+  @Test
+  public void testTooManyDuplicates() throws Exception {
+    // 1 origin part + 101 duplicates = 102
+    List<ClonePart> parts = new ArrayList<>(AbstractCpdEngine.MAX_CLONE_PART_PER_GROUP + 2);
+    for (int i = 0; i < AbstractCpdEngine.MAX_CLONE_PART_PER_GROUP + 2; i++) {
+      parts.add(new ClonePart(batchComponent1.key(), i, i, i + 1));
+    }
+    List<CloneGroup> groups = Arrays.asList(CloneGroup.builder().setLength(0).setOrigin(parts.get(0)).setParts(parts).build());
+    engine.saveDuplications(inputFile1, groups);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(1);
+    CloseableIterator<Duplication> dups = reader.readComponentDuplications(batchComponent1.batchId());
+    Duplication duplication = dups.next();
+    dups.close();
+    assertThat(duplication.getDuplicateList()).hasSize(AbstractCpdEngine.MAX_CLONE_PART_PER_GROUP);
+
+    assertThat(logTester.logs(LoggerLevel.WARN)).contains("Too many duplication references on file " + inputFile1.relativePath() + " for block at line 0. Keep only the first "
+      + AbstractCpdEngine.MAX_CLONE_PART_PER_GROUP + " references.");
+  }
+
+  @Test
+  public void testTooManyDuplications() throws Exception {
+    // 1 origin part + 101 duplicates = 102
+    List<CloneGroup> dups = new ArrayList<>(AbstractCpdEngine.MAX_CLONE_GROUP_PER_FILE + 1);
+    for (int i = 0; i < AbstractCpdEngine.MAX_CLONE_GROUP_PER_FILE + 1; i++) {
+      ClonePart clonePart = new ClonePart(batchComponent1.key(), i, i, i + 1);
+      ClonePart dupPart = new ClonePart(batchComponent1.key(), i + 1, i + 1, i + 2);
+      dups.add(newCloneGroup(clonePart, dupPart));
+    }
+    engine.saveDuplications(inputFile1, dups);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(AbstractCpdEngine.MAX_CLONE_GROUP_PER_FILE);
+
+    assertThat(logTester.logs(LoggerLevel.WARN))
+      .contains("Too many duplication groups on file " + inputFile1.relativePath() + ". Keep only the first " + AbstractCpdEngine.MAX_CLONE_GROUP_PER_FILE + " groups.");
+  }
+
+  @Test
+  public void testOneDuplicatedGroupInvolvingMoreThanTwoFiles() throws Exception {
+    List<CloneGroup> groups = Arrays
+      .asList(newCloneGroup(new ClonePart(batchComponent1.key(), 0, 5, 204), new ClonePart(batchComponent2.key(), 0, 15, 214), new ClonePart(batchComponent3.key(), 0, 25, 224)));
+    engine.saveDuplications(inputFile1, groups);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(1);
+    CloseableIterator<Duplication> dups = reader.readComponentDuplications(batchComponent1.batchId());
+    Duplication duplication = dups.next();
+    dups.close();
+    assertThat(duplication.getOriginPosition().getStartLine()).isEqualTo(5);
+    assertThat(duplication.getOriginPosition().getEndLine()).isEqualTo(204);
+    assertThat(duplication.getDuplicateList()).hasSize(2);
+    assertThat(duplication.getDuplicate(0).getOtherFileRef()).isEqualTo(batchComponent2.batchId());
+    assertThat(duplication.getDuplicate(0).getRange().getStartLine()).isEqualTo(15);
+    assertThat(duplication.getDuplicate(0).getRange().getEndLine()).isEqualTo(214);
+    assertThat(duplication.getDuplicate(1).getOtherFileRef()).isEqualTo(batchComponent3.batchId());
+    assertThat(duplication.getDuplicate(1).getRange().getStartLine()).isEqualTo(25);
+    assertThat(duplication.getDuplicate(1).getRange().getEndLine()).isEqualTo(224);
+  }
+
+  @Test
+  public void testTwoDuplicatedGroupsInvolvingThreeFiles() throws Exception {
+    List<CloneGroup> groups = Arrays.asList(
+      newCloneGroup(new ClonePart(batchComponent1.key(), 0, 5, 204), new ClonePart(batchComponent2.key(), 0, 15, 214)),
+      newCloneGroup(new ClonePart(batchComponent1.key(), 0, 15, 214), new ClonePart(batchComponent3.key(), 0, 15, 214)));
+    engine.saveDuplications(inputFile1, groups);
+
+    assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(2);
+    CloseableIterator<Duplication> dups = reader.readComponentDuplications(batchComponent1.batchId());
+    Duplication duplication1 = dups.next();
+    Duplication duplication2 = dups.next();
+    dups.close();
+    assertThat(duplication1.getOriginPosition().getStartLine()).isEqualTo(5);
+    assertThat(duplication1.getOriginPosition().getEndLine()).isEqualTo(204);
+    assertThat(duplication1.getDuplicateList()).hasSize(1);
+    assertThat(duplication1.getDuplicate(0).getOtherFileRef()).isEqualTo(batchComponent2.batchId());
+    assertThat(duplication1.getDuplicate(0).getRange().getStartLine()).isEqualTo(15);
+    assertThat(duplication1.getDuplicate(0).getRange().getEndLine()).isEqualTo(214);
+
+    assertThat(duplication2.getOriginPosition().getStartLine()).isEqualTo(15);
+    assertThat(duplication2.getOriginPosition().getEndLine()).isEqualTo(214);
+    assertThat(duplication2.getDuplicateList()).hasSize(1);
+    assertThat(duplication2.getDuplicate(0).getOtherFileRef()).isEqualTo(batchComponent3.batchId());
+    assertThat(duplication2.getDuplicate(0).getRange().getStartLine()).isEqualTo(15);
+    assertThat(duplication2.getDuplicate(0).getRange().getEndLine()).isEqualTo(214);
+  }
+
+  private CloneGroup newCloneGroup(ClonePart... parts) {
+    return CloneGroup.builder().setLength(0).setOrigin(parts[0]).setParts(Arrays.asList(parts)).build();
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/cpd/JavaCpdEngineTest.java b/sonar-batch/src/test/java/org/sonar/batch/cpd/JavaCpdEngineTest.java
deleted file mode 100644 (file)
index ea02cec..0000000
+++ /dev/null
@@ -1,134 +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.batch.cpd;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.duplication.NewDuplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.measure.Measure;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.duplications.index.CloneGroup;
-import org.sonar.duplications.index.ClonePart;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class JavaCpdEngineTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  SensorContext context = mock(SensorContext.class);
-  DefaultInputFile inputFile;
-  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);
-      }
-    });
-    when(context.newDuplication()).then(new Answer<NewDuplication>() {
-      @Override
-      public NewDuplication answer(InvocationOnMock invocation) throws Throwable {
-        return new DefaultDuplication(storage);
-      }
-    });
-    inputFile = (DefaultInputFile) new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(300);
-    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 DefaultDuplication()
-      .originBlock(inputFile, 2, 4)
-      .isDuplicatedBy("key2", 15, 17));
-  }
-
-  @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 DefaultDuplication()
-      .originBlock(inputFile, 5, 204)
-      .isDuplicatedBy("key1", 215, 414));
-  }
-
-  @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 DefaultDuplication()
-      .originBlock(inputFile, 5, 204)
-      .isDuplicatedBy("key2", 15, 214)
-      .isDuplicatedBy("key3", 25, 224));
-  }
-
-  @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 DefaultDuplication()
-      .originBlock(inputFile, 5, 204)
-      .isDuplicatedBy("key2", 15, 214));
-    verify(storage).store(new DefaultDuplication()
-      .originBlock(inputFile, 15, 214)
-      .isDuplicatedBy("key3", 15, 214));
-  }
-
-  private CloneGroup newCloneGroup(ClonePart... parts) {
-    return CloneGroup.builder().setLength(0).setOrigin(parts[0]).setParts(Arrays.asList(parts)).build();
-  }
-
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/duplication/DuplicationCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/duplication/DuplicationCacheTest.java
deleted file mode 100644 (file)
index f591381..0000000
+++ /dev/null
@@ -1,65 +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.batch.duplication;
-
-import org.sonar.batch.index.AbstractCachesTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class DuplicationCacheTest extends AbstractCachesTest {
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Test
-  public void should_add_clone_groups() {
-    DuplicationCache cache = new DuplicationCache(caches);
-
-    DefaultDuplication group1 = new DefaultDuplication()
-      .setOriginBlock(new Duplication.Block("foo", 1, 2));
-    group1.duplicates().add(new Duplication.Block("foo", 1, 2));
-    group1.duplicates().add(new Duplication.Block("foo2", 12, 22));
-    group1.duplicates().add(new Duplication.Block("foo3", 13, 23));
-
-    DefaultDuplication group2 = new DefaultDuplication()
-      .setOriginBlock(new Duplication.Block("2foo", 1, 2));
-    group2.duplicates().add(new Duplication.Block("2foo", 1, 2));
-    group2.duplicates().add(new Duplication.Block("2foo2", 12, 22));
-    group2.duplicates().add(new Duplication.Block("2foo3", 13, 23));
-
-    assertThat(cache.componentKeys()).hasSize(0);
-
-    cache.put("foo", group1);
-    cache.put("foo", group2);
-
-    assertThat(cache.componentKeys()).hasSize(1);
-    assertThat(cache.byComponent("foo")).hasSize(2);
-
-    Iterable<DefaultDuplication> entry = cache.byComponent("foo");
-    assertThat(entry.iterator().next().originBlock().resourceKey()).isEqualTo("foo");
-
-  }
-
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/DuplicationsPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/DuplicationsPublisherTest.java
deleted file mode 100644 (file)
index 6482786..0000000
+++ /dev/null
@@ -1,155 +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.batch.report;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collections;
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-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.internal.DefaultInputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.duplication.DuplicationCache;
-import org.sonar.batch.index.BatchComponentCache;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.protocol.output.BatchReportReader;
-import org.sonar.batch.protocol.output.BatchReportWriter;
-import org.sonar.core.util.CloseableIterator;
-import org.sonar.core.util.ContextException;
-
-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.when;
-
-public class DuplicationsPublisherTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-  @Rule
-  public ExpectedException expectedException = ExpectedException.none();
-
-  private DuplicationCache duplicationCache;
-  private DuplicationsPublisher publisher;
-
-  @Before
-  public void prepare() {
-    BatchComponentCache resourceCache = new BatchComponentCache();
-    Project p = new Project("foo");
-    resourceCache.add(p, null).setInputComponent(new DefaultInputModule("foo"));
-    org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
-    resourceCache.add(sampleFile, null).setInputComponent(new DefaultInputFile("foo", "src/Foo.php").setLines(5));
-    org.sonar.api.resources.Resource sampleFile2 = org.sonar.api.resources.File.create("src/Foo2.php").setEffectiveKey("foo:src/Foo2.php");
-    resourceCache.add(sampleFile2, null).setInputComponent(new DefaultInputFile("foo", "src/Foo2.php").setLines(5));
-    duplicationCache = mock(DuplicationCache.class);
-    when(duplicationCache.byComponent(anyString())).thenReturn(Collections.<DefaultDuplication>emptyList());
-    publisher = new DuplicationsPublisher(resourceCache, duplicationCache);
-  }
-
-  @Test
-  public void publishDuplications_throws_IAE_if_resource_of_duplicate_does_not_exist() throws Exception {
-
-    DefaultDuplication dup1 = new DefaultDuplication()
-        .setOriginBlock(new Duplication.Block("foo:src/Foo.php", 11, 10))
-        .isDuplicatedBy("another", 20, 50);
-    when(duplicationCache.byComponent("foo:src/Foo.php")).thenReturn(Arrays.asList(dup1));
-
-    expectedException.expect(ContextException.class);
-    expectedException.expectCause(new CauseMatcher(IllegalStateException.class, "No cross project duplication supported on batch side: another"));
-
-    File outputDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(outputDir);
-
-    publisher.publish(writer);
-  }
-
-  private static class CauseMatcher extends TypeSafeMatcher<Throwable> {
-
-    private final Class<? extends Throwable> type;
-    private final String expectedMessage;
-
-    public CauseMatcher(Class<? extends Throwable> type, String expectedMessage) {
-      this.type = type;
-      this.expectedMessage = expectedMessage;
-    }
-
-    @Override
-    protected boolean matchesSafely(Throwable item) {
-      return item.getClass().isAssignableFrom(type)
-          && item.getMessage().contains(expectedMessage);
-    }
-
-    @Override
-    public void describeTo(Description description) {
-      description.appendText("expects type ")
-          .appendValue(type)
-          .appendText(" and a message ")
-          .appendValue(expectedMessage);
-    }
-  }
-
-  @Test
-  public void publishDuplications() throws Exception {
-
-    DefaultDuplication dup1 = new DefaultDuplication()
-      .setOriginBlock(new Duplication.Block("foo:src/Foo.php", 1, 10))
-      .isDuplicatedBy("foo:src/Foo.php", 20, 50);
-    DefaultDuplication dup2 = new DefaultDuplication()
-      .setOriginBlock(new Duplication.Block("foo:src/Foo.php", 11, 10))
-      .isDuplicatedBy("foo:src/Foo2.php", 20, 50);
-    when(duplicationCache.byComponent("foo:src/Foo.php")).thenReturn(Arrays.asList(dup1, dup2));
-
-    File outputDir = temp.newFolder();
-    BatchReportWriter writer = new BatchReportWriter(outputDir);
-
-    publisher.publish(writer);
-
-    BatchReportReader reader = new BatchReportReader(outputDir);
-
-    assertThat(reader.readComponentDuplications(1)).hasSize(0);
-    try (CloseableIterator<BatchReport.Duplication> componentDuplications = reader.readComponentDuplications(2)) {
-      org.sonar.batch.protocol.output.BatchReport.Duplication savedDup1 = componentDuplications.next();
-      assertThat(savedDup1.getOriginPosition().getStartLine()).isEqualTo(1);
-      assertThat(savedDup1.getOriginPosition().getEndLine()).isEqualTo(10);
-      assertThat(savedDup1.getDuplicate(0).hasOtherFileRef()).isFalse();
-      assertThat(savedDup1.getDuplicate(0).getRange().getStartLine()).isEqualTo(20);
-      assertThat(savedDup1.getDuplicate(0).getRange().getEndLine()).isEqualTo(50);
-
-      org.sonar.batch.protocol.output.BatchReport.Duplication savedDup2 = componentDuplications.next();
-      assertThat(savedDup2.getOriginPosition().getStartLine()).isEqualTo(11);
-      assertThat(savedDup2.getOriginPosition().getEndLine()).isEqualTo(20);
-      assertThat(savedDup2.getDuplicate(0).getOtherFileRef()).isEqualTo(3);
-      assertThat(savedDup2.getDuplicate(0).getRange().getStartLine()).isEqualTo(20);
-      assertThat(savedDup2.getDuplicate(0).getRange().getEndLine()).isEqualTo(50);
-
-      assertThat(componentDuplications.hasNext()).isFalse();
-    }
-
-  }
-
-}
index 85ccba5628bfd447be83d4e68fd8b99837a93a15..618e5ea3a456e712df0ae9d17738cacda379f320 100644 (file)
@@ -39,7 +39,6 @@ import org.sonar.api.measures.Measure;
 import org.sonar.api.resources.File;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
-import org.sonar.batch.duplication.DuplicationCache;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.issue.ModuleIssues;
 import org.sonar.batch.report.ReportPublisher;
@@ -85,7 +84,7 @@ public class DefaultSensorStorageTest {
     when(coverageExclusions.accept(any(Resource.class), any(Measure.class))).thenReturn(true);
     resourceCache = new BatchComponentCache();
     sensorStorage = new DefaultSensorStorage(metricFinder,
-      moduleIssues, settings, fs, activeRules, mock(DuplicationCache.class), coverageExclusions, resourceCache, mock(ReportPublisher.class), measureCache);
+      moduleIssues, settings, fs, activeRules, coverageExclusions, resourceCache, mock(ReportPublisher.class), measureCache);
   }
 
   @Test
index 87a98418dffed81f54a63d437cdc9dde9943e353..0ae851463cecc0cf4b86578d2229a95ee664a20f 100644 (file)
 package org.sonar.api.batch.sensor;
 
 import com.google.common.annotations.Beta;
+import java.io.Serializable;
 import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.CpdMapping;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.sensor.coverage.NewCoverage;
-import org.sonar.api.batch.sensor.duplication.NewDuplication;
 import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorContextTester;
 import org.sonar.api.batch.sensor.issue.Issue;
@@ -34,8 +33,6 @@ import org.sonar.api.batch.sensor.measure.Measure;
 import org.sonar.api.batch.sensor.measure.NewMeasure;
 import org.sonar.api.config.Settings;
 
-import java.io.Serializable;
-
 /**
  * See {@link Sensor#execute(SensorContext)}
  * In order to write unit tests you can use {@link SensorContextTester}
@@ -89,14 +86,6 @@ public interface SensorContext {
 
   // TODO
 
-  // ------------ DUPLICATIONS ------------
-
-  /**
-   * Builder to manually register duplication in a file. This can be used in addition to {@link CpdMapping} extension point.
-   * Don't forget to call {@link NewDuplication#save()}.
-   */
-  NewDuplication newDuplication();
-
   // ------------ TESTS ------------
 
   /**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/Duplication.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/Duplication.java
deleted file mode 100644 (file)
index e445d5c..0000000
+++ /dev/null
@@ -1,106 +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.api.batch.sensor.duplication;
-
-import com.google.common.annotations.Beta;
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.batch.sensor.SensorContext;
-
-import java.util.List;
-
-/**
- * <p/>
- * A {@link Duplication} is a list of duplicated {@link Block}s. One block
- * is considered as the original code and all others are duplicates.
- * Use {@link SensorContext#newDuplication()} to manually create a duplication. Use {@link SensorContext#duplicationTokenBuilder(org.sonar.api.batch.fs.InputFile)}
- * to feed tokens and let the core compute duplications.
- * @since 5.1
- */
-@Beta
-public interface Duplication {
-
-  class Block {
-    private final String resourceKey;
-    private final int startLine;
-    private final int length;
-
-    public Block(String resourceKey, int startLine, int length) {
-      this.resourceKey = resourceKey;
-      this.startLine = startLine;
-      this.length = length;
-    }
-
-    public String resourceKey() {
-      return resourceKey;
-    }
-
-    public int startLine() {
-      return startLine;
-    }
-
-    public int length() {
-      return length;
-    }
-
-    // Just for unit tests
-    @Override
-    public boolean equals(Object obj) {
-      if (obj == null) {
-        return false;
-      }
-      if (obj == this) {
-        return true;
-      }
-      if (obj.getClass() != getClass()) {
-        return false;
-      }
-      Block rhs = (Block) obj;
-      return new EqualsBuilder()
-        .append(resourceKey, rhs.resourceKey)
-        .append(startLine, rhs.startLine)
-        .append(length, rhs.length).isEquals();
-    }
-
-    @Override
-    public int hashCode() {
-      return new HashCodeBuilder(13, 43)
-        .append(resourceKey)
-        .append(startLine)
-        .append(length).toHashCode();
-    }
-
-    @Override
-    public String toString() {
-      return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
-        append("resourceKey", resourceKey).
-        append("startLine", startLine).
-        append("length", length).
-        toString();
-    }
-  }
-
-  Block originBlock();
-
-  List<Block> duplicates();
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/NewDuplication.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/NewDuplication.java
deleted file mode 100644 (file)
index d4d06ba..0000000
+++ /dev/null
@@ -1,56 +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.api.batch.sensor.duplication;
-
-import com.google.common.annotations.Beta;
-import org.sonar.api.batch.fs.InputFile;
-
-/**
- * <p/>
- * This builder is used to declare duplications on files of the project.
- * Usage:
- * <code><pre>
- * context.newDuplication();
- *   .originBlock(inputFile, 2, 10)
- *   .isDuplicatedBy(inputFile, 14, 22)
- *   .isDuplicatedBy(anotherInputFile, 3, 11)
- *   .save();
- * </pre></code>
- * @since 5.1
- */
-@Beta
-public interface NewDuplication {
-
-  /**
-   * Declare duplication origin block. Then call {@link #isDuplicatedBy(InputFile, int, int)} to reference all duplicates of this block.
-   */
-  NewDuplication originBlock(InputFile originFile, int startLine, int endLine);
-
-  /**
-   * Declare duplicate block of the previously declared {@link #originBlock(int, int)}. Can be called several times.
-   * @param sameOrOtherFile duplicate can be in the same file or in another file.
-   */
-  NewDuplication isDuplicatedBy(InputFile sameOrOtherFile, int startLine, int endLine);
-
-  /**
-   * Save the duplication.
-   */
-  void save();
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplication.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplication.java
deleted file mode 100644 (file)
index 6c00e8b..0000000
+++ /dev/null
@@ -1,145 +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.api.batch.sensor.duplication.internal;
-
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-
-import com.google.common.base.Preconditions;
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-import org.sonar.api.batch.sensor.duplication.NewDuplication;
-import org.sonar.api.batch.sensor.internal.DefaultStorable;
-
-import javax.annotation.Nullable;
-
-import java.util.LinkedList;
-import java.util.List;
-
-public class DefaultDuplication extends DefaultStorable implements NewDuplication, Duplication {
-
-  private Block originBlock;
-  private List<Block> duplicates = new LinkedList<>();
-
-  public DefaultDuplication() {
-    super();
-  }
-
-  public DefaultDuplication(@Nullable SensorStorage storage) {
-    super(storage);
-  }
-
-  @Override
-  public DefaultDuplication originBlock(InputFile inputFile, int startLine, int endLine) {
-    Preconditions.checkArgument(inputFile != null, "InputFile can't be null");
-    validateLineArgument(inputFile, startLine, "startLine");
-    validateLineArgument(inputFile, endLine, "endLine");
-    originBlock = new Duplication.Block(((DefaultInputFile) inputFile).key(), startLine, endLine - startLine + 1);
-    return this;
-  }
-
-  @Override
-  public DefaultDuplication isDuplicatedBy(InputFile sameOrOtherFile, int startLine, int endLine) {
-    Preconditions.checkArgument(sameOrOtherFile != null, "InputFile can't be null");
-    validateLineArgument(sameOrOtherFile, startLine, "startLine");
-    validateLineArgument(sameOrOtherFile, endLine, "endLine");
-    return isDuplicatedBy(((DefaultInputFile) sameOrOtherFile).key(), startLine, endLine);
-  }
-
-  /**
-   * For internal use. Global duplications are referencing files outside of current project so
-   * no way to manipulate an InputFile.
-   */
-  public DefaultDuplication isDuplicatedBy(String fileKey, int startLine, int endLine) {
-    Preconditions.checkNotNull(originBlock, "Call originBlock() first");
-    duplicates.add(new Duplication.Block(fileKey, startLine, endLine - startLine + 1));
-    return this;
-  }
-
-  @Override
-  public void doSave() {
-    Preconditions.checkNotNull(originBlock, "Call originBlock() first");
-    Preconditions.checkState(!duplicates.isEmpty(), "No duplicates. Call isDuplicatedBy()");
-    storage.store(this);
-  }
-
-  @Override
-  public Block originBlock() {
-    return originBlock;
-  }
-
-  public DefaultDuplication setOriginBlock(Block originBlock) {
-    this.originBlock = originBlock;
-    return this;
-  }
-
-  @Override
-  public List<Block> duplicates() {
-    return duplicates;
-  }
-
-  // Just for unit tests
-  @Override
-  public boolean equals(Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (obj == this) {
-      return true;
-    }
-    if (obj.getClass() != getClass()) {
-      return false;
-    }
-    DefaultDuplication rhs = (DefaultDuplication) obj;
-    EqualsBuilder equalsBuilder = new EqualsBuilder()
-      .append(originBlock, rhs.originBlock)
-      .append(duplicates.size(), rhs.duplicates.size());
-    if (duplicates.size() == rhs.duplicates.size()) {
-      for (int i = 0; i < duplicates.size(); i++) {
-        equalsBuilder.append(duplicates.get(i), rhs.duplicates.get(i));
-      }
-    }
-    return equalsBuilder.isEquals();
-  }
-
-  @Override
-  public int hashCode() {
-    HashCodeBuilder hcBuilder = new HashCodeBuilder(17, 37)
-      .append(originBlock)
-      .append(duplicates.size());
-    for (int i = 0; i < duplicates.size(); i++) {
-      hcBuilder.append(duplicates.get(i));
-    }
-    return hcBuilder.toHashCode();
-  }
-
-  @Override
-  public String toString() {
-    return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).
-      append("origin", originBlock).
-      append("duplicates", duplicates, true).
-      toString();
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/internal/package-info.java
deleted file mode 100644 (file)
index 229366c..0000000
+++ /dev/null
@@ -1,21 +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.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.api.batch.sensor.duplication.internal;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/duplication/package-info.java
deleted file mode 100644 (file)
index 4973316..0000000
+++ /dev/null
@@ -1,21 +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.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.api.batch.sensor.duplication;
index df0e22ab0418a23d3055495177cd8e81d048670b..11030102a8b95083c71a40f812f07a20f9c85f41 100644 (file)
@@ -42,9 +42,6 @@ import org.sonar.api.batch.sensor.SensorContext;
 import org.sonar.api.batch.sensor.coverage.CoverageType;
 import org.sonar.api.batch.sensor.coverage.NewCoverage;
 import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
-import org.sonar.api.batch.sensor.duplication.Duplication;
-import org.sonar.api.batch.sensor.duplication.NewDuplication;
-import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
 import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
@@ -206,15 +203,6 @@ public class SensorContextTester implements SensorContext {
     return result;
   }
 
-  @Override
-  public NewDuplication newDuplication() {
-    return new DefaultDuplication(sensorStorage);
-  }
-
-  public Collection<Duplication> duplications() {
-    return sensorStorage.duplications;
-  }
-
   public static class MockAnalysisMode implements AnalysisMode {
     private boolean isPreview = false;
     private boolean isIssues = false;
@@ -252,8 +240,6 @@ public class SensorContextTester implements SensorContext {
     private Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
     private Map<String, Map<CoverageType, DefaultCoverage>> coverageByComponent = new HashMap<>();
 
-    private List<Duplication> duplications = new ArrayList<>();
-
     @Override
     public void store(Measure measure) {
       measuresByComponentAndMetric.row(measure.inputComponent().key()).put(measure.metric().key(), measure);
@@ -264,11 +250,6 @@ public class SensorContextTester implements SensorContext {
       allIssues.add(issue);
     }
 
-    @Override
-    public void store(Duplication duplication) {
-      duplications.add(duplication);
-    }
-
     @Override
     public void store(DefaultHighlighting highlighting) {
       highlightingByComponent.put(highlighting.inputFile().key(), highlighting);
index 60609262b7a21d842134f3a41ab7bd775d8cd321..c9955399506c77a8c03e4ea630ed009323982f1b 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.api.batch.sensor.internal;
 
 import org.sonar.api.batch.BatchSide;
 import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
-import org.sonar.api.batch.sensor.duplication.Duplication;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.issue.Issue;
 import org.sonar.api.batch.sensor.measure.Measure;
@@ -37,8 +36,6 @@ public interface SensorStorage {
 
   void store(Issue issue);
 
-  void store(Duplication duplication);
-
   void store(DefaultHighlighting highlighting);
 
   /**
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/DuplicationTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/DuplicationTest.java
deleted file mode 100644 (file)
index 45b5346..0000000
+++ /dev/null
@@ -1,43 +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.api.batch.sensor.duplication;
-
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class DuplicationTest {
-
-  @Test
-  public void testBlockEqualsAndCo() {
-    Duplication.Block b1 = new Duplication.Block("foo", 1, 10);
-    Duplication.Block b2 = new Duplication.Block("foo", 1, 10);
-    assertThat(b1).isEqualTo(b1);
-    assertThat(b1).isEqualTo(b2);
-    assertThat(b1).isNotEqualTo("");
-    assertThat(b1).isNotEqualTo(new Duplication.Block("foo1", 1, 10));
-    assertThat(b1).isNotEqualTo(new Duplication.Block("foo", 2, 10));
-    assertThat(b1).isNotEqualTo(new Duplication.Block("foo", 1, 11));
-
-    assertThat(b1.hashCode()).isEqualTo(188843970);
-    assertThat(b1.toString()).isEqualTo("Duplication.Block[resourceKey=foo,startLine=1,length=10]");
-  }
-
-}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplicationTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplicationTest.java
deleted file mode 100644 (file)
index efee043..0000000
+++ /dev/null
@@ -1,72 +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.api.batch.sensor.duplication.internal;
-
-import org.junit.Test;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.duplication.Duplication.Block;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class DefaultDuplicationTest {
-
-  @Test
-  public void testDuplicationEqualsAndCo() {
-    DefaultInputFile file1 = new DefaultInputFile("foo", "bar.txt").setLines(50);
-    DefaultInputFile file2 = new DefaultInputFile("foo", "bar2.txt").setLines(50);
-    DefaultDuplication d1 = new DefaultDuplication()
-      .originBlock(file1, 1, 10)
-      .isDuplicatedBy(file1, 20, 29)
-      .isDuplicatedBy(file2, 1, 10);
-    DefaultDuplication d2 = new DefaultDuplication()
-      .originBlock(file1, 1, 10)
-      .isDuplicatedBy(file1, 20, 29)
-      .isDuplicatedBy(file2, 1, 10);
-    DefaultDuplication d3 = new DefaultDuplication()
-      .originBlock(file1, 1, 10);
-    assertThat(d1).isEqualTo(d1);
-    assertThat(d1).isEqualTo(d2);
-    assertThat(d1).isNotEqualTo("");
-    assertThat(d1).isNotEqualTo(d3);
-
-    assertThat(d1.hashCode()).isNotNull();
-    assertThat(d1.toString()).contains("origin=Duplication.Block[resourceKey=foo:bar.txt,startLine=1,length=10]");
-    assertThat(d1.toString()).contains(
-      "duplicates=[Duplication.Block[resourceKey=foo:bar.txt,startLine=20,length=10], Duplication.Block[resourceKey=foo:bar2.txt,startLine=1,length=10]]");
-  }
-
-  @Test
-  public void test() {
-
-    DefaultInputFile file1 = new DefaultInputFile("foo", "foo.php").setLines(50);
-    DefaultInputFile file2 = new DefaultInputFile("foo", "foo2.php").setLines(50);
-
-    DefaultDuplication dup = new DefaultDuplication().originBlock(file1, 1, 11)
-      .isDuplicatedBy(file1, 40, 50)
-      .isDuplicatedBy(file2, 1, 10);
-
-    Block originBlock = dup.originBlock();
-    assertThat(originBlock.resourceKey()).isEqualTo("foo:foo.php");
-    assertThat(originBlock.startLine()).isEqualTo(1);
-    assertThat(originBlock.length()).isEqualTo(11);
-    assertThat(dup.duplicates()).hasSize(2);
-  }
-
-}
index 7895ab3f3eee44287437e5dae895806824123094..5e146870ea7ee8ae0d01bec55e98a20e09144414 100644 (file)
  */
 package org.sonar.api.batch.sensor.internal;
 
-import org.sonar.api.batch.sensor.coverage.NewCoverage;
-
-import org.junit.rules.ExpectedException;
-
 import java.io.File;
 import java.io.StringReader;
-
 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.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
@@ -37,11 +33,13 @@ import org.sonar.api.batch.fs.internal.FileMetadata;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.sensor.coverage.CoverageType;
+import org.sonar.api.batch.sensor.coverage.NewCoverage;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.issue.NewIssue;
 import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.rule.RuleKey;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class SensorContextTesterTest {
@@ -147,29 +145,18 @@ public class SensorContextTesterTest {
     assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 9)).containsExactly(TypeOfText.CONSTANT, TypeOfText.COMMENT);
   }
 
-  @Test
-  public void testDuplication() {
-    assertThat(tester.duplications()).isEmpty();
-    tester.newDuplication()
-      .originBlock(new DefaultInputFile("foo", "src/Foo.java").setLines(40), 1, 30)
-      .isDuplicatedBy(new DefaultInputFile("foo", "src/Foo2.java").setLines(40), 3, 33)
-      .isDuplicatedBy(new DefaultInputFile("foo", "src/Foo3.java").setLines(40), 4, 34)
-      .save();
-    assertThat(tester.duplications()).hasSize(1);
-  }
-
   @Test
   public void testCoverageAtLineZero() {
     assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull();
     assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 4)).isNull();
-    
+
     exception.expect(IllegalStateException.class);
     NewCoverage coverage = tester.newCoverage()
       .onFile(new DefaultInputFile("foo", "src/Foo.java").initMetadata(new FileMetadata().readMetadata(new StringReader("annot dsf fds foo bar"))))
       .ofType(CoverageType.UNIT)
       .lineHits(0, 3);
   }
-  
+
   @Test
   public void testCoverageAtLineOutOfRange() {
     assertThat(tester.lineHits("foo:src/Foo.java", CoverageType.UNIT, 1)).isNull();