Browse Source

[192-webreport] Updated project to the latest state, maven spotless applied, minor fixes in ReportObjectFactory, removed unnecessary files

cholakov11 4 years ago
parent
commit
dc147411ec

+ 5 - 0
jplag/pom.xml

@@ -20,6 +20,11 @@
             <artifactId>system-rules</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.13.0</version>
+        </dependency>
 
         <dependency>
             <groupId>de.jplag</groupId>

+ 13 - 13
jplag/src/main/java/de/jplag/reportingV2/JsonReport.java

@@ -1,29 +1,29 @@
 package de.jplag.reportingV2;
 
+import java.util.List;
+
 import de.jplag.JPlagResult;
 import de.jplag.reportingV2.jsonfactory.JsonFactory;
 import de.jplag.reportingV2.reportobject.ReportObjectFactory;
 import de.jplag.reportingV2.reportobject.model.JPlagReport;
 
-import java.util.List;
-
-//ReportImplementation -> JsonReport
+// ReportImplementation -> JsonReport
 
 /**
  * A report generator which reports the JPlagResult in Json format.
  */
 public class JsonReport implements Report {
 
-	@Override
-	public List<String> getReportStrings(JPlagResult result) {
-		JPlagReport report = ReportObjectFactory.getReportObject(result);
-		return JsonFactory.getJsonStrings(report);
-	}
+    @Override
+    public List<String> getReportStrings(JPlagResult result) {
+        JPlagReport report = ReportObjectFactory.getReportObject(result);
+        return JsonFactory.getJsonStrings(report);
+    }
 
-	@Override
-	public boolean saveReport(JPlagResult result) {
-		JPlagReport report = ReportObjectFactory.getReportObject(result);
-		return JsonFactory.saveJsonFiles(report, "./report-viewer/src/files/");
-	}
+    @Override
+    public boolean saveReport(JPlagResult result) {
+        JPlagReport report = ReportObjectFactory.getReportObject(result);
+        return JsonFactory.saveJsonFiles(report, "./report-viewer/src/files/");
+    }
 
 }

+ 17 - 19
jplag/src/main/java/de/jplag/reportingV2/Report.java

@@ -1,30 +1,28 @@
 package de.jplag.reportingV2;
 
-import de.jplag.JPlagResult;
-import de.jplag.reportingV2.reportobject.model.JPlagReport;
-
 import java.util.List;
 
-//ReportStrategy -> Report
+import de.jplag.JPlagResult;
+
+// ReportStrategy -> Report
 
 /**
- *  Strategy interface for reporting. A report generator should implement this interface.
+ * Strategy interface for reporting. A report generator should implement this interface.
  */
 public interface Report {
 
-	/**
-	 * This function returns a list containing the report objects as simple strings.
-	 * The first element is the string of the overview object. Each following element is a string
-	 * of a comparison report object.
-	 * @param result The result of a JPlag comparison
-	 * @return A list containing report objects to string. First element is Overview. Other elements are comparisons.
-	 */
-	List<String> getReportStrings(JPlagResult result);
+    /**
+     * This function returns a list containing the report objects as simple strings. The first element is the string of the
+     * overview object. Each following element is a string of a comparison report object.
+     * @param result The result of a JPlag comparison
+     * @return A list containing report objects to string. First element is Overview. Other elements are comparisons.
+     */
+    List<String> getReportStrings(JPlagResult result);
 
-	/**
-	 * Creates and saves JPlag report files to the disk.
-	 * @param result The result of a JPlag comparison.
-	 * @return True if the process is successful, otherwise false.
-	 */
-	boolean saveReport(JPlagResult result);
+    /**
+     * Creates and saves JPlag report files to the disk.
+     * @param result The result of a JPlag comparison.
+     * @return True if the process is successful, otherwise false.
+     */
+    boolean saveReport(JPlagResult result);
 }

+ 0 - 22
jplag/src/main/java/de/jplag/reportingV2/ReportingTest.java

@@ -1,22 +0,0 @@
-package de.jplag.reportingV2;
-
-import de.jplag.ExitException;
-import de.jplag.JPlag;
-import de.jplag.JPlagResult;
-import de.jplag.options.JPlagOptions;
-import de.jplag.options.LanguageOption;
-
-import java.util.List;
-
-public class ReportingTest {
-
-	public static void main(String[] args) throws ExitException {
-		JPlagOptions options = new JPlagOptions("C:\\Uni\\PISE\\JPlag\\jplag\\src\\test\\resources\\de\\jplag\\samples\\PartialPlagiarism", LanguageOption.JAVA_1_9);
-		JPlag jPlag = new JPlag(options);
-		JPlagResult result = jPlag.run();
-		Report reporting = new JsonReport();
-		if ( reporting.saveReport(result) ) {
-			System.out.println("Successfully saved report.");
-		}
-	}
-}

+ 46 - 47
jplag/src/main/java/de/jplag/reportingV2/jsonfactory/JsonFactory.java

@@ -1,61 +1,60 @@
 package de.jplag.reportingV2.jsonfactory;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import de.jplag.JPlagResult;
-import de.jplag.reportingV2.reportobject.model.ComparisonReport;
-import de.jplag.reportingV2.reportobject.model.JPlagReport;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.jplag.reportingV2.reportobject.model.ComparisonReport;
+import de.jplag.reportingV2.reportobject.model.JPlagReport;
+
 /**
  * Factory class, responsible for creating Json strings and writing them to files.
  */
 public class JsonFactory {
 
-	/**
-	 * Uses Jackson to create Json Strings from JPlagReport object.
-	 * @param jPlagReport
-	 * @return A list, first element is Json String of Overview object. The rest elements are Json Strings of
-	 * Comparison objects.
-	 */
-	public static List<String> getJsonStrings(JPlagReport jPlagReport) {
-		List<String> jsonReports = new ArrayList<>();
-		try {
-			ObjectMapper mapper = new ObjectMapper();
-			jsonReports.add(mapper.writeValueAsString(jPlagReport.getOverviewReport()));
-			for (ComparisonReport comparisonReport: jPlagReport.getComparisons()) {
-				jsonReports.add(mapper.writeValueAsString(comparisonReport));
-			}
-		} catch ( JsonProcessingException e) {
-			System.out.println("Error converting object to json " + e.getMessage());
-		}
-		return jsonReports;
-	}
+    /**
+     * Uses Jackson to create Json Strings from JPlagReport object.
+     * @return A list, first element is Json String of Overview object. The rest elements are Json Strings of Comparison
+     * objects.
+     */
+    public static List<String> getJsonStrings(JPlagReport jPlagReport) {
+        List<String> jsonReports = new ArrayList<>();
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            jsonReports.add(mapper.writeValueAsString(jPlagReport.getOverviewReport()));
+            for (ComparisonReport comparisonReport : jPlagReport.getComparisons()) {
+                jsonReports.add(mapper.writeValueAsString(comparisonReport));
+            }
+        } catch (JsonProcessingException e) {
+            System.out.println("Error converting object to json " + e.getMessage());
+        }
+        return jsonReports;
+    }
 
