Search in sources :

Example 21 with ModelingSubmission

use of de.tum.in.www1.artemis.domain.modeling.ModelingSubmission in project ArTEMiS by ls1intum.

the class ModelingPlagiarismDetectionService method checkPlagiarism.

/**
 * Convenience method to extract all latest submissions from a ModelingExercise and compute pair-wise distances.
 *
 * @param exerciseWithParticipationsSubmissionsResults Text Exercise with fetched participations and 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
 * @return List of submission id pairs and similarity score
 */
public ModelingPlagiarismResult checkPlagiarism(ModelingExercise exerciseWithParticipationsSubmissionsResults, double minimumSimilarity, int minimumModelSize, int minimumScore) {
    final List<ModelingSubmission> modelingSubmissions = modelingSubmissionsForComparison(exerciseWithParticipationsSubmissionsResults);
    log.info("Found {} modeling submissions in exercise {}", modelingSubmissions.size(), exerciseWithParticipationsSubmissionsResults.getId());
    Long exerciseId = exerciseWithParticipationsSubmissionsResults.getId();
    ModelingPlagiarismResult result = checkPlagiarism(modelingSubmissions, minimumSimilarity, minimumModelSize, minimumScore, exerciseId);
    result.setExercise(exerciseWithParticipationsSubmissionsResults);
    return result;
}
Also used : ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)

Example 22 with ModelingSubmission

use of de.tum.in.www1.artemis.domain.modeling.ModelingSubmission 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 23 with ModelingSubmission

use of de.tum.in.www1.artemis.domain.modeling.ModelingSubmission in project ArTEMiS by ls1intum.

the class ExamIntegrationTest method testStartExercisesWithModelingExercise.

@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void testStartExercisesWithModelingExercise() throws Exception {
    // TODO IMPORTANT test more complex exam configurations (mixed exercise type, more variants and more registered students)
    // registering users
    var student1 = database.getUserByLogin("student1");
    var student2 = database.getUserByLogin("student2");
    var registeredUsers = Set.of(student1, student2);
    exam2.setRegisteredUsers(registeredUsers);
    // setting dates
    exam2.setStartDate(now().plusHours(2));
    exam2.setEndDate(now().plusHours(3));
    exam2.setVisibleDate(now().plusHours(1));
    // creating exercise
    ModelingExercise modelingExercise = ModelFactory.generateModelingExerciseForExam(DiagramType.ClassDiagram, exam2.getExerciseGroups().get(0));
    exam2.getExerciseGroups().get(0).addExercise(modelingExercise);
    exerciseGroupRepository.save(exam2.getExerciseGroups().get(0));
    modelingExercise = exerciseRepo.save(modelingExercise);
    List<StudentExam> createdStudentExams = new ArrayList<>();
    // creating student exams
    for (User user : registeredUsers) {
        StudentExam studentExam = new StudentExam();
        studentExam.addExercise(modelingExercise);
        studentExam.setUser(user);
        exam2.addStudentExam(studentExam);
        createdStudentExams.add(studentExamRepository.save(studentExam));
    }
    exam2 = examRepository.save(exam2);
    // invoke start exercises
    Integer noGeneratedParticipations = request.postWithResponseBody("/api/courses/" + course1.getId() + "/exams/" + exam2.getId() + "/student-exams/start-exercises", Optional.empty(), Integer.class, HttpStatus.OK);
    assertThat(noGeneratedParticipations).isEqualTo(exam2.getStudentExams().size());
    List<Participation> studentParticipations = participationTestRepository.findAllWithSubmissions();
    for (Participation participation : studentParticipations) {
        assertThat(participation.getExercise()).isEqualTo(modelingExercise);
        assertThat(participation.getExercise().getCourseViaExerciseGroupOrCourseMember()).isNotNull();
        assertThat(participation.getExercise().getExerciseGroup()).isEqualTo(exam2.getExerciseGroups().get(0));
        assertThat(participation.getSubmissions()).hasSize(1);
        var textSubmission = (ModelingSubmission) participation.getSubmissions().iterator().next();
        assertThat(textSubmission.getModel()).isNull();
        assertThat(textSubmission.getExplanationText()).isNull();
    }
    // Cleanup of Bidirectional Relationships
    for (StudentExam studentExam : createdStudentExams) {
        exam2.removeStudentExam(studentExam);
    }
    examRepository.save(exam2);
}
Also used : Participation(de.tum.in.www1.artemis.domain.participation.Participation) StudentParticipation(de.tum.in.www1.artemis.domain.participation.StudentParticipation) WithMockUser(org.springframework.security.test.context.support.WithMockUser) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) StudentExam(de.tum.in.www1.artemis.domain.exam.StudentExam) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test)

Example 24 with ModelingSubmission

use of de.tum.in.www1.artemis.domain.modeling.ModelingSubmission in project ArTEMiS by ls1intum.

the class ExampleSubmissionIntegrationTest method importExampleSubmissionWithModelingSubmission_exerciseIdNotMatched.

