Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into report-viewer/print
Browse files Browse the repository at this point in the history
# Conflicts:
#	report-viewer/src/views/ComparisonView.vue
  • Loading branch information
Kr0nox committed Jan 17, 2024
2 parents bdcbaed + 1070c0f commit 23702a5
Show file tree
Hide file tree
Showing 29 changed files with 794 additions and 101 deletions.
Binary file added .github/workflows/files/progpedia.zip
Binary file not shown.
113 changes: 113 additions & 0 deletions .github/workflows/report-viewer-demo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: Report Viewer Demo Deployment

on:
workflow_dispatch: # Use this to dispatch from the Actions Tab
push:
branches:
- main

jobs:
build-jar:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 21
distribution: 'temurin'

- name: Build Assembly
run: mvn clean package assembly:single

- name: Upload Assembly
uses: actions/upload-artifact@v3
with:
name: "JPlag"
path: "cli/target/jplag-*-jar-with-dependencies.jar"


run-example:
needs: build-jar
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: 21
distribution: 'temurin'

- name: Get JAR
uses: actions/download-artifact@v3
with:
name: JPlag

- name: Copy and unzip submissions
run: unzip ./.github/workflows/files/progpedia.zip

- name: Rename jar
run: mv *.jar ./jplag.jar

- name: Run JPlag
run: java -jar jplag.jar ACCEPTED -bc base -r example

- name: Upload Result
uses: actions/upload-artifact@v3
with:
name: "Result"
path: "example.zip"


build-and-deploy:
needs: run-example
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "18"

- name: Set version of Report Viewer
shell: bash
run: |
VERSION=$(grep "<revision>" pom.xml | grep -oPm1 "(?<=<revision>)[^-|<]+")
MAJOR=$(echo $VERSION | cut -d '.' -f 1)
MINOR=$(echo $VERSION | cut -d '.' -f 2)
PATCH=$(echo $VERSION | cut -d '.' -f 3)
json=$(cat report-viewer/src/version.json)
json=$(echo "$json" | jq --arg MAJOR "$MAJOR" --arg MINOR "$MINOR" --arg PATCH "$PATCH" '.report_viewer_version |= { "major": $MAJOR | tonumber, "minor": $MINOR | tonumber, "patch": $PATCH | tonumber }')
echo "$json" > report-viewer/src/version.json
echo "Version of Report Viewer:"
cat report-viewer/src/version.json
- name: Download Results
uses: actions/download-artifact@v3
with:
name: Result
path: report-viewer/public

- name: Install and Build 🔧
working-directory: report-viewer
run: |
npm install
npm run build-demo
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.5.0
with:
branch: gh-pages
folder: report-viewer/dist
repository-name: JPlag/Demo
token: ${{ secrets.SDQ_DEV_DEPLOY_TOKEN }}
clean: true
single-commit: true

2 changes: 2 additions & 0 deletions cli/src/main/java/de/jplag/cli/CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public static void main(String[] args) {
JPlagResult result = JPlag.run(options);
ReportObjectFactory reportObjectFactory = new ReportObjectFactory();
reportObjectFactory.createAndSaveReport(result, cli.getResultFolder());

OutputFileGenerator.generateCsvOutput(result, new File(cli.getResultFolder()), cli.options);
}
} catch (ExitException exception) {
logger.error(exception.getMessage()); // do not pass exception here to keep log clean
Expand Down
3 changes: 3 additions & 0 deletions cli/src/main/java/de/jplag/cli/CliOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ public static class Advanced {
"--similarity-threshold"}, description = "Comparison similarity threshold [0.0-1.0]: All comparisons above this threshold will "
+ "be saved (default: ${DEFAULT-VALUE})%n")
public double similarityThreshold = JPlagOptions.DEFAULT_SIMILARITY_THRESHOLD;

@Option(names = "--csv-export", description = "If present, a csv export will be generated in addition to the zip file.")
public boolean csvExport = false;
}

