diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
index ccaa173503f9..476bb87449a3 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2020 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.
+// Copyright 2000-2021 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 com.intellij.packaging.impl.artifacts;
import com.intellij.compiler.server.BuildManager;
@@ -265,7 +265,7 @@ public final class ArtifactManagerImpl extends ArtifactManager implements Persis
@Nls(capitalization = Nls.Capitalization.Sentence) String errorMessage) {
final InvalidArtifactImpl artifact = new InvalidArtifactImpl(state, errorMessage, externalSource);
ProjectLoadingErrorsNotifier.getInstance(myProject).registerError(new ArtifactLoadingErrorDescription(myProject, artifact));
- UnknownFeaturesCollector.getInstance(myProject).registerUnknownFeature(FEATURE_TYPE, state.getArtifactType(), "Artifact");
+ UnknownFeaturesCollector.getInstance(myProject).registerUnknownFeature(FEATURE_TYPE, state.getArtifactType(), JavaCompilerBundle.message("plugins.advertiser.feature.artifact"));
return artifact;
}
diff --git a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties
index a26ac2e345b8..0b9d59977b3b 100644
--- a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties
+++ b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties
@@ -321,3 +321,4 @@ notification.title.cpu.snapshot.build.has.been.captured=Build CPU snapshot has b
action.show.snapshot.location.text=Show Snapshot Location
dialog.message.failed.to.determine.host.ip.for.wsl.jdk=Failed to determine host IP for WSL JDK
progress.preparing.wsl.build.environment=Preparing WSL build environment...
+plugins.advertiser.feature.artifact=artifact
diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml
index 9fcd12a81073..aa76191420e2 100644
--- a/java/java-impl/src/META-INF/JavaPlugin.xml
+++ b/java/java-impl/src/META-INF/JavaPlugin.xml
@@ -2154,6 +2154,8 @@
+
+
diff --git a/java/java-impl/src/com/intellij/ide/JavaDependencyCollector.kt b/java/java-impl/src/com/intellij/ide/JavaDependencyCollector.kt
new file mode 100644
index 000000000000..142deff5c9f2
--- /dev/null
+++ b/java/java-impl/src/com/intellij/ide/JavaDependencyCollector.kt
@@ -0,0 +1,35 @@
+// Copyright 2000-2021 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 com.intellij.ide
+
+import com.intellij.openapi.module.ModuleManager
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.rootManager
+import com.intellij.openapi.roots.LibraryOrderEntry
+import com.intellij.openapi.roots.impl.libraries.LibraryEx
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar
+import com.intellij.ide.plugins.DependencyCollector
+import org.jetbrains.idea.maven.utils.library.RepositoryLibraryProperties
+
+class JavaDependencyCollector : DependencyCollector {
+ override val dependencyKind: String
+ get() = "java"
+
+ override fun collectDependencies(project: Project): List {
+ val projectLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(project)
+ val result = mutableSetOf()
+ for (library in projectLibraryTable.libraries) {
+ val properties = (library as? LibraryEx)?.properties as? RepositoryLibraryProperties ?: continue
+ result.add(properties.groupId + ":" + properties.artifactId)
+ }
+ for (module in ModuleManager.getInstance(project).modules) {
+ for (orderEntry in module.rootManager.orderEntries) {
+ if (orderEntry is LibraryOrderEntry && orderEntry.isModuleLevel) {
+ val library = orderEntry.library
+ val properties = (library as? LibraryEx)?.properties as? RepositoryLibraryProperties ?: continue
+ result.add(properties.groupId + ":" + properties.artifactId)
+ }
+ }
+ }
+ return result.toList()
+ }
+}
\ No newline at end of file
diff --git a/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt b/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt
index 6a0e46211eff..a116cd1ed4ce 100644
--- a/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt
+++ b/platform/execution-impl/src/com/intellij/execution/impl/RunManagerImpl.kt
@@ -8,6 +8,7 @@ import com.intellij.execution.configurations.*
import com.intellij.execution.runners.ExecutionEnvironment
import com.intellij.execution.runners.ExecutionUtil
import com.intellij.execution.runners.ProgramRunner
+import com.intellij.ide.IdeBundle
import com.intellij.ide.plugins.DynamicPluginListener
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.ide.util.PropertiesComponent
@@ -999,7 +1000,7 @@ open class RunManagerImpl @JvmOverloads constructor(val project: Project, shared
if (checkUnknown && typeId != null) {
UnknownFeaturesCollector.getInstance(project).registerUnknownFeature(
CONFIGURATION_TYPE_FEATURE_ID,
- "Run Configuration",
+ ExecutionBundle.message("plugins.advertiser.feature.run.configuration"),
typeId,
factoryId ?: typeId,
)
diff --git a/platform/lang-api/resources/messages/ExecutionBundle.properties b/platform/lang-api/resources/messages/ExecutionBundle.properties
index 5f70f703a1f3..19e850f8623a 100644
--- a/platform/lang-api/resources/messages/ExecutionBundle.properties
+++ b/platform/lang-api/resources/messages/ExecutionBundle.properties
@@ -604,4 +604,6 @@ startup.tasks.confirmation.notification.action.review=Review
edit.configuration.templates=Edit configuration templates...
progress.title.patch.java.command.line.parameters=Patch Java command line parameters
status.text.add.new.run.configuration=Add new run configuration...
-status.text.or.select.run.configuration.to.edit=or select run configuration to edit
\ No newline at end of file
+status.text.or.select.run.configuration.to.edit=or select run configuration to edit
+
+plugins.advertiser.feature.run.configuration=run configuration
diff --git a/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java b/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java
index 8e9fed11aa0a..0d6b34d7fa9c 100644
--- a/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java
+++ b/platform/lang-impl/src/com/intellij/facet/FacetManagerBase.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2020 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.
+// Copyright 2000-2021 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 com.intellij.facet;
import com.intellij.facet.impl.FacetEventsPublisher;
@@ -11,6 +11,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.text.StringUtil;
@@ -140,7 +141,7 @@ public abstract class FacetManagerBase extends FacetManager {
FacetLoadingErrorDescription description = new FacetLoadingErrorDescription(facet);
ProjectLoadingErrorsNotifier.getInstance(project).registerError(description);
if (unknownType) {
- UnknownFeaturesCollector.getInstance(project).registerUnknownFeature(FEATURE_TYPE, state.getFacetType(), "Facet");
+ UnknownFeaturesCollector.getInstance(project).registerUnknownFeature(FEATURE_TYPE, state.getFacetType(), ProjectBundle.message("plugins.advertiser.feature.facet"));
}
}
}
diff --git a/platform/platform-api/resources/messages/IdeBundle.properties b/platform/platform-api/resources/messages/IdeBundle.properties
index eaf2cc6d456a..5fd02d35110d 100644
--- a/platform/platform-api/resources/messages/IdeBundle.properties
+++ b/platform/platform-api/resources/messages/IdeBundle.properties
@@ -1629,6 +1629,7 @@ plugins.advertiser.action.ignore.ultimate=Do not suggest Ultimate
plugins.advertiser.ultimate.features.detected=Features covered by IntelliJ IDEA Ultimate {0} are detected
plugins.advertiser.missing.feature={0,choice,1#Plugin|2#Plugins} supporting {1} ''{2}'' {0,choice,1#is|2#are} currently {3,choice,0#disabled|1#not installed}.
plugins.advertiser.missing.features={0,choice,1#Plugin|2#Plugins} supporting features ({1}) {0,choice,1#is|2#are} currently {2,choice,0#disabled|1#not installed}.
+plugins.advertiser.feature.dependency=dependency
do.not.ask.me.again=Don't ask again
diff --git a/platform/platform-api/resources/messages/ProjectBundle.properties b/platform/platform-api/resources/messages/ProjectBundle.properties
index b46dc8ac15a8..157b9c7ca0ae 100644
--- a/platform/platform-api/resources/messages/ProjectBundle.properties
+++ b/platform/platform-api/resources/messages/ProjectBundle.properties
@@ -283,3 +283,4 @@ list.item.group.by.type=Type
list.item.group.by.directory=Directory
label.directory.will.be.excluded.from.framework.detection=''{0}'' directory will be excluded from framework detection
label.framework.detection.will.be.disabled=''{0}'' framework detection will be disabled.
+plugins.advertiser.feature.facet=facet
diff --git a/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt b/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt
index fbd137fa7b60..b4278f1a181f 100644
--- a/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt
+++ b/platform/platform-api/src/com/intellij/ide/plugins/PluginFeatureService.kt
@@ -15,9 +15,6 @@ import com.intellij.util.xmlb.annotations.XMap
storages = [Storage(StoragePathMacros.CACHE_FILE, roamingType = RoamingType.DISABLED)],
)
class PluginFeatureService : SimplePersistentStateComponent(State()) {
-
- private val featureMappingsCollected = mutableSetOf()
-
@Tag("features")
class FeaturePluginsList : BaseState() {
@@ -65,8 +62,6 @@ class PluginFeatureService : SimplePersistentStateComponent String,
displayNameMapping: (T) -> String,
) {
- if (!featureMappingsCollected.add(featureType)) return
-
val pluginsList = state[featureType]
ep.processWithPluginDescriptor { ext, descriptor ->
pluginsList[idMapping(ext)] = FeaturePluginData(
diff --git a/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt b/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt
index 0fb4ef500d61..abd319492760 100644
--- a/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt
+++ b/platform/platform-api/src/com/intellij/ide/plugins/advertiser/data.kt
@@ -14,7 +14,7 @@ class PluginData @JvmOverloads constructor(
@Attribute("fromCustomRepository") val isFromCustomRepository: Boolean = false,
) : Comparable {
- val pluginId: PluginId = PluginId.getId(pluginIdString)
+ val pluginId: PluginId get() = PluginId.getId(pluginIdString)
val pluginName = nullablePluginName ?: pluginIdString
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/DependencyCollector.kt b/platform/platform-impl/src/com/intellij/ide/plugins/DependencyCollector.kt
new file mode 100644
index 000000000000..301a36f18f4d
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/DependencyCollector.kt
@@ -0,0 +1,44 @@
+// Copyright 2000-2021 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 com.intellij.ide.plugins
+
+import com.intellij.openapi.extensions.ExtensionPointName
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.startup.StartupActivity
+import com.intellij.util.xmlb.annotations.Attribute
+
+interface DependencyCollector {
+ val dependencyKind: String
+
+ fun collectDependencies(project: Project): List
+
+ companion object {
+ val EP_NAME = ExtensionPointName.create("com.intellij.dependencyCollector")
+ }
+}
+
+class DependencySupportBean {
+ @Attribute("kind")
+ @JvmField
+ var kind: String = ""
+
+ @Attribute("coordinate")
+ @JvmField
+ var coordinate: String = ""
+
+ companion object {
+ val EP_NAME = ExtensionPointName.create("com.intellij.dependencySupport")
+ }
+}
+
+const val DEPENDENCY_SUPPORT_FEATURE = "dependencySupport"
+
+class DependencyFeatureCollector : StartupActivity.Background {
+ override fun runActivity(project: Project) {
+ PluginFeatureService.instance.collectFeatureMapping(
+ DEPENDENCY_SUPPORT_FEATURE,
+ DependencySupportBean.EP_NAME,
+ { bean -> bean.kind + ":" + bean.coordinate },
+ { bean -> bean.kind + ":" + bean.coordinate }
+ )
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt
index 99ce5727a70d..56c3a97a311b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserService.kt
@@ -29,7 +29,7 @@ open class PluginAdvertiserService {
fun run(
project: Project,
customPlugins: List,
- unknownFeatures: Set,
+ unknownFeatures: Collection,
) {
val features = MultiMap.createSet()
val disabledPlugins = HashMap()
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt
index 2ed5bff408d0..0ed9a153092a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiserStartupActivity.kt
@@ -1,6 +1,9 @@
// Copyright 2000-2021 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 com.intellij.openapi.updateSettings.impl.pluginsAdvertisement
+import com.intellij.ide.IdeBundle
+import com.intellij.ide.plugins.DEPENDENCY_SUPPORT_FEATURE
+import com.intellij.ide.plugins.DependencyCollector
import com.intellij.ide.plugins.advertiser.KnownExtensions
import com.intellij.ide.plugins.advertiser.KnownExtensionsService
import com.intellij.ide.plugins.advertiser.PluginData
@@ -9,7 +12,6 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileTypes.FileTypeFactory
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity
-import com.intellij.openapi.updateSettings.impl.UpdateSettings
import com.intellij.ui.EditorNotifications
internal class PluginsAdvertiserStartupActivity : StartupActivity.Background {
@@ -17,8 +19,7 @@ internal class PluginsAdvertiserStartupActivity : StartupActivity.Background {
override fun runActivity(project: Project) {
val application = ApplicationManager.getApplication()
if (application.isUnitTestMode ||
- application.isHeadlessEnvironment ||
- !UpdateSettings.getInstance().isPluginsCheckNeeded) {
+ application.isHeadlessEnvironment) {
return
}
@@ -29,7 +30,10 @@ internal class PluginsAdvertiserStartupActivity : StartupActivity.Background {
val extensionsService = KnownExtensionsService.instance
val extensions = extensionsService.extensions
- val unknownFeatures = UnknownFeaturesCollector.getInstance(project).unknownFeatures
+
+ val unknownFeatures = UnknownFeaturesCollector.getInstance(project).unknownFeatures.toMutableList()
+ unknownFeatures.addAll(collectDependencyUnknownFeatures(project))
+
if (extensions != null && unknownFeatures.isEmpty()) {
return
}
@@ -54,6 +58,17 @@ internal class PluginsAdvertiserStartupActivity : StartupActivity.Background {
}
}
+ private fun collectDependencyUnknownFeatures(project: Project): List {
+ return DependencyCollector.EP_NAME.extensions.flatMap { dependencyCollector ->
+ dependencyCollector.collectDependencies(project).map { coordinate ->
+ UnknownFeature(DEPENDENCY_SUPPORT_FEATURE,
+ IdeBundle.message("plugins.advertiser.feature.dependency"),
+ dependencyCollector.dependencyKind + ":" + coordinate,
+ coordinate)
+ }
+ }
+ }
+
companion object {
@JvmStatic
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index 51ddaa4e5e83..6393604ba038 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -420,5 +420,8 @@
+
+
+
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index bcfa5d15a158..3bcfcc9b44fb 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -1228,7 +1228,9 @@
-
+
+
+/