@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void importExampleSubmissionWithModelingSubmission_exerciseIdNotMatched() throws Exception {
    Submission submission = ModelFactory.generateModelingSubmission(validModel, true);
    submission = database.addModelingSubmission(modelingExercise, (ModelingSubmission) submission, "student1");
    Exercise modelingExerciseToBeConflicted = new ModelingExercise();
    modelingExerciseToBeConflicted.setCourse(course);
    Exercise exercise = exerciseRepository.save(modelingExerciseToBeConflicted);
    importExampleSubmission(exercise.getId(), submission.getId(), HttpStatus.BAD_REQUEST);
}
Also used : ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 25 with ModelingSubmission

use of de.tum.in.www1.artemis.domain.modeling.ModelingSubmission in project ArTEMiS by ls1intum.

the class AssessmentKnowledgeIntegrationTest method testSetModelAssessmentKnowledgeToModelElements.

/**
 * Tests that a ModelAssessmentKnowledge is correctly set to model elements
 * based on the ModelAssessmentKnowledge of the respective exercise
 *
 * @throws Exception might be thrown from Network Call to Artemis API
 */
@Test
@WithMockUser(username = "instructor1", roles = "INSTRUCTOR")
public void testSetModelAssessmentKnowledgeToModelElements() throws Exception {
    ModelingSubmission submission1 = ModelFactory.generateModelingSubmission(FileUtils.loadFileFromResources("test-data/model-submission/model.54727.json"), true);
    submission1.setId(1L);
    ModelingSubmission submission2 = ModelFactory.generateModelingSubmission(FileUtils.loadFileFromResources("test-data/model-submission/model.54727.cpy.json"), true);
    submission2.setId(2L);
    ModelingSubmission submission3 = ModelFactory.generateModelingSubmission(FileUtils.loadFileFromResources("test-data/model-submission/model.54727.cpy.json"), true);
    submission3.setId(3L);
    ModelingSubmission submission4 = ModelFactory.generateModelingSubmission(FileUtils.loadFileFromResources("test-data/model-submission/model.54727.cpy.json"), true);
    submission4.setId(4L);
    Course course = database.addEmptyCourse();
    ModelingExercise exercise1 = modelingExerciseUtilService.createModelingExercise(course.getId());
    ModelingExercise exercise2 = modelingExerciseUtilService.createModelingExercise(course.getId());
    modelAssessmentKnowledgeService = new ModelAssessmentKnowledgeService(modelAssessmentKnowledgeRepository, modelingExerciseRepository);
    exercise1.setKnowledge(modelAssessmentKnowledgeService.createNewKnowledge());
    exercise2.setKnowledge(modelAssessmentKnowledgeService.createNewKnowledge());
    ModelClusterFactory modelClusterFactory = new ModelClusterFactory();
    List<ModelCluster> modelClusters1 = modelClusterFactory.buildClusters(List.of(submission1, submission2), exercise1);
    List<ModelCluster> modelClusters2 = modelClusterFactory.buildClusters(List.of(submission3, submission4), exercise2);
    ModelCluster modelCluster = modelClusters1.get(0);
    for (ModelElement element : modelCluster.getModelElements()) {
        assertThat(element.getKnowledge().getId()).isEqualTo(exercise1.getKnowledge().getId());
    }
    modelCluster = modelClusters2.get(0);
    for (ModelElement element : modelCluster.getModelElements()) {
        assertThat(element.getKnowledge().getId()).isEqualTo(exercise2.getKnowledge().getId());
    }
    assertThat(exercise1.getKnowledge().getId()).isNotEqualTo(exercise2.getKnowledge().getId());
}
Also used : ModelClusterFactory(de.tum.in.www1.artemis.service.compass.controller.ModelClusterFactory) ModelElement(de.tum.in.www1.artemis.domain.modeling.ModelElement) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) ModelAssessmentKnowledgeService(de.tum.in.www1.artemis.service.ModelAssessmentKnowledgeService) ModelCluster(de.tum.in.www1.artemis.domain.modeling.ModelCluster) Course(de.tum.in.www1.artemis.domain.Course) WithMockUser(org.springframework.security.test.context.support.WithMockUser) Test(org.junit.jupiter.api.Test)

Aggregations

ModelingSubmission (de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)160 Test (org.junit.jupiter.api.Test)108 WithMockUser (org.springframework.security.test.context.support.WithMockUser)106 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)36 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)22 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)20 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)16 ModelingPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult)16 TextPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult)12 JsonParser.parseString (com.google.gson.JsonParser.parseString)8 ModelCluster (de.tum.in.www1.artemis.domain.modeling.ModelCluster)8 ModelingSubmission (de.tum.in.www1.artemis.domain.ModelingSubmission)6 Result (de.tum.in.www1.artemis.domain.Result)6 ModelElement (de.tum.in.www1.artemis.domain.modeling.ModelElement)6 ModelClusterFactory (de.tum.in.www1.artemis.service.compass.controller.ModelClusterFactory)6 StudentExam (de.tum.in.www1.artemis.domain.exam.StudentExam)4 ExerciseHint (de.tum.in.www1.artemis.domain.hestia.ExerciseHint)4 Participation (de.tum.in.www1.artemis.domain.participation.Participation)4 PlagiarismComparison (de.tum.in.www1.artemis.domain.plagiarism.PlagiarismComparison)4 PlagiarismSubmission (de.tum.in.www1.artemis.domain.plagiarism.PlagiarismSubmission)4