Skip to content

Commit

Permalink
Major refactor, including update to Java 21, new IntelliJ Gradle Plug…
Browse files Browse the repository at this point in the history
…in, single-workspace model, and Artemis4j 2.0
  • Loading branch information
Feuermagier committed Sep 11, 2024
1 parent 10944ac commit fa4696d
Show file tree
Hide file tree
Showing 39 changed files with 1,190 additions and 1,732 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,5 @@ gradle-app.setting
# example project that is opened by the test IntelliJ instance
exampleProject/

grading-config-example.json
grading-config-example.json
.intellijPlatform/
24 changes: 22 additions & 2 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 24 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,33 +1,50 @@
// See https://github.com/JetBrains/gradle-intellij-plugin/
plugins {
id 'org.jetbrains.intellij' version '1.17.4'
id("org.jetbrains.intellij.platform") version "2.0.1"
id 'java'
id 'com.diffplug.spotless' version '6.25.0'
}

group 'edu.kit.kastel.sdq'
version '1.0-SNAPSHOT'

java {
sourceCompatibility = "21"
targetCompatibility = "21"
}

repositories {
mavenCentral()
mavenLocal()
mavenCentral()
intellijPlatform {
defaultRepositories()
}
}

dependencies {
implementation 'edu.kit.kastel.sdq:artemis4j:6.7.5'
intellijPlatform {
intellijIdeaCommunity('2024.2.1')
pluginVerifier()
bundledPlugin("com.intellij.java")
bundledPlugin("org.jetbrains.idea.maven")
instrumentationTools()
}
implementation 'edu.kit.kastel.sdq:artemis4j:7.4.3-SNAPSHOT'
implementation 'org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r'
implementation 'org.apache.commons:commons-io:1.3.2'
implementation 'de.firemage.autograder:autograder-cmd:' + AUTOGRADER_VERION
implementation 'de.firemage.autograder:autograder-core:' + AUTOGRADER_VERION
implementation 'de.firemage.autograder:autograder-extra:' + AUTOGRADER_VERION

// Tests
testImplementation 'org.junit.jupiter:junit-jupiter-api:' + JUNIT_VERSION
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:' + JUNIT_VERSION
}