-	/**
-	 * Creates Json Files for the given JPlagReport and saves them in the given folder.
-	 * @param jPlagReport
-	 * @param folderPath
-	 * @return A boolean, representing whether the process was successful.
-	 */
-	public static boolean saveJsonFiles(JPlagReport jPlagReport, String folderPath ) {
-		String sanitizedFolderPath = folderPath;
-		if ( !folderPath.endsWith("/") ) { sanitizedFolderPath = folderPath.concat("/"); }
-		try {
-			ObjectMapper mapper = new ObjectMapper();
-			mapper.writeValue( new File( sanitizedFolderPath.concat("overview.json") ), jPlagReport.getOverviewReport() );
-			for (ComparisonReport r : jPlagReport.getComparisons()) {
-				String name = r.getFirst_submission_id().concat("-").concat(r.getSecond_submission_id()).concat(".json");
-				mapper.writeValue(new File(folderPath + name), r);
-			}
-		} catch ( IOException e) {
-			System.out.println("Failed to save json files: " + e.getMessage());
-			return false;
-		}
-		return true;
-	}
+    /**
+     * Creates Json Files for the given JPlagReport and saves them in the given folder.
+     * @return A boolean, representing whether the process was successful.
+     */
+    public static boolean saveJsonFiles(JPlagReport jPlagReport, String folderPath) {
+        String sanitizedFolderPath = folderPath;
+        if (!folderPath.endsWith("/")) {
+            sanitizedFolderPath = folderPath.concat("/");
+        }
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.writeValue(new File(sanitizedFolderPath.concat("overview.json")), jPlagReport.getOverviewReport());
+            for (ComparisonReport r : jPlagReport.getComparisons()) {
+                String name = r.getFirst_submission_id().concat("-").concat(r.getSecond_submission_id()).concat(".json");
+                mapper.writeValue(new File(folderPath + name), r);
+            }
+        } catch (IOException e) {
+            System.out.println("Failed to save json files: " + e.getMessage());
+            return false;
+        }
+        return true;
+    }
 }

+ 185 - 214
jplag/src/main/java/de/jplag/reportingV2/reportobject/ReportObjectFactory.java

@@ -1,10 +1,5 @@
 package de.jplag.reportingV2.reportobject;
 