public static class Clustering {
Expand Down
36 changes: 36 additions & 0 deletions cli/src/main/java/de/jplag/cli/OutputFileGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package de.jplag.cli;

import java.io.File;
import java.io.IOException;

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

import de.jplag.JPlagResult;
import de.jplag.csv.comparisons.CsvComparisonOutput;

public final class OutputFileGenerator {
private static final Logger logger = LoggerFactory.getLogger(OutputFileGenerator.class);

private OutputFileGenerator() {
// Prevents default constructor
}

/**
* Exports the given result as csvs, if the csvExport is activated in the options. Both a full and an anonymized version
* will be written.
* @param result The result to export
* @param outputRoot The root folder for the output
* @param options The cli options
*/
public static void generateCsvOutput(JPlagResult result, File outputRoot, CliOptions options) {
if (options.advanced.csvExport) {
try {
CsvComparisonOutput.writeCsvResults(result.getAllComparisons(), false, outputRoot, "results");
CsvComparisonOutput.writeCsvResults(result.getAllComparisons(), true, outputRoot, "results-anonymous");
} catch (IOException e) {
logger.warn("Could not write csv results", e);
}
}
}
}
22 changes: 22 additions & 0 deletions core/src/main/java/de/jplag/csv/CsvDataMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.jplag.csv;

import java.util.Optional;

/**
* Provides mappings for csv rows and optionally names for the columns. Needs to always return the same number of
* columns.
* @param <T> The type of data that is mapped
*/
public interface CsvDataMapper<T> {
/**
* Provides the cell values for one row
* @param value The original object
* @return The cell values
*/
String[] provideData(T value);

/**
* @return The names of the columns if present
*/
Optional<String[]> getTitleRow();
}
144 changes: 144 additions & 0 deletions core/src/main/java/de/jplag/csv/CsvPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package de.jplag.csv;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

import de.jplag.util.FileUtils;

/**
* Prints a csv according to the specification in
* <a href="https://datatracker.ietf.org/doc/html/rfc4180#section-2">...</a>. If you need to deviate from this
* definition slightly you can modify the line end and separator characters.
* @param <T>
*/
public class CsvPrinter<T> {
private static final char DEFAULT_SEPARATOR = ',';
private static final String DEFAULT_LINE_END = "\r\n"; // not System.lineSeparator(), because of csv specification
private static final char LITERAL = '"';

private final CsvDataMapper<T> dataSource;
private final List<String[]> data;

private char separator;
private String lineEnd;

/**
* @param dataSource The data source used to map the given object to rows.
*/
public CsvPrinter(CsvDataMapper<T> dataSource) {
this.dataSource = dataSource;
this.data = new ArrayList<>();

this.separator = DEFAULT_SEPARATOR;
this.lineEnd = DEFAULT_LINE_END;
}

/**
* Adds a new row to this csv
* @param value the value to add
*/
public void addRow(T value) {
this.data.add(this.dataSource.provideData(value));
}

/**
* Adds multiple rows to this csv
* @param values The values to add
*/
public void addRows(Collection<T> values) {
values.forEach(this::addRow);
}

/**
* Changes the separator between cells
* @param separator The new separator
*/
public void setSeparator(char separator) {
this.separator = separator;
}

/**
* Sets the string to separate lines with
* @param lineEnd the new line end
*/
public void setLineEnd(String lineEnd) {
this.lineEnd = lineEnd;
}

/**
* Prints this csv with all current data to a file
* @param file The file to write
* @throws IOException on io errors
*/
public void printToFile(File file) throws IOException {
try (Writer writer = FileUtils.openFileWriter(file)) {
this.printCsv(writer);
}
}

public String printToString() throws IOException {
String csv;

try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
try (Writer writer = new OutputStreamWriter(outputStream)) {
this.printCsv(writer);
}

csv = outputStream.toString();
}

return csv;
}

private void printCsv(Writer writer) throws IOException {
this.writeTitleRow(writer);

for (String[] datum : this.data) {
this.printRow(writer, datum);
}
}

private void writeTitleRow(Writer writer) throws IOException {
Optional<String[]> titleRow = this.dataSource.getTitleRow();
if (titleRow.isPresent()) {
this.printRow(writer, titleRow.get());
}
}

private void printRow(Writer writer, String[] data) throws IOException {
Iterator<String> dataIterator = Arrays.stream(data).iterator();

if (dataIterator.hasNext()) {
printCell(writer, dataIterator.next());
}

while (dataIterator.hasNext()) {
writer.write(this.separator);
printCell(writer, dataIterator.next());
}

writer.write(this.lineEnd);
}

private void printCell(Writer writer, String cellValue) throws IOException {
boolean literalsNeeded = cellValue.contains(String.valueOf(LITERAL));
String actualValue = cellValue;
if (literalsNeeded) {
writer.write(LITERAL);
actualValue = actualValue.replace("\"", "\"\"");
}
writer.write(actualValue);
if (literalsNeeded) {
writer.write(LITERAL);
}
}
}
18 changes: 18 additions & 0 deletions core/src/main/java/de/jplag/csv/CsvValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package de.jplag.csv;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Used with {@link ReflectiveCsvDataMapper} to identify fields and methods, that should be used for the csv.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface CsvValue {
/**
* The index of the csv field. Has to be used as the compiler sometimes changes the order of fields/methods
*/
int value();
}
Loading

0 comments on commit 23702a5

Please sign in to comment.