use of de.jplag.options.JPlagOptions in project JPlag by jplag.
the class TestBase method runJPlag.
protected JPlagResult runJPlag(List<String> testPaths, Consumer<JPlagOptions> customization) throws ExitException {
JPlagOptions options = new JPlagOptions(testPaths, LanguageOption.JAVA);
options.setVerbosity(Verbosity.LONG);
customization.accept(options);
JPlag jplag = new JPlag(options);
return jplag.run();
}
use of de.jplag.options.JPlagOptions in project ArTEMiS by ls1intum.
the class TextPlagiarismDetectionService method checkPlagiarism.
/**
* Download all submissions of the exercise, run JPlag, and return the result
*
* @param textExercise to detect plagiarism for
* @param similarityThreshold ignore comparisons whose similarity is below this threshold (%)
* @param minimumScore consider only submissions whose score is greater or equal to this value
* @param minimumSize consider only submissions whose size is greater or equal to this value
* @return a zip file that can be returned to the client
* @throws ExitException is thrown if JPlag exits unexpectedly
*/
public TextPlagiarismResult checkPlagiarism(TextExercise textExercise, float similarityThreshold, int minimumScore, int minimumSize) throws ExitException {
long start = System.nanoTime();
String topic = plagiarismWebsocketService.getTextExercisePlagiarismCheckTopic(textExercise.getId());
// TODO: why do we have such a strange folder name?
final var submissionsFolderName = "./tmp/submissions";
final var submissionFolderFile = new File(submissionsFolderName);
submissionFolderFile.mkdirs();
final List<TextSubmission> textSubmissions = textSubmissionsForComparison(textExercise, minimumScore, minimumSize);
final var submissionsSize = textSubmissions.size();
log.info("Save text submissions for JPlag text comparison with {} submissions", submissionsSize);
if (textSubmissions.size() < 2) {
log.info("Insufficient amount of submissions for plagiarism detection. Return empty result.");
TextPlagiarismResult textPlagiarismResult = new TextPlagiarismResult();
textPlagiarismResult.setExercise(textExercise);
textPlagiarismResult.setSimilarityDistribution(new int[0]);
return textPlagiarismResult;
}
AtomicInteger processedSubmissionCount = new AtomicInteger(1);
textSubmissions.forEach(submission -> {
var progressMessage = "Getting submission: " + processedSubmissionCount + "/" + textSubmissions.size();
plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.RUNNING, List.of(progressMessage));
submission.setResults(new ArrayList<>());
StudentParticipation participation = (StudentParticipation) submission.getParticipation();
participation.setExercise(null);
participation.setSubmissions(null);
String participantIdentifier = participation.getParticipantIdentifier();
if (participantIdentifier == null) {
participantIdentifier = "unknown";
}
try {
textSubmissionExportService.saveSubmissionToFile(submission, participantIdentifier, submissionsFolderName);
} catch (IOException e) {
log.error(e.getMessage());
}
processedSubmissionCount.getAndIncrement();
});
log.info("Saving text submissions done");
JPlagOptions options = new JPlagOptions(submissionsFolderName, LanguageOption.TEXT);
options.setMinimumTokenMatch(minimumSize);
// Important: for large courses with more than 1000 students, we might get more than one million results and 10 million files in the file system due to many 0% results,
// therefore we limit the results to at least 50% or 0.5 similarity, the passed threshold is between 0 and 100%
options.setSimilarityThreshold(similarityThreshold);
log.info("Start JPlag Text comparison");
JPlag jplag = new JPlag(options);
JPlagResult jPlagResult = jplag.run();
log.info("JPlag Text comparison finished with {} comparisons. Will limit the number of comparisons to 500", jPlagResult.getComparisons().size());
log.info("Delete submission folder");
if (submissionFolderFile.exists()) {
FileSystemUtils.deleteRecursively(submissionFolderFile);
}
TextPlagiarismResult textPlagiarismResult = new TextPlagiarismResult();
textPlagiarismResult.convertJPlagResult(jPlagResult);
textPlagiarismResult.setExercise(textExercise);
log.info("JPlag text comparison for {} submissions done in {}", submissionsSize, TimeLogUtil.formatDurationFrom(start));
plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.COMPLETED, List.of());
return textPlagiarismResult;
}
use of de.jplag.options.JPlagOptions in project Artemis by ls1intum.
the class TextPlagiarismDetectionService method checkPlagiarism.
/**
* Download all submissions of the exercise, run JPlag, and return the result
*
* @param textExercise to detect plagiarism for
* @param similarityThreshold ignore comparisons whose similarity is below this threshold (%)
* @param minimumScore consider only submissions whose score is greater or equal to this value
* @param minimumSize consider only submissions whose size is greater or equal to this value
* @return a zip file that can be returned to the client
* @throws ExitException is thrown if JPlag exits unexpectedly
*/
public TextPlagiarismResult checkPlagiarism(TextExercise textExercise, float similarityThreshold, int minimumScore, int minimumSize) throws ExitException {
long start = System.nanoTime();
String topic = plagiarismWebsocketService.getTextExercisePlagiarismCheckTopic(textExercise.getId());
// TODO: why do we have such a strange folder name?
final var submissionsFolderName = "./tmp/submissions";
final var submissionFolderFile = new File(submissionsFolderName);
submissionFolderFile.mkdirs();
final List<TextSubmission> textSubmissions = textSubmissionsForComparison(textExercise, minimumScore, minimumSize);
final var submissionsSize = textSubmissions.size();
log.info("Save text submissions for JPlag text comparison with {} submissions", submissionsSize);
if (textSubmissions.size() < 2) {
log.info("Insufficient amount of submissions for plagiarism detection. Return empty result.");
TextPlagiarismResult textPlagiarismResult = new TextPlagiarismResult();
textPlagiarismResult.setExercise(textExercise);
textPlagiarismResult.setSimilarityDistribution(new int[0]);
return textPlagiarismResult;
}
AtomicInteger processedSubmissionCount = new AtomicInteger(1);
textSubmissions.forEach(submission -> {
var progressMessage = "Getting submission: " + processedSubmissionCount + "/" + textSubmissions.size();
plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.RUNNING, List.of(progressMessage));
submission.setResults(new ArrayList<>());
StudentParticipation participation = (StudentParticipation) submission.getParticipation();
participation.setExercise(null);
participation.setSubmissions(null);
String participantIdentifier = participation.getParticipantIdentifier();
if (participantIdentifier == null) {
participantIdentifier = "unknown";
}
try {
textSubmissionExportService.saveSubmissionToFile(submission, participantIdentifier, submissionsFolderName);
} catch (IOException e) {
log.error(e.getMessage());
}
processedSubmissionCount.getAndIncrement();
});
log.info("Saving text submissions done");
JPlagOptions options = new JPlagOptions(submissionsFolderName, LanguageOption.TEXT);
options.setMinimumTokenMatch(minimumSize);
// Important: for large courses with more than 1000 students, we might get more than one million results and 10 million files in the file system due to many 0% results,
// therefore we limit the results to at least 50% or 0.5 similarity, the passed threshold is between 0 and 100%
options.setSimilarityThreshold(similarityThreshold);
log.info("Start JPlag Text comparison");
JPlag jplag = new JPlag(options);
JPlagResult jPlagResult = jplag.run();
log.info("JPlag Text comparison finished with {} comparisons. Will limit the number of comparisons to 500", jPlagResult.getComparisons().size());
log.info("Delete submission folder");
if (submissionFolderFile.exists()) {
FileSystemUtils.deleteRecursively(submissionFolderFile);
}
TextPlagiarismResult textPlagiarismResult = new TextPlagiarismResult();
textPlagiarismResult.convertJPlagResult(jPlagResult);
textPlagiarismResult.setExercise(textExercise);
log.info("JPlag text comparison for {} submissions done in {}", submissionsSize, TimeLogUtil.formatDurationFrom(start));
plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.COMPLETED, List.of());
return textPlagiarismResult;
}
use of de.jplag.options.JPlagOptions in project JPlag by jplag.
the class CLI method buildOptionsFromArguments.
/**
* Builds a options instance from parsed arguments.
* @param namespace encapsulates the parsed arguments in a {@link Namespace} format.
* @return the newly built options.F
*/
public JPlagOptions buildOptionsFromArguments(Namespace namespace) {
String fileSuffixString = SUFFIXES.getFrom(namespace);
String[] fileSuffixes = new String[] {};
if (fileSuffixString != null) {
fileSuffixes = fileSuffixString.replaceAll("\\s+", "").split(",");
}
LanguageOption language = LanguageOption.fromDisplayName(LANGUAGE.getFrom(namespace));
JPlagOptions options = new JPlagOptions(ROOT_DIRECTORY.getListFrom(namespace), language);
options.setBaseCodeSubmissionName(BASE_CODE.getFrom(namespace));
options.setVerbosity(Verbosity.fromOption(VERBOSITY.getFrom(namespace)));
options.setDebugParser(DEBUG.getFrom(namespace));
options.setSubdirectoryName(SUBDIRECTORY.getFrom(namespace));
options.setFileSuffixes(fileSuffixes);
options.setExclusionFileName(EXCLUDE_FILE.getFrom(namespace));
options.setMinimumTokenMatch(MIN_TOKEN_MATCH.getFrom(namespace));
options.setSimilarityThreshold(SIMILARITY_THRESHOLD.getFrom(namespace));
options.setMaximumNumberOfComparisons(SHOWN_COMPARISONS.getFrom(namespace));
ComparisonMode.fromName(COMPARISON_MODE.getFrom(namespace)).ifPresentOrElse(it -> options.setComparisonMode(it), () -> System.out.println("Unknown comparison mode, using default mode!"));
ClusteringOptions.Builder clusteringBuilder = new ClusteringOptions.Builder();
Optional.ofNullable((Boolean) CLUSTER_ENABLE.getFrom(namespace)).ifPresent(clusteringBuilder::enabled);
Optional.ofNullable((ClusteringAlgorithm) CLUSTER_ALGORITHM.getFrom(namespace)).ifPresent(clusteringBuilder::algorithm);
Optional.ofNullable((SimilarityMetric) CLUSTER_METRIC.getFrom(namespace)).ifPresent(clusteringBuilder::similarityMetric);
Optional.ofNullable((Float) CLUSTER_SPECTRAL_BANDWIDTH.getFrom(namespace)).ifPresent(clusteringBuilder::spectralKernelBandwidth);
Optional.ofNullable((Float) CLUSTER_SPECTRAL_NOISE.getFrom(namespace)).ifPresent(clusteringBuilder::spectralGaussianProcessVariance);
Optional.ofNullable((Integer) CLUSTER_SPECTRAL_MIN_RUNS.getFrom(namespace)).ifPresent(clusteringBuilder::spectralMinRuns);
Optional.ofNullable((Integer) CLUSTER_SPECTRAL_MAX_RUNS.getFrom(namespace)).ifPresent(clusteringBuilder::spectralMaxRuns);
Optional.ofNullable((Integer) CLUSTER_SPECTRAL_KMEANS_ITERATIONS.getFrom(namespace)).ifPresent(clusteringBuilder::spectralMaxKMeansIterationPerRun);
Optional.ofNullable((Float) CLUSTER_AGGLOMERATIVE_THRESHOLD.getFrom(namespace)).ifPresent(clusteringBuilder::agglomerativeThreshold);
Optional.ofNullable((InterClusterSimilarity) CLUSTER_AGGLOMERATIVE_INTER_CLUSTER_SIMILARITY.getFrom(namespace)).ifPresent(clusteringBuilder::agglomerativeInterClusterSimilarity);
Optional.ofNullable((Boolean) CLUSTER_PREPROCESSING_NONE.getFrom(namespace)).ifPresent(none -> {
if (none) {
clusteringBuilder.preprocessor(Preprocessing.NONE);
}
});
Optional.ofNullable((Boolean) CLUSTER_PREPROCESSING_CDF.getFrom(namespace)).ifPresent(cdf -> {
if (cdf) {
clusteringBuilder.preprocessor(Preprocessing.CUMULATIVE_DISTRIBUTION_FUNCTION);
}
});
Optional.ofNullable((Float) CLUSTER_PREPROCESSING_PERCENTILE.getFrom(namespace)).ifPresent(percentile -> {
clusteringBuilder.preprocessor(Preprocessing.PERCENTILE);
clusteringBuilder.preprocessorPercentile(percentile);
});
Optional.ofNullable((Float) CLUSTER_PREPROCESSING_THRESHOLD.getFrom(namespace)).ifPresent(threshold -> {
clusteringBuilder.preprocessor(Preprocessing.THRESHOLD);
clusteringBuilder.preprocessorPercentile(threshold);
});
options.setClusteringOptions(clusteringBuilder.build());
return options;
}
use of de.jplag.options.JPlagOptions in project JPlag by jplag.
the class CLI method main.
/**
* Main class for using JPlag via the CLI.
* @param args are the CLI arguments that will be passed to JPlag.
*/
public static void main(String[] args) {
try {
CLI cli = new CLI();
Namespace arguments = cli.parseArguments(args);
JPlagOptions options = cli.buildOptionsFromArguments(arguments);
JPlag program = new JPlag(options);
System.out.println("JPlag initialized");
JPlagResult result = program.run();
Report report = new JsonReport();
report.saveReport(result, arguments.getString(RESULT_FOLDER.flagWithoutDash()));
} catch (ExitException exception) {
System.out.println("Error: " + exception.getMessage());
System.exit(1);
}
}
Aggregations