void (final @NotNull ProjectSystemId externalSystemId, final @NotNull NotificationData notificationData, @Nullable Key<String> notificationKey) { Disposer.register(this, notificationData); if (ApplicationManager.getApplication().isHeadlessEnvironment()) { if (notificationData.getNotificationCategory() == NotificationCategory.INFO) { LOG.debug(notificationData.getMessage()); } else { LOG.warn(notificationData.getMessage()); } } if (ApplicationManager.getApplication().isUnitTestMode()) { @SuppressWarnings("UseOfSystemOutOrSystemErr") PrintStream out = notificationData.getNotificationCategory() == NotificationCategory.INFO ? System.out : System.err; out.println(notificationData.getMessage()); return; } if (notificationKey != null && isNotificationActive(notificationKey)) return; myUpdateQueue.queue(new Update(new Object()) { @Override public void run() { if (isDisposedOrNotOpen()) return; assert myProject != null; Project project = myProject; final Application app = ApplicationManager.getApplication(); Runnable action = () -> { if (!initializedExternalSystem.contains(externalSystemId)) { app.runWriteAction(() -> { if (isDisposedOrNotOpen()) return; ExternalSystemUtil.ensureToolWindowContentInitialized(project, externalSystemId); initializedExternalSystem.add(externalSystemId); }); } if (isDisposedOrNotOpen()) return; NotificationGroup group; if (notificationData.getBalloonGroup() == null) { ExternalProjectsView externalProjectsView = ExternalProjectsManagerImpl.getInstance(project).getExternalProjectsView(externalSystemId); group = externalProjectsView instanceof ExternalProjectsViewImpl ? ((ExternalProjectsViewImpl)externalProjectsView).getNotificationGroup() : null; } else { group = notificationData.getBalloonGroup(); } if (group == null) return; final Notification notification = group .createNotification(notificationData.getTitle(), notificationData.getMessage(), notificationData.getNotificationCategory().getNotificationType()) .setListener(notificationData.getListener()); if (notificationKey == null) { myNotifications.add(notification); } else { Notification oldNotification = myUniqueNotifications.put(notificationKey, notification); if (oldNotification != null) { oldNotification.expire(); } } if (notificationData.isBalloonNotification()) { applyNotification(notification); } else { addMessage(notification, externalSystemId, notificationData); } }; app.invokeLater(action, ModalityState.defaultModalityState(), project.getDisposed()); } }); }