-import de.jplag.*;
-import de.jplag.options.JPlagOptions;
-import de.jplag.reportingV2.reportobject.model.*;
-import de.jplag.reportingV2.reportobject.model.Match;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -13,218 +8,194 @@ import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import de.jplag.*;
+import de.jplag.options.JPlagOptions;
+import de.jplag.reportingV2.reportobject.model.*;
+import de.jplag.reportingV2.reportobject.model.Match;
+
 /**
  * Factory class, responsible for converting a JPlagResult object to Overview and Comparison DTO classes.
  */
 public class ReportObjectFactory {
 
-	/**
-	 * Converts a JPlagResult to a JPlagReport.
-	 * @param result
-	 * @return JPlagReport for the given JPlagResult.
-	 */
-	public static JPlagReport getReportObject(JPlagResult result) {
-		OverviewReport overviewReport = generateOverviewReport(result);
-		List<ComparisonReport> comparisons = generateComparisonReports(result);
-		return new JPlagReport(overviewReport, comparisons);
-	}
-
-	/**
-	 * Generates an Overview DTO of a JPlagResult.
-	 * @param result
-	 * @return
-	 */
-	private static  OverviewReport generateOverviewReport(JPlagResult result) {
-		List<JPlagComparison> comparisons = result.getComparisons();
-		OverviewReport overviewReport = new OverviewReport();
-
-		overviewReport.setSubmission_folder_path(result.getOptions().getRootDirectoryName());
-
-		String baseCodePath = result.getOptions().hasBaseCode()? result.getOptions().getBaseCodeSubmissionName() : "";
-		overviewReport.setBase_code_folder_path(baseCodePath);
-
-		overviewReport.setLanguage(result.getOptions().getLanguage().getName());
-		overviewReport.setFile_extensions(List.of(result.getOptions().getFileSuffixes()));
-		overviewReport.setSubmission_ids(extractSubmissionNames(comparisons));
-		overviewReport.setFailed_submission_names(List.of());  //No number of failed submissions
-		overviewReport.setExcluded_files(getExcludedFilesNames(result.getOptions())); //Read exclusion file
-		overviewReport.setMatch_sensitivity(result.getOptions().getMinimumTokenMatch());
-		overviewReport.setDate_of_execution(getDate());
-		overviewReport.setExecution_time(result.getDuration());
-		overviewReport.setComparison_names(getComparisonNames(comparisons));
-		overviewReport.setMetrics(getMetrics(result));
-
-		return overviewReport;
-	}
-
-	/**
-	 * Generates detailed ComparisonReport DTO for each comparison in a JPlagResult.
-	 * @param result
-	 * @return A list with ComparisonReport DTOs.
-	 */
-	private static List<ComparisonReport> generateComparisonReports(JPlagResult result) {
-		List<ComparisonReport> comparisons = new ArrayList<>();
-		result.getComparisons().forEach( c -> comparisons.add(
-			new ComparisonReport(
-				c.getFirstSubmission().getName(),
-				c.getSecondSubmission().getName(),
-				c.similarity(),
-				getFilesForSubmission(c.getFirstSubmission()),
-				getFilesForSubmission(c.getSecondSubmission()),
-				c.getMatches().stream().map(m -> convertMatchToReportMatch(c, m,
-						result.getOptions().getLanguage().usesIndex())).collect(Collectors.toList())
-			)
-		));
-		return comparisons;
-	}
-
-	/**
-	 * Gets the names of all submissions.
-	 * @param comparisons
-	 * @return A list containing all submission names.
-	 */
-	private static List<String> extractSubmissionNames(List<JPlagComparison> comparisons) {
-		HashSet<String> names = new HashSet<>();
-		comparisons.forEach(c -> {
-			names.add(c.getFirstSubmission().getName());
-			names.add(c.getSecondSubmission().getName());
-		});
-		return new ArrayList<>(names);
-	}
-
-	/**
-	 * Gets the names of all comparison.
-	 * @param comparisons
-	 * @return A list containing all comparisons.
-	 */
-	private static List<String> getComparisonNames(List<JPlagComparison> comparisons) {
-		List<String> names = new ArrayList<>();
-		comparisons.forEach(
-				c -> names.add(String.join("-", c.getFirstSubmission().getName(), c.getSecondSubmission().getName()))
-		);
-		return names;
-	}
-
-	// Currently, only one metric can be obtained.
-
-	/**
-	 * Gets the used metric in a JPlag comparison.
-	 * @param result
-	 * @return A list contains Metric DTOs.
-	 */
-	private static List<Metric> getMetrics(JPlagResult result) {
-		List<Metric> metrics = new ArrayList<>();
-		metrics.add(new Metric(
-				result.getOptions().getSimilarityMetric().name(),
-				result.getOptions().getSimilarityThreshold(),
-				intArrayToList(result.getSimilarityDistribution()),
-				getTopComparisons(result.getComparisons())
-		));
-		return metrics;
-	}
-
-
-	/**
-	 * Converts JPlagComparison to a DTO for displaying only comparisons. See {@link #generateComparisonReports(JPlagResult)}
-	 * for a more detailed representation of a comparison.
-	 * @param comparisons
-	 * @return List containing TopComparison DTOs.
-	 */
-	private static List<TopComparison> getTopComparisons(List<JPlagComparison> comparisons) {
-		List<TopComparison> topComparisons = new ArrayList<>();
-		comparisons.forEach( c -> topComparisons.add(new TopComparison(c.getFirstSubmission().getName(), c.getSecondSubmission().getName(), c.similarity())));
-		return topComparisons;
-	}
-
-	/**
-	 * Gets the names of excluded files in a JPlag comparison.
-	 * To be changed in the future to direct access to the file names. No file reading.
-	 * @param options
-	 * @return List with the names of the files.
-	 */
-	private static List<String> getExcludedFilesNames(JPlagOptions options) {
-		if (options.getExclusionFileName() == null) {
-			return List.of();
-		}
-		HashSet<String> excludedFileNames = new HashSet<>();
-
-		try {
-			BufferedReader reader = new BufferedReader(new FileReader(options.getExclusionFileName(), JPlagOptions.CHARSET));
-			String line;
-
-			while ((line = reader.readLine()) != null) {
-				excludedFileNames.add(line.trim());
-			}
-
-			reader.close();
-		} catch (IOException exception) {
-			System.out.println("Could not read exclusion file: " + exception.getMessage());
-		}
-
-		return new ArrayList<>(excludedFileNames);
-	}
-
-	/**
-	 * Converts files of a submission to FilesOFSubmission DTO.
-	 * @param submission
-	 * @return A list containing FilesOfSubmission DTOs.
-	 */
-	private static List<FilesOfSubmission> getFilesForSubmission(Submission submission) {
-		return submission.getFiles().stream().map( f -> new FilesOfSubmission(f.getName(), readFileLines(f))).collect(Collectors.toList());
-	}
-
-	/**
-	 * Converts a JPlag Match object to a Match DTO.
-	 * @param comparison The comparison from which the match originates.
-	 * @param match The match to be converted.
-	 * @param usesIndex Indicates whether the language uses indexes.
-	 * @return A Match DTO.
-	 */
-	private static Match convertMatchToReportMatch(JPlagComparison comparison, de.jplag.Match match, Boolean usesIndex) {
-		TokenList tokensFirst = comparison.getFirstSubmission().getTokenList();
-		TokenList tokensSecond = comparison.getSecondSubmission().getTokenList();
-		Token startFirstToken = tokensFirst.getToken(match.getStartOfFirst());
-		Token endFirstToken = tokensFirst.getToken(match.getStartOfFirst() + match.getLength() - 1);
-		Token startSecondToken = tokensSecond.getToken(match.getStartOfSecond());
-		Token endSecondToken = tokensSecond.getToken(match.getStartOfSecond() + match.getLength() - 1);
-
-		int startFirst = usesIndex ? startFirstToken.getIndex() : startFirstToken.getLine();
-		int endFirst = usesIndex ? endFirstToken.getIndex() : endFirstToken.getLine();
-		int startSecond = usesIndex ? startSecondToken.getIndex() : startSecondToken.getLine();
-		int endSecond = usesIndex ? endSecondToken.getIndex() : endSecondToken.getLine();
-		int tokens = match.getLength();
-
-		return new Match(startFirstToken.file, startSecondToken.file,
-				startFirst,
-				endFirst,
-				startSecond,
-				endSecond,
-				tokens
-		);
-	}
-
-	private static List<String> readFileLines(File file) {
-		ArrayList<String> lines = new ArrayList<>();
-		try {
-			BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
-			String line;
-			while ((line = bufferedReader.readLine()) != null) {
-				lines.add(line);
-			}
-		} catch ( IOException exception) {
-			System.out.println("Could not read file: " + exception.getMessage());
-		}
-		return lines;
-	}
-
-	private static String getDate() {
-		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
-		Date date = new Date();
-		return dateFormat.format(date);
-	}
-
-	private static List<Integer> intArrayToList(int[] array) {
-		return Arrays.stream(array).boxed().collect(Collectors.toList());
-	}
+    /**
+     * Converts a JPlagResult to a JPlagReport.
+     * @return JPlagReport for the given JPlagResult.
+     */
+    public static JPlagReport getReportObject(JPlagResult result) {
+        OverviewReport overviewReport = generateOverviewReport(result);
+        List<ComparisonReport> comparisons = generateComparisonReports(result);
+        return new JPlagReport(overviewReport, comparisons);
+    }
+
+    /**
+     * Generates an Overview DTO of a JPlagResult.
+     */
+    private static OverviewReport generateOverviewReport(JPlagResult result) {
+        List<JPlagComparison> comparisons = result.getComparisons();
+        OverviewReport overviewReport = new OverviewReport();
+
+        //New update in JPlagOption. Not a single root dir but a list. Needs re-thinking and
+        //implementation also in report model.
+        overviewReport.setSubmission_folder_path(result.getOptions().getRootDirectoryNames().get(0));
+
+        String baseCodePath = result.getOptions().hasBaseCode() ? result.getOptions().getBaseCodeSubmissionName().orElse("") : "";
+        overviewReport.setBase_code_folder_path(baseCodePath);
+
+        overviewReport.setLanguage(result.getOptions().getLanguage().getName());
+        overviewReport.setFile_extensions(List.of(result.getOptions().getFileSuffixes()));
+        overviewReport.setSubmission_ids(extractSubmissionNames(comparisons));
+        overviewReport.setFailed_submission_names(List.of());  // No number of failed submissions
+        overviewReport.setExcluded_files(getExcludedFilesNames(result.getOptions())); // Read exclusion file
+        overviewReport.setMatch_sensitivity(result.getOptions().getMinimumTokenMatch());
+        overviewReport.setDate_of_execution(getDate());
+        overviewReport.setExecution_time(result.getDuration());
+        overviewReport.setComparison_names(getComparisonNames(comparisons));
+        overviewReport.setMetrics(getMetrics(result));
+
+        return overviewReport;
+    }
+
+    /**
+     * Generates detailed ComparisonReport DTO for each comparison in a JPlagResult.
+     * @return A list with ComparisonReport DTOs.
+     */
+    private static List<ComparisonReport> generateComparisonReports(JPlagResult result) {
+        List<ComparisonReport> comparisons = new ArrayList<>();
+        result.getComparisons().forEach(c -> comparisons.add(new ComparisonReport(c.getFirstSubmission().getName(), c.getSecondSubmission().getName(),
+                c.similarity(), getFilesForSubmission(c.getFirstSubmission()), getFilesForSubmission(c.getSecondSubmission()), c.getMatches().stream()
+                        .map(m -> convertMatchToReportMatch(c, m, result.getOptions().getLanguage().usesIndex())).collect(Collectors.toList()))));
+        return comparisons;
+    }
+
+    /**
+     * Gets the names of all submissions.
+     * @return A list containing all submission names.
+     */
+    private static List<String> extractSubmissionNames(List<JPlagComparison> comparisons) {
+        HashSet<String> names = new HashSet<>();
+        comparisons.forEach(c -> {
+            names.add(c.getFirstSubmission().getName());
+            names.add(c.getSecondSubmission().getName());
+        });
+        return new ArrayList<>(names);
+    }
+
+    /**
+     * Gets the names of all comparison.
+     * @return A list containing all comparisons.
+     */
+    private static List<String> getComparisonNames(List<JPlagComparison> comparisons) {
+        List<String> names = new ArrayList<>();
+        comparisons.forEach(c -> names.add(String.join("-", c.getFirstSubmission().getName(), c.getSecondSubmission().getName())));
+        return names;
+    }
+
+    // Currently, only one metric can be obtained.
+
+    /**
+     * Gets the used metric in a JPlag comparison.
+     * @return A list contains Metric DTOs.
+     */
+    private static List<Metric> getMetrics(JPlagResult result) {
+        List<Metric> metrics = new ArrayList<>();
+        metrics.add(new Metric(result.getOptions().getSimilarityMetric().name(), result.getOptions().getSimilarityThreshold(),
+                intArrayToList(result.getSimilarityDistribution()), getTopComparisons(result.getComparisons())));
+        return metrics;
+    }
+
+    /**
+     * Converts JPlagComparison to a DTO for displaying only comparisons. See
+     * {@link #generateComparisonReports(JPlagResult)} for a more detailed representation of a comparison.
+     * @return List containing TopComparison DTOs.
+     */
+    private static List<TopComparison> getTopComparisons(List<JPlagComparison> comparisons) {
+        List<TopComparison> topComparisons = new ArrayList<>();
+        comparisons.forEach(
+                c -> topComparisons.add(new TopComparison(c.getFirstSubmission().getName(), c.getSecondSubmission().getName(), c.similarity())));
+        return topComparisons;
+    }
+
+    /**
+     * Gets the names of excluded files in a JPlag comparison. To be changed in the future to direct access to the file
+     * names. No file reading.
+     * @return List with the names of the files.
+     */
+    private static List<String> getExcludedFilesNames(JPlagOptions options) {
+        if (options.getExclusionFileName() == null) {
+            return List.of();
+        }
+        HashSet<String> excludedFileNames = new HashSet<>();
+
+        try {
+            BufferedReader reader = new BufferedReader(new FileReader(options.getExclusionFileName(), JPlagOptions.CHARSET));
+            String line;
+
+            while ((line = reader.readLine()) != null) {
+                excludedFileNames.add(line.trim());
+            }
+
+            reader.close();
+        } catch (IOException exception) {
+            System.out.println("Could not read exclusion file: " + exception.getMessage());
+        }
+
+        return new ArrayList<>(excludedFileNames);
+    }
+
+    /**
+     * Converts files of a submission to FilesOFSubmission DTO.
+     * @return A list containing FilesOfSubmission DTOs.
+     */
+    private static List<FilesOfSubmission> getFilesForSubmission(Submission submission) {
+        return submission.getFiles().stream().map(f -> new FilesOfSubmission(f.getName(), readFileLines(f))).collect(Collectors.toList());
+    }
+
+    /**
+     * Converts a JPlag Match object to a Match DTO.
+     * @param comparison The comparison from which the match originates.
+     * @param match The match to be converted.
+     * @param usesIndex Indicates whether the language uses indexes.
+     * @return A Match DTO.
+     */
+    private static Match convertMatchToReportMatch(JPlagComparison comparison, de.jplag.Match match, Boolean usesIndex) {
+        TokenList tokensFirst = comparison.getFirstSubmission().getTokenList();
+        TokenList tokensSecond = comparison.getSecondSubmission().getTokenList();
+        Token startFirstToken = tokensFirst.getToken(match.getStartOfFirst());
+        Token endFirstToken = tokensFirst.getToken(match.getStartOfFirst() + match.getLength() - 1);
+        Token startSecondToken = tokensSecond.getToken(match.getStartOfSecond());
+        Token endSecondToken = tokensSecond.getToken(match.getStartOfSecond() + match.getLength() - 1);
+
+        int startFirst = usesIndex ? startFirstToken.getIndex() : startFirstToken.getLine();
+        int endFirst = usesIndex ? endFirstToken.getIndex() : endFirstToken.getLine();
+        int startSecond = usesIndex ? startSecondToken.getIndex() : startSecondToken.getLine();
+        int endSecond = usesIndex ? endSecondToken.getIndex() : endSecondToken.getLine();
+        int tokens = match.getLength();
+
+        return new Match(startFirstToken.file, startSecondToken.file, startFirst, endFirst, startSecond, endSecond, tokens);
+    }
+
+    private static List<String> readFileLines(File file) {
+        ArrayList<String> lines = new ArrayList<>();
+        try {
+            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                lines.add(line);
+            }
+        } catch (IOException exception) {
+            System.out.println("Could not read file: " + exception.getMessage());
+        }
+        return lines;
+    }
+
+    private static String getDate() {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
+        Date date = new Date();
+        return dateFormat.format(date);
+    }
+
+    private static List<Integer> intArrayToList(int[] array) {
+        return Arrays.stream(array).boxed().collect(Collectors.toList());
+    }
 }
