Search in sources :

Example 11 with PlagiarismSubmission

use of de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission in project ArTEMiS by ls1intum.

the class ModelingPlagiarismDetectionService method checkPlagiarism.

/**
 * Pairwise comparison of text submissions using a TextComparisonStrategy
 *
 * @param modelingSubmissions List of modeling submissions
 * @param minimumSimilarity   the minimum similarity so that the result is considered
 * @param minimumModelSize    the minimum number of model elements to be considered as plagiarism
 * @param minimumScore        the minimum result score (if available) to be considered as plagiarism
 * @param exerciseId          the id of the exercise for which the modeling submissions are compared
 *
 * @return List of submission id pairs and similarity score
 */
public ModelingPlagiarismResult checkPlagiarism(List<ModelingSubmission> modelingSubmissions, double minimumSimilarity, int minimumModelSize, int minimumScore, Long exerciseId) {
    String topic = plagiarismWebsocketService.getModelingExercisePlagiarismCheckTopic(exerciseId);
    ModelingPlagiarismResult result = new ModelingPlagiarismResult();
    Map<UMLDiagram, ModelingSubmission> models = new HashMap<>();
    ObjectMapper objectMapper = new ObjectMapper();
    AtomicInteger processedSubmissionCount = new AtomicInteger(1);
    modelingSubmissions.stream().filter(modelingSubmission -> !modelingSubmission.isEmpty(objectMapper)).filter(modelingSubmission -> minimumScore == 0 || modelingSubmission.getLatestResult() != null && modelingSubmission.getLatestResult().getScore() != null && modelingSubmission.getLatestResult().getScore() >= minimumScore).forEach(modelingSubmission -> {
        String progressMessage = "Getting UML diagram for submission: " + processedSubmissionCount + "/" + modelingSubmissions.size();
        plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.RUNNING, List.of(progressMessage));
        try {
            log.debug("Build UML diagram from json");
            UMLDiagram model = UMLModelParser.buildModelFromJSON(parseString(modelingSubmission.getModel()).getAsJsonObject(), modelingSubmission.getId());
            if (model.getAllModelElements().size() >= minimumModelSize) {
                models.put(model, modelingSubmission);
            }
        } catch (IOException e) {
            log.error("Parsing the modeling submission " + modelingSubmission.getId() + " did throw an exception:", e);
        }
        processedSubmissionCount.getAndIncrement();
    });
    log.info("Found {} modeling submissions with at least {} elements to compare", models.size(), minimumModelSize);
    Set<PlagiarismComparison<ModelingSubmissionElement>> comparisons = new HashSet<>();
    List<UMLDiagram> nonEmptyDiagrams = new ArrayList<>(models.keySet());
    long timeBeforeStartInMillis = System.currentTimeMillis();
    // similarity between two different submissions once
    for (int i = 0; i < nonEmptyDiagrams.size(); i++) {
        String progressMessage = "Comparing submissions: " + (i + 1) + "/" + nonEmptyDiagrams.size();
        plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.RUNNING, List.of(progressMessage));
        for (int j = i + 1; j < nonEmptyDiagrams.size(); j++) {
            UMLDiagram model1 = nonEmptyDiagrams.get(i);
            UMLDiagram model2 = nonEmptyDiagrams.get(j);
            final double similarity = model1.similarity(model2);
            log.debug("Compare result {} with {}: {}", i, j, similarity);
            if (similarity < minimumSimilarity) {
                // ignore comparison results with too small similarity
                continue;
            }
            ModelingSubmission modelingSubmissionA = models.get(model1);
            ModelingSubmission modelingSubmissionB = models.get(model2);
            log.info("Found similar models {} with {}: {}", i, j, similarity);
            PlagiarismSubmission<ModelingSubmissionElement> submissionA = PlagiarismSubmission.fromModelingSubmission(modelingSubmissionA);
            submissionA.setSize(model1.getAllModelElements().size());
            submissionA.setElements(model1.getAllModelElements().stream().map(ModelingSubmissionElement::fromUMLElement).collect(Collectors.toList()));
            PlagiarismSubmission<ModelingSubmissionElement> submissionB = PlagiarismSubmission.fromModelingSubmission(modelingSubmissionB);
            submissionB.setSize(model2.getAllModelElements().size());
            submissionB.setElements(model2.getAllModelElements().stream().map(ModelingSubmissionElement::fromUMLElement).collect(Collectors.toList()));
            PlagiarismComparison<ModelingSubmissionElement> comparison = new PlagiarismComparison<>();
            comparison.setPlagiarismResult(result);
            comparison.setSimilarity(similarity * 100);
            comparison.setSubmissionA(submissionA);
            comparison.setSubmissionB(submissionB);
            // TODO: Add matches to highlight similar modeling elements
            comparison.setMatches(new HashSet<>());
            comparisons.add(comparison);
        }
    }
    log.info("Found {} similar modeling submission combinations (>{})", comparisons.size(), minimumSimilarity);
    plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.COMPLETED, List.of());
    long durationInMillis = System.currentTimeMillis() - timeBeforeStartInMillis;
    int[] similarityDistribution = calculateSimilarityDistribution(comparisons);
    result.setComparisons(comparisons);
    result.setDuration(durationInMillis);
    result.setSimilarityDistribution(similarityDistribution);
    return result;
}
Also used : java.util(java.util) ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult) Logger(org.slf4j.Logger) JsonParser.parseString(com.google.gson.JsonParser.parseString) UMLDiagram(de.tum.in.www1.artemis.service.compass.umlmodel.UMLDiagram) Participation(de.tum.in.www1.artemis.domain.participation.Participation) LoggerFactory(org.slf4j.LoggerFactory) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) PlagiarismCheckState(de.tum.in.www1.artemis.domain.PlagiarismCheckState) PlagiarismComparison(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Service(org.springframework.stereotype.Service) ModelingSubmissionElement(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingSubmissionElement) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) PlagiarismSubmission(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission) UMLModelParser(de.tum.in.www1.artemis.service.compass.umlmodel.parsers.UMLModelParser) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) PlagiarismComparison(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) JsonParser.parseString(com.google.gson.JsonParser.parseString) IOException(java.io.IOException) ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult) UMLDiagram(de.tum.in.www1.artemis.service.compass.umlmodel.UMLDiagram) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ModelingSubmissionElement(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingSubmissionElement) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 12 with PlagiarismSubmission

