Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plagiarism checks: Add possibility for continuous daily plagiarism checks #6666

Merged
merged 97 commits into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from 82 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
6156876
daily plagiarism checks
jakubriegel Jun 3, 2023
0060764
autoincrement plagiarism_checks_config id
jakubriegel Jun 5, 2023
67ce9fa
plagiarisms configuration form for text exercises
jakubriegel Jun 5, 2023
483589b
plagiarisms configuration form for modeling exercises
jakubriegel Jun 5, 2023
2b5510a
plagiarisms configuration form for programming exercises
jakubriegel Jun 5, 2023
b43670d
stored config for manual plagiarisms detection
jakubriegel Jun 6, 2023
4c63376
erge remote-tracking branch 'origin/develop' into automated-plagiaris…
jakubriegel Jun 6, 2023
b9f2132
fix broken flows and tests
jakubriegel Jun 8, 2023
d39dd75
add javadoc for cpc schedule
jakubriegel Jun 8, 2023
41318fa
make cpc exercise members optional in the client
jakubriegel Jun 8, 2023
806923f
fix FileUploadExerciseIntegrationTest
jakubriegel Jun 8, 2023
63d2eb4
fix null safe property access
jakubriegel Jun 8, 2023
ff2bd75
remove redundant empty constructor
jakubriegel Jun 8, 2023
2870563
Add javadoc
jakubriegel Jun 8, 2023
e0ab20a
Fix /100 for modelling exercises
jakubriegel Jun 10, 2023
d2eb8eb
Create unit test for ContinuousPlagiarismControlService
jakubriegel Jun 10, 2023
cf84bd5
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 10, 2023
88d22c9
Add default value for continuous_plagiarism_control_enabled
jakubriegel Jun 10, 2023
a122c00
Change Detection -> Plagiarism detection
jakubriegel Jun 10, 2023
f263939
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 11, 2023
321aeb4
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 12, 2023
6e395ff
change de caution msg
jakubriegel Jun 12, 2023
662d31f
add similarity threshold test for programming ex. form
jakubriegel Jun 13, 2023
52e76f0
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 13, 2023
d2e90d2
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 14, 2023
6e28701
fix loading existing plagiarism checks config in the client
jakubriegel Jun 17, 2023
7e25c6d
enable lazy loading of plagiarism checks config; separate PlagiarismC…
jakubriegel Jun 17, 2023
920becb
merge develop and fix tests
jakubriegel Jun 18, 2023
1e4b599
fix code style
jakubriegel Jun 18, 2023
94f4f36
fix code style
jakubriegel Jun 18, 2023
92f10fe
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 18, 2023
75f800f
revert debug code
jakubriegel Jun 18, 2023
dd32d03
add missing javadoc
jakubriegel Jun 18, 2023
00d5dcc
merge develop
jakubriegel Jun 24, 2023
9b5490c
fix generateJPlagReport always shown
jakubriegel Jun 24, 2023
74f9b88
fix codestyle (codacy)
jakubriegel Jun 26, 2023
cb379e4
Merge branch 'develop' into automated-plagiarism-checks
jakubriegel Jun 26, 2023
60c5d98
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 26, 2023
de32589
merge develop
jakubriegel Jun 30, 2023
6536f1f
merge develop
jakubriegel Jul 1, 2023
a7bce9d
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 1, 2023
e581f12
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 1, 2023
08e8127
remove unnecessary default value
jakubriegel Jul 1, 2023
4410402
rename type
jakubriegel Jul 1, 2023
d86bc85
fix german copy
jakubriegel Jul 1, 2023
0129c23
move continuousPlagiarismControlEnabled to PlagiarismChecksConfig
jakubriegel Jul 1, 2023
2dbb57a
make exercise.plagiarismChecksConfig non null
jakubriegel Jul 1, 2023
611bf50
remove unused import
jakubriegel Jul 1, 2023
aaef7a9
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 2, 2023
0af7ae3
fix german copy
jakubriegel Jul 2, 2023
395a37a
Merge branch 'develop' into automated-plagiarism-checks
jakubriegel Jul 3, 2023
a65d37e
fix tests
jakubriegel Jul 3, 2023
d3645ae
remove unnecessary assignment
jakubriegel Jul 4, 2023
cb13aef
assert that nothing is thrown
jakubriegel Jul 4, 2023
3b99e9f
add nullability to fix compiler issues
jakubriegel Jul 4, 2023
d445b99
replace junit with assertj
jakubriegel Jul 4, 2023
4eebe33
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 5, 2023
5c09ed3
add setting continuousPlagiarismControlEnabled on PlagiarismChecksCon…
jakubriegel Jul 5, 2023
bb18252
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 7, 2023
6a40dc9
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 8, 2023
0d8b61d
read cron expression from application.yml
jakubriegel Jul 8, 2023
7243d27
add beta badge to cpc enabled setting and move it below plagiarism co…
jakubriegel Jul 8, 2023
0c79470
add cpc tooltip on exercise form
jakubriegel Jul 8, 2023
65653e5
improve styling of plagiarism detection config
jakubriegel Jul 8, 2023
4faae2e
set cpc cron for 4am
jakubriegel Jul 8, 2023
44a90ad
fix german translation
jakubriegel Jul 8, 2023
16775d6
fix singular form
jakubriegel Jul 8, 2023
b79855b
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 8, 2023
9121863
Update src/main/webapp/i18n/en/plagiarism.json
jakubriegel Jul 9, 2023
01eb73e
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 12, 2023
2f665ab
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 13, 2023
66c0aea
fix input naming
jakubriegel Jul 16, 2023
b9e0ad1
merge develop
jakubriegel Jul 16, 2023
cf2066d
add colons to plagiarism configuration labels
jakubriegel Jul 16, 2023
e0b7ce0
add missing @Column
jakubriegel Jul 16, 2023
a534bda
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 20, 2023
22407a3
fix default value type
jakubriegel Jul 20, 2023
78f34a4
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 24, 2023
5b29dc3
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 25, 2023
215fd09
move migration to the end
jakubriegel Jul 25, 2023
90363ab
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 25, 2023
01e00fe
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 26, 2023
0e268ca
Development: Explicitly state the actor of the performance reviewer's…
maximiliansoelch Jul 26, 2023
2516380
Development: Add hint for windows to local version control and contin…
laurenzfb Jul 26, 2023
852e6bd
Development: Delete old files properly when updating file submissions…
MarkusPaulsen Jul 26, 2023
51f1a8b
Development: Improve programming exercise file response (#6989)
pal03377 Jul 26, 2023
31ce700
Development: Use 1.0 instead of 1.0+ for sticky grade to avoid castin…
Jul 26, 2023
c4b47ba
Development: Fix an issue when catching exceptions during a quiz
Jul 26, 2023
719c4c5
Development: Bump version to 6.3.9
Jul 26, 2023
3c08a37
merge develop
jakubriegel Jul 30, 2023
8af4981
Merge branch 'develop' into automated-plagiarism-checks
jakubriegel Aug 2, 2023
c41d587
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Aug 4, 2023
f1edae4
disable scheduling for migration tests
jakubriegel Aug 4, 2023
d848265
fix continuous_plagiarism_control_enabled type
jakubriegel Aug 4, 2023
4f13f18
add localci to migration tests
jakubriegel Aug 4, 2023
63665bc
make programmingLanguageFeatureService optional
jakubriegel Aug 4, 2023
3af111d
revert migration check env
jakubriegel Aug 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/main/java/de/tum/in/www1/artemis/domain/Exercise.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import de.tum.in.www1.artemis.domain.participation.StudentParticipation;
import de.tum.in.www1.artemis.domain.participation.TutorParticipation;
import de.tum.in.www1.artemis.domain.plagiarism.PlagiarismCase;
import de.tum.in.www1.artemis.domain.plagiarism.PlagiarismChecksConfig;
import de.tum.in.www1.artemis.domain.quiz.QuizExercise;
import de.tum.in.www1.artemis.domain.view.QuizView;
import de.tum.in.www1.artemis.service.ExerciseDateService;
Expand Down Expand Up @@ -143,6 +144,11 @@ public abstract class Exercise extends BaseExercise implements LearningObject {
@JsonIncludeProperties({ "id" })
private Set<PlagiarismCase> plagiarismCases = new HashSet<>();

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonIgnoreProperties("exercise")
private PlagiarismChecksConfig plagiarismChecksConfig;

// NOTE: Helpers variable names must be different from Getter name, so that Jackson ignores the @Transient annotation, but Hibernate still respects it
@Transient
private DueDateStat numberOfSubmissionsTransient;
Expand Down Expand Up @@ -400,6 +406,14 @@ public void setPlagiarismCases(Set<PlagiarismCase> plagiarismCases) {
this.plagiarismCases = plagiarismCases;
}

public PlagiarismChecksConfig getPlagiarismChecksConfig() {
return plagiarismChecksConfig;
}

public void setPlagiarismChecksConfig(PlagiarismChecksConfig plagiarismChecksConfig) {
this.plagiarismChecksConfig = plagiarismChecksConfig;
}

// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove

public Set<Competency> getCompetencies() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package de.tum.in.www1.artemis.domain.plagiarism;

import javax.persistence.*;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

import de.tum.in.www1.artemis.domain.DomainObject;
import de.tum.in.www1.artemis.domain.Exercise;

/**
* Stores configuration for manual and continuous plagiarism control.
*/
@Entity
@Table(name = "plagiarism_checks_config")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class PlagiarismChecksConfig extends DomainObject {

@OneToOne(mappedBy = "plagiarismChecksConfig", fetch = FetchType.LAZY)
@JsonIgnoreProperties("plagiarismChecksConfig")
private Exercise exercise;

@Column(name = "continuous_plagiarism_control_enabled")
private boolean continuousPlagiarismControlEnabled = false;

@Column(name = "similarity_threshold")
private float similarityThreshold;

@Column(name = "minimum_score")
private int minimumScore;

@Column(name = "minimum_size")
private int minimumSize;

public Exercise getExercise() {
return exercise;
}

public void setExercise(Exercise exercise) {
this.exercise = exercise;
}

public boolean isContinuousPlagiarismControlEnabled() {
return continuousPlagiarismControlEnabled;
}

public void setContinuousPlagiarismControlEnabled(boolean continuousPlagiarismControlEnabled) {
this.continuousPlagiarismControlEnabled = continuousPlagiarismControlEnabled;
}

public float getSimilarityThreshold() {
return similarityThreshold;
}

public int getMinimumScore() {
return minimumScore;
}

public int getMinimumSize() {
return minimumSize;
}

public void setSimilarityThreshold(float similarityThreshold) {
this.similarityThreshold = similarityThreshold;
}

public void setMinimumScore(int minimumScore) {
this.minimumScore = minimumScore;
}

public void setMinimumSize(int minimumSize) {
this.minimumSize = minimumSize;
}

/**
* Creates PlagiarismChecksConfig with default data
*
* @return PlagiarismChecksConfig with default values
*/
public static PlagiarismChecksConfig createDefault() {
var config = new PlagiarismChecksConfig();
config.setContinuousPlagiarismControlEnabled(false);
config.setSimilarityThreshold(0.5f);
config.setMinimumScore(0);
config.setMinimumSize(0);
return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ public interface ExerciseRepository extends JpaRepository<Exercise, Long> {
""")
Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDate(@Param("now") ZonedDateTime now);

@Query("""
SELECT e FROM Exercise e
LEFT JOIN FETCH e.plagiarismChecksConfig c
LEFT JOIN FETCH e.studentParticipations p
LEFT JOIN FETCH p.submissions s
LEFT JOIN FETCH s.results
WHERE e.course.testCourse = FALSE
AND e.dueDate >= :now
AND c.continuousPlagiarismControlEnabled = TRUE
ORDER BY e.dueDate ASC
""")
Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue(@Param("now") ZonedDateTime now);

@Query("""
SELECT e FROM Exercise e
WHERE e.course.testCourse = FALSE
Expand Down Expand Up @@ -307,6 +320,16 @@ default Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDate() {
return findAllExercisesWithCurrentOrUpcomingDueDate(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS));
}

/**
* Finds all exercises where the due date is today or in the future and continuos plagiarism control is enabled
* (does not return exercises belonging to test courses).
*
* @return set of exercises
*/
default Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue() {
return findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS));
}

/**
* Find exercise by exerciseId and load participations in this exercise.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public interface ModelingExerciseRepository extends JpaRepository<ModelingExerci
""")
List<ModelingExercise> findByCourseIdWithCategories(@Param("courseId") Long courseId);

@EntityGraph(type = LOAD, attributePaths = { "exampleSubmissions", "teamAssignmentConfig", "categories", "competencies", "exampleSubmissions.submission.results" })
Optional<ModelingExercise> findWithEagerExampleSubmissionsAndCompetenciesById(@Param("exerciseId") Long exerciseId);
@EntityGraph(type = LOAD, attributePaths = { "exampleSubmissions", "teamAssignmentConfig", "categories", "competencies", "exampleSubmissions.submission.results",
"plagiarismChecksConfig" })
Optional<ModelingExercise> findWithEagerExampleSubmissionsAndCompetenciesAndPlagiarismChecksConfigById(@Param("exerciseId") Long exerciseId);

@Query("select modelingExercise from ModelingExercise modelingExercise left join fetch modelingExercise.exampleSubmissions exampleSubmissions left join fetch exampleSubmissions.submission submission left join fetch submission.results results left join fetch results.feedbacks left join fetch results.assessor left join fetch modelingExercise.teamAssignmentConfig where modelingExercise.id = :#{#exerciseId}")
Optional<ModelingExercise> findByIdWithExampleSubmissionsAndResults(@Param("exerciseId") Long exerciseId);
Expand Down Expand Up @@ -65,14 +66,19 @@ public interface ModelingExerciseRepository extends JpaRepository<ModelingExerci
@EntityGraph(type = LOAD, attributePaths = { "studentParticipations", "studentParticipations.submissions", "studentParticipations.submissions.results" })
Optional<ModelingExercise> findWithStudentParticipationsSubmissionsResultsById(Long exerciseId);

@EntityGraph(type = LOAD, attributePaths = { "studentParticipations", "studentParticipations.submissions", "studentParticipations.submissions.results",
"plagiarismChecksConfig" })
Optional<ModelingExercise> findWithStudentParticipationsSubmissionsResultsAndPlagiarismChecksConfigById(Long exerciseId);

@NotNull
default ModelingExercise findByIdElseThrow(long exerciseId) {
return findById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
}

@NotNull
default ModelingExercise findWithEagerExampleSubmissionsAndCompetenciesByIdElseThrow(long exerciseId) {
return findWithEagerExampleSubmissionsAndCompetenciesById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
default ModelingExercise findWithEagerExampleSubmissionsAndCompetenciesAndPlagiarismChecksConfigByIdElseThrow(long exerciseId) {
return findWithEagerExampleSubmissionsAndCompetenciesAndPlagiarismChecksConfigById(exerciseId)
.orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
}

@NotNull
Expand All @@ -84,4 +90,10 @@ default ModelingExercise findByIdWithExampleSubmissionsAndResultsElseThrow(long
default ModelingExercise findByIdWithStudentParticipationsSubmissionsResultsElseThrow(long exerciseId) {
return findWithStudentParticipationsSubmissionsResultsById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
}

@NotNull
default ModelingExercise findByIdWithStudentParticipationsSubmissionsResultsAndPlagiarismChecksConfigElseThrow(long exerciseId) {
return findWithStudentParticipationsSubmissionsResultsAndPlagiarismChecksConfigById(exerciseId)
.orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
"submissionPolicy" })
Optional<ProgrammingExercise> findWithTemplateAndSolutionParticipationTeamAssignmentConfigCategoriesAndCompetenciesById(Long exerciseId);

@EntityGraph(type = LOAD, attributePaths = { "templateParticipation", "solutionParticipation", "teamAssignmentConfig", "categories", "competencies", "auxiliaryRepositories",
"submissionPolicy", "plagiarismChecksConfig" })
Optional<ProgrammingExercise> findWithTemplateAndSolutionParticipationTeamAssignmentConfigCategoriesAndCompetenciesAndPlagiarismChecksConfigById(Long exerciseId);

@EntityGraph(type = LOAD, attributePaths = { "templateParticipation", "solutionParticipation", "auxiliaryRepositories" })
Optional<ProgrammingExercise> findWithTemplateAndSolutionParticipationAndAuxiliaryRepositoriesById(Long exerciseId);

Expand Down Expand Up @@ -448,6 +452,9 @@
""")
List<ProgrammingExercise> findAllProgrammingExercisesInCourseOrInExamsOfCourse(@Param("course") Course course);

@EntityGraph(type = LOAD, attributePaths = { "plagiarismChecksConfig" })
Optional<ProgrammingExercise> findWithPlagiarismChecksConfigById(long id);

Check notice on line 456 in src/main/java/de/tum/in/www1/artemis/repository/ProgrammingExerciseRepository.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/main/java/de/tum/in/www1/artemis/repository/ProgrammingExerciseRepository.java#L456

Avoid variables with short names like id

long countByShortNameAndCourse(String shortName, Course course);

long countByTitleAndCourse(String shortName, Course course);
Expand Down Expand Up @@ -476,6 +483,17 @@
return findById(programmingExerciseId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise", programmingExerciseId));
}

/**
* Find a programming exercise with plagiarism checks config by its id and throw an EntityNotFoundException if it cannot be found
*
* @param programmingExerciseId of the programming exercise.
* @return The programming exercise related to the given id
*/
@NotNull
default ProgrammingExercise findByIdWithPlagiarismChecksConfigElseThrow(Long programmingExerciseId) throws EntityNotFoundException {
return findWithPlagiarismChecksConfigById(programmingExerciseId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise", programmingExerciseId));
}

/**
* Find a programming exercise with auxiliary repositories by its id and throw an EntityNotFoundException if it cannot be found
*
Expand Down Expand Up @@ -591,6 +609,14 @@
return programmingExercise.orElseThrow(() -> new EntityNotFoundException("Programming Exercise", programmingExerciseId));
}

@NotNull
default ProgrammingExercise findByIdWithTemplateAndSolutionParticipationTeamAssignmentConfigCategoriesAndCompetenciesAndPlagiarismChecksConfigElseThrow(
long programmingExerciseId) throws EntityNotFoundException {
Optional<ProgrammingExercise> programmingExercise = findWithTemplateAndSolutionParticipationTeamAssignmentConfigCategoriesAndCompetenciesAndPlagiarismChecksConfigById(
programmingExerciseId);
return programmingExercise.orElseThrow(() -> new EntityNotFoundException("Programming Exercise", programmingExerciseId));
}

/**
* Find a programming exercise by its id, with eagerly loaded template and solution participation, submissions and results
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public interface TextExerciseRepository extends JpaRepository<TextExercise, Long
""")
List<TextExercise> findByCourseIdWithCategories(@Param("courseId") Long courseId);

@EntityGraph(type = LOAD, attributePaths = { "teamAssignmentConfig", "categories", "competencies" })
Optional<TextExercise> findWithEagerTeamAssignmentConfigAndCategoriesAndCompetenciesById(Long exerciseId);
@EntityGraph(type = LOAD, attributePaths = { "teamAssignmentConfig", "categories", "competencies", "plagiarismChecksConfig" })
Optional<TextExercise> findWithEagerTeamAssignmentConfigAndCategoriesAndCompetenciesAndPlagiarismChecksConfigById(Long exerciseId);

List<TextExercise> findByAssessmentTypeAndDueDateIsAfter(AssessmentType assessmentType, ZonedDateTime dueDate);

Expand All @@ -43,6 +43,10 @@ public interface TextExerciseRepository extends JpaRepository<TextExercise, Long
@EntityGraph(type = LOAD, attributePaths = { "studentParticipations", "studentParticipations.submissions", "studentParticipations.submissions.results" })
Optional<TextExercise> findWithStudentParticipationsAndSubmissionsById(Long exerciseId);

@EntityGraph(type = LOAD, attributePaths = { "studentParticipations", "studentParticipations.submissions", "studentParticipations.submissions.results",
"plagiarismChecksConfig" })
Optional<TextExercise> findWithStudentParticipationsAndSubmissionsAndPlagiarismChecksConfigById(Long exerciseId);

@NotNull
default TextExercise findByIdElseThrow(long exerciseId) {
return findById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Text Exercise", exerciseId));
Expand All @@ -58,6 +62,11 @@ default TextExercise findByIdWithStudentParticipationsAndSubmissionsElseThrow(lo
return findWithStudentParticipationsAndSubmissionsById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Text Exercise", exerciseId));
}

@NotNull
default TextExercise findByIdWithStudentParticipationsAndSubmissionsAndPlagiarismChecksConfigElseThrow(long exerciseId) {
return findWithStudentParticipationsAndSubmissionsAndPlagiarismChecksConfigById(exerciseId).orElseThrow(() -> new EntityNotFoundException("Text Exercise", exerciseId));
}

/**
* Find all exercises with *Due Date* in the future.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import de.tum.in.www1.artemis.domain.*;
import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode;
import de.tum.in.www1.artemis.domain.plagiarism.PlagiarismChecksConfig;
import de.tum.in.www1.artemis.repository.*;

public abstract class ExerciseImportService {
Expand Down Expand Up @@ -63,6 +64,22 @@ void copyExerciseBasis(final Exercise newExercise, final Exercise importedExerci
newExercise.setTeamAssignmentConfig(importedExercise.getTeamAssignmentConfig().copyTeamAssignmentConfig());
}
}

if (importedExercise.getPlagiarismChecksConfig() != null) {
var plagiarismChecksConfig = new PlagiarismChecksConfig();

var importedPlagiarismChecksConfig = importedExercise.getPlagiarismChecksConfig();
plagiarismChecksConfig.setContinuousPlagiarismControlEnabled(importedPlagiarismChecksConfig.isContinuousPlagiarismControlEnabled());
plagiarismChecksConfig.setSimilarityThreshold(importedPlagiarismChecksConfig.getSimilarityThreshold());
plagiarismChecksConfig.setMinimumSize(importedPlagiarismChecksConfig.getMinimumSize());
plagiarismChecksConfig.setMinimumScore(importedPlagiarismChecksConfig.getMinimumScore());

newExercise.setPlagiarismChecksConfig(plagiarismChecksConfig);
julian-christl marked this conversation as resolved.
Show resolved Hide resolved
}
else {
newExercise.setPlagiarismChecksConfig(null);
}

}

/**
Expand Down
Loading
Loading