-

+ 65 - 69
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/ComparisonReport.java

@@ -4,73 +4,69 @@ import java.util.List;
 
 public class ComparisonReport {
 
-	private String first_submission_id;
-	private String second_submission_id;
-	private float match_percentage;
-	private List<FilesOfSubmission> files_of_first_submission;
-	private List<FilesOfSubmission> files_of_second_submission;
-	private List<Match> matches;
-
-	public ComparisonReport(String first_submission_id,
-							String second_submission_id,
-							float match_percentage,
-							List<FilesOfSubmission> files_of_first_submission,
-							List<FilesOfSubmission> files_of_second_submission,
-							List<Match> matches) {
-
-		this.first_submission_id = first_submission_id;
-		this.second_submission_id = second_submission_id;
-		this.match_percentage = match_percentage;
-		this.files_of_first_submission = files_of_first_submission;
-		this.files_of_second_submission = files_of_second_submission;
-		this.matches = matches;
-	}
-
-	public String getFirst_submission_id() {
-		return first_submission_id;
-	}
-
-	public String getSecond_submission_id() {
-		return second_submission_id;
-	}
-
-	public float getMatch_percentage() {
-		return match_percentage;
-	}
-
-	public List<FilesOfSubmission> getFiles_of_first_submission() {
-		return files_of_first_submission;
-	}
-
-	public List<FilesOfSubmission> getFiles_of_second_submission() {
-		return files_of_second_submission;
-	}
-
-	public List<Match> getMatches() {
-		return matches;
-	}
-
-	public void setFirst_submission_id(String first_submission_id) {
-		this.first_submission_id = first_submission_id;
-	}
-
-	public void setSecond_submission_id(String second_submission_id) {
-		this.second_submission_id = second_submission_id;
-	}
-
-	public void setMatch_percentage(float match_percentage) {
-		this.match_percentage = match_percentage;
-	}
-
-	public void setFiles_of_first_submission(List<FilesOfSubmission> files_of_first_submission) {
-		this.files_of_first_submission = files_of_first_submission;
-	}
-
-	public void setFiles_of_second_submission(List<FilesOfSubmission> files_of_second_submission) {
-		this.files_of_second_submission = files_of_second_submission;
-	}
-
-	public void setMatches(List<Match> matches) {
-		this.matches = matches;
-	}
+    private String first_submission_id;
+    private String second_submission_id;
+    private float match_percentage;
+    private List<FilesOfSubmission> files_of_first_submission;
+    private List<FilesOfSubmission> files_of_second_submission;
+    private List<Match> matches;
+
+    public ComparisonReport(String first_submission_id, String second_submission_id, float match_percentage,
+            List<FilesOfSubmission> files_of_first_submission, List<FilesOfSubmission> files_of_second_submission, List<Match> matches) {
+
+        this.first_submission_id = first_submission_id;
+        this.second_submission_id = second_submission_id;
+        this.match_percentage = match_percentage;
+        this.files_of_first_submission = files_of_first_submission;
+        this.files_of_second_submission = files_of_second_submission;
+        this.matches = matches;
+    }
+
+    public String getFirst_submission_id() {
+        return first_submission_id;
+    }
+
+    public String getSecond_submission_id() {
+        return second_submission_id;
+    }
+
+    public float getMatch_percentage() {
+        return match_percentage;
+    }
+
+    public List<FilesOfSubmission> getFiles_of_first_submission() {
+        return files_of_first_submission;
+    }
+
+    public List<FilesOfSubmission> getFiles_of_second_submission() {
+        return files_of_second_submission;
+    }
+
+    public List<Match> getMatches() {
+        return matches;
+    }
+
+    public void setFirst_submission_id(String first_submission_id) {
+        this.first_submission_id = first_submission_id;
+    }
+
+    public void setSecond_submission_id(String second_submission_id) {
+        this.second_submission_id = second_submission_id;
+    }
+
+    public void setMatch_percentage(float match_percentage) {
+        this.match_percentage = match_percentage;
+    }
+
+    public void setFiles_of_first_submission(List<FilesOfSubmission> files_of_first_submission) {
+        this.files_of_first_submission = files_of_first_submission;
+    }
+
+    public void setFiles_of_second_submission(List<FilesOfSubmission> files_of_second_submission) {
+        this.files_of_second_submission = files_of_second_submission;
+    }
+
+    public void setMatches(List<Match> matches) {
+        this.matches = matches;
+    }
 }

