Skip to content

Commit

Permalink
Merge branch 'refs/heads/develop' into feature/idleBars
Browse files Browse the repository at this point in the history
# Conflicts:
#	cli/src/main/java/de/jplag/cli/CLI.java
#	core/src/main/java/de/jplag/logging/ProgressBarType.java
  • Loading branch information
TwoOfTwelve committed Apr 17, 2024
2 parents e4d4f33 + da0c5b9 commit b811025
Show file tree
Hide file tree
Showing 38 changed files with 904 additions and 695 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- name: Upload Assembly
uses: actions/upload-artifact@v4
with:
name: "JPlag"
path: "jplag.cli/target/jplag-*-jar-with-dependencies.jar"
name: "JPlag Jar"
path: "cli/target/jplag-*-jar-with-dependencies.jar"


287 changes: 62 additions & 225 deletions cli/src/main/java/de/jplag/cli/CLI.java

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions cli/src/main/java/de/jplag/cli/JPlagOptionsBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package de.jplag.cli;

import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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

import de.jplag.cli.options.CliOptions;
import de.jplag.cli.picocli.CliInputHandler;
import de.jplag.clustering.ClusteringOptions;
import de.jplag.clustering.Preprocessing;
import de.jplag.merging.MergingOptions;
import de.jplag.options.JPlagOptions;

/**
* Handles the building of JPlag options from the cli options
*/
public class JPlagOptionsBuilder {
private static final Logger logger = LoggerFactory.getLogger(JPlagOptionsBuilder.class);

private final CliInputHandler cliInputHandler;
private final CliOptions cliOptions;

/**
* @param cliInputHandler The cli handler containing the parsed cli options
*/
public JPlagOptionsBuilder(CliInputHandler cliInputHandler) {
this.cliInputHandler = cliInputHandler;
this.cliOptions = this.cliInputHandler.getCliOptions();
}

/**
* Builds the JPlag options
* @return The JPlag options
* @throws CliException If the input handler could properly parse everything.
*/
public JPlagOptions buildOptions() throws CliException {
Set<File> submissionDirectories = new HashSet<>(List.of(this.cliOptions.rootDirectory));
Set<File> oldSubmissionDirectories = Set.of(this.cliOptions.oldDirectories);
List<String> suffixes = List.of(this.cliOptions.advanced.suffixes);
submissionDirectories.addAll(List.of(this.cliOptions.newDirectories));
submissionDirectories.addAll(this.cliInputHandler.getSubcommandSubmissionDirectories());

JPlagOptions jPlagOptions = initializeJPlagOptions(submissionDirectories, oldSubmissionDirectories, suffixes);

String baseCodePath = this.cliOptions.baseCode;
File baseCodeDirectory = baseCodePath == null ? null : new File(baseCodePath);
if (baseCodeDirectory == null || baseCodeDirectory.exists()) {
return jPlagOptions.withBaseCodeSubmissionDirectory(baseCodeDirectory);
}
logger.error("Using legacy partial base code API. Please migrate to new full path base code API.");
return jPlagOptions.withBaseCodeSubmissionName(baseCodePath);
}

private JPlagOptions initializeJPlagOptions(Set<File> submissionDirectories, Set<File> oldSubmissionDirectories, List<String> suffixes)
throws CliException {
ClusteringOptions clusteringOptions = getClusteringOptions();
MergingOptions mergingOptions = getMergingOptions();

return new JPlagOptions(this.cliInputHandler.getSelectedLanguage(), this.cliOptions.minTokenMatch, submissionDirectories,
oldSubmissionDirectories, null, this.cliOptions.advanced.subdirectory, suffixes, this.cliOptions.advanced.exclusionFileName,
JPlagOptions.DEFAULT_SIMILARITY_METRIC, this.cliOptions.advanced.similarityThreshold, this.cliOptions.shownComparisons,
clusteringOptions, this.cliOptions.advanced.debug, mergingOptions, this.cliOptions.normalize);
}

private ClusteringOptions getClusteringOptions() {
ClusteringOptions clusteringOptions = new ClusteringOptions().withEnabled(!this.cliOptions.clustering.disable)
.withAlgorithm(this.cliOptions.clustering.enabled.algorithm).withSimilarityMetric(this.cliOptions.clustering.enabled.metric)
.withSpectralKernelBandwidth(this.cliOptions.clusterSpectralBandwidth)
.withSpectralGaussianProcessVariance(this.cliOptions.clusterSpectralNoise).withSpectralMinRuns(this.cliOptions.clusterSpectralMinRuns)
.withSpectralMaxRuns(this.cliOptions.clusterSpectralMaxRuns)
.withSpectralMaxKMeansIterationPerRun(this.cliOptions.clusterSpectralKMeansIterations)
.withAgglomerativeThreshold(this.cliOptions.clusterAgglomerativeThreshold)
.withAgglomerativeInterClusterSimilarity(this.cliOptions.clusterAgglomerativeInterClusterSimilarity);

if (this.cliOptions.clusterPreprocessingNone) {
clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.NONE);
}

if (this.cliOptions.clusterPreprocessingCdf) {
clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.CUMULATIVE_DISTRIBUTION_FUNCTION);
}

