import org.sonar.api.utils.SonarException;
import org.sonar.batch.cpd.index.IndexFactory;
import org.sonar.batch.cpd.index.SonarDuplicationsIndex;
-import org.sonar.duplications.DuplicationPredicates;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.internal.pmd.TokenizerBridge;
--- /dev/null
+/*
+ * 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.Predicate;
+import org.sonar.duplications.index.CloneGroup;
+
+import javax.annotation.Nullable;
+
+public final class DuplicationPredicates {
+
+ private DuplicationPredicates() {
+ }
+
+ public static Predicate<CloneGroup> numberOfUnitsNotLessThan(int min) {
+ return new NumberOfUnitsNotLessThan(min);
+ }
+
+ private static class NumberOfUnitsNotLessThan implements Predicate<CloneGroup> {
+ private final int min;
+
+ public NumberOfUnitsNotLessThan(int min) {
+ this.min = min;
+ }
+
+ @Override
+ public boolean apply(@Nullable CloneGroup input) {
+ return input != null && input.getLengthInUnits() >= min;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.Predicate;
+import org.junit.Test;
+import org.sonar.duplications.index.CloneGroup;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DuplicationPredicatesTest {
+
+ @Test
+ public void testNumberOfUnitsNotLessThan() {
+ Predicate<CloneGroup> predicate = DuplicationPredicates.numberOfUnitsNotLessThan(5);
+ assertThat(predicate.apply(CloneGroup.builder().setLengthInUnits(6).build())).isTrue();
+ assertThat(predicate.apply(CloneGroup.builder().setLengthInUnits(5).build())).isTrue();
+ assertThat(predicate.apply(CloneGroup.builder().setLengthInUnits(4).build())).isFalse();
+ }
+
+}
*/
package net.sourceforge.pmd.cpd;
-import com.google.common.io.Closeables;
-
-import java.io.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.io.StringReader;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
protected abstract Reader getReader() throws Exception;
protected List<String> load() {
- LineNumberReader lnr = null;
- try {
- lnr = new LineNumberReader(getReader());
+ try (LineNumberReader lnr = new LineNumberReader(getReader())) {
List<String> lines = new ArrayList<>();
String currentLine;
while ((currentLine = lnr.readLine()) != null) {
return lines;
} catch (Exception e) {
throw new IllegalStateException("Problem while reading " + getFileName() + ":" + e.getMessage(), e);
- } finally {
- Closeables.closeQuietly(lnr);
}
}
}
*/
package net.sourceforge.pmd.cpd;
-import com.google.common.annotations.Beta;
-import org.apache.commons.lang.builder.ToStringBuilder;
-
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.lang.builder.ToStringBuilder;
/**
* @since 2.2
*
* @since 2.14
*/
- @Beta
public String getValue() {
return value;
}
*/
package org.sonar.duplications;
-import com.google.common.annotations.Beta;
/**
* TODO Enforce contracts of this interface in concrete classes by using preconditions, currently this leads to failures of tests.
*
* @since 2.14
*/
-@Beta
public interface CodeFragment {
/**
*/
package org.sonar.duplications.block;
-import com.google.common.annotations.Beta;
import org.sonar.duplications.CodeFragment;
/**
return this;
}
- @Beta
public Builder setUnit(int start, int end) {
this.startUnit = start;
this.endUnit = end;
/**
* @since 2.14
*/
- @Beta
public int getStartUnit() {
return startUnit;
}
/**
* @since 2.14
*/
- @Beta
public int getEndUnit() {
return endUnit;
}
*/
package org.sonar.duplications.block;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
import org.sonar.duplications.statement.Statement;
import java.util.Collections;
}
public List<Block> chunk(String resourceId, List<Statement> statements) {
- List<Statement> filtered = Lists.newArrayList();
+ List<Statement> filtered = new ArrayList<>();
int i = 0;
while (i < statements.size()) {
Statement first = statements.get(i);
return Collections.emptyList();
}
Statement[] statementsArr = statements.toArray(new Statement[statements.size()]);
- List<Block> blocks = Lists.newArrayListWithCapacity(statementsArr.length - blockSize + 1);
+ List<Block> blocks = new ArrayList<>(statementsArr.length - blockSize + 1);
long hash = 0;
int first = 0;
int last = 0;
*/
package org.sonar.duplications.detector.original;
+import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
-
import org.sonar.duplications.block.Block;
import org.sonar.duplications.utils.FastStringComparator;
-import com.google.common.collect.Lists;
-
/**
* Set of {@link Block}s, which internally stored as a sorted list.
*/
protected final List<Block> blocks;
private BlocksGroup() {
- this.blocks = Lists.newArrayList();
+ this.blocks = new ArrayList<>();
}
public int size() {
}
private static List<Block[]> pairs(BlocksGroup beginGroup, BlocksGroup endGroup, int len) {
- List<Block[]> result = Lists.newArrayList();
+ List<Block[]> result = new ArrayList<>();
List<Block> beginBlocks = beginGroup.blocks;
List<Block> endBlocks = endGroup.blocks;
int i = 0;
c = beginBlock.getIndexInFile() + len - 1 - endBlock.getIndexInFile();
}
if (c == 0) {
- result.add(new Block[] { beginBlock, endBlock });
+ result.add(new Block[] {beginBlock, endBlock});
i++;
j++;
}
package org.sonar.duplications.detector.original;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
-
import org.sonar.duplications.detector.ContainsInComparator;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.index.ClonePart;
import org.sonar.duplications.utils.SortedListsUtils;
-import com.google.common.collect.Lists;
-
/**
* Performs incremental and brute force algorithm in order to filter clones, which are fully covered by other clones.
* All clones for filtering must be of the same origin - there is no sanity check on this.
*
* @see #add(CloneGroup)
*/
- private final List<CloneGroup> filtered = Lists.newLinkedList();
+ private final List<CloneGroup> filtered = new LinkedList<>();
/**
* @return current results of filtering
List<ClonePart> firstParts = first.getCloneParts();
List<ClonePart> secondParts = second.getCloneParts();
return SortedListsUtils.contains(secondParts, firstParts, new ContainsInComparator(second.getCloneUnitLength(), first.getCloneUnitLength()))
- && SortedListsUtils.contains(firstParts, secondParts, ContainsInComparator.RESOURCE_ID_COMPARATOR);
+ && SortedListsUtils.contains(firstParts, secondParts, ContainsInComparator.RESOURCE_ID_COMPARATOR);
}
}
*/
package org.sonar.duplications.detector.original;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.index.CloneIndex;
import org.sonar.duplications.index.ClonePart;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
/**
* Implementation of algorithm described in paper
* <a href="http://www4.in.tum.de/~juergens/publications/icsm2010_crc.pdf">Index-Based Code Clone Detection: Incremental, Distributed, Scalable</a>
// Godin: create one group per unique hash
// TODO Godin: can we create map with expected size?
- Map<ByteArray, BlocksGroup> groupsByHash = Maps.newHashMap();
+ Map<ByteArray, BlocksGroup> groupsByHash = new HashMap<>();
for (Block fileBlock : fileBlocks) {
ByteArray hash = fileBlock.getBlockHash();
BlocksGroup sameHash = groupsByHash.get(hash);
List<Block[]> pairs = beginGroup.pairs(endGroup, cloneLength);
ClonePart origin = null;
- List<ClonePart> parts = Lists.newArrayList();
+ List<ClonePart> parts = new ArrayList<>();
for (int i = 0; i < pairs.size(); i++) {
Block[] pair = pairs.get(i);
Block firstBlock = pair[0];
Block lastBlock = pair[1];
ClonePart part = new ClonePart(firstBlock.getResourceId(),
- firstBlock.getIndexInFile(),
- firstBlock.getStartLine(),
- lastBlock.getEndLine());
+ firstBlock.getIndexInFile(),
+ firstBlock.getStartLine(),
+ lastBlock.getEndLine());
if (originResourceId.equals(part.getResourceId())) {
if (origin == null) {
*/
package org.sonar.duplications.detector.suffixtree;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.detector.ContainsInComparator;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.index.ClonePart;
import org.sonar.duplications.utils.SortedListsUtils;
-import java.util.Collections;
-import java.util.List;
-
/**
* Implementation of {@link Search.Collector}, which constructs {@link CloneGroup}s.
*/
private final TextSet text;
private final String originResourceId;
- private final List<CloneGroup> filtered = Lists.newArrayList();
+ private final List<CloneGroup> filtered = new ArrayList<>();
private int length;
private int count;
*
* @param start number of first block from text for this part
* @param end number of last block from text for this part
- * @param len number of blocks in this part
*/
@Override
public void part(int start, int end) {
CloneGroup.Builder builder = CloneGroup.builder().setLength(length);
- List<ClonePart> parts = Lists.newArrayListWithCapacity(count);
+ List<ClonePart> parts = new ArrayList<>(count);
for (int[] b : blockNumbers) {
Block firstBlock = text.getBlock(b[0]);
Block lastBlock = text.getBlock(b[1]);
ClonePart part = new ClonePart(
- firstBlock.getResourceId(),
- firstBlock.getIndexInFile(),
- firstBlock.getStartLine(),
- lastBlock.getEndLine());
+ firstBlock.getResourceId(),
+ firstBlock.getIndexInFile(),
+ firstBlock.getStartLine(),
+ lastBlock.getEndLine());
// TODO Godin: maybe use FastStringComparator here ?
if (originResourceId.equals(part.getResourceId())) {
*/
package org.sonar.duplications.detector.suffixtree;
-import com.google.common.collect.Lists;
-
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
public final class Search {
private final TextSet text;
private final Collector reporter;
- private final List<Integer> list = Lists.newArrayList();
- private final List<Node> innerNodes = Lists.newArrayList();
+ private final List<Integer> list = new ArrayList<>();
+ private final List<Node> innerNodes = new ArrayList<>();
public static void perform(TextSet text, Collector reporter) {
new Search(SuffixTree.create(text), text, reporter).compute();
* Depth-first search (DFS).
*/
private void dfs() {
- Deque<Node> stack = Lists.newLinkedList();
+ Deque<Node> stack = new LinkedList<>();
stack.add(tree.getRootNode());
while (!stack.isEmpty()) {
Node node = stack.removeLast();
*/
package org.sonar.duplications.detector.suffixtree;
-import java.util.*;
-
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.index.CloneIndex;
-import com.google.common.collect.*;
-
public final class SuffixTreeCloneDetectionAlgorithm {
public static List<CloneGroup> detect(CloneIndex cloneIndex, Collection<Block> fileBlocks) {
if (fileBlocks.isEmpty()) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
TextSet text = createTextSet(cloneIndex, fileBlocks);
if (text == null) {
- return Collections.EMPTY_LIST;
+ return Collections.emptyList();
}
DuplicationsCollector reporter = new DuplicationsCollector(text);
Search.perform(text, reporter);
}
private static TextSet createTextSet(CloneIndex index, Collection<Block> fileBlocks) {
- Set<ByteArray> hashes = Sets.newHashSet();
+ Set<ByteArray> hashes = new HashSet<>();
for (Block fileBlock : fileBlocks) {
hashes.add(fileBlock.getBlockHash());
}
private static TextSet createTextSet(Collection<Block> fileBlocks, Map<String, List<Block>> fromIndex) {
TextSet.Builder textSetBuilder = TextSet.builder();
// TODO Godin: maybe we can reduce size of tree and so memory consumption by removing non-repeatable blocks
- List<Block> sortedFileBlocks = Lists.newArrayList(fileBlocks);
+ List<Block> sortedFileBlocks = new ArrayList<>(fileBlocks);
Collections.sort(sortedFileBlocks, BLOCK_COMPARATOR);
textSetBuilder.add(sortedFileBlocks);
}
private static Map<String, List<Block>> retrieveFromIndex(CloneIndex index, String originResourceId, Set<ByteArray> hashes) {
- Map<String, List<Block>> collection = Maps.newHashMap();
+ Map<String, List<Block>> collection = new HashMap<>();
for (ByteArray hash : hashes) {
Collection<Block> blocks = index.getBySequenceHash(hash);
for (Block blockFromIndex : blocks) {
if (!originResourceId.equals(resourceId)) {
List<Block> list = collection.get(resourceId);
if (list == null) {
- list = Lists.newArrayList();
+ list = new ArrayList<>();
collection.put(resourceId, list);
}
list.add(blockFromIndex);
*/
package org.sonar.duplications.detector.suffixtree;
+import java.util.ArrayList;
import java.util.List;
import org.sonar.duplications.block.Block;
-import com.google.common.collect.Lists;
/**
* Simplifies construction of <a href="http://en.wikipedia.org/wiki/Generalised_suffix_tree">generalised suffix-tree</a>.
public static final class Builder {
- private List<Object> symbols = Lists.newArrayList();
+ private List<Object> symbols = new ArrayList();
private Integer lengthOfOrigin;
private int count;
*/
package org.sonar.duplications.index;
-import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-
import java.util.ArrayList;
import java.util.List;
*
* @since 2.14
*/
- @Beta
public int getLengthInUnits() {
return length;
}
*/
package org.sonar.duplications.index;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;
import org.sonar.duplications.utils.FastStringComparator;
-import java.util.Collection;
-import java.util.List;
-
/**
* Provides an index optimized by memory.
* <p>
int index = DataUtils.binarySearch(byResourceId);
- List<Block> result = Lists.newArrayList();
+ List<Block> result = new ArrayList<>();
int realIndex = resourceIdsIndex[index];
while (index < size && FastStringComparator.INSTANCE.compare(resourceIds[realIndex], resourceId) == 0) {
// extract block (note that there is no need to extract resourceId)
int endUnit = blockData[offset];
Block block = blockBuilder
- .setResourceId(resourceId)
- .setBlockHash(new ByteArray(hash))
- .setIndexInFile(indexInFile)
- .setLines(firstLineNumber, lastLineNumber)
- .setUnit(startUnit, endUnit)
- .build();
+ .setResourceId(resourceId)
+ .setBlockHash(new ByteArray(hash))
+ .setIndexInFile(indexInFile)
+ .setLines(firstLineNumber, lastLineNumber)
+ .setUnit(startUnit, endUnit)
+ .build();
result.add(block);
index++;
int index = DataUtils.binarySearch(byBlockHash);
- List<Block> result = Lists.newArrayList();
+ List<Block> result = new ArrayList<>();
while (index < size && !isLessByHash(size, index)) {
// extract block (note that there is no need to extract hash)
String resourceId = resourceIds[index];
int endUnit = blockData[offset];
Block block = blockBuilder
- .setResourceId(resourceId)
- .setBlockHash(sequenceHash)
- .setIndexInFile(indexInFile)
- .setLines(firstLineNumber, lastLineNumber)
- .setUnit(startUnit, endUnit)
- .build();
+ .setResourceId(resourceId)
+ .setBlockHash(sequenceHash)
+ .setIndexInFile(indexInFile)
+ .setLines(firstLineNumber, lastLineNumber)
+ .setUnit(startUnit, endUnit)
+ .build();
result.add(block);
index++;
}
*/
package org.sonar.duplications.internal.pmd;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
+import java.util.List;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;
-import java.util.List;
-
/**
* Differences with {@link org.sonar.duplications.block.BlockChunker}:
* works with {@link TokensLine},
* @return ArrayList as we need a serializable object
*/
public List<Block> chunk(String resourceId, List<TokensLine> fragments) {
- List<TokensLine> filtered = Lists.newArrayList();
+ List<TokensLine> filtered = new ArrayList<>();
int i = 0;
while (i < fragments.size()) {
TokensLine first = fragments.get(i);
fragments = filtered;
if (fragments.size() < blockSize) {
- return Lists.newArrayList();
+ return new ArrayList<>();
}
TokensLine[] fragmentsArr = fragments.toArray(new TokensLine[fragments.size()]);
- List<Block> blocks = Lists.newArrayListWithCapacity(fragmentsArr.length - blockSize + 1);
+ List<Block> blocks = new ArrayList<>(fragmentsArr.length - blockSize + 1);
long hash = 0;
int first = 0;
int last = 0;