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: Introduce continuos plagiarism control #7302

Merged
merged 134 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
6926ebf
extract plagiarism detection service
jakubriegel Sep 7, 2023
4051833
fix similarity for modeling exercises
jakubriegel Sep 7, 2023
fc8c70e
fix code tests
jakubriegel Sep 7, 2023
9dfc891
extract save logic to a method
jakubriegel Sep 7, 2023
9fe3bc8
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 7, 2023
c83eefb
remove unused field
jakubriegel Sep 7, 2023
c23635b
add doc
jakubriegel Sep 7, 2023
cbfa5f2
Merge remote-tracking branch 'origin/develop' into extract-plagiarism…
jakubriegel Sep 7, 2023
c80f975
add missing @param
jakubriegel Sep 7, 2023
c433abc
fix field removal
jakubriegel Sep 8, 2023
ce8c57a
Merge remote-tracking branch 'origin/develop' into extract-plagiarism…
jakubriegel Sep 9, 2023
ede87ea
add minimum length for programming exercises
jakubriegel Sep 10, 2023
521dee1
merge develop
jakubriegel Sep 10, 2023
ecfcb43
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 10, 2023
18fa06f
add doc and fix code style
jakubriegel Sep 10, 2023
759cd15
fix repos filtering
jakubriegel Sep 11, 2023
2647011
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 11, 2023
7fa694c
add missing @param
jakubriegel Sep 11, 2023
19b12ed
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 11, 2023
43dfddc
use abs of diff lines
jakubriegel Sep 11, 2023
7f61990
fox order of git diff
jakubriegel Sep 11, 2023
211c5ec
revert unnecessary changes
jakubriegel Sep 11, 2023
10f2e48
improve minimum size tooltips
jakubriegel Sep 11, 2023
3cf1869
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 13, 2023
9010352
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 13, 2023
8c33e94
fix tooltips and add de translation
jakubriegel Sep 13, 2023
d2912b7
log calculating number of diff lines error
jakubriegel Sep 13, 2023
281740c
use dedicated method
jakubriegel Sep 13, 2023
b1cfb28
fix method parameter
jakubriegel Sep 13, 2023
650a501
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 14, 2023
7b462c8
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 14, 2023
b7da306
Merge branch 'develop' into extract-plagiarism-detection-service
MarkusPaulsen Sep 16, 2023
926e4e0
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 18, 2023
aa561a5
merge develop
jakubriegel Sep 18, 2023
e14508f
use absolute line diff
jakubriegel Sep 18, 2023
64448e7
remove unnecessary fields
jakubriegel Sep 18, 2023
017da6c
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 18, 2023
172cbfa
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 18, 2023
1426eeb
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 20, 2023
5e575f3
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 20, 2023
9e030b9
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 20, 2023
44b514b
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 20, 2023
aeb4ca6
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 22, 2023
91b6a13
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 22, 2023
1eaf3f1
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 23, 2023
64dea57
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 23, 2023
0b2ab59
Merge branch 'develop' into extract-plagiarism-detection-service
jakubriegel Sep 24, 2023
b06ef5d
Merge branch 'extract-plagiarism-detection-service' into plagiarism-d…
jakubriegel Sep 24, 2023
be6657c
introduce cpc control service and move plagiarism checks config to th…
jakubriegel Sep 24, 2023
6dda5a4
Merge branch 'develop' into plagiarism-detection-cpc
jakubriegel Sep 30, 2023
295bc29
fix column name
jakubriegel Sep 30, 2023
94f9ce3
add submission.plagiarism_suspected and db migration
jakubriegel Sep 30, 2023
718bce2
add null guards for plagiarism detection config
jakubriegel Sep 30, 2023
e23d642
fix javadoc
jakubriegel Sep 30, 2023
89e1e27
add default cron for cpc
jakubriegel Oct 1, 2023
0d769ce
add plagiarism and cpc config to exercise model
jakubriegel Oct 1, 2023
a53383e
improve code style and add missing docs
jakubriegel Oct 1, 2023
d85d53d
custom parameters for manual plagiarism checks
jakubriegel Oct 1, 2023
bcd4903
fix for custom parameters for manual plagiarism checks
jakubriegel Oct 1, 2023
cf748e1
change plagiarism checks default params
jakubriegel Oct 2, 2023
0ed6c46
update cpc tooltip EN
jakubriegel Oct 2, 2023
9fee04a
fix repository method used and remove unused ones
jakubriegel Oct 2, 2023
ca48a9a
fix field name
jakubriegel Oct 2, 2023
f175ad3
improve style of cpc settings
jakubriegel Oct 2, 2023
7e4fb82
revert manual plagiarism checks warning
jakubriegel Oct 2, 2023
b82ba92
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 2, 2023
2df6f7c
add plagiarism configuration to modeling import
jakubriegel Oct 2, 2023
935babd
add ContinuousPlagiarismControlServiceTest
jakubriegel Oct 2, 2023
bb8dcd4
mark submissions detected by cpc as suspected plagiarism
jakubriegel Oct 2, 2023
758f9c7
mark submissions detected by cpc as suspected plagiarism (client)
jakubriegel Oct 2, 2023
227ea99
code quality
jakubriegel Oct 2, 2023
17034e0
add PlagiarismDetectionConfigHelperTest
jakubriegel Oct 2, 2023
f005632
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 4, 2023
648402b
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 4, 2023
6ca4956
create plagiarism cases for cpc detected submissions
jakubriegel Oct 4, 2023
138e7e3
revert unnecessary changes
jakubriegel Oct 4, 2023
8786347
revert unnecessary changes
jakubriegel Oct 4, 2023
58f4f19
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 7, 2023
d20d621
allow to create cpc plagiarism cases posts with no author
jakubriegel Oct 8, 2023
a134332
properly display cpc plagiarism cases posts with no author
jakubriegel Oct 8, 2023
43c173b
automatically create plagiarism cases by cpc
jakubriegel Oct 8, 2023
f657707
add created by cpc flag to plagiarism case
jakubriegel Oct 8, 2023
a204ca9
mark cpc plagiarism cases as similarity on client side
jakubriegel Oct 8, 2023
aef8f76
fix start imports
jakubriegel Oct 8, 2023
8155c84
add missing docs
jakubriegel Oct 8, 2023
f701cd2
don't show reply incentive when plagiarism case in created by cpc
jakubriegel Oct 9, 2023
0d66ea3
add dedicated copy dor cpc plagiarism case creation
jakubriegel Oct 9, 2023
937aa95
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 9, 2023
0dc8f30
add copy for cpc plagiarism case post and email
jakubriegel Oct 9, 2023
0196896
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 9, 2023
0b05707
fix ContinuousPlagiarismControlService test
jakubriegel Oct 9, 2023
5c57c85
improve Exercise->PlagiarismDetectionConfig relation and add default …
jakubriegel Oct 9, 2023
ed2c35a
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 10, 2023
ba41060
join plagiarism checks config on demand
jakubriegel Oct 11, 2023
3c3d29e
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 11, 2023
2d3d911
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 11, 2023
11a895d
fix cpc cron
jakubriegel Oct 11, 2023
03628ed
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 15, 2023
aba940e
optimize join
jakubriegel Oct 15, 2023
907b44b
reformat query
jakubriegel Oct 15, 2023
b2bf9b8
add brackets to if
jakubriegel Oct 15, 2023
4f148b2
remove unused method
jakubriegel Oct 15, 2023
a2691df
remove unnecessary filter method
jakubriegel Oct 15, 2023
7a12d9d
revert unnecessary change
jakubriegel Oct 15, 2023
17b2c43
fix comments
jakubriegel Oct 15, 2023
73b9408
add DE translations
jakubriegel Oct 15, 2023
4540c6b
Merge remote-tracking branch 'origin/develop' into plagiarism-detecti…
jakubriegel Oct 16, 2023
c8e98a2
Merge branch 'develop' into plagiarism-detection-cpc
jakubriegel Oct 17, 2023
318412a
Merge branch 'develop' into plagiarism-detection-cpc
jakubriegel Oct 17, 2023
6a5aeb9
fix similarity threshold
jakubriegel Oct 17, 2023
89b4059
enable emails for cpc
jakubriegel Oct 17, 2023
e9a7e91
add missing messages
jakubriegel Oct 17, 2023
b28a81a
Development: Add student code of conduct and apso as a static assets …
jakubriegel Oct 18, 2023
6845cb8
Merge branch 'develop' into plagiarism-detection-cpc
Strohgelaender Oct 18, 2023
59ef21b
fix migration id and order
jakubriegel Oct 18, 2023
699ade8
fix query formatting
jakubriegel Oct 18, 2023
e3c9f88
fix types
jakubriegel Oct 18, 2023
05a5f6e
update javadoc
jakubriegel Oct 18, 2023
0d5ff11
Update src/main/java/de/tum/in/www1/artemis/repository/ExerciseReposi…
jakubriegel Oct 18, 2023
d54fe31
update translations
jakubriegel Oct 18, 2023
9149de7
Merge remote-tracking branch 'origin/plagiarism-detection-cpc' into p…
jakubriegel Oct 18, 2023
118a9e7
Catch mail exceptions to so that notification for the second student …
jakubriegel Oct 19, 2023
47ccceb
fix migration
jakubriegel Oct 19, 2023
54c51c2
improve text style
jakubriegel Oct 20, 2023
4737800
Merge branch 'develop' into plagiarism-detection-cpc
MarkusPaulsen Oct 20, 2023
5acba39
disable cpc config for exam mode
jakubriegel Oct 20, 2023
33d5f1e
Merge remote-tracking branch 'origin/plagiarism-detection-cpc' into p…
jakubriegel Oct 20, 2023
4eee599
set plagiarism detection config for new exercises
jakubriegel Oct 20, 2023
c9efd8d
Merge branch 'develop' into plagiarism-detection-cpc
jakubriegel Oct 22, 2023
52e2929
don't add plagiarism checks config to exam exercises; fix importing p…
jakubriegel Oct 23, 2023
201cdd9
Merge branch 'develop' into plagiarism-detection-cpc
jakubriegel Oct 24, 2023
8436a08
Merge branch 'develop' into plagiarism-detection-cpc
jakubriegel Oct 27, 2023
9713260
merge develop
jakubriegel Oct 27, 2023
6053def
revert unwanted change
jakubriegel Oct 27, 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.PlagiarismDetectionConfig;
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, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "plagiarism_detection_config_id")
@JsonIgnoreProperties("exercise")
private PlagiarismDetectionConfig plagiarismDetectionConfig;