+ 18 - 19
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/FilesOfSubmission.java

@@ -4,28 +4,27 @@ import java.util.List;
 
 public class FilesOfSubmission {
 
-	private String file_name;
-	private List<String> lines;
+    private String file_name;
+    private List<String> lines;
 
-	public FilesOfSubmission(String file_name, List<String> file_code) {
-		this.file_name = file_name;
-		this.lines = file_code;
-	}
+    public FilesOfSubmission(String file_name, List<String> file_code) {
+        this.file_name = file_name;
+        this.lines = file_code;
+    }
 
-	public String getFile_name() {
-		return file_name;
-	}
+    public String getFile_name() {
+        return file_name;
+    }
 
-	public List<String> getLines() {
-		return lines;
-	}
+    public List<String> getLines() {
+        return lines;
+    }
 
-	public void setFile_name(String file_name) {
-		this.file_name = file_name;
-	}
+    public void setFile_name(String file_name) {
+        this.file_name = file_name;
+    }
 
-	public void setLines(List<String> lines) {
-		this.lines = lines;
-	}
+    public void setLines(List<String> lines) {
+        this.lines = lines;
+    }
 }
-

+ 12 - 12
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/JPlagReport.java

@@ -3,19 +3,19 @@ package de.jplag.reportingV2.reportobject.model;
 import java.util.List;
 
 public class JPlagReport {
-	private OverviewReport overviewReport;
-	private List<ComparisonReport> comparisons;
+    private final OverviewReport overviewReport;
+    private final List<ComparisonReport> comparisons;
 
-	public JPlagReport( OverviewReport overviewReport, List<ComparisonReport> comparisons) {
-		this.overviewReport = overviewReport;
-		this.comparisons = comparisons;
-	}
+    public JPlagReport(OverviewReport overviewReport, List<ComparisonReport> comparisons) {
+        this.overviewReport = overviewReport;
+        this.comparisons = comparisons;
+    }
 
-	public OverviewReport getOverviewReport() {
-		return overviewReport;
-	}
+    public OverviewReport getOverviewReport() {
+        return overviewReport;
+    }
 
-	public List<ComparisonReport> getComparisons() {
-		return comparisons;
-	}
+    public List<ComparisonReport> getComparisons() {
+        return comparisons;
+    }
 }

