Procházet zdrojové kódy

refactor submission directories to type Set<File> instead of List<String>

Jan Wittler před 4 roky
rodič
revize
9d8353ce1d

+ 9 - 5
cli/src/main/java/de/jplag/CLI.java

@@ -29,11 +29,13 @@ import static de.jplag.CommandLineArgument.SUBDIRECTORY;
 import static de.jplag.CommandLineArgument.SUFFIXES;
 import static de.jplag.CommandLineArgument.SUFFIXES;
 import static de.jplag.CommandLineArgument.VERBOSITY;
 import static de.jplag.CommandLineArgument.VERBOSITY;
 
 
+import java.io.File;
 import java.security.SecureRandom;
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 import java.util.Random;
 import java.util.Random;
+import java.util.stream.Collectors;
 
 
 import net.sourceforge.argparse4j.ArgumentParsers;
 import net.sourceforge.argparse4j.ArgumentParsers;
 import net.sourceforge.argparse4j.inf.ArgumentParser;
 import net.sourceforge.argparse4j.inf.ArgumentParser;
@@ -142,11 +144,13 @@ public final class CLI {
         }
         }
 
 
         // Collect the root directories.
         // Collect the root directories.
-        List<String> submissionDirectories = new ArrayList<>();
-        List<String> oldSubmissionDirectories = new ArrayList<>();
-        addAllMultiValueArgument(ROOT_DIRECTORY.getListFrom(namespace), submissionDirectories);
-        addAllMultiValueArgument(NEW_DIRECTORY.getListFrom(namespace), submissionDirectories);
-        addAllMultiValueArgument(OLD_DIRECTORY.getListFrom(namespace), oldSubmissionDirectories);
+        List<String> submissionDirectoryPaths = new ArrayList<>();
+        List<String> oldSubmissionDirectoryPaths = new ArrayList<>();
+        addAllMultiValueArgument(ROOT_DIRECTORY.getListFrom(namespace), submissionDirectoryPaths);
+        addAllMultiValueArgument(NEW_DIRECTORY.getListFrom(namespace), submissionDirectoryPaths);
+        addAllMultiValueArgument(OLD_DIRECTORY.getListFrom(namespace), oldSubmissionDirectoryPaths);
+        var submissionDirectories = submissionDirectoryPaths.stream().map(path -> new File(path)).collect(Collectors.toSet());
+        var oldSubmissionDirectories = oldSubmissionDirectoryPaths.stream().map(path -> new File(path)).collect(Collectors.toSet());
 
 
         var language = LanguageLoader.getLanguage(LANGUAGE.getFrom(namespace)).orElseThrow();
         var language = LanguageLoader.getLanguage(LANGUAGE.getFrom(namespace)).orElseThrow();
         ClusteringOptions clusteringOptions = getClusteringOptions(namespace);
         ClusteringOptions clusteringOptions = getClusteringOptions(namespace);

+ 8 - 9
core/src/main/java/de/jplag/SubmissionSetBuilder.java

