Skip to content

Commit

Permalink
Release v1.0.3 (#12) (#13)
Browse files Browse the repository at this point in the history
* [Refactor] Memory optimizing with OOP Refactoring (#11)

* [Refactor] Apply Flyweight Pattern for UI Memory Optimization

- Components in EditorPanel uses same instance, such as `JLabel` and `JBorder`
- These components are immutable objects, so by creating one and sharing it, we can save memory.
- So, I apply Flyweight pattern

* [Refactor] Seperate Component with responsibility

- according to Single Responsibility Principle in `Object Oriented Programming Principles`, They must have only their responsibility.

- so seperate responsibility and Use IOC&DI with interface

* [Feat] Add `remove all action`

* [Refactor] Remove ToolbarPanel Dependency in mainViewPanel

In mainView, toolbarPanel is not neccessary. so remove it.

* [Refactor] Change ThreadStore's Creational Patterns, Singleton to Normal Object

for making tests easier

* [Refactor] Restructure to Enable DI in ToolWindowFactory and Remove Singleton Pattern

* [Test] Add Action Tests

- AddTest
- RemoveAllTest
- RemoveTest
- RunAllTest
- RunTest
- StopAllTest

* [Refactor] Remove dependencies each editor components from EditorPanel using interface and abstract class

* [Test] Adding EditorPanel tests

* [Test] Adding MyTestList tests

* [Refactor] Remove dependencies subTestList from TestListPanel using interface and abstract class

* [Test] Adding TestListPanel tests

* [Test] Adding MainView tests

---------

Signed-off-by: Hyeon-Uk <[email protected]>
  • Loading branch information
Hyeon-Uk authored May 11, 2024
1 parent fee975b commit b4438e4
Show file tree
Hide file tree
Showing 60 changed files with 2,582 additions and 519 deletions.
76 changes: 39 additions & 37 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,61 +1,63 @@
plugins {
id("java")
id("org.jetbrains.kotlin.jvm") version "1.9.0"
id("org.jetbrains.intellij") version "1.15.0"
id("java")
id("org.jetbrains.kotlin.jvm") version "1.9.0"
id("org.jetbrains.intellij") version "1.15.0"
}

group = "com.example"
version = "1.0.2"

repositories {
mavenCentral()
mavenCentral()
}

// Configure Gradle IntelliJ Plugin
// Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
intellij {
version.set("2022.2.5")
type.set("IC") // Target IDE Platform
version.set("2022.2.5")
type.set("IC") // Target IDE Platform

plugins.set(listOf("com.intellij.java","org.jetbrains.plugins.terminal"))
plugins.set(listOf("com.intellij.java", "org.jetbrains.plugins.terminal"))
}

dependencies{
dependencies {
// implementation("junit:junit:4.13.2")
// testImplementation("junit:junit:4.13.2")
// testImplementation("org.mockito:mockito-core:3.4.6")
// testImplementation("org.powermock:powermock-module-junit4:2.0.9")
// testImplementation("org.powermock:powermock-api-mockito2:2.0.9")
testImplementation("org.mockito:mockito-junit-jupiter:5.8.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
testImplementation("org.mockito:mockito-junit-jupiter:5.8.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
// https://mvnrepository.com/artifact/org.mockito/mockito-inline
testImplementation("org.mockito:mockito-inline:5.2.0")
}

tasks {
// Set the JVM compatibility versions
withType<JavaCompile> {
sourceCompatibility = "17"
targetCompatibility = "17"
}
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions.jvmTarget = "17"
}

patchPluginXml {
sinceBuild.set("222")
untilBuild.set("232.*")
}

signPlugin {
certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
privateKey.set(System.getenv("PRIVATE_KEY"))
password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
}

publishPlugin {
token.set(System.getenv("PUBLISH_TOKEN"))
}
test {
useJUnitPlatform()
}
// Set the JVM compatibility versions
withType<JavaCompile> {
sourceCompatibility = "17"
targetCompatibility = "17"
}
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions.jvmTarget = "17"
}

patchPluginXml {
sinceBuild.set("222")
untilBuild.set("232.*")
}

signPlugin {
certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
privateKey.set(System.getenv("PRIVATE_KEY"))
password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
}

publishPlugin {
token.set(System.getenv("PUBLISH_TOKEN"))
}
test {
useJUnitPlatform()
}
}
81 changes: 76 additions & 5 deletions src/main/java/com/example/pssupporter/MyToolWindowFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,103 @@

package com.example.pssupporter;

import com.example.pssupporter.ui.MyMainView;
import com.example.pssupporter.actions.*;
import com.example.pssupporter.ui.editor.EditorPanel;
import com.example.pssupporter.ui.editor.MyEditorPanel;
import com.example.pssupporter.ui.editor.panel.*;
import com.example.pssupporter.ui.list.MyCellRenderer;
import com.example.pssupporter.ui.list.MySubTestList;
import com.example.pssupporter.ui.list.MyTestListPanel;
import com.example.pssupporter.ui.list.TestListPanel;
import com.example.pssupporter.ui.main.MyMainView;
import com.example.pssupporter.ui.toolbar.MyToolbarPanel;
import com.example.pssupporter.utils.thread.MyThreadStore;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;

public class MyToolWindowFactory implements ToolWindowFactory {
private MyMainView myMainView;
private TestListPanel myTestListPanel;
private EditorPanel myEditorPanel;
private MyToolbarPanel myToolbarPanel;
private MyThreadStore myThreadStore;

private MyThreadStore createThreadStore() {
return new MyThreadStore();
}

private void createActionGroup() {
DefaultActionGroup myActionGroup = new DefaultActionGroup();
myActionGroup.add(new MyLoadTestDataAction(myThreadStore));
myActionGroup.add(new MyAddTestAction(myTestListPanel, myThreadStore));
myActionGroup.add(new MyRemoveTestAction(myTestListPanel, myEditorPanel, myThreadStore));
myActionGroup.add(new MyRemoveAllTestAction(myTestListPanel, myEditorPanel, myThreadStore));
myActionGroup.add(new MyRunAllTestsAction(myTestListPanel, myEditorPanel, myMainView, myThreadStore));
myActionGroup.add(new MyRunTestAction(myTestListPanel, myEditorPanel, myMainView, myThreadStore));
myActionGroup.add(new MyStopAllTestsAction(myTestListPanel, myThreadStore));

ActionManager actionManager = ActionManager.getInstance();
actionManager.registerAction("myActionGroup", myActionGroup);
}

private ActionGroup getActionGroup(String actionGroupId) {
ActionManager actionManager = ActionManager.getInstance();
return (ActionGroup) actionManager.getAction(actionGroupId);
}

private MyToolbarPanel createToolbarPanel(JComponent targetComponent, String actionId) {
ActionGroup action = getActionGroup(actionId);
return new MyToolbarPanel(action, targetComponent);
}

private TestListPanel createTestListPanel() {
MySubTestList mySubTestList = new MySubTestList(new MyCellRenderer());
return new MyTestListPanel(mySubTestList, (e) -> myMainView.changeTestData());
}

private EditorPanel createEditorPanel() {
InputEditorPanel inputEditorPanel = new MyInputEditorPanel();
OutputEditorPanel outputEditorPanel = new MyOutputEditorPanel();
ResultEditorPanel resultEditorPanel = new MyResultEditorPanel();
return new MyEditorPanel(inputEditorPanel, outputEditorPanel, resultEditorPanel);
}

@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
ApplicationManager.getApplication().invokeLater(() -> {
ContentManager contentManager = toolWindow.getContentManager();
ContentFactory contentFactory = ContentFactory.getInstance();
myTestListPanel = createTestListPanel();
myEditorPanel = createEditorPanel();
myMainView = new MyMainView(myTestListPanel, myEditorPanel, toolWindow.getAnchor().isHorizontal());

myThreadStore = createThreadStore();
createActionGroup();
myToolbarPanel = createToolbarPanel(myMainView, "myActionGroup");

JBPanel totalView = new JBPanel(new BorderLayout());
totalView.add(myToolbarPanel, BorderLayout.NORTH);
totalView.add(myMainView, BorderLayout.CENTER);

myMainView = new MyMainView(project, toolWindow.getAnchor().isHorizontal());
ContentFactory contentFactory = ContentFactory.getInstance();
ContentManager contentManager = toolWindow.getContentManager();

Content content = contentFactory.createContent(myMainView, "Supporter", false);
Content content = contentFactory.createContent(totalView, "Supporter", false);

contentManager.addContent(content);
setupToolWindowEventListener(project);
Expand Down
20 changes: 14 additions & 6 deletions src/main/java/com/example/pssupporter/actions/MyAddTestAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,34 @@

package com.example.pssupporter.actions;

import com.example.pssupporter.ui.MyTestListPanel;
import com.example.pssupporter.utils.ComponentManager;
import com.example.pssupporter.utils.thread.GlobalThreadStore;
import com.example.pssupporter.ui.list.TestListPanel;
import com.example.pssupporter.utils.thread.MyThreadStore;
import com.example.pssupporter.utils.thread.vo.ThreadGroupName;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;

public class MyAddTestAction extends AnAction {
private final TestListPanel myTestListPanel;
private final MyThreadStore myThreadStore;

public MyAddTestAction(TestListPanel myTestListPanel, MyThreadStore myThreadStore) {
super("Add Test Data", "This action can add Test", AllIcons.General.Add);
this.myTestListPanel = myTestListPanel;
this.myThreadStore = myThreadStore;
}

@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
boolean isRunning = GlobalThreadStore.getInstance()
boolean isRunning = myThreadStore
.hasRunningThreads(ThreadGroupName.TEST_RUNNING);
e.getPresentation().setEnabled(!isRunning);
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
MyTestListPanel myTestListPanel = ComponentManager.getInstance().getComponent("myTestListPanel", MyTestListPanel.class);
myTestListPanel.addTest();
myTestListPanel.addTestData();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,32 @@

package com.example.pssupporter.actions;

import com.example.pssupporter.ui.MyTestListPanel;
import com.example.pssupporter.utils.ComponentManager;
import com.example.pssupporter.utils.StringUtils;
import com.example.pssupporter.utils.crawling.CrawlerProvider;
import com.example.pssupporter.utils.crawling.vo.Site;
import com.example.pssupporter.utils.thread.GlobalThreadStore;
import com.example.pssupporter.utils.thread.MyThreadStore;
import com.example.pssupporter.utils.thread.vo.ThreadGroupName;
import com.example.pssupporter.vo.TestData;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class MyLoadTestDataAction extends AnAction {
private final MyThreadStore myThreadStore;

public MyLoadTestDataAction(MyThreadStore myThreadStore) {
super("Load Test DataSets", "This action can load test data sets", AllIcons.Actions.Find);
this.myThreadStore = myThreadStore;
}

@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
boolean isRunning = GlobalThreadStore.getInstance()
boolean isRunning = myThreadStore
.hasRunningThreads(ThreadGroupName.TEST_RUNNING);
e.getPresentation().setEnabled(!isRunning);
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Messages.showMessageDialog("Currently, this feature is not available because Baekjun has banned scraping.\nReference : <a href=\"https://help.acmicpc.net/rule\">BOJ Homepage</a>","Caution", AllIcons.Actions.Exit);
return;
// MyTestListPanel myTestListPanel = ComponentManager.getInstance().getComponent("myTestListPanel", MyTestListPanel.class);
// String selected = Messages.showInputDialog(e.getProject(), "Input Baekjoon number", "Load Test Data", null);
// if (!StringUtils.isBlank(selected)) {
// ComponentManager.getInstance().removeChildrenComponentsByName("myEditorPanel");
//
// try {
// long number = Long.parseLong(selected);
// List<TestData> examples = CrawlerProvider.getCrawler(Site.BAEKJOON_OJ).getExamples(number);
//
// myTestListPanel.removeAllTests();
//
// for (TestData testData : examples) {
// myTestListPanel.addTest(testData);
// }
//
// } catch (NumberFormatException ne) {
// Messages.showMessageDialog(e.getProject(), "Input number!", "Load Test Error", null);
// }
// }
Messages.showMessageDialog("Currently, this feature is not available because Baekjun has banned scraping.\nReference : <a href=\"https://help.acmicpc.net/rule\">BOJ Homepage</a>", "Caution", AllIcons.Actions.Exit);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package com.example.pssupporter.actions;

import com.example.pssupporter.ui.editor.EditorPanel;
import com.example.pssupporter.ui.list.TestListPanel;
import com.example.pssupporter.utils.thread.MyThreadStore;
import com.example.pssupporter.utils.thread.vo.ThreadGroupName;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.jetbrains.annotations.NotNull;

public class MyRemoveAllTestAction extends AnAction {
private final TestListPanel myTestListPanel;
private final EditorPanel myEditorPanel;
private final MyThreadStore myThreadStore;

public MyRemoveAllTestAction(TestListPanel myTestListPanel, EditorPanel myEditorPanel, MyThreadStore myThreadStore) {
super("Remove All Test DataSets", "This action can remove all test data sets", AllIcons.Actions.GC);
this.myTestListPanel = myTestListPanel;
this.myEditorPanel = myEditorPanel;
this.myThreadStore = myThreadStore;
}

@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
boolean isRunning = myThreadStore
.hasRunningThreads(ThreadGroupName.TEST_RUNNING);
e.getPresentation().setEnabled(!isRunning);
}

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
myEditorPanel.clearAll();
myTestListPanel.removeAllTestDatas();
}
}
Loading

0 comments on commit b4438e4

Please sign in to comment.