use of de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission in project ArTEMiS by ls1intum.

the class PlagiarismCaseService method createOrAddToPlagiarismCaseForStudent.

/**
 * Create or add to a plagiarism case for a student defined via the submission involved in a plagiarism comparison.
 * The following logic applies:
 *      * <ul>
 *      *     <li>Create a new plagiarism case if the student isn't already part of a plagiarism case in the exercise</li>
 *      *     <li>Add the submission of the student to existing plagiarism case otherwise</li>
 *      * </ul>
 *
 * @param plagiarismComparison  the plagiarism comparison for which to create the plagiarism case
 * @param plagiarismSubmission  the plagiarism submission of the student for which to create the plagiarism case
 */
public void createOrAddToPlagiarismCaseForStudent(PlagiarismComparison<?> plagiarismComparison, PlagiarismSubmission<?> plagiarismSubmission) {
    var plagiarismCase = plagiarismCaseRepository.findByStudentLoginAndExerciseIdWithPlagiarismSubmissions(plagiarismSubmission.getStudentLogin(), plagiarismComparison.getPlagiarismResult().getExercise().getId());
    if (plagiarismCase.isPresent()) {
        // add submission to existing PlagiarismCase for student
        plagiarismSubmission.setPlagiarismCase(plagiarismCase.get());
        plagiarismComparisonRepository.save(plagiarismComparison);
    } else {
        // create new PlagiarismCase for student
        var student = userRepository.getUserByLoginElseThrow(plagiarismSubmission.getStudentLogin());
        PlagiarismCase newPlagiarismCase = new PlagiarismCase();
        newPlagiarismCase.setExercise(plagiarismComparison.getPlagiarismResult().getExercise());
        newPlagiarismCase.setStudent(student);
        var savedPlagiarismCase = plagiarismCaseRepository.save(newPlagiarismCase);
        plagiarismSubmission.setPlagiarismCase(savedPlagiarismCase);
        plagiarismComparisonRepository.save(plagiarismComparison);
    }
}
Also used : PlagiarismCase(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismCase)