intellij {
version = '2024.1.4'
plugins = ['com.intellij.java']
intellijPlatform {
pluginConfiguration {
name = "IntelliGrade"
}
}
patchPluginXml {
changeNotes = """"""
Expand All @@ -38,7 +55,7 @@ test {

tasks {
runIde {
autoReloadPlugins = true
autoReload = true
}

buildSearchableOptions {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
/* Licensed under EPL-2.0 2024. */
package edu.kit.kastel.actions.edu.kit.kastel.actions;

import java.util.List;
import java.util.Locale;

import com.intellij.DynamicBundle;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import edu.kit.kastel.sdq.artemis4j.api.grading.IMistakeType;
import edu.kit.kastel.state.AssessmentModeHandler;
import edu.kit.kastel.utils.AnnotationUtils;
import edu.kit.kastel.wrappers.DisplayableMistakeType;
import com.intellij.ui.components.JBLabel;
import edu.kit.kastel.sdq.artemis4j.grading.penalty.MistakeType;
import edu.kit.kastel.state.PluginState;
import org.jetbrains.annotations.NotNull;

public class AddAnnotationPopupAction extends AnAction {
private static final Locale LOCALE = DynamicBundle.getLocale();

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
Expand All @@ -29,42 +30,37 @@ public void update(@NotNull AnActionEvent e) {
// if no exercise config is loaded, we cannot make annotations
// if there is no caret we can not sensibly display a popup
e.getPresentation()
.setEnabledAndVisible(caret != null
&& AssessmentModeHandler.getInstance()
.getCurrentExerciseConfig()
.isPresent());
.setEnabledAndVisible(caret != null && PluginState.getInstance().isAssessing());
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {

Caret caret = e.getData(CommonDataKeys.CARET);

// if no exercise config is loaded, we cannot make annotations
// if there is no caret we can not sensibly display a popup
if (caret == null
|| AssessmentModeHandler.getInstance()
.getCurrentExerciseConfig()
.isEmpty()) {
if (caret == null | !PluginState.getInstance().isAssessing()) {
return;
}

// collect all mistake types that can be annotated
List<IMistakeType> mistakeTypes =
AssessmentModeHandler.getInstance().getCurrentExerciseConfig().get().getRatingGroups().stream()
.flatMap(ratingGroup -> ratingGroup.getMistakeTypes().stream())
.toList();
var mistakeTypes = PluginState.getInstance()
.getActiveAssessment()
.orElseThrow()
.getGradingConfig()
.getMistakeTypes();

// create a popup with all possible mistakes
JBPopupFactory.getInstance()
.createPopupChooserBuilder(
mistakeTypes.stream().map(DisplayableMistakeType::new).toList())
.createPopupChooserBuilder(mistakeTypes)
.setRenderer((list, mistakeType, index, isSelected, cellHasFocus) ->
new JBLabel(mistakeType.getButtonText().translateTo(LOCALE)))
.setItemChosenCallback(this::addQuickAnnotation)
.createPopup()
.showInBestPositionFor(caret.getEditor());
}

private void addQuickAnnotation(@NotNull DisplayableMistakeType mistakeType) {
AnnotationUtils.addAnnotationByMistakeType(mistakeType.getWrappedValue());
private void addQuickAnnotation(@NotNull MistakeType mistakeType) {
PluginState.getInstance().getActiveAssessment().orElseThrow().addAnnotationAtCaret(mistakeType, false);
}
}
12 changes: 0 additions & 12 deletions src/main/java/edu/kit/kastel/exceptions/ImplementationMissing.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.swing.table.AbstractTableModel;

import com.intellij.DynamicBundle;
import edu.kit.kastel.sdq.artemis4j.grading.model.annotation.Annotation;
import edu.kit.kastel.utils.AssessmentUtils;
import edu.kit.kastel.sdq.artemis4j.grading.Annotation;
import edu.kit.kastel.state.PluginState;
import edu.kit.kastel.wrappers.AnnotationWithTextSelection;

/**
* The table model for the annotations table.
*/
public class AnnotationsTableModel extends AbstractTableModel {

private static final String[] HEADINGS = {
"Mistake type", "Start Line", "End Line", "File", "Message", "Custom Penalty"
};
private static final String[] HEADINGS = {"Mistake type", "Line(s)", "File", "Source", "Message", "Custom Penalty"};

private static final String LOCALE = DynamicBundle.getLocale().getLanguage();
private static final Locale LOCALE = DynamicBundle.getLocale();

private final List<AnnotationWithTextSelection> annotations = new ArrayList<>();

Expand All @@ -41,45 +40,48 @@ public String getColumnName(int column) {

@Override
public Object getValueAt(int i, int i1) {
Annotation queriedAnnotation = annotations.get(i);
Annotation annotation = annotations.get(i).annotation();

if (queriedAnnotation == null) {
if (annotation == null) {
return "";
}

return switch (i1) {
case 0 -> queriedAnnotation.getMistakeType().getButtonText(LOCALE);
case 1 -> queriedAnnotation.getStartLine();
case 2 -> queriedAnnotation.getEndLine();
case 3 -> queriedAnnotation.getClassFilePath();
case 4 -> queriedAnnotation.getCustomMessage().orElse("");
case 5 -> queriedAnnotation.getCustomPenalty().orElse(0.0);
case 0 -> annotation.getMistakeType().getButtonText().translateTo(LOCALE);
case 1 -> formatLines(annotation);
case 2 -> annotation.getFilePath();
case 3 -> annotation.getSource();
case 4 -> annotation.getCustomMessage().orElse("");
case 5 -> annotation.getCustomScore().orElse(0.0);
default -> {
System.err.printf("No table data at index %d:%d\n", i, i1);
yield "n.A.";
}
};
}

/**
* Add an annotation to the Table model.
*
* @param annotation the Annotation to be added
*/
public void addAnnotation(AnnotationWithTextSelection annotation) {
this.annotations.add(annotation);
public void setAnnotations(List<AnnotationWithTextSelection> annotations) {
this.annotations.clear();
this.annotations.addAll(annotations);
}

public void clearAnnotations() {
this.annotations.clear();
}

/**
* Delete an annotation with a specified index from the Table, its model and the AnnotationManager
*
* @param itemIndex the index of the item to be deleted TODO: not necesarrily the same as
* the selected item if a TableSorter is used. Implement sorting.
*/
public void deleteItem(int itemIndex) {
AnnotationWithTextSelection annotation = this.annotations.get(itemIndex);
annotation.deleteHighlighter();
AssessmentUtils.deleteAnnotation(annotation);
this.annotations.remove(annotation);
PluginState.getInstance().getActiveAssessment().orElseThrow().deleteAnnotation(annotation);
}

private String formatLines(Annotation annotation) {
int startLine = annotation.getStartLine() + 1;
int endLine = annotation.getEndLine() + 1;

if (startLine == endLine) {
return String.valueOf(startLine);
} else {
return String.format("%d - %d", startLine, endLine);
}
}
}
Loading

0 comments on commit fa4696d

Please sign in to comment.