Skip to content

Commit

Permalink
mainly fixed same root and submission problem and did some enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
cyfml committed Dec 4, 2022
1 parent 3c02c0c commit 7303bf7
Show file tree
Hide file tree
Showing 189 changed files with 15,794 additions and 26 deletions.
9 changes: 8 additions & 1 deletion core/src/main/java/de/jplag/JPlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import de.jplag.clustering.ClusteringFactory;
import de.jplag.exceptions.ExitException;
import de.jplag.exceptions.RootDirectoryException;
import de.jplag.exceptions.SubmissionException;
import de.jplag.options.JPlagOptions;
import de.jplag.reporting.reportobject.model.Version;
Expand Down Expand Up @@ -38,7 +39,13 @@ private static Version loadVersion() {
* @param options determines the parameterization.
*/
public JPlag(JPlagOptions options) {
this.options = options;
PreventSameRootName preventSameRootName = null;
try {
preventSameRootName = new PreventSameRootName(options);
} catch (RootDirectoryException e) {
e.printStackTrace();
}
this.options = preventSameRootName.getOptions();
language = this.options.language();
GreedyStringTiling coreAlgorithm = new GreedyStringTiling(options);
comparisonStrategy = new ParallelComparisonStrategy(options, coreAlgorithm);
Expand Down
141 changes: 141 additions & 0 deletions core/src/main/java/de/jplag/PreventSameRootName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package de.jplag;

import java.io.File;
import java.nio.file.Path;
import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.jplag.exceptions.RootDirectoryException;
import de.jplag.options.JPlagOptions;

/**
* This class prevents the same root name of submissions.
*/
public class PreventSameRootName {
private static final Logger logger = LoggerFactory.getLogger(PreventSameRootName.class);

private final Map<String, Integer> statistic = new HashMap<>(); // uses to store information of same roots (Key: same root name ---> Value: number
// of the same root name)
private final JPlagOptions options;

/**
* Creates and initializes a PreventSameRootName instance, parameterized by a set of options. If there are same names of
* root directories, they will be re-named before generating zip file and IDs. (e.g. two same root names: root ===>
* root_1 && root_2)
* @param options determines the parameterization
*/
public PreventSameRootName(JPlagOptions options) throws RootDirectoryException {
Set<File> newChangedSubmissionDirectories;
Set<File> oldChangedSubmissionDirectories;
Set<File> newSubmissionDirectories = options.submissionDirectories();
Set<File> oldSubmissionDirectories = options.oldSubmissionDirectories();
if (oldSubmissionDirectories == null && newSubmissionDirectories == null) {
throw new RootDirectoryException("No submission");
}
boolean hasSameRoots = false;
hasSameRoots = hasSameRoots(newSubmissionDirectories, oldSubmissionDirectories);
if (hasSameRoots) {
logger.info("Detected same name of root directories, the name will be re-named...");
newChangedSubmissionDirectories = renameRoots(newSubmissionDirectories);
oldChangedSubmissionDirectories = renameRoots(oldSubmissionDirectories);
} else {
newChangedSubmissionDirectories = newSubmissionDirectories;
oldChangedSubmissionDirectories = oldSubmissionDirectories;
}
this.options = new JPlagOptions(options.language(), options.minimumTokenMatch(), newChangedSubmissionDirectories,
oldChangedSubmissionDirectories, options.baseCodeSubmissionDirectory(), options.subdirectoryName(), options.fileSuffixes(),
options.exclusionFileName(), options.similarityMetric(), options.similarityThreshold(), options.maximumNumberOfComparisons(),
options.clusteringOptions(), options.debugParser());
}

/**
* @return a new options instance
*/
public JPlagOptions getOptions() {
return options;
}

/**
* @return the statistic map
*/
public Map<String, Integer> getStatistic() {
return statistic;
}

/**
* Counts the root directory names and their number with Map(named statistic).
* @param submissionDirectories SubmissionDirectories that need to be counted
*/
public void rootsClassification(Set<File> submissionDirectories) {
if (submissionDirectories == null)
return;
for (File submissionDirectory : submissionDirectories) {
String rootDirectory = getRootName(submissionDirectory);
statistic.put(rootDirectory, statistic.getOrDefault(rootDirectory, 0) + 1);
}
}

/**
* Renames the same root directory name.
* @param submissionDirectories SubmissionDirectories that need to be re-named
* @return SubmissionDirectories that have been re-named
*/
public Set<File> renameRoots(Set<File> submissionDirectories) {
if (submissionDirectories == null)
return Set.of();
Set<File> set = new HashSet<>();
for (File submissionDirectory : submissionDirectories) {
String rootDirectory = getRootName(submissionDirectory);
int index = statistic.getOrDefault(rootDirectory, -1);
if (index == -1)
continue;
String newRootDirectory = rootDirectory + "_" + index;
statistic.put(rootDirectory, statistic.get(rootDirectory) - 1);
File newFile = new File(Path.of(submissionDirectory.getParent(), newRootDirectory).toString());
set.add(newFile);
submissionDirectory.renameTo(newFile);
logger.info("Original submission path ===> Current submission path:" + submissionDirectory.getPath() + " ===> " + newFile.getPath());
}
return Set.copyOf(set);
}

/**
* Gets root name of a submissionDirectory.
* @param submissionDirectory A single submissionDirectory
* @return Root name of the submission
*/
public String getRootName(File submissionDirectory) {
return submissionDirectory.getPath().substring(submissionDirectory.getParent().length() + 1);
}

/**
* Determines if there are the same root directories.
* @param newSubmissionDirectories The new submissionDirectories
* @param oldSubmissionDirectories The old submissionDirectories
* @return True, if there are the same root directories. False, otherwise.
*/
public boolean hasSameRoots(Set<File> newSubmissionDirectories, Set<File> oldSubmissionDirectories) throws RootDirectoryException {
checkDirectoryExist(newSubmissionDirectories);
checkDirectoryExist(oldSubmissionDirectories);
rootsClassification(newSubmissionDirectories);
rootsClassification(oldSubmissionDirectories);
Set<Map.Entry<String, Integer>> entries = statistic.entrySet();
entries.removeIf(entry -> entry.getValue() == 1);
return !statistic.isEmpty();
}

/**
* Checks if directories exist. If not, throws RootDirectoryException.
* @param submissionDirectories The submissionDirectories which needs to be checked
*/
public void checkDirectoryExist(Set<File> submissionDirectories) throws RootDirectoryException {
for (File submissionDirectory : submissionDirectories) {
boolean exists = submissionDirectory.exists();
if (!exists) {
throw new RootDirectoryException("Submission Directory doesn't exist: " + submissionDirectory.getPath());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ private Match convertMatchToReportMatch(JPlagComparison comparison, de.jplag.Mat

private String relativizedFilePath(File file, Submission submission) {
if (file.toPath().equals(submission.getRoot().toPath())) {
return Path.of(submission.getName(), submission.getName()).toString();
return Path.of(submissionToIdFunction.apply(submission), submission.getName()).toString();
}
return Path.of(submission.getName(), submission.getRoot().toPath().relativize(file.toPath()).toString()).toString();
return Path.of(submissionToIdFunction.apply(submission), submission.getRoot().toPath().relativize(file.toPath()).toString()).toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ public static File createDirectory(String path, String name, File file, File sub
File directory;
String fileName = file.getPath();
String submissionRootPath = submissionRoot.getPath();
int lastDirectoryIndex = findRootDirIndex(name, submissionRootPath);
fileName = fileName.substring(lastDirectoryIndex).replaceFirst(name, "");
fileName = fileName.substring(submissionRootPath.length());
String outputRootDirectory = Path.of(path, name).toString();
if ("".equals(fileName)) {
directory = new File(Path.of(outputRootDirectory, name).toString());
Expand Down Expand Up @@ -119,15 +118,4 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce
logger.info("Display the results with the report viewer at https://jplag.github.io/JPlag/");
return true;
}

/**
* finds the start index of root directory according to this name
* @param name The name of the root directory. According to this name we can find the index of this directory.
* @param submissionRootPath The path of the root directory
* @return The start index of the root directory
*/
public static int findRootDirIndex(String name, String submissionRootPath) {
int submissionRootPathLength = submissionRootPath.length();
return submissionRootPathLength - name.length();
}
}
85 changes: 85 additions & 0 deletions core/src/test/java/de/jplag/PreventSameRootNameTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package de.jplag;

import static org.junit.jupiter.api.Assertions.fail;

import java.io.File;
import java.nio.file.Path;
import java.util.Set;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import de.jplag.exceptions.RootDirectoryException;
import de.jplag.options.JPlagOptions;

/**
* Test for the same root cases that will be re-named.
*/
public class PreventSameRootNameTest extends TestBase {

private static final JPlagOptions BASEOPTIONS = new JPlagOptions(new de.jplag.java.Language(), Set.of(), Set.of());
private static final String NOTEXISTDIRECTORY = Path.of(TestBase.BASE_PATH, "basecode", "NotExistDirectory").toString();
private static final String SAMPLE_SAMEROOTNAME_1 = Path.of(TestBase.BASE_PATH, "SameRootName", "2019", "root").toString();
private static final String SAMPLE_SAMEROOTNAME_2 = Path.of(TestBase.BASE_PATH, "SameRootName", "2020", "root").toString();

@Test
@DisplayName("test same root directory with withSubmissionDirectories options")
void testSameRootWithNew() {
JPlagOptions options = BASEOPTIONS.withSubmissionDirectories(Set.of(new File(SAMPLE_SAMEROOTNAME_1), new File(SAMPLE_SAMEROOTNAME_2)));
try {
PreventSameRootName preventSameRootName = new PreventSameRootName(options);
JPlagOptions newOptions = preventSameRootName.getOptions();
File submissionDirectory_2 = options.submissionDirectories().stream().toList().get(0);
File submissionDirectory_1 = options.submissionDirectories().stream().toList().get(1);
File newChangedSubmissionDirectory_2 = newOptions.submissionDirectories().stream().toList().get(0);
File newChangedSubmissionDirectory_1 = newOptions.submissionDirectories().stream().toList().get(1);
Assertions.assertEquals(submissionDirectory_2.getPath() + "_2", newChangedSubmissionDirectory_2.getPath());
Assertions.assertEquals(submissionDirectory_1.getPath() + "_1", newChangedSubmissionDirectory_1.getPath());
} catch (RootDirectoryException e) {
fail("PreventSameRootName Class threw an exception:", e);
}
}

@Test
@DisplayName("test same root directory with withSubmissionDirectories and oldSubmissionDirectories options")
void testSameRootWithNewAndOld() {
JPlagOptions options = BASEOPTIONS.withSubmissionDirectories(Set.of(new File(SAMPLE_SAMEROOTNAME_2)))
.withOldSubmissionDirectories(Set.of(new File(SAMPLE_SAMEROOTNAME_1)));
try {
PreventSameRootName preventSameRootName = new PreventSameRootName(options);
JPlagOptions newOptions = preventSameRootName.getOptions();
File oldSubmissionDirectory = options.oldSubmissionDirectories().stream().toList().get(0);
File submissionDirectory = options.submissionDirectories().stream().toList().get(0);
File newChangedOldSubmissionDirectory = newOptions.oldSubmissionDirectories().stream().toList().get(0);
File newChangedSubmissionDirectory = newOptions.submissionDirectories().stream().toList().get(0);
Assertions.assertEquals(submissionDirectory.getPath() + "_2", newChangedSubmissionDirectory.getPath());
Assertions.assertEquals(oldSubmissionDirectory.getPath() + "_1", newChangedOldSubmissionDirectory.getPath());
} catch (RootDirectoryException e) {
fail("PreventSameRootName Class threw an exception:", e);
}
}

@Test
@DisplayName("test not existed root directory with withSubmissionDirectories option")
void testCheckDirectoryExistWithNewSubmissionDirectories() {
JPlagOptions options = BASEOPTIONS.withSubmissionDirectories(Set.of(new File(NOTEXISTDIRECTORY)));
testRootDirectoryException(options);
}

@Test
@DisplayName("test not existed root directory with withOldSubmissionDirectories option")
void testCheckDirectoryExistWithOldSubmissionDirectories() {
JPlagOptions options = BASEOPTIONS.withOldSubmissionDirectories(Set.of(new File(NOTEXISTDIRECTORY)));
testRootDirectoryException(options);
}

/**
* Test RootDirectoryException for a given Jplag-options.
* @param options is the customized Jplag-options.
*/
void testRootDirectoryException(JPlagOptions options) {
RootDirectoryException exception = Assertions.assertThrows(RootDirectoryException.class, () -> new PreventSameRootName(options));
Assertions.assertEquals("Submission Directory doesn't exist: " + NOTEXISTDIRECTORY, exception.getMessage());
}
}
Loading

0 comments on commit 7303bf7

Please sign in to comment.