Explorar el Código

Introduce SubmissionSet class.

Alberth hace 5 años
padre
commit
2fcab6463a

+ 30 - 27
jplag/src/main/java/de/jplag/JPlag.java

@@ -14,6 +14,7 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 import de.jplag.options.JPlagOptions;
 import de.jplag.options.JPlagOptions;
@@ -29,7 +30,6 @@ import de.jplag.strategy.ParallelComparisonStrategy;
 public class JPlag implements Program {
 public class JPlag implements Program {
 
 
     // INPUT:
     // INPUT:
-    private Submission baseCodeSubmission = null;
     private HashSet<String> excludedFileNames = null; // Set of file names to be excluded in comparison.
     private HashSet<String> excludedFileNames = null; // Set of file names to be excluded in comparison.
     private Language language;
     private Language language;
 
 
@@ -72,18 +72,20 @@ public class JPlag implements Program {
         readExclusionFile(); // This file contains all files names which are excluded
         readExclusionFile(); // This file contains all files names which are excluded
 
 
         // 2. Parse and validate submissions:
         // 2. Parse and validate submissions:
-        ArrayList<Submission> submissions = findSubmissions(rootDir);
-        parseAllSubmissions(submissions, baseCodeSubmission);
-        submissions = filterValidSubmissions(submissions);
-        if (submissions.size() < 2) {
+        SubmissionSet submissionSet = findSubmissions(rootDir);
+        parseAllSubmissions(submissionSet);
+        submissionSet.setSubmissions(filterValidSubmissions(submissionSet.getSubmissions()));
+
+        int submCount = submissionSet.numberOfSubmissions();
+        if (submCount < 2) {
             printErrors();
             printErrors();
-            throw new ExitException("Not enough valid submissions! (found " + submissions.size() + " valid submissions)",
+            throw new ExitException("Not enough valid submissions! (found " + submCount + " valid submissions)",
                     ExitException.NOT_ENOUGH_SUBMISSIONS_ERROR);
                     ExitException.NOT_ENOUGH_SUBMISSIONS_ERROR);
         }
         }
 
 
         // 3. Compare valid submissions:
         // 3. Compare valid submissions:
         errorVector = null; // errorVector is not needed anymore
         errorVector = null; // errorVector is not needed anymore
-        JPlagResult result = comparisonStrategy.compareSubmissions(submissions, baseCodeSubmission);
+        JPlagResult result = comparisonStrategy.compareSubmissions(submissionSet);
         System.out.println("Total time for comparing submissions: " + formatComparisonDuration(result.getDuration()));
         System.out.println("Total time for comparing submissions: " + formatComparisonDuration(result.getDuration()));
         return result;
         return result;
     }
     }
@@ -176,14 +178,14 @@ public class JPlag implements Program {
         }
         }
     }
     }
 
 
-    private ArrayList<Submission> filterValidSubmissions(ArrayList<Submission> submissions) {
+    private List<Submission> filterValidSubmissions(List<Submission> submissions) {
         return submissions.stream().filter(submission -> !submission.hasErrors()).collect(Collectors.toCollection(ArrayList::new));
         return submissions.stream().filter(submission -> !submission.hasErrors()).collect(Collectors.toCollection(ArrayList::new));
     }
     }
 
 
     /**
     /**
      * Find all submissions in the given root directory.
      * Find all submissions in the given root directory.
      */
      */
