diff --git a/README.md b/README.md index 8578a7c..e1fe6fb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Reset Your IDE Eval Information -1. Download and install plugin from [Download Link](https://plugins.zhile.io/files/ide-eval-resetter-2.1.3.zip). +1. Download and install plugin from [Download Link](https://plugins.zhile.io/files/ide-eval-resetter-2.1.5.zip). * Alternative installation method: * Add "Custom Plugin Repository": `https://plugins.zhile.io` manually (`Settings/Preferences` -> `Plugins`) * Search and install plugin: `IDE Eval Reset` diff --git a/build.gradle b/build.gradle index eb01083..9a059f0 100644 --- a/build.gradle +++ b/build.gradle @@ -4,10 +4,10 @@ plugins { } group 'io.zhile.research.intellij' -version '2.1.4' +version '2.1.5' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 1.7 +targetCompatibility = 1.7 repositories { mavenCentral() @@ -29,6 +29,8 @@ intellij { patchPluginXml { changeNotes """
+Release v2.1.5
+  1. fix memory leak
 Release v2.1.4
   1. fix reference
 Release v2.1.3
diff --git a/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java b/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java
index b1eac47..8cfa8b0 100644
--- a/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java
+++ b/src/main/java/io/zhile/research/intellij/ier/action/ResetAction.java
@@ -16,7 +16,6 @@ import io.zhile.research.intellij.ier.component.ResetTimer;
 import io.zhile.research.intellij.ier.helper.Constants;
 import io.zhile.research.intellij.ier.helper.CustomRepository;
 import io.zhile.research.intellij.ier.helper.PluginHelper;
-import io.zhile.research.intellij.ier.helper.ProjectHelper;
 import io.zhile.research.intellij.ier.tw.MainToolWindowFactory;
 import io.zhile.research.intellij.ier.ui.dialog.MainDialog;
 import org.jetbrains.annotations.NotNull;
@@ -35,7 +34,7 @@ public class ResetAction extends AnAction implements DumbAware {
 
     @Override
     public void actionPerformed(@NotNull AnActionEvent e) {
-        Project project = ProjectHelper.getProject(e);
+        Project project = e.getProject();
 
         Notification notification = NOTIFICATION_KEY.getData(e.getDataContext());
         if (null != notification) {
diff --git a/src/main/java/io/zhile/research/intellij/ier/action/RestartAction.java b/src/main/java/io/zhile/research/intellij/ier/action/RestartAction.java
index 6bdec23..77433da 100644
--- a/src/main/java/io/zhile/research/intellij/ier/action/RestartAction.java
+++ b/src/main/java/io/zhile/research/intellij/ier/action/RestartAction.java
@@ -14,6 +14,11 @@ public class RestartAction extends AnAction implements DumbAware {
 
     @Override
     public void actionPerformed(@NotNull AnActionEvent e) {
-        ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().restart());
+        ApplicationManager.getApplication().invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                ApplicationManager.getApplication().restart();
+            }
+        });
     }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/common/Resetter.java b/src/main/java/io/zhile/research/intellij/ier/common/Resetter.java
index 3c4f3af..451e006 100644
--- a/src/main/java/io/zhile/research/intellij/ier/common/Resetter.java
+++ b/src/main/java/io/zhile/research/intellij/ier/common/Resetter.java
@@ -8,13 +8,13 @@ import com.intellij.openapi.util.SystemInfo;
 import io.zhile.research.intellij.ier.helper.Constants;
 import io.zhile.research.intellij.ier.helper.NotificationHelper;
 import io.zhile.research.intellij.ier.helper.ReflectionHelper;
+import org.jdom.Attribute;
 import org.jdom.Element;
 
 import java.io.File;
 import java.lang.reflect.Method;
 import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.prefs.BackingStoreException;
 import java.util.prefs.Preferences;
@@ -33,27 +33,40 @@ public class Resetter {
 
         File evalDir = getEvalDir();
         if (evalDir.exists()) {
-            File[] files = evalDir.listFiles((dir, name) -> name.endsWith(".key"));
+            File[] files = evalDir.listFiles();
             if (files == null) {
                 NotificationHelper.showError(null, "List eval license file failed!");
             } else {
-                Arrays.stream(files).forEach(file -> list.add(new LicenseFileRecord(file)));
+                for (File file : files) {
+                    if (!file.getName().endsWith(".key")) {
+                        continue;
+                    }
+
+                    list.add(new LicenseFileRecord(file));
+                }
             }
         }
 
         Element state = PropertyRecord.PROPS.getState();
         if (state != null) {
-            state.getChildren().stream().filter(element -> {
+            Attribute attrName, attrValue;
+            for (Element element : state.getChildren()) {
                 if (!element.getName().equals("property")) {
-                    return false;
+                    continue;
                 }
 
-                if (element.getAttribute("name") == null || element.getAttribute("value") == null) {
-                    return false;
+                attrName = element.getAttribute("name");
+                attrValue = element.getAttribute("value");
+                if (attrName == null || attrValue == null) {
+                    continue;
                 }
 
-                return element.getAttribute("name").getValue().startsWith(EVAL_KEY);
-            }).forEach(element -> list.add(new PropertyRecord(element.getAttribute("name").getValue())));
+                if (!attrName.getValue().startsWith(EVAL_KEY)) {
+                    continue;
+                }
+
+                list.add(new PropertyRecord(attrName.getValue()));
+            }
         }
 
         PreferenceRecord[] prefsValue = new PreferenceRecord[]{
@@ -61,7 +74,13 @@ public class Resetter {
                 new PreferenceRecord(NEW_MACHINE_ID_KEY),
                 new PreferenceRecord(DEVICE_ID_KEY),
         };
-        Arrays.stream(prefsValue).filter(record -> record.getValue() != null).forEach(list::add);
+        for (PreferenceRecord record : prefsValue) {
+            if (record.getValue() == null) {
+                continue;
+            }
+
+            list.add(record);
+        }
 
         try {
             List prefsList = new ArrayList<>();
@@ -79,12 +98,16 @@ public class Resetter {
                 }
             }
 
-            prefsList.stream().filter(key -> key.contains(EVAL_KEY)).forEach(key -> {
+            for (String key : prefsList) {
+                if (!key.contains(EVAL_KEY)) {
+                    continue;
+                }
+
                 if (key.startsWith("/")) {
                     key = key.substring(1).replace('/', '.');
                 }
                 list.add(new PreferenceRecord(key));
-            });
+            }
         } catch (Exception e) {
             NotificationHelper.showError(null, "List eval preferences failed!");
         }
@@ -103,7 +126,9 @@ public class Resetter {
     }
 
     public static void reset(List records) {
-        records.forEach(Resetter::reset);
+        for (EvalRecord record : records) {
+            Resetter.reset(record);
+        }
     }
 
     public static void reset(EvalRecord record) {
diff --git a/src/main/java/io/zhile/research/intellij/ier/component/ResetTimer.java b/src/main/java/io/zhile/research/intellij/ier/component/ResetTimer.java
index 26d8288..b299f5f 100644
--- a/src/main/java/io/zhile/research/intellij/ier/component/ResetTimer.java
+++ b/src/main/java/io/zhile/research/intellij/ier/component/ResetTimer.java
@@ -5,22 +5,26 @@ import com.intellij.ide.Prefs;
 import com.intellij.notification.Notification;
 import com.intellij.notification.NotificationType;
 import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.application.ApplicationActivationListener;
 import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.util.concurrency.AppExecutorUtil;
+import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.util.messages.MessageBusConnection;
+import io.zhile.research.intellij.ier.action.ResetAction;
 import io.zhile.research.intellij.ier.action.RestartAction;
 import io.zhile.research.intellij.ier.common.Resetter;
-import io.zhile.research.intellij.ier.helper.*;
+import io.zhile.research.intellij.ier.helper.Constants;
+import io.zhile.research.intellij.ier.helper.DateTime;
+import io.zhile.research.intellij.ier.helper.NotificationHelper;
+import io.zhile.research.intellij.ier.helper.PluginHelper;
 import io.zhile.research.intellij.ier.listener.AppEventListener;
 
 import java.lang.ref.WeakReference;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
 
 public class ResetTimer {
     private static final long RESET_PERIOD = 2160000000L; // 25 days
     private static final String RESET_KEY = Constants.PLUGIN_PREFS_PREFIX + "." + Constants.IDE_NAME_LOWER + "." + Constants.IDE_HASH;
 
-    private static ScheduledFuture scheduledFuture;
+    private static MessageBusConnection connection;
 
     public static long getLastResetTime() {
         return Prefs.getLong(RESET_KEY, 0L);
@@ -37,39 +41,56 @@ public class ResetTimer {
         return lastResetTime > 0 ? DateTime.getStringFromTimestamp(lastResetTime) : "Not yet";
     }
 
-    public synchronized static void start(final WeakReference weakResetAction) {
-        if (scheduledFuture != null) {
+    public synchronized static void start(final WeakReference weakResetAction) {
+        if (connection != null) {
             return;
         }
 
         ApplicationManager.getApplication().getMessageBus().connect().subscribe(AppLifecycleListener.TOPIC, new AppEventListener());
-        scheduledFuture = AppExecutorUtil.getAppScheduledExecutorService().scheduleWithFixedDelay(() -> {
-            if (System.currentTimeMillis() - getLastResetTime() <= RESET_PERIOD) {
-                return;
+
+        connection = ApplicationManager.getApplication().getMessageBus().connect();
+        connection.subscribe(ApplicationActivationListener.TOPIC, new ApplicationActivationListener() {
+            public void applicationActivated(IdeFrame ideFrame) {
+                if (System.currentTimeMillis() - getLastResetTime() <= RESET_PERIOD) {
+                    return;
+                }
+
+                stop();
+
+                AnAction resetAction = weakResetAction.get();
+                if (resetAction == null) {
+                    return;
+                }
+
+                AnAction action = resetAction;
+                NotificationType type = NotificationType.INFORMATION;
+                String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
+                if (Resetter.isAutoReset()) {
+                    action = new RestartAction();
+                    type = NotificationType.WARNING;
+                }
+
+                Notification notification = NotificationHelper.NOTIFICATION_GROUP.createNotification(PluginHelper.getPluginName(), null, message, type);
+                notification.addAction(action);
+                notification.notify(null);
             }
 
-            stop();
-
-            AnAction resetAction = weakResetAction.get();
-            if (resetAction == null) {
-                return;
+            public void applicationDeactivated(IdeFrame ideFrame) {
+                applicationActivated(ideFrame);
             }
 
-            AnAction action = Resetter.isAutoReset() ? new RestartAction() : resetAction;
-            String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
-            Notification notification = NotificationHelper.NOTIFICATION_GROUP.createNotification(PluginHelper.getPluginName(), null, message, NotificationType.INFORMATION);
-            notification.addAction(action);
+            public void delayedApplicationDeactivated(IdeFrame ideFrame) {
 
-            notification.notify(ProjectHelper.getCurrentProject());
-        }, 3, 600, TimeUnit.SECONDS);
+            }
+        });
     }
 
     public synchronized static void stop() {
-        if (scheduledFuture == null || scheduledFuture.isCancelled()) {
+        if (connection == null) {
             return;
         }
 
-        scheduledFuture.cancel(false);
-        scheduledFuture = null;
+        connection.disconnect();
+        connection = null;
     }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/helper/CustomRepository.java b/src/main/java/io/zhile/research/intellij/ier/helper/CustomRepository.java
index 75c3086..025caf7 100644
--- a/src/main/java/io/zhile/research/intellij/ier/helper/CustomRepository.java
+++ b/src/main/java/io/zhile/research/intellij/ier/helper/CustomRepository.java
@@ -11,8 +11,10 @@ public class CustomRepository {
 
     public static void checkAndAdd(@NotNull String host) {
         List hosts = UpdateSettings.getInstance().getStoredPluginHosts();
-        if (hosts.stream().anyMatch(s -> s.equalsIgnoreCase(host))) {
-            return;
+        for (String s : hosts) {
+            if (s.equalsIgnoreCase(host)) {
+                return;
+            }
         }
 
         hosts.add(host);
diff --git a/src/main/java/io/zhile/research/intellij/ier/helper/ProjectHelper.java b/src/main/java/io/zhile/research/intellij/ier/helper/ProjectHelper.java
deleted file mode 100644
index cccac7e..0000000
--- a/src/main/java/io/zhile/research/intellij/ier/helper/ProjectHelper.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package io.zhile.research.intellij.ier.helper;
-
-import com.intellij.ide.DataManager;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-
-public class ProjectHelper {
-    public static Project getCurrentProject() {
-        if (ProjectManager.getInstance().getOpenProjects().length == 0) {
-            return null;
-        }
-
-        DataContext dataContext = DataManager.getInstance().getDataContextFromFocus().getResultSync();
-        return CommonDataKeys.PROJECT.getData(dataContext);
-    }
-
-    public static Project getProject(AnActionEvent e) {
-        Project project = e.getProject();
-
-        if (project == null) {
-            return getCurrentProject();
-        }
-
-        return project;
-    }
-}
diff --git a/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java b/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java
index fd9e7c9..4178fc3 100644
--- a/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java
+++ b/src/main/java/io/zhile/research/intellij/ier/listener/PluginListener.java
@@ -3,12 +3,8 @@ package io.zhile.research.intellij.ier.listener;
 import com.intellij.ide.plugins.DynamicPluginListener;
 import com.intellij.ide.plugins.IdeaPluginDescriptor;
 import com.intellij.openapi.actionSystem.ActionManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.wm.ToolWindowManager;
-import io.zhile.research.intellij.ier.component.ResetTimer;
-import io.zhile.research.intellij.ier.helper.Constants;
 import io.zhile.research.intellij.ier.helper.NotificationHelper;
-import io.zhile.research.intellij.ier.helper.ProjectHelper;
+import io.zhile.research.intellij.ier.tw.MainToolWindowFactory;
 import org.jetbrains.annotations.NotNull;
 
 public class PluginListener implements DynamicPluginListener {
@@ -21,13 +17,6 @@ public class PluginListener implements DynamicPluginListener {
 
     @Override
     public void beforePluginUnload(@NotNull IdeaPluginDescriptor pluginDescriptor, boolean isUpdate) {
-        ResetTimer.stop();
-
-        Project project = ProjectHelper.getCurrentProject();
-        if (project == null) {
-            return;
-        }
-
-        ToolWindowManager.getInstance(project).unregisterToolWindow(Constants.ACTION_NAME);
+        MainToolWindowFactory.unregisterAll();
     }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java b/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java
index 2fc42c9..ad0ca04 100644
--- a/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java
+++ b/src/main/java/io/zhile/research/intellij/ier/tw/MainToolWindowFactory.java
@@ -2,10 +2,13 @@ package io.zhile.research.intellij.ier.tw;
 
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.openapi.wm.ToolWindowFactory;
+import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.ui.content.Content;
 import com.intellij.ui.content.ContentFactory;
+import io.zhile.research.intellij.ier.helper.Constants;
 import io.zhile.research.intellij.ier.ui.form.MainForm;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,4 +19,10 @@ public class MainToolWindowFactory implements ToolWindowFactory, DumbAware {
         Content content = ContentFactory.SERVICE.getInstance().createContent(mainForm.getContent(), "", true);
         toolWindow.getContentManager().addContent(content);
     }
+
+    public static void unregisterAll() {
+        for (Project project : ProjectManager.getInstance().getOpenProjects()) {
+            ToolWindowManager.getInstance(project).unregisterToolWindow(Constants.ACTION_NAME);
+        }
+    }
 }
diff --git a/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java b/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java
index ae286c9..0eb30cf 100644
--- a/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java
+++ b/src/main/java/io/zhile/research/intellij/ier/ui/form/MainForm.java
@@ -84,7 +84,9 @@ public class MainForm {
         listModel.clear();
 
         List recordItemList = Resetter.getEvalRecords();
-        recordItemList.forEach(record -> listModel.addElement(record.toString()));
+        for (EvalRecord record : recordItemList) {
+            listModel.addElement(record.toString());
+        }
     }
 
     private void resetEvalItems() {
@@ -101,7 +103,12 @@ public class MainForm {
         }
 
         AppEventListener.disable();
-        ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().restart());
+        ApplicationManager.getApplication().invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                ApplicationManager.getApplication().restart();
+            }
+        });
     }
 
     private static void boldFont(Component component) {