Example 13 with PlagiarismSubmission

use of de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission in project ArTEMiS by ls1intum.

the class ModelingSubmissionIntegrationTest method getModelSubmissionWithResult_involved_allowed.

@Test
@WithMockUser(username = "student1", roles = "USER")
public void getModelSubmissionWithResult_involved_allowed() throws Exception {
    ModelingSubmission submission = ModelFactory.generateModelingSubmission(validModel, true);
    submission = database.addModelingSubmission(classExercise, submission, "student1");
    PlagiarismComparison<ModelingSubmissionElement> plagiarismComparison = new PlagiarismComparison<>();
    PlagiarismSubmission<ModelingSubmissionElement> submissionA = new PlagiarismSubmission<>();
    submissionA.setStudentLogin("student1");
    submissionA.setSubmissionId(submission.getId());
    plagiarismComparison.setSubmissionA(submissionA);
    PlagiarismCase plagiarismCase = new PlagiarismCase();
    plagiarismCase = plagiarismCaseRepository.save(plagiarismCase);
    Post post = new Post();
    post.setAuthor(userRepo.getUserByLoginElseThrow("instructor1"));
    post.setTitle("Title Plagiarism Case Post");
    post.setContent("Content Plagiarism Case Post");
    post.setVisibleForStudents(true);
    post.setPlagiarismCase(plagiarismCase);
    postRepository.save(post);
    submissionA.setPlagiarismCase(plagiarismCase);
    plagiarismComparisonRepository.save(plagiarismComparison);
    var submissionResult = request.get("/api/modeling-submissions/" + submission.getId(), HttpStatus.OK, ModelingSubmission.class);
    assertThat(submissionResult.getParticipation()).as("Should anonymize participation").isNull();
    assertThat(submissionResult.getResults()).as("Should anonymize results").isEmpty();
    assertThat(submissionResult.getSubmissionDate()).as("Should anonymize submission date").isNull();
}
Also used : PlagiarismComparison(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison) PlagiarismCase(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismCase) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingSubmissionElement(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingSubmissionElement) PlagiarismSubmission(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission) Post(de.tum.in.www1.artemis.domain.metis.Post) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test)

Example 14 with PlagiarismSubmission

use of de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission in project ArTEMiS by ls1intum.

the class SingleUserNotificationFactoryTest method setUp.

/**
 * sets up all needed mocks and their wanted behavior once for all test cases.
 */
@BeforeAll
public static void setUp() {
    course = new Course();
    course.setId(COURSE_ID);
    lecture = new Lecture();
    lecture.setId(LECTURE_ID);
    lecture.setCourse(course);
    exercise = new TextExercise();
    exercise.setId(EXERCISE_ID);
    exercise.setTitle(EXERCISE_TITLE);
    exercise.setCourse(course);
    exercise.setProblemStatement(PROBLEM_STATEMENT);
    post = new Post();
    post.setExercise(exercise);
    post.setLecture(lecture);
    answerPost = new AnswerPost();
    answerPost.setPost(post);
    cheatingUser = new User();
    cheatingUser.setLogin(USER_LOGIN);
    plagiarismResult = new TextPlagiarismResult();
    plagiarismResult.setExercise(exercise);
    plagiarismSubmission = new PlagiarismSubmission();
    plagiarismSubmission.setStudentLogin(USER_LOGIN);
    plagiarismSubmissionSet = new HashSet<>();
    plagiarismSubmissionSet.add(plagiarismSubmission);
    plagiarismComparison = new PlagiarismComparison();
    plagiarismComparison.setPlagiarismResult(plagiarismResult);
    plagiarismComparison.setSubmissionA(plagiarismSubmission);
    plagiarismCase = new PlagiarismCase();
    plagiarismCase.setExercise(exercise);
    plagiarismCase.setStudent(cheatingUser);
    plagiarismCase.setPlagiarismSubmissions(plagiarismSubmissionSet);
}
Also used : PlagiarismComparison(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison) PlagiarismCase(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismCase) TextPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult) AnswerPost(de.tum.in.www1.artemis.domain.metis.AnswerPost) Post(de.tum.in.www1.artemis.domain.metis.Post) PlagiarismSubmission(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission) AnswerPost(de.tum.in.www1.artemis.domain.metis.AnswerPost) BeforeAll(org.junit.jupiter.api.BeforeAll)