if (this.cliOptions.clusterPreprocessingPercentile != 0) {
clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.PERCENTILE)
.withPreprocessorPercentile(this.cliOptions.clusterPreprocessingPercentile);
}

if (this.cliOptions.clusterPreprocessingThreshold != 0) {
clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.THRESHOLD)
.withPreprocessorThreshold(this.cliOptions.clusterPreprocessingThreshold);
}

return clusteringOptions;
}

private MergingOptions getMergingOptions() {
return new MergingOptions(this.cliOptions.merging.enabled, this.cliOptions.merging.minimumNeighborLength,
this.cliOptions.merging.maximumGapSize);
}
}
52 changes: 52 additions & 0 deletions cli/src/main/java/de/jplag/cli/JPlagRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package de.jplag.cli;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;

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

import de.jplag.JPlag;
import de.jplag.JPlagResult;
import de.jplag.cli.server.ReportViewer;
import de.jplag.exceptions.ExitException;
import de.jplag.options.JPlagOptions;

/**
* Wraps the execution of the JPlag components
*/
public final class JPlagRunner {
private static final Logger logger = LoggerFactory.getLogger(JPlagRunner.class);

private JPlagRunner() {
}

/**
* Executes JPlag
* @param options The options to pass to JPlag
* @return The result returned by JPlag
* @throws ExitException If JPlag throws an error
*/
public static JPlagResult runJPlag(JPlagOptions options) throws ExitException {
return JPlag.run(options);
}

/**
* Runs the internal server. Blocks until the server has stopped.
* @param zipFile The zip file to pass to the server. May be null.
* @param port The port to open the server on
* @throws IOException If the internal server throws an exception
*/
public static void runInternalServer(File zipFile, int port) throws IOException {
ReportViewer reportViewer = new ReportViewer(zipFile, port);
int actualPort = reportViewer.start();
logger.info("ReportViewer started on port http://localhost:{}", actualPort);
Desktop.getDesktop().browse(URI.create("http://localhost:" + actualPort + "/"));

System.out.println("Press Enter key to exit...");
System.in.read();
reportViewer.stop();
}
}
22 changes: 20 additions & 2 deletions cli/src/main/java/de/jplag/cli/OutputFileGenerator.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package de.jplag.cli;

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

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

import de.jplag.JPlagResult;
import de.jplag.cli.options.CliOptions;
import de.jplag.csv.comparisons.CsvComparisonOutput;
import de.jplag.reporting.reportobject.ReportObjectFactory;

/**
* Manages the creation of output files
*/
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
* 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
Expand All @@ -33,4 +38,17 @@ public static void generateCsvOutput(JPlagResult result, File outputRoot, CliOpt
}
}
}

/**
* Generates the JPLag result zip
* @param result The JPlag result
* @param outputFile The output file
* @throws FileNotFoundException If the file cannot be written
*/
public static void generateJPlagResultZip(JPlagResult result, File outputFile) throws FileNotFoundException {
ReportObjectFactory reportObjectFactory = new ReportObjectFactory(outputFile);
reportObjectFactory.createAndSaveReport(result);
logger.info("Successfully written the result: {}", outputFile.getPath());
logger.info("View the result using --mode or at: https://jplag.github.io/JPlag/");
}
}
Loading

0 comments on commit b811025

Please sign in to comment.