+ 75 - 76
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/Match.java

@@ -2,80 +2,79 @@ package de.jplag.reportingV2.reportobject.model;
 
 public class Match {
 
-	private String first_file_name;
-	private String second_file_name;
-	private int start_in_first;
-	private int end_in_first;
-	private int start_in_second;
-	private int end_in_second;
-	private int tokens;
-
-	public Match(String first_file_name,
-				 String second_file_name,
-				 int start_in_first,
-				 int end_in_first,
-				 int start_in_second,
-				 int end_in_second,
-				 int tokens) {
-
-		this.first_file_name = first_file_name;
-		this.second_file_name = second_file_name;
-		this.start_in_first = start_in_first;
-		this.end_in_first = end_in_first;
-		this.start_in_second = start_in_second;
-		this.end_in_second = end_in_second;
-		this.tokens = tokens;
-	}
-
-	public String getFirst_file_name() {
-		return first_file_name;
-	}
-
-	public String getSecond_file_name() {
-		return second_file_name;
-	}
-
-	public int getStart_in_first() {
-		return start_in_first;
-	}
-
-	public int getEnd_in_first() {
-		return end_in_first;
-	}
-
-	public int getStart_in_second() {
-		return start_in_second;
-	}
-
-	public int getEnd_in_second() {
-		return end_in_second;
-	}
-
-	public int getTokens() { return tokens; }
-
-	public void setFirst_file_name(String first_file_name) {
-		this.first_file_name = first_file_name;
-	}
-
-	public void setSecond_file_name(String second_file_name) {
-		this.second_file_name = second_file_name;
-	}
-
-	public void setStart_in_first(int start_in_first) {
-		this.start_in_first = start_in_first;
-	}
-
-	public void setEnd_in_first(int end_in_first) {
-		this.end_in_first = end_in_first;
-	}
-
-	public void setStart_in_second(int start_in_second) {
-		this.start_in_second = start_in_second;
-	}
-
-	public void setEnd_in_second(int end_in_second) {
-		this.end_in_second = end_in_second;
-	}
-
-	public void setTokens(int tokens) { this.tokens = tokens; }
+    private String first_file_name;
+    private String second_file_name;
+    private int start_in_first;
+    private int end_in_first;
+    private int start_in_second;
+    private int end_in_second;
+    private int tokens;
+
+    public Match(String first_file_name, String second_file_name, int start_in_first, int end_in_first, int start_in_second, int end_in_second,
+            int tokens) {
+
+        this.first_file_name = first_file_name;
+        this.second_file_name = second_file_name;
+        this.start_in_first = start_in_first;
+        this.end_in_first = end_in_first;
+        this.start_in_second = start_in_second;
+        this.end_in_second = end_in_second;
+        this.tokens = tokens;
+    }
+
+    public String getFirst_file_name() {
+        return first_file_name;
+    }
+
+    public String getSecond_file_name() {
+        return second_file_name;
+    }
+
+    public int getStart_in_first() {
+        return start_in_first;
+    }
+
+    public int getEnd_in_first() {
+        return end_in_first;
+    }
+
+    public int getStart_in_second() {
+        return start_in_second;
+    }
+
+    public int getEnd_in_second() {
+        return end_in_second;
+    }
+
+    public int getTokens() {
+        return tokens;
+    }
+
+    public void setFirst_file_name(String first_file_name) {
+        this.first_file_name = first_file_name;
+    }
+
+    public void setSecond_file_name(String second_file_name) {
+        this.second_file_name = second_file_name;
+    }
+
+    public void setStart_in_first(int start_in_first) {
+        this.start_in_first = start_in_first;
+    }
+
+    public void setEnd_in_first(int end_in_first) {
+        this.end_in_first = end_in_first;
+    }
+
+    public void setStart_in_second(int start_in_second) {
+        this.start_in_second = start_in_second;
+    }
+
+    public void setEnd_in_second(int end_in_second) {
+        this.end_in_second = end_in_second;
+    }
+
+    public void setTokens(int tokens) {
+        this.tokens = tokens;
+    }
 }

+ 22 - 22
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/Metric.java