Example 15 with PlagiarismSubmission

use of de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission in project Artemis by ls1intum.

the class ModelingPlagiarismDetectionService method checkPlagiarism.

/**
 * Pairwise comparison of text submissions using a TextComparisonStrategy
 *
 * @param modelingSubmissions List of modeling submissions
 * @param minimumSimilarity   the minimum similarity so that the result is considered
 * @param minimumModelSize    the minimum number of model elements to be considered as plagiarism
 * @param minimumScore        the minimum result score (if available) to be considered as plagiarism
 * @param exerciseId          the id of the exercise for which the modeling submissions are compared
 *
 * @return List of submission id pairs and similarity score
 */
public ModelingPlagiarismResult checkPlagiarism(List<ModelingSubmission> modelingSubmissions, double minimumSimilarity, int minimumModelSize, int minimumScore, Long exerciseId) {
    String topic = plagiarismWebsocketService.getModelingExercisePlagiarismCheckTopic(exerciseId);
    ModelingPlagiarismResult result = new ModelingPlagiarismResult();
    Map<UMLDiagram, ModelingSubmission> models = new HashMap<>();
    ObjectMapper objectMapper = new ObjectMapper();
    AtomicInteger processedSubmissionCount = new AtomicInteger(1);
    modelingSubmissions.stream().filter(modelingSubmission -> !modelingSubmission.isEmpty(objectMapper)).filter(modelingSubmission -> minimumScore == 0 || modelingSubmission.getLatestResult() != null && modelingSubmission.getLatestResult().getScore() != null && modelingSubmission.getLatestResult().getScore() >= minimumScore).forEach(modelingSubmission -> {
        String progressMessage = "Getting UML diagram for submission: " + processedSubmissionCount + "/" + modelingSubmissions.size();
        plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.RUNNING, List.of(progressMessage));
        try {
            log.debug("Build UML diagram from json");
            UMLDiagram model = UMLModelParser.buildModelFromJSON(parseString(modelingSubmission.getModel()).getAsJsonObject(), modelingSubmission.getId());
            if (model.getAllModelElements().size() >= minimumModelSize) {
                models.put(model, modelingSubmission);
            }
        } catch (IOException e) {
            log.error("Parsing the modeling submission " + modelingSubmission.getId() + " did throw an exception:", e);
        }
        processedSubmissionCount.getAndIncrement();
    });
    log.info("Found {} modeling submissions with at least {} elements to compare", models.size(), minimumModelSize);
    Set<PlagiarismComparison<ModelingSubmissionElement>> comparisons = new HashSet<>();
    List<UMLDiagram> nonEmptyDiagrams = new ArrayList<>(models.keySet());
    long timeBeforeStartInMillis = System.currentTimeMillis();
    // similarity between two different submissions once
    for (int i = 0; i < nonEmptyDiagrams.size(); i++) {
        String progressMessage = "Comparing submissions: " + (i + 1) + "/" + nonEmptyDiagrams.size();
        plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.RUNNING, List.of(progressMessage));
        for (int j = i + 1; j < nonEmptyDiagrams.size(); j++) {
            UMLDiagram model1 = nonEmptyDiagrams.get(i);
            UMLDiagram model2 = nonEmptyDiagrams.get(j);
            final double similarity = model1.similarity(model2);
            log.debug("Compare result {} with {}: {}", i, j, similarity);
            if (similarity < minimumSimilarity) {
                // ignore comparison results with too small similarity
                continue;
            }
            ModelingSubmission modelingSubmissionA = models.get(model1);
            ModelingSubmission modelingSubmissionB = models.get(model2);
            log.info("Found similar models {} with {}: {}", i, j, similarity);
            PlagiarismSubmission<ModelingSubmissionElement> submissionA = PlagiarismSubmission.fromModelingSubmission(modelingSubmissionA);
            submissionA.setSize(model1.getAllModelElements().size());
            submissionA.setElements(model1.getAllModelElements().stream().map(ModelingSubmissionElement::fromUMLElement).collect(Collectors.toList()));
            PlagiarismSubmission<ModelingSubmissionElement> submissionB = PlagiarismSubmission.fromModelingSubmission(modelingSubmissionB);
            submissionB.setSize(model2.getAllModelElements().size());
            submissionB.setElements(model2.getAllModelElements().stream().map(ModelingSubmissionElement::fromUMLElement).collect(Collectors.toList()));
            PlagiarismComparison<ModelingSubmissionElement> comparison = new PlagiarismComparison<>();
            comparison.setPlagiarismResult(result);
            comparison.setSimilarity(similarity * 100);
            comparison.setSubmissionA(submissionA);
            comparison.setSubmissionB(submissionB);
            // TODO: Add matches to highlight similar modeling elements
            comparison.setMatches(new HashSet<>());
            comparisons.add(comparison);
        }
    }
    log.info("Found {} similar modeling submission combinations (>{})", comparisons.size(), minimumSimilarity);
    plagiarismWebsocketService.notifyInstructorAboutPlagiarismState(topic, PlagiarismCheckState.COMPLETED, List.of());
    long durationInMillis = System.currentTimeMillis() - timeBeforeStartInMillis;
    int[] similarityDistribution = calculateSimilarityDistribution(comparisons);
    result.setComparisons(comparisons);
    result.setDuration(durationInMillis);
    result.setSimilarityDistribution(similarityDistribution);
    return result;
}
Also used : java.util(java.util) ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult) Logger(org.slf4j.Logger) JsonParser.parseString(com.google.gson.JsonParser.parseString) UMLDiagram(de.tum.in.www1.artemis.service.compass.umlmodel.UMLDiagram) Participation(de.tum.in.www1.artemis.domain.participation.Participation) LoggerFactory(org.slf4j.LoggerFactory) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) PlagiarismCheckState(de.tum.in.www1.artemis.domain.PlagiarismCheckState) PlagiarismComparison(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Service(org.springframework.stereotype.Service) ModelingSubmissionElement(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingSubmissionElement) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) PlagiarismSubmission(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission) UMLModelParser(de.tum.in.www1.artemis.service.compass.umlmodel.parsers.UMLModelParser) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) PlagiarismComparison(de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) JsonParser.parseString(com.google.gson.JsonParser.parseString) IOException(java.io.IOException) ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult) UMLDiagram(de.tum.in.www1.artemis.service.compass.umlmodel.UMLDiagram) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ModelingSubmissionElement(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingSubmissionElement) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Aggregations

