IDEA-252720 Introduce a way to declare notification ids in code (IDEA-CR-68058)
authorAnastasia Ivanova <anastasia.ivanova@jetbrains.com>
Mon, 26 Oct 2020 08:49:50 +0000 (09:49 +0100)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Thu, 29 Oct 2020 18:20:48 +0000 (18:20 +0000)
GitOrigin-RevId: d9bcb883ba88c60a797c832185e2185f06fa8f57

platform/platform-impl/src/com/intellij/notification/impl/NotificationCollector.java
platform/platform-impl/src/com/intellij/notification/impl/NotificationIdsHolder.java [new file with mode: 0644]
platform/platform-impl/src/com/intellij/notification/impl/NotificationsEventLogGroup.kt
platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
platform/vcs-impl/resources/META-INF/VcsExtensions.xml
platform/vcs-impl/src/com/intellij/openapi/vcs/ExternallyAddedFilesProcessorImpl.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/ProjectConfigurationFilesProcessorImpl.kt
platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotificationIdsHolder.kt [new file with mode: 0644]
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ignore/IgnoreFilesProcessorImpl.kt

index 1c6921e3f7b5fbc6e90b763e71a15c1a505add15..ed962128dd355f27175d3ac64c1f0b40613ae195 100644 (file)
@@ -5,6 +5,7 @@ import com.intellij.internal.statistic.collectors.fus.actions.persistence.Action
 import com.intellij.internal.statistic.collectors.fus.actions.persistence.ActionsEventLogGroup;
 import com.intellij.internal.statistic.eventLog.events.EventFields;
 import com.intellij.internal.statistic.eventLog.events.EventPair;
+import com.intellij.internal.statistic.eventLog.events.ObjectEventData;
 import com.intellij.internal.statistic.eventLog.validator.ValidationResultType;
 import com.intellij.internal.statistic.eventLog.validator.rules.EventContext;
 import com.intellij.internal.statistic.eventLog.validator.rules.impl.CustomValidationRule;