@@ -3,31 +3,31 @@ package de.jplag.reportingV2.reportobject.model;
 import java.util.List;
 
 public class Metric {
-	private String name;
-	private float threshold;
-	private List<Integer> distribution;
-	private List<TopComparison> topComparisons;
+    private final String name;
+    private final float threshold;
+    private final List<Integer> distribution;
+    private final List<TopComparison> topComparisons;
 
-	public Metric(String name, float threshold, List<Integer> distribution, List<TopComparison> topComparisons) {
-		this.name = name;
-		this.threshold = threshold;
-		this.distribution = distribution;
-		this.topComparisons = topComparisons;
-	}
+    public Metric(String name, float threshold, List<Integer> distribution, List<TopComparison> topComparisons) {
+        this.name = name;
+        this.threshold = threshold;
+        this.distribution = distribution;
+        this.topComparisons = topComparisons;
+    }
 
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public float getThreshold() {
-		return threshold;
-	}
+    public float getThreshold() {
+        return threshold;
+    }
 
-	public List<Integer> getDistribution() {
-		return distribution;
-	}
+    public List<Integer> getDistribution() {
+        return distribution;
+    }
 
-	public List<TopComparison> getTopComparisons() {
-		return topComparisons;
-	}
+    public List<TopComparison> getTopComparisons() {
+        return topComparisons;
+    }
 }

+ 128 - 133
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/OverviewReport.java

@@ -4,138 +4,133 @@ import java.util.List;
 
 public class OverviewReport {
 
-	private String submission_folder_path;
-	private String base_code_folder_path;
-	private String language;
-	private List<String> file_extensions;
-	private List<String> submission_ids;
-	private List<String> failed_submission_names;
-	private List<String> excluded_files;
-	private int match_sensitivity;
-	private String date_of_execution;
-	private long execution_time;
-	private List<String> comparison_names;
-	private List<Metric> metrics;
-
-	public OverviewReport() {
-		submission_folder_path = "";
-		base_code_folder_path ="";
-		language ="";
-		file_extensions = List.of();
-		submission_ids = List.of();
-		failed_submission_names = List.of();
-		excluded_files = List.of();
-		match_sensitivity = 0;
-		date_of_execution = "";
-		execution_time = 0;
-	}
-
-	/*******************************
-	 *
-	 *  GETTERS
-	 *
-	 *******************************/
-
-	public String getSubmission_folder_path() {
-		return submission_folder_path;
-	}
-
-	public String getBase_code_folder_path() {
-		return base_code_folder_path;
-	}
-
-	public String getLanguage() {
-		return language;
-	}
-
-	public List<String> getFile_extensions() {
-		return file_extensions;
-	}
-
-	public List<String> getSubmission_ids() {
-		return submission_ids;
-	}
-
-	public List<String> getFailed_submission_names() {
-		return failed_submission_names;
-	}
-
-	public List<String> getExcluded_files() {
-		return excluded_files;
-	}
-
-	public int getMatch_sensitivity() {
-		return match_sensitivity;
-	}
-
-	public String getDate_of_execution() {
-		return date_of_execution;
-	}
-
-	public long getExecution_time() {
-		return execution_time;
-	}
-
-	public List<String> getComparison_names() {
-		return comparison_names;
-	}
-
-	public List<Metric> getMetrics() {
-		return metrics;
-	}
-
-	/*******************************
-	 *
-	 *  SETTERS
-	 *
-	 *******************************/
-
-	public void setSubmission_folder_path(String submission_folder_path) {
-		this.submission_folder_path = submission_folder_path;
-	}
-
-	public void setBase_code_folder_path(String base_code_folder_path) {
-		this.base_code_folder_path = base_code_folder_path;
-	}
-
-	public void setLanguage(String language) {
-		this.language = language;
-	}
-
-	public void setFile_extensions(List<String> file_extensions) {
-		this.file_extensions = file_extensions;
-	}
-
-	public void setSubmission_ids(List<String> submission_ids) {
-		this.submission_ids = submission_ids;
-	}
-
-	public void setFailed_submission_names(List<String> failed_submission_names) {
-		this.failed_submission_names = failed_submission_names;
-	}
-
-	public void setExcluded_files(List<String> excluded_files) {
-		this.excluded_files = excluded_files;
-	}
-
-	public void setMatch_sensitivity(int match_sensitivity) {
-		this.match_sensitivity = match_sensitivity;
-	}
-
-	public void setDate_of_execution(String date_of_execution) {
-		this.date_of_execution = date_of_execution;
-	}
-
-	public void setExecution_time(long execution_time) {
-		this.execution_time = execution_time;
-	}
+    private String submission_folder_path;
+    private String base_code_folder_path;
+    private String language;
+    private List<String> file_extensions;
+    private List<String> submission_ids;
+    private List<String> failed_submission_names;
+    private List<String> excluded_files;
+    private int match_sensitivity;
+    private String date_of_execution;
+    private long execution_time;
+    private List<String> comparison_names;
+    private List<Metric> metrics;
+
+    public OverviewReport() {
+        submission_folder_path = "";
+        base_code_folder_path = "";
+        language = "";
+        file_extensions = List.of();
+        submission_ids = List.of();
+        failed_submission_names = List.of();
+        excluded_files = List.of();
+        match_sensitivity = 0;
+        date_of_execution = "";
+        execution_time = 0;
+    }
+
+    /*******************************
+     * GETTERS
+     *******************************/
+
+    public String getSubmission_folder_path() {
+        return submission_folder_path;
+    }
+
+    public String getBase_code_folder_path() {
+        return base_code_folder_path;
+    }
+
+    public String getLanguage() {
+        return language;
+    }
+
+    public List<String> getFile_extensions() {
+        return file_extensions;
+    }
+
+    public List<String> getSubmission_ids() {
+        return submission_ids;
+    }
+
+    public List<String> getFailed_submission_names() {
+        return failed_submission_names;
+    }
+
+    public List<String> getExcluded_files() {
+        return excluded_files;
+    }
+
+    public int getMatch_sensitivity() {
+        return match_sensitivity;
+    }
+
+    public String getDate_of_execution() {
+        return date_of_execution;
+    }
+
+    public long getExecution_time() {
+        return execution_time;
+    }
+
+    public List<String> getComparison_names() {
+        return comparison_names;
+    }
+
+    public List<Metric> getMetrics() {
+        return metrics;
+    }
+
+    /*******************************
+     * SETTERS
+     *******************************/
+
+    public void setSubmission_folder_path(String submission_folder_path) {
+        this.submission_folder_path = submission_folder_path;
+    }
+
+    public void setBase_code_folder_path(String base_code_folder_path) {
+        this.base_code_folder_path = base_code_folder_path;
+    }
+
+    public void setLanguage(String language) {
+        this.language = language;
+    }
+
+    public void setFile_extensions(List<String> file_extensions) {
+        this.file_extensions = file_extensions;
+    }
+
+    public void setSubmission_ids(List<String> submission_ids) {
+        this.submission_ids = submission_ids;
+    }
+
+    public void setFailed_submission_names(List<String> failed_submission_names) {
+        this.failed_submission_names = failed_submission_names;
+    }
+
+    public void setExcluded_files(List<String> excluded_files) {
+        this.excluded_files = excluded_files;
+    }
+
+    public void setMatch_sensitivity(int match_sensitivity) {
+        this.match_sensitivity = match_sensitivity;
+    }
+
+    public void setDate_of_execution(String date_of_execution) {
+        this.date_of_execution = date_of_execution;
+    }
+
+    public void setExecution_time(long execution_time) {
+        this.execution_time = execution_time;
+    }
+
+    public void setComparison_names(List<String> comparison_names) {
+        this.comparison_names = comparison_names;
+    }
 
-
-	public void setComparison_names(List<String> comparison_names) {
-		this.comparison_names = comparison_names;
-	}
-
-	public void setMetrics(List<Metric> metrics) {
-		this.metrics = metrics;
-	}
+    public void setMetrics(List<Metric> metrics) {
+        this.metrics = metrics;
+    }
 }