PlagiarismSubmission (de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission)28 PlagiarismComparison (de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison)26 TextSubmissionElement (de.tum.in.www1.artemis.domain.plagiarism.text.TextSubmissionElement)24 WithMockUser (org.springframework.security.test.context.support.WithMockUser)24 TextPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult)22 Test (org.junit.jupiter.api.Test)22 Course (de.tum.in.www1.artemis.domain.Course)18 TextExercise (de.tum.in.www1.artemis.domain.TextExercise)18 PlagiarismCase (de.tum.in.www1.artemis.domain.plagiarism.PlagiarismCase)10 Post (de.tum.in.www1.artemis.domain.metis.Post)8 PlagiarismComparisonStatusDTO (de.tum.in.www1.artemis.web.rest.dto.PlagiarismComparisonStatusDTO)6 ModelingSubmission (de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)4 ModelingSubmissionElement (de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingSubmissionElement)4 BeforeEach (org.junit.jupiter.api.BeforeEach)4 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 JsonParser.parseString (com.google.gson.JsonParser.parseString)2 PlagiarismCheckState (de.tum.in.www1.artemis.domain.PlagiarismCheckState)2 User (de.tum.in.www1.artemis.domain.User)2 AnswerPost (de.tum.in.www1.artemis.domain.metis.AnswerPost)2 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)2