From a89cda43907a48e53af5548fead13dc749046c90 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 5 Aug 2013 09:21:29 +0400 Subject: [PATCH] IDEA-111532 External system: Expand the api in order to allow to customize notification shown to the end-user --- .../util/ExternalSystemApiUtil.java | 28 ++++++ .../ExternalSystemIdeNotificationManager.java | 38 +++++++- .../ExternalSystemNotificationExtension.java | 93 +++++++++++++++++++ .../util/ExternalSystemUtil.java | 32 +------ .../ExternalSystemExtensionPoints.xml | 2 + 5 files changed, 159 insertions(+), 34 deletions(-) create mode 100644 platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationExtension.java diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java index 9d1182cf15e1..b2c18c6bd5b9 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.externalSystem.util; +import com.intellij.execution.rmi.RemoteUtil; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; @@ -22,6 +23,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware; import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.DataNode; +import com.intellij.openapi.externalSystem.model.ExternalSystemException; import com.intellij.openapi.externalSystem.model.Key; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.fileTypes.FileTypes; @@ -45,6 +47,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -439,4 +443,28 @@ public class ExternalSystemApiUtil { } return null; } + + /** + * {@link RemoteUtil#unwrap(Throwable) unwraps} given exception if possible and builds error message for it. + * + * @param e exception to process + * @return error message for the given exception + */ + @SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "IOResourceOpenedButNotSafelyClosed"}) + @NotNull + public static String buildErrorMessage(@NotNull Throwable e) { + Throwable unwrapped = RemoteUtil.unwrap(e); + String reason = unwrapped.getLocalizedMessage(); + if (!StringUtil.isEmpty(reason)) { + return reason; + } + else if (unwrapped.getClass() == ExternalSystemException.class) { + return String.format("exception during working with external system: %s", ((ExternalSystemException)unwrapped).getOriginalReason()); + } + else { + StringWriter writer = new StringWriter(); + unwrapped.printStackTrace(new PrintWriter(writer)); + return writer.toString(); + } + } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java index d23c8c3803c9..bdcb5b4b32b8 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemIdeNotificationManager.java @@ -37,7 +37,7 @@ public class ExternalSystemIdeNotificationManager { @NotNull private final AtomicReference myNotification = new AtomicReference(); - public void processExternalProjectRefreshError(@NotNull String message, + public void processExternalProjectRefreshError(@NotNull Throwable error, @NotNull final Project project, @NotNull String externalProjectName, @NotNull ProjectSystemId externalSystemId) @@ -49,13 +49,14 @@ public class ExternalSystemIdeNotificationManager { if (!(manager instanceof ExternalSystemConfigurableAware)) { return; } - final Configurable configurable = ((ExternalSystemConfigurableAware)manager).getConfigurable(project); - EditorNotifications.getInstance(project).updateAllNotifications(); + String message = ExternalSystemApiUtil.buildErrorMessage(error); String title = ExternalSystemBundle.message("notification.project.refresh.fail.description", externalSystemId.getReadableName(), externalProjectName, message); String messageToShow = ExternalSystemBundle.message("notification.action.show.settings", externalSystemId.getReadableName()); - showNotification(title, messageToShow, NotificationType.WARNING, project, externalSystemId, new NotificationListener() { + NotificationType notificationType = NotificationType.WARNING; + final Configurable configurable = ((ExternalSystemConfigurableAware)manager).getConfigurable(project); + NotificationListener listener = new NotificationListener() { @Override public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { @@ -63,7 +64,34 @@ public class ExternalSystemIdeNotificationManager { } ShowSettingsUtil.getInstance().editConfigurable(project, configurable); } - }); + }; + + for (ExternalSystemNotificationExtension extension : ExternalSystemNotificationExtension.EP_NAME.getExtensions()) { + if (!externalSystemId.equals(extension.getTargetExternalSystemId())) { + continue; + } + ExternalSystemNotificationExtension.CustomizationResult customizationResult = extension.customize( + project, error, ExternalSystemNotificationExtension.UsageHint.PROJECT_REFRESH + ); + if (customizationResult == null) { + continue; + } + if (customizationResult.getTitle() != null) { + title = customizationResult.getTitle(); + } + if (customizationResult.getMessage() != null) { + messageToShow = customizationResult.getMessage(); + } + if (customizationResult.getNotificationType() != null) { + notificationType = customizationResult.getNotificationType(); + } + if (customizationResult.getListener() != null) { + listener = customizationResult.getListener(); + } + } + + EditorNotifications.getInstance(project).updateAllNotifications(); + showNotification(title, messageToShow, notificationType, project, externalSystemId, listener); } public void showNotification(@NotNull final String title, diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationExtension.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationExtension.java new file mode 100644 index 000000000000..1a0d50cb280b --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/notification/ExternalSystemNotificationExtension.java @@ -0,0 +1,93 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.externalSystem.service.notification; + +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.externalSystem.model.ProjectSystemId; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Allows to customize {@link ExternalSystemIdeNotificationManager external system notifications} shown to end-user by the ide. + * + * @author Denis Zhdanov + * @since 8/5/13 8:52 AM + */ +public interface ExternalSystemNotificationExtension { + + ExtensionPointName EP_NAME + = ExtensionPointName.create("com.intellij.externalSystemNotificationExtension"); + + @NotNull + ProjectSystemId getTargetExternalSystemId(); + + /** + * Allows to customize external system processing error. + * + * @param project target ide project + * @param error error occurred during external system processing + * @param hint hint for a use-case during processing of which given error occurs + * @return customization result (if applicable) + */ + @Nullable + CustomizationResult customize(@NotNull Project project, @NotNull Throwable error, @Nullable UsageHint hint); + + enum UsageHint { + PROJECT_REFRESH + } + + class CustomizationResult { + + @Nullable private final String myTitle; + @Nullable private final String myMessage; + @Nullable private final NotificationType myNotificationType; + @Nullable private final NotificationListener myListener; + + public CustomizationResult(@Nullable String title, + @Nullable String message, + @Nullable NotificationType notificationType, + @Nullable NotificationListener listener) + { + myTitle = title; + myMessage = message; + myNotificationType = notificationType; + myListener = listener; + } + + @Nullable + public String getTitle() { + return myTitle; + } + + @Nullable + public String getMessage() { + return myMessage; + } + + @Nullable + public NotificationType getNotificationType() { + return myNotificationType; + } + + @Nullable + public NotificationListener getListener() { + return myListener; + } + } +} diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index e4e7c616a8aa..b995a795c404 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -76,8 +76,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.*; import java.util.List; @@ -156,30 +154,6 @@ public class ExternalSystemUtil { return null; } - /** - * {@link RemoteUtil#unwrap(Throwable) unwraps} given exception if possible and builds error message for it. - * - * @param e exception to process - * @return error message for the given exception - */ - @SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "IOResourceOpenedButNotSafelyClosed"}) - @NotNull - public static String buildErrorMessage(@NotNull Throwable e) { - Throwable unwrapped = RemoteUtil.unwrap(e); - String reason = unwrapped.getLocalizedMessage(); - if (!StringUtil.isEmpty(reason)) { - return reason; - } - else if (unwrapped.getClass() == ExternalSystemException.class) { - return String.format("exception during working with external system: %s", ((ExternalSystemException)unwrapped).getOriginalReason()); - } - else { - StringWriter writer = new StringWriter(); - unwrapped.printStackTrace(new PrintWriter(writer)); - return writer.toString(); - } - } - /** * Asks to refresh all external projects of the target external system linked to the given ide project. *

@@ -411,7 +385,7 @@ public class ExternalSystemUtil { callback.onSuccess(externalProject); return; } - String message = buildErrorMessage(error); + String message = ExternalSystemApiUtil.buildErrorMessage(error); if (StringUtil.isEmpty(message)) { message = String.format( "Can't resolve %s project at '%s'. Reason: %s", @@ -423,7 +397,7 @@ public class ExternalSystemUtil { ExternalSystemIdeNotificationManager notificationManager = ServiceManager.getService(ExternalSystemIdeNotificationManager.class); if (notificationManager != null) { - notificationManager.processExternalProjectRefreshError(message, project, projectName, externalSystemId); + notificationManager.processExternalProjectRefreshError(error, project, projectName, externalSystemId); } } }; @@ -476,7 +450,7 @@ public class ExternalSystemUtil { } String name = AbstractExternalSystemTaskConfigurationType.generateName(project, taskSettings); - RunnerAndConfigurationSettings settings = RunManagerEx.getInstanceEx(project).createConfiguration(name, configurationType.getFactory()); + RunnerAndConfigurationSettings settings = RunManager.getInstance(project).createRunConfiguration(name, configurationType.getFactory()); ExternalSystemRunConfiguration runConfiguration = (ExternalSystemRunConfiguration)settings.getConfiguration(); runConfiguration.getSettings().setExternalProjectPath(taskSettings.getExternalProjectPath()); runConfiguration.getSettings().setTaskNames(taskSettings.getTaskNames()); diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensionPoints.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensionPoints.xml index 21159cdc9201..5ba85986d0d9 100644 --- a/platform/platform-resources/src/META-INF/ExternalSystemExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensionPoints.xml @@ -5,5 +5,7 @@ interface="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService"/> + \ No newline at end of file