@@ -34,7 +35,7 @@ public final class NotificationCollector {
   private static final Logger LOG = Logger.getInstance(NotificationCollector.class);
   private static final Map<String, PluginInfo> ourNotificationGroupsWhitelist = new ConcurrentHashMap<>();
   private static final Set<String> ourNotificationsWhitelist = new HashSet<>();
-  private static final String UNKNOWN = "unknown";
+  public static final String UNKNOWN = "unknown";
 
   private NotificationCollector() {
     NotificationWhitelistEP.EP_NAME.getExtensionList().forEach(NotificationCollector::addNotificationsToWhitelist);
@@ -131,7 +132,7 @@ public final class NotificationCollector {
                                                                     @Nullable String displayId) {
     ArrayList<EventPair<?>> data = new ArrayList<>();
     data.add(ID.with(id));
-    data.add(NOTIFICATION_ID.with(Strings.isNotEmpty(displayId) ? displayId : UNKNOWN));
+    data.add(ADDITIONAL.with(new ObjectEventData(NOTIFICATION_ID.with(Strings.isNotEmpty(displayId) ? displayId : UNKNOWN))));
     data.add(NOTIFICATION_GROUP_ID.with(Strings.isNotEmpty(groupId) ? groupId : UNKNOWN));
     data.add(EventFields.PluginInfo.with(getPluginInfo(groupId)));
     return data;
diff --git a/platform/platform-impl/src/com/intellij/notification/impl/NotificationIdsHolder.java b/platform/platform-impl/src/com/intellij/notification/impl/NotificationIdsHolder.java
new file mode 100644 (file)
index 0000000..2d7103f
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+package com.intellij.notification.impl;
+
+import com.intellij.notification.Notification;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.ApiStatus;
+
+import java.util.List;
+
+/**
+ * Class that provides constant list of possible notification ids.
+ * If extension is registered in the platform or in a plugin bundled with IntelliJ Ultimate,
+ * these ids will be registered in statistic metadata repository automatically.
+ *
+ * Otherwise, create a YT issue in FUS project or use com.intellij.notification.impl.NotificationGroupEP#notificationIds
+ */
+@ApiStatus.Internal
+public interface NotificationIdsHolder {
+  ExtensionPointName<NotificationIdsHolder> EP_NAME = ExtensionPointName.create("com.intellij.statistics.notificationIdsHolder");
+
+  /**
+   * List of notificationIds which should be recorded in feature usage statistics.
+   * @see Notification#displayId
+   */
+  List<String> getNotificationIds();
+}
\ No newline at end of file
index 89e3fbc9d8cd31d4d6569370cbfb4d151ff51505..db229eb628fb4850a1f44821341d5e1b996ddc61 100644 (file)
@@ -11,13 +11,14 @@ import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesColle
 import com.intellij.notification.NotificationDisplayType
 import com.intellij.notification.NotificationType
 import com.intellij.notification.impl.NotificationCollector.NotificationPlace
+import java.util.stream.Collectors
 
 class NotificationsEventLogGroup : CounterUsagesCollector() {
   override fun getGroup(): EventLogGroup = GROUP
 
   companion object {
     @JvmField
-    val GROUP = EventLogGroup("notifications", 58)
+    val GROUP = EventLogGroup("notifications", 59)
 
     @JvmField
     val DISPLAY_TYPE: EnumEventField<NotificationDisplayType> = Enum("display_type", NotificationDisplayType::class.java)
@@ -35,7 +36,20 @@ class NotificationsEventLogGroup : CounterUsagesCollector() {
     }
 
     @JvmField
-    val NOTIFICATION_ID = StringValidatedByCustomRule("display_id", "notification_display_id")
+    val NOTIFICATION_ID = object : StringEventField("display_id") {
+      override val validationRule: List<String>
+        get() {
+          val validationRules = NotificationIdsHolder.EP_NAME.extensionList.stream()
+            .flatMap { holder: NotificationIdsHolder -> holder.notificationIds.stream() }
+            .collect(Collectors.toList())
+          validationRules.add(NotificationCollector.UNKNOWN)
+          validationRules.add("{util#notification_display_id}")
+          return validationRules
+        }
+    }
+
+    @JvmField
+    val ADDITIONAL = ObjectEventField("additional", NOTIFICATION_ID)
 
     @JvmField
     val NOTIFICATION_GROUP_ID = StringValidatedByCustomRule("notification_group", "notification_group")
index 4542ee90aa41d6a8bd56be67009396a2bae4cdef..59d4cbd61de798f5ea1c3827a711e1468d43ce5e 100644 (file)
     <extensionPoint name="statistics.validation.customValidationRule" interface="com.intellij.internal.statistic.eventLog.validator.rules.impl.CustomValidationRule" dynamic="true"/>
     <extensionPoint name="statistics.collectorExtension" interface="com.intellij.internal.statistic.service.fus.collectors.FeatureUsageCollectorExtension"/>
     <extensionPoint name="statistics.actionCustomPlaceAllowlist" beanClass="com.intellij.internal.statistic.collectors.fus.ActionCustomPlaceAllowlist" dynamic="true"/>
+    <extensionPoint name="statistics.notificationIdsHolder" interface="com.intellij.notification.impl.NotificationIdsHolder" dynamic="true"/>
 
     <extensionPoint name="editorHighlighterProvider" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint" dynamic="true">
       <with attribute="implementationClass" implements="com.intellij.openapi.fileTypes.EditorHighlighterProvider"/>
index a5b246de014356d5e31032fb05727fea5d1f2b3b..d80972e00e67d8f9dac353d9c5406abd4078f8f6 100644 (file)
 
     <statistics.projectUsagesCollector implementation="com.intellij.openapi.vcs.statistics.VcsOptionsUsagesCollector"/>
     <statistics.projectUsagesCollector implementation="com.intellij.openapi.vcs.statistics.VcsUsagesCollector"/>
+    <statistics.notificationIdsHolder implementation="com.intellij.openapi.vcs.VcsNotificationIdsHolder"/>
   </extensions>
 
   <extensions defaultExtensionNs="org.jetbrains">
index e7253c39183420de410ce27de51f135d734adf02..46e5449a24c4a086da7ea65ab9461db1490116af 100644 (file)
@@ -118,7 +118,7 @@ internal class ExternallyAddedFilesProcessorImpl(project: Project,
     }
   }
 
-  override val notificationDisplayId: String = "externally.added.files.notification"
+  override val notificationDisplayId: String = VcsNotificationIdsHolder.EXTERNALLY_ADDED_FILES
   override val askedBeforeProperty = ASKED_ADD_EXTERNAL_FILES_PROPERTY
   override val doForCurrentProjectProperty: String? = null
 
index 7dafd85320db38e82d16143af97152101c67b74e..e402654e53a3b25211cd87be41bcc5f8c7cc95f1 100644 (file)
@@ -86,7 +86,7 @@ class ProjectConfigurationFilesProcessorImpl(project: Project,
     addChosenFiles(files)
   }
 
-  override val notificationDisplayId: String = "project.configuration.files.added.notification"
+  override val notificationDisplayId: String = VcsNotificationIdsHolder.PROJECT_CONFIGURATION_FILES_ADDED
 
   override val askedBeforeProperty = ASKED_SHARE_PROJECT_CONFIGURATION_FILES_PROPERTY
 
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotificationIdsHolder.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotificationIdsHolder.kt
new file mode 100644 (file)
index 0000000..c33b9bf
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+package com.intellij.openapi.vcs
+
+import com.intellij.notification.impl.NotificationIdsHolder
+
+class VcsNotificationIdsHolder : NotificationIdsHolder {
+  override fun getNotificationIds(): List<String> {
+    return listOf(IGNORED_TO_EXCLUDE_SYNCHRONIZATION,
+                  EXTERNALLY_ADDED_FILES,
+                  PROJECT_CONFIGURATION_FILES_ADDED,
+                  MANAGE_IGNORE_FILES)
+  }
+
+  companion object {
+    const val IGNORED_TO_EXCLUDE_SYNCHRONIZATION = "ignored.to.exclude.synchronization.notification"
+    const val EXTERNALLY_ADDED_FILES = "externally.added.files.notification"
+    const val PROJECT_CONFIGURATION_FILES_ADDED = "project.configuration.files.added.notification"
+    const val MANAGE_IGNORE_FILES = "manage.ignore.files.notification"
+  }
+}
+
index e394ac04d0d20038d2c9ccfc8811812ed919b439..6d34f5d1fe1f6293162ebcb32497537a42aec126 100644 (file)
@@ -183,7 +183,7 @@ class IgnoreFilesProcessorImpl(project: Project, private val vcs: AbstractVcs, p
     applicationSettings.MANAGE_IGNORE_FILES = true
   }
 
-  override val notificationDisplayId: String = "manage.ignore.files.notification"
+  override val notificationDisplayId: String = VcsNotificationIdsHolder.MANAGE_IGNORE_FILES
 
   override val askedBeforeProperty = ASKED_MANAGE_IGNORE_FILES_PROPERTY