+ 33 - 33
jplag/src/main/java/de/jplag/reportingV2/reportobject/model/TopComparison.java

@@ -2,37 +2,37 @@ package de.jplag.reportingV2.reportobject.model;
 
 public class TopComparison {
 
-	private String first_submission;
-	private String second_submission;
-	private float match_percentage;
-
-	public TopComparison(String first_submission, String second_submission, float match_percentage) {
-		this.first_submission = first_submission;
-		this.second_submission = second_submission;
-		this.match_percentage = match_percentage;
-	}
-
-	public String getFirst_submission() {
-		return first_submission;
-	}
-
-	public String getSecond_submission() {
-		return second_submission;
-	}
-
-	public float getMatch_percentage() {
-		return match_percentage;
-	}
-
-	public void setFirst_submission(String first_submission) {
-		this.first_submission = first_submission;
-	}
-
-	public void setSecond_submission(String second_submission) {
-		this.second_submission = second_submission;
-	}
-
-	public void setMatch_percentage(float match_percentage) {
-		this.match_percentage = match_percentage;
-	}
+    private String first_submission;
+    private String second_submission;
+    private float match_percentage;
+
+    public TopComparison(String first_submission, String second_submission, float match_percentage) {
+        this.first_submission = first_submission;
+        this.second_submission = second_submission;
+        this.match_percentage = match_percentage;
+    }
+
+    public String getFirst_submission() {
+        return first_submission;
+    }
+
+    public String getSecond_submission() {
+        return second_submission;
+    }
+
+    public float getMatch_percentage() {
+        return match_percentage;
+    }
+
+    public void setFirst_submission(String first_submission) {
+        this.first_submission = first_submission;
+    }
+
+    public void setSecond_submission(String second_submission) {
+        this.second_submission = second_submission;
+    }
+
+    public void setMatch_percentage(float match_percentage) {
+        this.match_percentage = match_percentage;
+    }
 }

+ 0 - 113
report-viewer/src/files/overview.json

@@ -1,113 +0,0 @@
-{
-  "submission_folder_path": "C:\\Uni\\PISE\\JPlag\\jplag\\src\\test\\resources\\de\\jplag\\samples\\PartialPlagiarism",
-  "base_code_folder_path": "",
-  "language": "Javac 1.9+ based AST plugin",
-  "file_extensions": [
-    ".java",
-    ".JAVA"
-  ],
-  "submission_ids": [
-    "A",
-    "B",
-    "C",
-    "D",
-    "E"
-  ],
-  "failed_submission_names": [],
-  "excluded_files": [],
-  "match_sensitivity": 9,
-  "date_of_execution": "27/12/21",
-  "execution_time": 94,
-  "comparison_names": [
-    "C-A",
-    "D-A",
-    "D-C",
-    "B-D",
-    "B-A",
-    "B-C",
-    "E-A",
-    "E-B",
-    "E-C",
-    "E-D"
-  ],
-  "metrics": [
-    {
-      "name": "AVG",
-      "threshold": 0.0,
-      "distribution": [
-        4,
-        0,
-        3,
-        0,
-        0,
-        0,
-        0,
-        2,
-        0,
-        1
-      ],
-      "topComparisons": [
-        {
-          "first_submission": "C",
-          "second_submission": "A",
-          "match_percentage": 99.6633
-        },
-        {
-          "first_submission": "D",
-          "second_submission": "A",
-          "match_percentage": 77.87255
-        },
-        {
-          "first_submission": "D",
-          "second_submission": "C",
-          "match_percentage": 77.87255
-        },
-        {
-          "first_submission": "B",
-          "second_submission": "D",
-          "match_percentage": 28.278688
-        },
-        {
-          "first_submission": "B",
-          "second_submission": "A",
-          "match_percentage": 24.576895
-        },
-        {
-          "first_submission": "B",
-          "second_submission": "C",
-          "match_percentage": 24.576895
-        },
-        {
-          "first_submission": "E",
-          "second_submission": "A",
-          "match_percentage": 0.0
-        },
-        {
-          "first_submission": "E",
-          "second_submission": "B",
-          "match_percentage": 0.0
-        },
-        {
-          "first_submission": "E",
-          "second_submission": "C",
-          "match_percentage": 0.0
-        },
-        {
-          "first_submission": "E",
-          "second_submission": "D",
-          "match_percentage": 0.0
-        }
-      ]
-    }
-  ],
-  "clusters": [
-    {
-      "avgSim": 30,
-      "members": ["A", "B", "C"]
-    },
-    {
-      "avgSim": 80,
-      "members": ["A", "B", "D", "E"]
-    }
-  ]
-}