@@ -81,26 +81,25 @@ public class SubmissionSetBuilder {
     /**
     /**
      * Verify that the given root directories exist and have no duplicate entries.
      * Verify that the given root directories exist and have no duplicate entries.
      */
      */
-    private Set<File> verifyRootDirectories(List<String> rootDirectoryNames, boolean areNewDirectories) throws ExitException {
+    private Set<File> verifyRootDirectories(Set<File> rootDirectoryNames, boolean areNewDirectories) throws ExitException {
         if (areNewDirectories && rootDirectoryNames.isEmpty()) {
         if (areNewDirectories && rootDirectoryNames.isEmpty()) {
             throw new RootDirectoryException("No root directories specified with submissions to check for plagiarism!");
             throw new RootDirectoryException("No root directories specified with submissions to check for plagiarism!");
         }
         }
 
 
         Set<File> canonicalRootDirectories = new HashSet<>(rootDirectoryNames.size());
         Set<File> canonicalRootDirectories = new HashSet<>(rootDirectoryNames.size());
-        for (String rootDirectoryName : rootDirectoryNames) {
-            File rootDirectory = new File(rootDirectoryName);
-
+        for (final File rootDirectory : rootDirectoryNames) {
             if (!rootDirectory.exists()) {
             if (!rootDirectory.exists()) {
-                throw new RootDirectoryException(String.format("Root directory \"%s\" does not exist!", rootDirectoryName));
+                throw new RootDirectoryException(String.format("Root directory \"%s\" does not exist!", rootDirectory));
             }
             }
             if (!rootDirectory.isDirectory()) {
             if (!rootDirectory.isDirectory()) {
-                throw new RootDirectoryException(String.format("Root directory \"%s\" is not a directory!", rootDirectoryName));
+                throw new RootDirectoryException(String.format("Root directory \"%s\" is not a directory!", rootDirectory));
             }
             }
 
 
-            rootDirectory = makeCanonical(rootDirectory, it -> new RootDirectoryException("Cannot read root directory: " + rootDirectoryName, it));
-            if (!canonicalRootDirectories.add(rootDirectory)) {
+            File canonicalRootDirectory = makeCanonical(rootDirectory,
+                    it -> new RootDirectoryException("Cannot read root directory: " + rootDirectory, it));
+            if (!canonicalRootDirectories.add(canonicalRootDirectory)) {
                 // Root directory was already added, report a warning.
                 // Root directory was already added, report a warning.
-                logger.warn("Root directory \"{}\" was specified more than once, duplicates will be ignored.", rootDirectoryName);
+                logger.warn("Root directory \"{}\" was specified more than once, duplicates will be ignored.", canonicalRootDirectory);
             }
             }
         }
         }
         return canonicalRootDirectories;
         return canonicalRootDirectories;

+ 8 - 7
core/src/main/java/de/jplag/options/JPlagOptions.java

@@ -3,6 +3,7 @@ package de.jplag.options;
 import static de.jplag.options.Verbosity.LONG;
 import static de.jplag.options.Verbosity.LONG;
 
 
 import java.io.BufferedReader;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.Charset;
@@ -45,7 +46,7 @@ import de.jplag.clustering.ClusteringOptions;
  * @param verbosity Level of output verbosity.
  * @param verbosity Level of output verbosity.
  * @param debugParser If true, submissions that cannot be parsed will be stored in a separate directory.
  * @param debugParser If true, submissions that cannot be parsed will be stored in a separate directory.
  */
  */
-public record JPlagOptions(Language language, Integer minimumTokenMatch, List<String> submissionDirectories, List<String> oldSubmissionDirectories,
+public record JPlagOptions(Language language, Integer minimumTokenMatch, Set<File> submissionDirectories, Set<File> oldSubmissionDirectories,
         String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
         String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
         SimilarityMetric similarityMetric, double similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
         SimilarityMetric similarityMetric, double similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
         Verbosity verbosity, boolean debugParser) {
         Verbosity verbosity, boolean debugParser) {
@@ -58,12 +59,12 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
 
 
     private static final Logger logger = LoggerFactory.getLogger(JPlag.class);
     private static final Logger logger = LoggerFactory.getLogger(JPlag.class);
 
 
-    public JPlagOptions(Language language, List<String> submissionDirectories, List<String> oldSubmissionDirectories) {
+    public JPlagOptions(Language language, Set<File> submissionDirectories, Set<File> oldSubmissionDirectories) {
         this(language, null, submissionDirectories, oldSubmissionDirectories, null, null, null, null, DEFAULT_SIMILARITY_METRIC,
         this(language, null, submissionDirectories, oldSubmissionDirectories, null, null, null, null, DEFAULT_SIMILARITY_METRIC,
                 DEFAULT_SIMILARITY_THRESHOLD, DEFAULT_SHOWN_COMPARISONS, new ClusteringOptions(), null, false);
                 DEFAULT_SIMILARITY_THRESHOLD, DEFAULT_SHOWN_COMPARISONS, new ClusteringOptions(), null, false);
     }
     }
 
 
-    public JPlagOptions(Language language, Integer minimumTokenMatch, List<String> submissionDirectories, List<String> oldSubmissionDirectories,
+    public JPlagOptions(Language language, Integer minimumTokenMatch, Set<File> submissionDirectories, Set<File> oldSubmissionDirectories,
             String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
             String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
             SimilarityMetric similarityMetric, double similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
             SimilarityMetric similarityMetric, double similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
             Verbosity verbosity, boolean debugParser) {
             Verbosity verbosity, boolean debugParser) {
@@ -75,8 +76,8 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
         this.similarityMetric = similarityMetric;
         this.similarityMetric = similarityMetric;
         this.minimumTokenMatch = normalizeMinimumTokenMatch(minimumTokenMatch);
         this.minimumTokenMatch = normalizeMinimumTokenMatch(minimumTokenMatch);
         this.exclusionFileName = exclusionFileName;
         this.exclusionFileName = exclusionFileName;
-        this.submissionDirectories = submissionDirectories == null ? null : Collections.unmodifiableList(submissionDirectories);
-        this.oldSubmissionDirectories = oldSubmissionDirectories == null ? null : Collections.unmodifiableList(oldSubmissionDirectories);
+        this.submissionDirectories = submissionDirectories == null ? null : Collections.unmodifiableSet(submissionDirectories);
+        this.oldSubmissionDirectories = oldSubmissionDirectories == null ? null : Collections.unmodifiableSet(oldSubmissionDirectories);
         this.baseCodeSubmissionName = (baseCodeSubmissionName == null || baseCodeSubmissionName.isBlank()) ? null : baseCodeSubmissionName;
         this.baseCodeSubmissionName = (baseCodeSubmissionName == null || baseCodeSubmissionName.isBlank()) ? null : baseCodeSubmissionName;
         this.subdirectoryName = subdirectoryName;
         this.subdirectoryName = subdirectoryName;
         this.verbosity = verbosity;
         this.verbosity = verbosity;
@@ -131,13 +132,13 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
                 clusteringOptions, verbosity, debugParser);
                 clusteringOptions, verbosity, debugParser);
     }
     }
 
 
-    public JPlagOptions withSubmissionDirectories(List<String> submissionDirectories) {
+    public JPlagOptions withSubmissionDirectories(Set<File> submissionDirectories) {
         return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionName,
         return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionName,
                 subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
                 subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
                 clusteringOptions, verbosity, debugParser);
                 clusteringOptions, verbosity, debugParser);
     }
     }
 
 
-    public JPlagOptions withOldSubmissionDirectories(List<String> oldSubmissionDirectories) {
+    public JPlagOptions withOldSubmissionDirectories(Set<File> oldSubmissionDirectories) {
         return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionName,
         return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionName,
                 subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
                 subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
                 clusteringOptions, verbosity, debugParser);
                 clusteringOptions, verbosity, debugParser);

+ 2 - 2
core/src/main/java/de/jplag/reporting/reportobject/ReportObjectFactory.java

@@ -134,14 +134,14 @@ public class ReportObjectFactory {
 
 
     private void writeOverview(JPlagResult result, String path) {
     private void writeOverview(JPlagResult result, String path) {
 
 
-        List<String> folders = new ArrayList<>();
+        List<File> folders = new ArrayList<>();
         folders.addAll(result.getOptions().submissionDirectories());
         folders.addAll(result.getOptions().submissionDirectories());
         folders.addAll(result.getOptions().oldSubmissionDirectories());
         folders.addAll(result.getOptions().oldSubmissionDirectories());
 
 
         String baseCodePath = result.getOptions().hasBaseCode() ? result.getOptions().baseCodeSubmissionName() : "";
         String baseCodePath = result.getOptions().hasBaseCode() ? result.getOptions().baseCodeSubmissionName() : "";
         ClusteringResultMapper clusteringResultMapper = new ClusteringResultMapper(submissionToIdFunction);
         ClusteringResultMapper clusteringResultMapper = new ClusteringResultMapper(submissionToIdFunction);
 
 
-        OverviewReport overviewReport = new OverviewReport(folders, // submissionFolderPath
+        OverviewReport overviewReport = new OverviewReport(folders.stream().map(File::getName).toList(), // submissionFolderPath
                 baseCodePath, // baseCodeFolderPath
                 baseCodePath, // baseCodeFolderPath
                 result.getOptions().language().getName(), // language
                 result.getOptions().language().getName(), // language
                 result.getOptions().fileSuffixes(), // fileExtensions
                 result.getOptions().fileSuffixes(), // fileExtensions

+ 2 - 2
core/src/test/java/de/jplag/BaseCodeTest.java

@@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 
 import java.io.File;
 import java.io.File;
-import java.util.List;
+import java.util.Set;
 
 
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 
 
@@ -53,7 +53,7 @@ public class BaseCodeTest extends TestBase {
 
 
     @Test
     @Test
     void testInvalidRoot() {
     void testInvalidRoot() {
-        assertThrows(RootDirectoryException.class, () -> runJPlag("basecode", it -> it.withSubmissionDirectories(List.of("WrongRoot"))));
+        assertThrows(RootDirectoryException.class, () -> runJPlag("basecode", it -> it.withSubmissionDirectories(Set.of(new File("WrongRoot")))));
     }
     }
 
 
     @Test
     @Test

+ 4 - 1
core/src/test/java/de/jplag/TestBase.java

@@ -5,6 +5,7 @@ import java.nio.file.Path;
 import java.util.List;
 import java.util.List;
 import java.util.StringJoiner;
 import java.util.StringJoiner;
 import java.util.function.Function;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 
 import de.jplag.exceptions.ExitException;
 import de.jplag.exceptions.ExitException;
 import de.jplag.java.Language;
 import de.jplag.java.Language;
@@ -48,7 +49,9 @@ public abstract class TestBase {
 
 
     protected JPlagResult runJPlag(List<String> newPaths, List<String> oldPaths, Function<JPlagOptions, JPlagOptions> customization)
     protected JPlagResult runJPlag(List<String> newPaths, List<String> oldPaths, Function<JPlagOptions, JPlagOptions> customization)
             throws ExitException {
             throws ExitException {
-        JPlagOptions options = new JPlagOptions(LanguageLoader.getLanguage(Language.IDENTIFIER).orElseThrow(), newPaths, oldPaths);
+        var newFiles = newPaths.stream().map(path -> new File(path)).collect(Collectors.toSet());
+        var oldFiles = oldPaths.stream().map(path -> new File(path)).collect(Collectors.toSet());
+        JPlagOptions options = new JPlagOptions(LanguageLoader.getLanguage(Language.IDENTIFIER).orElseThrow(), newFiles, oldFiles);
         options = customization.apply(options);
         options = customization.apply(options);
         options = options.withVerbosity(Verbosity.LONG);
         options = options.withVerbosity(Verbosity.LONG);
         JPlag jplag = new JPlag(options);
         JPlag jplag = new JPlag(options);

+ 5 - 2
endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java

@@ -3,6 +3,7 @@ package de.jplag.endtoend;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 
+import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -13,7 +14,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Optional;
+import java.util.Set;
 import java.util.StringJoiner;
 import java.util.StringJoiner;
+import java.util.stream.Collectors;
 
 
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.DynamicTest;
 import org.junit.jupiter.api.DynamicTest;
@@ -147,8 +150,8 @@ public class EndToEndSuiteTest {
         String[] submissionPath = FileHelper.createNewTestCaseDirectory(testFiles);
         String[] submissionPath = FileHelper.createNewTestCaseDirectory(testFiles);
 
 
         var language = LanguageLoader.getLanguage(languageIdentifier).orElseThrow();
         var language = LanguageLoader.getLanguage(languageIdentifier).orElseThrow();
-        JPlagOptions jplagOptions = new JPlagOptions(language, Arrays.asList(submissionPath), new ArrayList<>())
-                .withMinimumTokenMatch(options.minimumTokenMatch());
+        JPlagOptions jplagOptions = new JPlagOptions(language, Arrays.stream(submissionPath).map(path -> new File(path)).collect(Collectors.toSet()),
+                Set.of()).withMinimumTokenMatch(options.minimumTokenMatch());
         JPlagResult jplagResult = new JPlag(jplagOptions).run();
         JPlagResult jplagResult = new JPlag(jplagOptions).run();
 
 
         List<JPlagComparison> currentJPlagComparison = jplagResult.getAllComparisons();
         List<JPlagComparison> currentJPlagComparison = jplagResult.getAllComparisons();