Search in sources :

Example 1 with JPlagOptions

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();
}
Also used : JPlagOptions(de.jplag.options.JPlagOptions)

Example 2 with JPlagOptions

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;
}
Also used : JPlagOptions(de.jplag.options.JPlagOptions) IOException(java.io.IOException) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) JPlag(de.jplag.JPlag) TextPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) File(java.io.File) JPlagResult(de.jplag.JPlagResult) TextSubmission(de.tum.in.www1.artemis.domain.TextSubmission)

Example 3 with JPlagOptions

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;
}
Also used : JPlagOptions(de.jplag.options.JPlagOptions) IOException(java.io.IOException) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) JPlag(de.jplag.JPlag) TextPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) File(java.io.File) JPlagResult(de.jplag.JPlagResult) TextSubmission(de.tum.in.www1.artemis.domain.TextSubmission)

Example 4 with JPlagOptions

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;
}
Also used : JPlagOptions(de.jplag.options.JPlagOptions) ClusteringOptions(de.jplag.clustering.ClusteringOptions) ClusteringAlgorithm(de.jplag.clustering.ClusteringAlgorithm) SimilarityMetric(de.jplag.options.SimilarityMetric) InterClusterSimilarity(de.jplag.clustering.algorithm.InterClusterSimilarity) LanguageOption(de.jplag.options.LanguageOption)

Example 5 with JPlagOptions

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);
    }
}
Also used : JPlagOptions(de.jplag.options.JPlagOptions) Report(de.jplag.reporting2.Report) JsonReport(de.jplag.reporting2.JsonReport) JsonReport(de.jplag.reporting2.JsonReport) ExitException(de.jplag.exceptions.ExitException) Namespace(net.sourceforge.argparse4j.inf.Namespace)

Aggregations

JPlagOptions (de.jplag.options.JPlagOptions)5 JPlag (de.jplag.JPlag)2 JPlagResult (de.jplag.JPlagResult)2 TextSubmission (de.tum.in.www1.artemis.domain.TextSubmission)2 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)2 TextPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult)2 File (java.io.File)2 IOException (java.io.IOException)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 ClusteringAlgorithm (de.jplag.clustering.ClusteringAlgorithm)1 ClusteringOptions (de.jplag.clustering.ClusteringOptions)1 InterClusterSimilarity (de.jplag.clustering.algorithm.InterClusterSimilarity)1 ExitException (de.jplag.exceptions.ExitException)1 LanguageOption (de.jplag.options.LanguageOption)1 SimilarityMetric (de.jplag.options.SimilarityMetric)1 JsonReport (de.jplag.reporting2.JsonReport)1 Report (de.jplag.reporting2.Report)1 Namespace (net.sourceforge.argparse4j.inf.Namespace)1