IDEA-CR-49630 added unsubscription from external system API events

GitOrigin-RevId: 6b0f0f2f8f595fe7743ca4cb5ed6b0dd53290267
This commit is contained in:
Sergei Vorobyov
2019-07-16 14:05:07 +03:00
committed by intellij-monorepo-bot
parent 130a8c3204
commit b22f775cc2
6 changed files with 126 additions and 5 deletions
@@ -71,10 +71,28 @@ public abstract class AbstractExternalSystemSettings<
* <p/>
* That's why this method allows to wrap given 'generic listener' into external system-specific one.
*
* @param subscription is a disposable to unsubscribe from external system settings events
* @param listener target generic listener to wrap to external system-specific implementation
*/
public void subscribe(@NotNull Disposable subscription, @NotNull ExternalSystemSettingsListener<PS> listener) {
subscribe(listener);
}
/**
* @deprecated use {@link AbstractExternalSystemSettings#subscribe(Disposable, ExternalSystemSettingsListener)} instead
*/
@Deprecated
public abstract void subscribe(@NotNull ExternalSystemSettingsListener<PS> listener);
/**
* Generic subscribe implementation
*
* @see AbstractExternalSystemSettings#subscribe(Disposable, ExternalSystemSettingsListener)
*/
protected void doSubscribe(@NotNull Disposable subscription, @NotNull L listener) {
getProject().getMessageBus().connect(subscription).subscribe(getChangesTopic(), listener);
}
public void copyFrom(@NotNull SS settings) {
for (PS projectSettings : settings.getLinkedProjectsSettings()) {
myLinkedProjectsSettings.put(projectSettings.getExternalProjectPath(), projectSettings);
@@ -3,6 +3,7 @@ package com.intellij.openapi.externalSystem.util;
import com.intellij.execution.rmi.RemoteUtil;
import com.intellij.ide.highlighter.ArchiveFileType;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.*;
import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
@@ -683,7 +684,15 @@ public class ExternalSystemApiUtil {
@NotNull ProjectSystemId systemId,
@NotNull ExternalSystemSettingsListener listener) {
//noinspection unchecked
getSettings(project, systemId).subscribe(listener);
getSettings(project, systemId).subscribe(project, listener);
}
public static void subscribe(@NotNull Project project,
@NotNull ProjectSystemId systemId,
@NotNull Disposable subscription,
@NotNull ExternalSystemSettingsListener listener) {
//noinspection unchecked
getSettings(project, systemId).subscribe(subscription, listener);
}
@NotNull
@@ -1,6 +1,7 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.settings;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
@@ -43,8 +44,12 @@ public class GradleSettings extends AbstractExternalSystemSettings<GradleSetting
@Override
public void subscribe(@NotNull ExternalSystemSettingsListener<GradleProjectSettings> listener) {
getProject().getMessageBus().connect(getProject()).subscribe(GradleSettingsListener.TOPIC,
new DelegatingGradleSettingsListenerAdapter(listener));
subscribe(getProject(), listener);
}
@Override
public void subscribe(@NotNull Disposable subscription, @NotNull ExternalSystemSettingsListener<GradleProjectSettings> listener) {
doSubscribe(subscription, new DelegatingGradleSettingsListenerAdapter(listener));
}
@Override
@@ -6,12 +6,14 @@ import com.intellij.notification.NotificationAction
import com.intellij.notification.NotificationType
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationNamesInfo
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter
import org.jetbrains.plugins.gradle.service.project.GradleNotification
@@ -30,7 +32,9 @@ class GradleUnlinkedProjectProcessor : StartupActivity, DumbAware {
}
companion object {
private const val SHOW_UNLINKED_GRADLE_POPUP = "show.inlinked.gradle.project.popup"
private const val SHOW_UNLINKED_GRADLE_POPUP = "show.unlinked.gradle.project.popup"
private val LOG = Logger.getInstance(GradleUnlinkedProjectProcessor::class.java)
private fun showNotification(project: Project) {
if (!GradleSettings.getInstance(project).linkedProjectsSettings.isEmpty()) return
@@ -61,12 +65,15 @@ class GradleUnlinkedProjectProcessor : StartupActivity, DumbAware {
override fun actionPerformed(e: AnActionEvent) {}
}
val subscription = Disposer.newDisposable()
val settingsListener = object : GradleSettingsListenerAdapter() {
override fun onProjectsLinked(settings: MutableCollection<GradleProjectSettings>) {
notification.expire()
debug("Unlinked project notification expired")
Disposer.dispose(subscription)
}
}
ExternalSystemApiUtil.subscribe(project, GradleConstants.SYSTEM_ID, settingsListener)
ExternalSystemApiUtil.subscribe(project, GradleConstants.SYSTEM_ID, subscription, settingsListener)
notification.notify(project)
}
@@ -82,5 +89,9 @@ class GradleUnlinkedProjectProcessor : StartupActivity, DumbAware {
fun enableNotifications(project: Project) {
PropertiesComponent.getInstance(project).setValue(SHOW_UNLINKED_GRADLE_POPUP, true, false)
}
private fun debug(message: String) {
if (LOG.isDebugEnabled) LOG.debug(message)
}
}
}
@@ -0,0 +1,34 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.settings
import com.intellij.openapi.util.Disposer
import org.junit.Test
class GradleSubscriptionTest : GradleSubscriptionTestCase() {
@Test
fun `test external system subscription`() {
var linkingCounter = 0
onProjectLinked {
linkingCounter += 1
}
linkProject()
unlinkProject()
linkProject()
assertEquals(2, linkingCounter)
}
@Test
fun `test external system unsubscription`() {
var linkingCounter = 0
val subscription = Disposer.newDisposable()
onProjectLinked(subscription) {
linkingCounter += 1
Disposer.dispose(subscription)
}
linkProject()
unlinkProject()
linkProject()
assertEquals(1, linkingCounter)
}
}
@@ -0,0 +1,44 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.settings
import com.intellij.openapi.Disposable
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import org.jetbrains.plugins.gradle.config.GradleSettingsListenerAdapter
import org.jetbrains.plugins.gradle.importing.GradleBuildScriptBuilderEx
import org.jetbrains.plugins.gradle.importing.GradleImportingTestCase
import org.junit.runners.Parameterized
abstract class GradleSubscriptionTestCase : GradleImportingTestCase() {
protected fun linkProject() {
importProject(GradleBuildScriptBuilderEx().withJavaPlugin().generate())
}
protected fun unlinkProject() {
val settings = ExternalSystemApiUtil.getSettings(myProject, externalSystemId)
settings.unlinkExternalProject(currentExternalProjectSettings.externalProjectPath)
}
protected fun onProjectLinked(subscription: Disposable, listener: () -> Unit) {
val settingsListener = object : GradleSettingsListenerAdapter() {
override fun onProjectsLinked(settings: MutableCollection<GradleProjectSettings>) = listener()
}
ExternalSystemApiUtil.subscribe(myProject, externalSystemId, subscription, settingsListener)
}
protected fun onProjectLinked(listener: () -> Unit) {
val settingsListener = object : GradleSettingsListenerAdapter() {
override fun onProjectsLinked(settings: MutableCollection<GradleProjectSettings>) = listener()
}
ExternalSystemApiUtil.subscribe(myProject, externalSystemId, settingsListener)
}
companion object {
/**
* It's sufficient to run the test against one gradle version
*/
@Parameterized.Parameters(name = "with Gradle-{0}")
@JvmStatic
fun tests(): Collection<Array<out String>> = arrayListOf(arrayOf(BASE_GRADLE_VERSION))
}
}