// 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 PlagiarismDetectionConfig getPlagiarismDetectionConfig() {
return plagiarismDetectionConfig;
}

public void setPlagiarismDetectionConfig(PlagiarismDetectionConfig plagiarismDetectionConfig) {
this.plagiarismDetectionConfig = plagiarismDetectionConfig;
}

// 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
Expand Up @@ -4,9 +4,9 @@ public enum NotificationType {
EXERCISE_SUBMISSION_ASSESSED, ATTACHMENT_CHANGE, EXERCISE_RELEASED, EXERCISE_PRACTICE, QUIZ_EXERCISE_STARTED, EXERCISE_UPDATED, NEW_REPLY_FOR_EXERCISE_POST,
NEW_REPLY_FOR_LECTURE_POST, NEW_REPLY_FOR_COURSE_POST, NEW_EXERCISE_POST, NEW_LECTURE_POST, NEW_COURSE_POST, NEW_ANNOUNCEMENT_POST, FILE_SUBMISSION_SUCCESSFUL,
COURSE_ARCHIVE_STARTED, COURSE_ARCHIVE_FINISHED, COURSE_ARCHIVE_FAILED, PROGRAMMING_TEST_CASES_CHANGED, DUPLICATE_TEST_CASE, EXAM_ARCHIVE_STARTED, EXAM_ARCHIVE_FINISHED,
EXAM_ARCHIVE_FAILED, ILLEGAL_SUBMISSION, NEW_PLAGIARISM_CASE_STUDENT, PLAGIARISM_CASE_VERDICT_STUDENT, NEW_MANUAL_FEEDBACK_REQUEST, TUTORIAL_GROUP_REGISTRATION_STUDENT,
TUTORIAL_GROUP_DEREGISTRATION_STUDENT, TUTORIAL_GROUP_REGISTRATION_TUTOR, TUTORIAL_GROUP_MULTIPLE_REGISTRATION_TUTOR, TUTORIAL_GROUP_DEREGISTRATION_TUTOR,
TUTORIAL_GROUP_DELETED, TUTORIAL_GROUP_UPDATED, TUTORIAL_GROUP_ASSIGNED, TUTORIAL_GROUP_UNASSIGNED, CONVERSATION_NEW_MESSAGE, CONVERSATION_NEW_REPLY_MESSAGE,
CONVERSATION_CREATE_ONE_TO_ONE_CHAT, CONVERSATION_CREATE_GROUP_CHAT, CONVERSATION_ADD_USER_GROUP_CHAT, CONVERSATION_ADD_USER_CHANNEL, CONVERSATION_REMOVE_USER_GROUP_CHAT,
CONVERSATION_REMOVE_USER_CHANNEL, CONVERSATION_DELETE_CHANNEL, DATA_EXPORT_CREATED, DATA_EXPORT_FAILED
EXAM_ARCHIVE_FAILED, ILLEGAL_SUBMISSION, NEW_PLAGIARISM_CASE_STUDENT, NEW_CPC_PLAGIARISM_CASE_STUDENT, PLAGIARISM_CASE_VERDICT_STUDENT, NEW_MANUAL_FEEDBACK_REQUEST,
TUTORIAL_GROUP_REGISTRATION_STUDENT, TUTORIAL_GROUP_DEREGISTRATION_STUDENT, TUTORIAL_GROUP_REGISTRATION_TUTOR, TUTORIAL_GROUP_MULTIPLE_REGISTRATION_TUTOR,
TUTORIAL_GROUP_DEREGISTRATION_TUTOR, TUTORIAL_GROUP_DELETED, TUTORIAL_GROUP_UPDATED, TUTORIAL_GROUP_ASSIGNED, TUTORIAL_GROUP_UNASSIGNED, CONVERSATION_NEW_MESSAGE,
CONVERSATION_NEW_REPLY_MESSAGE, CONVERSATION_CREATE_ONE_TO_ONE_CHAT, CONVERSATION_CREATE_GROUP_CHAT, CONVERSATION_ADD_USER_GROUP_CHAT, CONVERSATION_ADD_USER_CHANNEL,
CONVERSATION_REMOVE_USER_GROUP_CHAT, CONVERSATION_REMOVE_USER_CHANNEL, CONVERSATION_DELETE_CHANNEL, DATA_EXPORT_CREATED, DATA_EXPORT_FAILED
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class NotificationConstants {

public static final String NEW_PLAGIARISM_CASE_STUDENT_TITLE = "artemisApp.singleUserNotification.title.newPlagiarismCaseStudent";

public static final String NEW_CPC_PLAGIARISM_CASE_STUDENT_TITLE = "artemisApp.singleUserNotification.title.newPlagiarismCaseStudentSignificantSimilarity";

public static final String PLAGIARISM_CASE_VERDICT_STUDENT_TITLE = "artemisApp.singleUserNotification.title.plagiarismCaseVerdictStudent";

public static final String TUTORIAL_GROUP_REGISTRATION_STUDENT_TITLE = "artemisApp.singleUserNotification.title.tutorialGroupRegistrationStudent";
Expand Down Expand Up @@ -153,6 +155,8 @@ public class NotificationConstants {

public static final String NEW_PLAGIARISM_CASE_STUDENT_TEXT = "artemisApp.singleUserNotification.text.newPlagiarismCaseStudent";

public static final String NEW_CPC_PLAGIARISM_CASE_STUDENT_TEXT = "artemisApp.singleUserNotification.text.newPlagiarismCaseStudentSignificantSimilarity";

public static final String PLAGIARISM_CASE_VERDICT_STUDENT_TEXT = "artemisApp.singleUserNotification.text.plagiarismCaseVerdictStudent";

public static final String TUTORIAL_GROUP_REGISTRATION_STUDENT_TEXT = "artemisApp.singleUserNotification.text.tutorialGroupRegistrationStudent";
Expand Down Expand Up @@ -225,8 +229,8 @@ public class NotificationConstants {
.put(COURSE_ARCHIVE_FINISHED, COURSE_ARCHIVE_FINISHED_TITLE).put(COURSE_ARCHIVE_FAILED, COURSE_ARCHIVE_FAILED_TITLE)
.put(EXAM_ARCHIVE_STARTED, EXAM_ARCHIVE_STARTED_TITLE).put(EXAM_ARCHIVE_FAILED, EXAM_ARCHIVE_FAILED_TITLE).put(EXAM_ARCHIVE_FINISHED, EXAM_ARCHIVE_FINISHED_TITLE)
.put(PROGRAMMING_TEST_CASES_CHANGED, PROGRAMMING_TEST_CASES_CHANGED_TITLE).put(NEW_MANUAL_FEEDBACK_REQUEST, NEW_MANUAL_FEEDBACK_REQUEST_TITLE)
.put(NEW_PLAGIARISM_CASE_STUDENT, NEW_PLAGIARISM_CASE_STUDENT_TITLE).put(PLAGIARISM_CASE_VERDICT_STUDENT, PLAGIARISM_CASE_VERDICT_STUDENT_TITLE)
.put(TUTORIAL_GROUP_REGISTRATION_STUDENT, TUTORIAL_GROUP_REGISTRATION_STUDENT_TITLE)
.put(NEW_PLAGIARISM_CASE_STUDENT, NEW_PLAGIARISM_CASE_STUDENT_TITLE).put(NEW_CPC_PLAGIARISM_CASE_STUDENT, NEW_CPC_PLAGIARISM_CASE_STUDENT_TITLE)
.put(PLAGIARISM_CASE_VERDICT_STUDENT, PLAGIARISM_CASE_VERDICT_STUDENT_TITLE).put(TUTORIAL_GROUP_REGISTRATION_STUDENT, TUTORIAL_GROUP_REGISTRATION_STUDENT_TITLE)
.put(TUTORIAL_GROUP_DEREGISTRATION_STUDENT, TUTORIAL_GROUP_DEREGISTRATION_STUDENT_TITLE).put(TUTORIAL_GROUP_REGISTRATION_TUTOR, TUTORIAL_GROUP_REGISTRATION_TUTOR_TITLE)
.put(TUTORIAL_GROUP_DEREGISTRATION_TUTOR, TUTORIAL_GROUP_DEREGISTRATION_TUTOR_TITLE).put(TUTORIAL_GROUP_DELETED, TUTORIAL_GROUP_DELETED_TITLE)
.put(TUTORIAL_GROUP_UPDATED, TUTORIAL_GROUP_UPDATED_TITLE).put(TUTORIAL_GROUP_MULTIPLE_REGISTRATION_TUTOR, TUTORIAL_GROUP_REGISTRATION_MULTIPLE_TUTOR_TITLE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ public static SingleUserNotification createNotification(PlagiarismCase plagiaris
placeholderValues = new String[] { affectedExercise.getCourseViaExerciseGroupOrCourseMember().getTitle(),
affectedExercise.getExerciseType().toString().toLowerCase(), affectedExercise.getTitle() };
}
case NEW_CPC_PLAGIARISM_CASE_STUDENT -> {
title = NEW_CPC_PLAGIARISM_CASE_STUDENT_TITLE;
notificationText = NEW_CPC_PLAGIARISM_CASE_STUDENT_TEXT;
placeholderValues = new String[] { affectedExercise.getCourseViaExerciseGroupOrCourseMember().getTitle(),
affectedExercise.getExerciseType().toString().toLowerCase(), affectedExercise.getTitle() };
}
case PLAGIARISM_CASE_VERDICT_STUDENT -> {
title = PLAGIARISM_CASE_VERDICT_STUDENT_TITLE;
notificationText = PLAGIARISM_CASE_VERDICT_STUDENT_TEXT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public class PlagiarismCase extends AbstractAuditingEntity {
@Column(name = "verdict_point_deduction")
private int verdictPointDeduction;

@Column(name = "created_by_continuous_plagiarism_control")
private boolean createdByContinuousPlagiarismControl;

public Exercise getExercise() {
return exercise;
}
Expand Down Expand Up @@ -151,6 +154,14 @@ public void setVerdictPointDeduction(int verdictPointDeduction) {
this.verdictPointDeduction = verdictPointDeduction;
}

public boolean isCreatedByContinuousPlagiarismControl() {
return createdByContinuousPlagiarismControl;
}

public void setCreatedByContinuousPlagiarismControl(boolean createdByContinuousPlagiarismControl) {
this.createdByContinuousPlagiarismControl = createdByContinuousPlagiarismControl;
}

@Override
public String toString() {
return "PlagiarismCase{" + "exercise=" + exercise + ", student=" + student + ", post=" + post + ", verdict=" + verdict + ", verdictMessage=" + verdictMessage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,124 @@
package de.tum.in.www1.artemis.domain.plagiarism;

import java.util.Objects;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

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

import com.fasterxml.jackson.annotation.JsonInclude;

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

/**
* Stores configuration for plagiarism detection.
* Stores configuration for manual and continuous plagiarism control.
*/
public record PlagiarismDetectionConfig(float similarityThreshold, int minimumScore, int minimumSize) {
@Entity
@Table(name = "plagiarism_detection_config")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class PlagiarismDetectionConfig extends DomainObject {

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

@Column(name = "continuous_plagiarism_control_post_due_date_checks_enabled")
private boolean continuousPlagiarismControlPostDueDateChecksEnabled = false;

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

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

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

public boolean isContinuousPlagiarismControlEnabled() {
return continuousPlagiarismControlEnabled;
}

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

public boolean isContinuousPlagiarismControlPostDueDateChecksEnabled() {
return continuousPlagiarismControlPostDueDateChecksEnabled;
}

public void setContinuousPlagiarismControlPostDueDateChecksEnabled(boolean continuousPlagiarismControlPostDueDateChecksEnabled) {
this.continuousPlagiarismControlPostDueDateChecksEnabled = continuousPlagiarismControlPostDueDateChecksEnabled;
}

public float getSimilarityThreshold() {
return similarityThreshold;
}

public int getMinimumScore() {
return minimumScore;
}

public int getMinimumSize() {
return minimumSize;
}

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

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

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

/**
* Creates PlagiarismDetectionConfig with default data
*
* @return PlagiarismDetectionConfig with default values
*/
public static PlagiarismDetectionConfig createDefault() {
var config = new PlagiarismDetectionConfig();
config.setContinuousPlagiarismControlEnabled(false);
config.setContinuousPlagiarismControlPostDueDateChecksEnabled(false);
config.setSimilarityThreshold(90);
config.setMinimumScore(0);
config.setMinimumSize(50);
return config;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
PlagiarismDetectionConfig that = (PlagiarismDetectionConfig) o;
return continuousPlagiarismControlEnabled == that.continuousPlagiarismControlEnabled
&& continuousPlagiarismControlPostDueDateChecksEnabled == that.continuousPlagiarismControlPostDueDateChecksEnabled
&& Float.compare(similarityThreshold, that.similarityThreshold) == 0 && minimumScore == that.minimumScore && minimumSize == that.minimumSize;
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), continuousPlagiarismControlEnabled, continuousPlagiarismControlPostDueDateChecksEnabled, similarityThreshold, minimumScore,
minimumSize);
}

@Override
public String toString() {
return "PlagiarismDetectionConfig{continuousPlagiarismControlEnabled=" + continuousPlagiarismControlEnabled + ", continuousPlagiarismControlPostDueDateChecksEnabled="
+ continuousPlagiarismControlPostDueDateChecksEnabled + ", similarityThreshold=" + similarityThreshold + ", minimumScore=" + minimumScore + ", minimumSize="
+ minimumSize + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,17 @@ GROUP BY TYPE(e)
List<ExerciseTypeMetricsEntry> countActiveStudentsInExercisesWithReleaseDateBetweenGroupByExerciseType(@Param("minDate") ZonedDateTime minDate,
@Param("maxDate") ZonedDateTime maxDate, @Param("activeUserLogins") List<String> activeUserLogins);

@Query("""
SELECT e FROM Exercise e
LEFT JOIN FETCH e.plagiarismDetectionConfig c
LEFT JOIN FETCH e.studentParticipations p
LEFT JOIN FETCH p.submissions s
LEFT JOIN FETCH s.results
WHERE e.dueDate >= :time
AND c.continuousPlagiarismControlEnabled = TRUE
""")
Set<Exercise> findAllExercisesWithDueDateOnOrAfterAndContinuousPlagiarismControlEnabledIsTrue(@Param("time") ZonedDateTime time);

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

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

/**
* Find exercise by exerciseId and load participations in this exercise.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,23 @@ public interface ModelingExerciseRepository extends JpaRepository<ModelingExerci
@EntityGraph(type = LOAD, attributePaths = { "exampleSubmissions", "teamAssignmentConfig", "categories", "competencies", "exampleSubmissions.submission.results" })
Optional<ModelingExercise> findWithEagerExampleSubmissionsAndCompetenciesById(@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);
@EntityGraph(type = LOAD, attributePaths = { "exampleSubmissions", "teamAssignmentConfig", "categories", "competencies", "exampleSubmissions.submission.results",
"plagiarismDetectionConfig" })
Optional<ModelingExercise> findWithEagerExampleSubmissionsAndCompetenciesAndPlagiarismDetectionConfigById(@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
LEFT JOIN FETCH modelingExercise.plagiarismDetectionConfig
WHERE modelingExercise.id = :#{#exerciseId}
""")
Optional<ModelingExercise> findByIdWithExampleSubmissionsAndResultsAndPlagiarismDetectionConfig(@Param("exerciseId") Long exerciseId);

/**
* Get all modeling exercises that need to be scheduled: Those must satisfy one of the following requirements:
Expand Down Expand Up @@ -76,8 +91,14 @@ default ModelingExercise findWithEagerExampleSubmissionsAndCompetenciesByIdElseT
}

@NotNull
default ModelingExercise findByIdWithExampleSubmissionsAndResultsElseThrow(long exerciseId) {
return findByIdWithExampleSubmissionsAndResults(exerciseId).orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
default ModelingExercise findWithEagerExampleSubmissionsAndCompetenciesAndPlagiarismDetectionConfigByIdElseThrow(long exerciseId) {
return findWithEagerExampleSubmissionsAndCompetenciesAndPlagiarismDetectionConfigById(exerciseId)
.orElseThrow(() -> new EntityNotFoundException("Modeling Exercise", exerciseId));
}

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

@NotNull
Expand Down
Loading
Loading