-    private ArrayList<Submission> findSubmissions(File rootDir) throws ExitException {
+    private SubmissionSet findSubmissions(File rootDir) throws ExitException {
         String[] fileNamesInRootDir;
         String[] fileNamesInRootDir;
 
 
         try {
         try {
@@ -237,8 +239,9 @@ public class JPlag implements Program {
         System.out.println("Initialized language " + this.getLanguage().getName());
         System.out.println("Initialized language " + this.getLanguage().getName());
     }
     }
 
 
-    private ArrayList<Submission> mapFileNamesInRootDirToSubmissions(String[] fileNames, File rootDir) throws ExitException {
-        ArrayList<Submission> submissions = new ArrayList<>();
+    private SubmissionSet mapFileNamesInRootDirToSubmissions(String[] fileNames, File rootDir) throws ExitException {
+        List<Submission> submissions = new ArrayList<>();
+        Optional<Submission> baseCodeSubmission = Optional.empty();
 
 
         for (String fileName : fileNames) {
         for (String fileName : fileNames) {
             File submissionFile = new File(rootDir, fileName);
             File submissionFile = new File(rootDir, fileName);
@@ -270,22 +273,28 @@ public class JPlag implements Program {
             Submission submission = new Submission(fileName, submissionFile, this);
             Submission submission = new Submission(fileName, submissionFile, this);
 
 
             if (options.hasBaseCode() && options.getBaseCodeSubmissionName().equals(fileName)) {
             if (options.hasBaseCode() && options.getBaseCodeSubmissionName().equals(fileName)) {
-                baseCodeSubmission = submission;
+                baseCodeSubmission = Optional.of(submission);
             } else {
             } else {
                 submissions.add(submission);
                 submissions.add(submission);
             }
             }
         }
         }
 
 
-        return submissions;
+        return new SubmissionSet(submissions, baseCodeSubmission);
     }
     }
 
 
     /**
     /**
      * TODO PB: Find a better way to separate parseSubmissions(...) and parseBaseCodeSubmission(...)
      * TODO PB: Find a better way to separate parseSubmissions(...) and parseBaseCodeSubmission(...)
      */
      */
-    private void parseAllSubmissions(ArrayList<Submission> submissions, Submission baseCodeSubmission) throws ExitException {
+    private void parseAllSubmissions(SubmissionSet submissionSet) throws ExitException {
         try {
         try {
-            parseSubmissions(submissions);
-            parseBaseCodeSubmission(baseCodeSubmission);
+            parseSubmissions(submissionSet.getSubmissions());
+
+            if (submissionSet.hasBaseCode()) {
+                parseBaseCodeSubmission(submissionSet.getBaseCode());
+            } else {
+                // TODO:
+                // options.useBasecode = false;
+            }
         } catch (OutOfMemoryError e) {
         } catch (OutOfMemoryError e) {
             throw new ExitException("Out of memory during parsing of submission \"" + currentSubmissionName + "\"");
             throw new ExitException("Out of memory during parsing of submission \"" + currentSubmissionName + "\"");
         } catch (Throwable e) {
         } catch (Throwable e) {
@@ -298,12 +307,6 @@ public class JPlag implements Program {
      * Parse the given base code submission.
      * Parse the given base code submission.
      */
      */
     private void parseBaseCodeSubmission(Submission subm) throws ExitException {
     private void parseBaseCodeSubmission(Submission subm) throws ExitException {
-        if (subm == null) {
-            // TODO:
-            // options.useBasecode = false;
-            return;
-        }
-
         long startTime = System.currentTimeMillis();
         long startTime = System.currentTimeMillis();
         print("----- Parsing basecode submission: " + subm.getName() + "\n", null);
         print("----- Parsing basecode submission: " + subm.getName() + "\n", null);
 
 
@@ -315,7 +318,7 @@ public class JPlag implements Program {
         }
         }
 
 
         if (subm.getTokenList() != null && subm.getNumberOfTokens() < options.getMinimumTokenMatch()) {
         if (subm.getTokenList() != null && subm.getNumberOfTokens() < options.getMinimumTokenMatch()) {
-            throw new ExitException("Basecode submission contains fewer tokens " + "than minimum match length allows!\n");
+            throw new ExitException("Basecode submission contains fewer tokens than minimum match length allows!\n");
         }
         }
 
 
         if (options.hasBaseCode()) {
         if (options.hasBaseCode()) {
@@ -331,9 +334,9 @@ public class JPlag implements Program {
     /**
     /**
      * Parse all given submissions.
      * Parse all given submissions.
      */
      */
-    private void parseSubmissions(ArrayList<Submission> submissions) {
-        if (submissions == null) {
-            System.out.println("Nothing to parse!");
+    private void parseSubmissions(List<Submission> submissions) {
+        if (submissions.isEmpty()) {
+            System.out.println("No submissions to parse!");
             return;
             return;
         }
         }
 
 
@@ -358,7 +361,7 @@ public class JPlag implements Program {
             count++;
             count++;
 
 
             if (subm.getTokenList() != null && subm.getNumberOfTokens() < options.getMinimumTokenMatch()) {
             if (subm.getTokenList() != null && subm.getNumberOfTokens() < options.getMinimumTokenMatch()) {
-                print(null, "Submission contains fewer tokens than minimum match " + "length allows!\n");
+                print(null, "Submission contains fewer tokens than minimum match length allows!\n");
                 subm.setTokenList(null);
                 subm.setTokenList(null);
                 invalid++;
                 invalid++;
                 removed = true;
                 removed = true;

+ 77 - 0
jplag/src/main/java/de/jplag/SubmissionSet.java

@@ -0,0 +1,77 @@
+package de.jplag;
+
+import static java.util.Collections.emptyList;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Collection of submissions and their basecode if it exists.
+ */
+public class SubmissionSet {
+    /**
+     * Submissions to check for plagiarism.
+     */
+    private List<Submission> submissions;
+
+    /**
+     * Base code submission if it exists.
+     */
+    private final Optional<Submission> baseCodeSubmission;
+
+    /**
+     * @param submissions Submissions to check for plagiarism.
+     * @param baseCodeSubmission Base code submission if it exists.
+     */
+    public SubmissionSet(List<Submission> submissions, Optional<Submission> baseCodeSubmission) {
+        setSubmissions(submissions);
+        this.baseCodeSubmission = baseCodeSubmission;
+    }
+
+    /**
+     * @return Whether a basecode is available for this collection.
+     */
+    public boolean hasBaseCode() {
+        return !baseCodeSubmission.isEmpty();
+    }
+
+    /**
+     * Retrieve the base code of this collection.
+     * @return The base code submission.
+     * @note Asking for a non-existing basecode crashes the program.
+     * @see #hasBaseCode
+     */
+    public Submission getBaseCode() {
+        if (baseCodeSubmission.isEmpty()) {
+            throw new AssertionError("Querying a non-existing basecode submission.");
+        }
+        return baseCodeSubmission.get();
+    }
+
+    /**
+     * @return The number of submissions.
+     */
+    public int numberOfSubmissions() {
+        return submissions.size();
+    }
+
+    /**
+     * Obtain the submissions.
+     * @note Changes in the list are reflected in this instance.
+     */
+    public List<Submission> getSubmissions() {
+        return submissions;
+    }
+
+    /**
+     * Give the submissions to the set.
+     * @param submissions New submissions to store.
+     */
+    public void setSubmissions(List<Submission> submissions) {
+        if (submissions == null) {
+            this.submissions = emptyList();
+        } else {
+            this.submissions = submissions;
+        }
+    }
+}

+ 9 - 3
jplag/src/main/java/de/jplag/strategy/AbstractComparisonStrategy.java

@@ -1,12 +1,12 @@
 package de.jplag.strategy;
 package de.jplag.strategy;
 
 
 import java.util.Hashtable;
 import java.util.Hashtable;
-import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 
 
 import de.jplag.GreedyStringTiling;
 import de.jplag.GreedyStringTiling;
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagComparison;
 import de.jplag.Submission;
 import de.jplag.Submission;
+import de.jplag.SubmissionSet;
 import de.jplag.options.JPlagOptions;
 import de.jplag.options.JPlagOptions;
 
 
 public abstract class AbstractComparisonStrategy implements ComparisonStrategy {
 public abstract class AbstractComparisonStrategy implements ComparisonStrategy {
@@ -24,8 +24,14 @@ public abstract class AbstractComparisonStrategy implements ComparisonStrategy {
         this.options = options;
         this.options = options;
     }
     }
 
 
-    protected void compareSubmissionsToBaseCode(List<Submission> submissions, Submission baseCodeSubmission) {
-        for (Submission currentSubmission : submissions) {
+    /**
+     * Compare all submissions to the basecode.
+     * <p>Caller must ensure that the provided set does have a basecode submission before calling.</p>
+     * @param submissionSet Submissions and basecode to compare.
+     */
+    protected void compareSubmissionsToBaseCode(SubmissionSet submissionSet) {
+        Submission baseCodeSubmission = submissionSet.getBaseCode();
+        for (Submission currentSubmission : submissionSet.getSubmissions()) {
             JPlagComparison baseCodeMatch = greedyStringTiling.compareWithBaseCode(currentSubmission, baseCodeSubmission);
             JPlagComparison baseCodeMatch = greedyStringTiling.compareWithBaseCode(currentSubmission, baseCodeSubmission);
             baseCodeMatches.put(currentSubmission.getName(), baseCodeMatch);
             baseCodeMatches.put(currentSubmission.getName(), baseCodeMatch);
             baseCodeSubmission.resetBaseCode();
             baseCodeSubmission.resetBaseCode();

+ 3 - 6
jplag/src/main/java/de/jplag/strategy/ComparisonStrategy.java

@@ -1,9 +1,7 @@
 package de.jplag.strategy;
 package de.jplag.strategy;
 
 
-import java.util.List;
-
 import de.jplag.JPlagResult;
 import de.jplag.JPlagResult;
-import de.jplag.Submission;
+import de.jplag.SubmissionSet;
 
 
 /**
 /**
  * Strategy for comparing a set of submissions.
  * Strategy for comparing a set of submissions.
@@ -12,9 +10,8 @@ public interface ComparisonStrategy {
 
 
     /**
     /**
      * Compares submissions from a set of submissions while considering a given base code.
      * Compares submissions from a set of submissions while considering a given base code.
-     * @param submissions is the set of submissions.
-     * @param baseCodeSubmission is the base code on which each submission is based on.
+     * @param submissionSet Collection of submissions with optional basecode to compare.
      * @return the comparison results.
      * @return the comparison results.
      */
      */
-    JPlagResult compareSubmissions(List<Submission> submissions, Submission baseCodeSubmission);
+    JPlagResult compareSubmissions(SubmissionSet submissionSet);
 }
 }

+ 5 - 3
jplag/src/main/java/de/jplag/strategy/NormalComparisonStrategy.java

@@ -7,6 +7,7 @@ import de.jplag.GreedyStringTiling;
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagResult;
 import de.jplag.JPlagResult;
 import de.jplag.Submission;
 import de.jplag.Submission;
+import de.jplag.SubmissionSet;
 import de.jplag.options.JPlagOptions;
 import de.jplag.options.JPlagOptions;
 
 
 public class NormalComparisonStrategy extends AbstractComparisonStrategy {
 public class NormalComparisonStrategy extends AbstractComparisonStrategy {
@@ -16,12 +17,13 @@ public class NormalComparisonStrategy extends AbstractComparisonStrategy {
     }
     }
 
 
     @Override
     @Override
-    public JPlagResult compareSubmissions(List<Submission> submissions, Submission baseCodeSubmission) {
-        boolean withBaseCode = baseCodeSubmission != null;
+    public JPlagResult compareSubmissions(SubmissionSet submissionSet) {
+        boolean withBaseCode = submissionSet.hasBaseCode();
         if (withBaseCode) {
         if (withBaseCode) {
-            compareSubmissionsToBaseCode(submissions, baseCodeSubmission);
+            compareSubmissionsToBaseCode(submissionSet);
         }
         }
 
 
+        List<Submission> submissions = submissionSet.getSubmissions();
         long timeBeforeStartInMillis = System.currentTimeMillis();
         long timeBeforeStartInMillis = System.currentTimeMillis();
         int i, j, numberOfSubmissions = submissions.size();
         int i, j, numberOfSubmissions = submissions.size();
         Submission first, second;
         Submission first, second;

+ 5 - 3
jplag/src/main/java/de/jplag/strategy/ParallelComparisonStrategy.java

@@ -15,6 +15,7 @@ import de.jplag.GreedyStringTiling;
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagResult;
 import de.jplag.JPlagResult;
 import de.jplag.Submission;
 import de.jplag.Submission;
+import de.jplag.SubmissionSet;
 import de.jplag.options.JPlagOptions;
 import de.jplag.options.JPlagOptions;
 
 
 /**
 /**
@@ -35,12 +36,12 @@ public class ParallelComparisonStrategy extends AbstractComparisonStrategy {
     }
     }
 
 
     @Override
     @Override
-    public JPlagResult compareSubmissions(List<Submission> submissions, Submission baseCodeSubmission) {
+    public JPlagResult compareSubmissions(SubmissionSet submissionSet) {
         // Initialize:
         // Initialize:
         long timeBeforeStartInMillis = System.currentTimeMillis();
         long timeBeforeStartInMillis = System.currentTimeMillis();
-        boolean withBaseCode = baseCodeSubmission != null;
+        boolean withBaseCode = submissionSet.hasBaseCode();
         if (withBaseCode) {
         if (withBaseCode) {
-            compareSubmissionsToBaseCode(submissions, baseCodeSubmission);
+            compareSubmissionsToBaseCode(submissionSet);
         }
         }
         threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
         threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
         comparisons.clear();
         comparisons.clear();
@@ -48,6 +49,7 @@ public class ParallelComparisonStrategy extends AbstractComparisonStrategy {
         successfulComparisons = 0;
         successfulComparisons = 0;
 
 
         // Parallel compare:
         // Parallel compare:
+        List<Submission> submissions = submissionSet.getSubmissions();
         List<SubmissionTuple> tuples = buildComparisonTuples(submissions);
         List<SubmissionTuple> tuples = buildComparisonTuples(submissions);
         Collections.shuffle(tuples); // Reduces how often submission pairs must be re-submitted
         Collections.shuffle(tuples); // Reduces how often submission pairs must be re-submitted
         for (SubmissionTuple tuple : tuples) {
         for (SubmissionTuple tuple : tuples) {