|
|
@@ -1,47 +1,63 @@
|
|
|
package de.jplag.reporting.reportobject;
|
|
|
|
|
|
-import java.io.BufferedReader;
|
|
|
import java.io.File;
|
|
|
-import java.io.FileReader;
|
|
|
import java.io.IOException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.StandardCopyOption;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.HashSet;
|
|
|
-import java.util.List;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
-import de.jplag.*;
|
|
|
+import de.jplag.JPlagComparison;
|
|
|
+import de.jplag.JPlagResult;
|
|
|
+import de.jplag.Submission;
|
|
|
+import de.jplag.reporting.jsonfactory.FileWriter;
|
|
|
import de.jplag.reporting.reportobject.mapper.ClusteringResultMapper;
|
|
|
+import de.jplag.reporting.reportobject.mapper.ComparisonReportMapper;
|
|
|
import de.jplag.reporting.reportobject.mapper.MetricMapper;
|
|
|
-import de.jplag.reporting.reportobject.model.*;
|
|
|
-import de.jplag.reporting.reportobject.model.Match;
|
|
|
+import de.jplag.reporting.reportobject.model.Metric;
|
|
|
+import de.jplag.reporting.reportobject.model.OverviewReport;
|
|
|
|
|
|
/**
|
|
|
* Factory class, responsible for converting a JPlagResult object to Overview and Comparison DTO classes.
|
|
|
*/
|
|
|
public class ReportObjectFactory {
|
|
|
-
|
|
|
private static final Logger logger = LoggerFactory.getLogger(ReportObjectFactory.class);
|
|
|
+
|
|
|
private static final ClusteringResultMapper clusteringResultMapper = new ClusteringResultMapper();
|
|
|
private static final MetricMapper metricMapper = new MetricMapper();
|
|
|
+ private static final ComparisonReportMapper comparisonReportMapper = new ComparisonReportMapper();
|
|
|
+ private static final FileWriter fileWriter = new FileWriter();
|
|
|
+ public static final String OVERVIEW_FILE_NAME = "overview.json";
|
|
|
+ public static final String SUBMISSIONS_FOLDER = "submissions";
|
|
|
|
|
|
/**
|
|
|
- * Converts a JPlagResult to a JPlagReport.
|
|
|
- * @return JPlagReport for the given JPlagResult.
|
|
|
+ * @param result The JPlagResult to be converted into a report.
|
|
|
+ * @param path The Path to save the report to
|
|
|
*/
|
|
|
- public static JPlagReport getReportObject(JPlagResult result) {
|
|
|
- OverviewReport overviewReport = generateOverviewReport(result);
|
|
|
- List<ComparisonReport> comparisons = generateComparisonReports(result);
|
|
|
- return new JPlagReport(overviewReport, comparisons);
|
|
|
+ public static void createAndSaveReport(JPlagResult result, String path) {
|
|
|
+ createDirectory(path);
|
|
|
+ writeOverview(result, path);
|
|
|
+ copySubmissionFilesToReport(path, result);
|
|
|
+ comparisonReportMapper.writeComparisonReports(result, path);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Generates an Overview DTO of a JPlagResult.
|
|
|
- */
|
|
|
- private static OverviewReport generateOverviewReport(JPlagResult result) {
|
|
|
+ private static File createDirectory(String path, String name) {
|
|
|
+ File directory = new File(path.concat("/").concat(name));
|
|
|
+ if (!directory.exists() && !directory.mkdirs()) {
|
|
|
+ logger.error("Failed to create dir.");
|
|
|
+ }
|
|
|
+ return directory;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void createDirectory(String path) {
|
|
|
+ createDirectory(path, "");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void writeOverview(JPlagResult result, String path) {
|
|
|
List<JPlagComparison> comparisons = getComparisons(result);
|
|
|
OverviewReport overviewReport = new OverviewReport();
|
|
|
|
|
|
@@ -66,24 +82,31 @@ public class ReportObjectFactory {
|
|
|
overviewReport.setMetrics(getMetrics(result));
|
|
|
overviewReport.setClusters(clusteringResultMapper.map(result));
|
|
|
|
|
|
- return overviewReport;
|
|
|
+ fileWriter.saveAsJSON(overviewReport, path, OVERVIEW_FILE_NAME);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 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<>();
|
|
|
- getComparisons(result).forEach(comparison -> comparisons.add( //
|
|
|
- new ComparisonReport(comparison.getFirstSubmission().getName(), //
|
|
|
- comparison.getSecondSubmission().getName(), //
|
|
|
- comparison.similarity(), //
|
|
|
- getFilesForSubmission(comparison.getFirstSubmission()), //
|
|
|
- getFilesForSubmission(comparison.getSecondSubmission()), //
|
|
|
- convertMatchesToReportMatches(result, comparison, comparison.getMatches()) //
|
|
|
- )));
|
|
|
- return comparisons;
|
|
|
+ private static void copySubmissionFilesToReport(String path, JPlagResult result) {
|
|
|
+ List<JPlagComparison> comparisons = result.getComparisons(result.getOptions().getMaximumNumberOfComparisons());
|
|
|
+ var submissions = getSubmissions(comparisons);
|
|
|
+ var submissionsPath = createDirectory(path, SUBMISSIONS_FOLDER);
|
|
|
+ for (var submission : submissions) {
|
|
|
+ File directory = createDirectory(submissionsPath.getPath(), submission.getName());
|
|
|
+ for (var file : submission.getFiles()) {
|
|
|
+ try {
|
|
|
+ Files.copy(file.toPath(), (new File(directory, file.getName())).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
|
|
+ } catch (IOException e) {
|
|
|
+ logger.error("Could not save submission file " + file, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Set<Submission> getSubmissions(List<JPlagComparison> comparisons) {
|
|
|
+ var submissions = comparisons.stream().map(JPlagComparison::getFirstSubmission).collect(Collectors.toSet());
|
|
|
+ Set<Submission> secondSubmissions = comparisons.stream().map(JPlagComparison::getSecondSubmission).collect(Collectors.toSet());
|
|
|
+ submissions.addAll(secondSubmissions);
|
|
|
+ return submissions;
|
|
|
}
|
|
|
|
|
|
private static List<JPlagComparison> getComparisons(JPlagResult result) {
|
|
|
@@ -91,11 +114,6 @@ public class ReportObjectFactory {
|
|
|
return result.getComparisons(numberOfComparisons);
|
|
|
}
|
|
|
|
|
|
- private static List<Match> convertMatchesToReportMatches(JPlagResult result, JPlagComparison comparison, List<de.jplag.Match> matches) {
|
|
|
- return matches.stream().map(match -> convertMatchToReportMatch(comparison, match, !result.getOptions().getLanguage().supportsColumns()))
|
|
|
- .toList();
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* Gets the names of all submissions.
|
|
|
* @return A list containing all submission names.
|
|
|
@@ -129,51 +147,6 @@ public class ReportObjectFactory {
|
|
|
return List.of(metricMapper.getAverageMetric(result), metricMapper.getMaxMetric(result));
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 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(file -> new FilesOfSubmission(file.getName(), readFileLines(file))).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 startTokenFirst = tokensFirst.getToken(match.startOfFirst());
|
|
|
- Token endTokenFirst = tokensFirst.getToken(match.startOfFirst() + match.length() - 1);
|
|
|
- Token startTokenSecond = tokensSecond.getToken(match.startOfSecond());
|
|
|
- Token endTokenSecond = tokensSecond.getToken(match.startOfSecond() + match.length() - 1);
|
|
|
-
|
|
|
- int startFirst = usesIndex ? startTokenFirst.getIndex() : startTokenFirst.getLine();
|
|
|
- int endFirst = usesIndex ? endTokenFirst.getIndex() : endTokenFirst.getLine();
|
|
|
- int startSecond = usesIndex ? startTokenSecond.getIndex() : startTokenSecond.getLine();
|
|
|
- int endSecond = usesIndex ? endTokenSecond.getIndex() : endTokenSecond.getLine();
|
|
|
- int tokens = match.length();
|
|
|
-
|
|
|
- return new Match(startTokenFirst.getFile(), startTokenSecond.getFile(), startFirst, endFirst, startSecond, endSecond, tokens);
|
|
|
- }
|
|
|
-
|
|
|
- private static List<String> readFileLines(File file) {
|
|
|
- List<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) {
|
|
|
- logger.error("Could not read file: " + exception.getMessage(), exception);
|
|
|
- }
|
|
|
- return lines;
|
|
|
- }
|
|
|
-
|
|
|
private static String getDate() {
|
|
|
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
|
|
|
Date date = new Date();
|