IDEA-111532 External system: Expand the api in order to allow to customize notification shown to the end-user

This commit is contained in:
Denis.Zhdanov
2013-08-05 09:21:29 +04:00
parent 81a1657da6
commit a89cda4390
5 changed files with 159 additions and 34 deletions
@@ -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();
}
}
}
@@ -37,7 +37,7 @@ public class ExternalSystemIdeNotificationManager {
@NotNull private final AtomicReference<Notification> myNotification = new AtomicReference<Notification>();
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,
@@ -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<ExternalSystemNotificationExtension> 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;
}
}
}
@@ -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.
* <p/>
@@ -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());
@@ -5,5 +5,7 @@
interface="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService"/>
<extensionPoint name="externalSystemConfigLocator"
interface="com.intellij.openapi.externalSystem.service.settings.ExternalSystemConfigLocator"/>
<extensionPoint name="externalSystemNotificationExtension"
interface="com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationExtension"/>
</extensionPoints>
</idea-plugin>