Github: Add Messages thread safety

This commit is contained in:
Aleksey Pivovarov
2013-06-27 14:05:56 +04:00
parent 1143eae185
commit 9aec51de1d
6 changed files with 185 additions and 109 deletions
@@ -66,7 +66,7 @@ public class GithubCheckoutProvider implements CheckoutProvider {
}
catch (IOException e) {
LOG.info(e);
GithubUtil.notifyError(project, "Couldn't get the list of GitHub repositories", GithubUtil.getErrorTextFromException(e));
GithubNotifications.showError(project, "Couldn't get the list of GitHub repositories", e);
}
}
});
@@ -18,9 +18,6 @@ package org.jetbrains.plugins.github;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.intellij.ide.BrowserUtil;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
@@ -38,14 +35,12 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import git4idea.GitVcs;
import git4idea.Notificator;
import icons.GithubIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.ui.GitHubCreateGistDialog;
import javax.swing.event.HyperlinkEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -129,7 +124,7 @@ public class GithubCreateGistAction extends DumbAwareAction {
}
});
if (authDataRef.isNull()) {
showWarning(project, FAILED_TO_CREATE_GIST, "You have to login to GitHub to create non-anonymous Gists.");
GithubNotifications.showWarning(project, FAILED_TO_CREATE_GIST, "You have to login to GitHub to create non-anonymous Gists.");
return;
}
auth = authDataRef.get();
@@ -147,7 +142,7 @@ public class GithubCreateGistAction extends DumbAwareAction {
BrowserUtil.launchBrowser(url);
}
else {
showNotificationWithLink(project, url);
GithubNotifications.showInfoURL(project, "Gist Created Successfully", "Your gist url", url);
}
}
});
@@ -177,12 +172,6 @@ public class GithubCreateGistAction extends DumbAwareAction {
}.queue();
}
private static void showNotificationWithLink(@NotNull Project project, @NotNull final String url) {
Notificator.getInstance(project)
.notify(GitVcs.IMPORTANT_ERROR_NOTIFICATION, "Gist Created Successfully", "Your gist url: <a href='open'>" + url + "</a>",
NotificationType.INFORMATION, NotificationListener.URL_OPENING_LISTENER);
}
@NotNull
private static List<NamedContent> collectContents(@NotNull Project project,
@Nullable Editor editor,
@@ -215,7 +204,7 @@ public class GithubCreateGistAction extends DumbAwareAction {
boolean isPrivate,
@NotNull String description) {
if (contents.isEmpty()) {
showWarning(project, "Failed to create gist", "Can't create empty gist");
GithubNotifications.showWarning(project, "Failed to create gist", "Can't create empty gist");
return null;
}
String requestBody = prepareJsonRequest(description, isPrivate, contents);
@@ -277,11 +266,6 @@ public class GithubCreateGistAction extends DumbAwareAction {
LOG.info("Couldn't parse response as json data: \n" + content + "\n" + details, e);
}
private static void showWarning(@NotNull Project project, @NotNull String title, @NotNull String message) {
Notification notification = new Notification(GithubUtil.GITHUB_NOTIFICATION_GROUP, title, message, NotificationType.WARNING);
Notificator.getInstance(project).notify(notification);
}
@NotNull
private static String prepareJsonRequest(@NotNull String description, boolean isPrivate, @NotNull List<NamedContent> contents) {
JsonObject json = new JsonObject();
@@ -0,0 +1,145 @@
/*
* 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 org.jetbrains.plugins.github;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import git4idea.Notificator;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.io.IOException;
/**
* @author Aleksey Pivovarov
*/
public class GithubNotifications {
private static final Logger LOG = Logger.getInstance(GithubNotifications.class);
private static final String GITHUB_NOTIFICATION_GROUP = "github";
public static void showInfo(@NotNull Project project, @NotNull String title, @NotNull String message) {
Notification notification = new Notification(GITHUB_NOTIFICATION_GROUP, title, message, NotificationType.INFORMATION);
Notificator.getInstance(project).notify(notification);
}
public static void showWarning(@NotNull Project project, @NotNull String title, @NotNull String message) {
Notification notification = new Notification(GITHUB_NOTIFICATION_GROUP, title, message, NotificationType.WARNING);
Notificator.getInstance(project).notify(notification);
}
public static void showError(@NotNull Project project, @NotNull String title, @NotNull String message) {
Notification notification = new Notification(GITHUB_NOTIFICATION_GROUP, title, message, NotificationType.ERROR);
Notificator.getInstance(project).notify(notification);
}
public static void showError(@NotNull Project project, @NotNull String title, @NotNull IOException e) {
Notification notification =
new Notification(GITHUB_NOTIFICATION_GROUP, title, GithubUtil.getErrorTextFromException(e), NotificationType.ERROR);
Notificator.getInstance(project).notify(notification);
}
public static void showInfoURL(@NotNull Project project, @NotNull String title, @NotNull String message, @NotNull String url) {
Notification notification =
new Notification(GITHUB_NOTIFICATION_GROUP, title, "<a href='" + url + "'>" + message + "</a>", NotificationType.INFORMATION,
NotificationListener.URL_OPENING_LISTENER);
Notificator.getInstance(project).notify(notification);
}
public static void showInfoDialog(final @NotNull Project project, final @NotNull String title, final @NotNull String message) {
if (EventQueue.isDispatchThread()) {
Messages.showInfoMessage(project, message, title);
}
else {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
Messages.showInfoMessage(project, message, title);
}
});
}
catch (Exception e) {
LOG.error("Notification error", e);
}
}
}
public static void showWarningDialog(final @NotNull Project project, final @NotNull String title, final @NotNull String message) {
if (EventQueue.isDispatchThread()) {
Messages.showWarningDialog(project, message, title);
}
else {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
Messages.showWarningDialog(project, message, title);
}
});
}
catch (Exception e) {
LOG.error("Notification error", e);
}
}
}
public static void showErrorDialog(final @NotNull Project project, final @NotNull String title, final @NotNull String message) {
if (EventQueue.isDispatchThread()) {
Messages.showErrorDialog(project, message, title);
}
else {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(project, message, title);
}
});
}
catch (Exception e) {
LOG.error("Notification error", e);
}
}
}
public static int showYesNoDialog(final @NotNull Project project, final @NotNull String title, final @NotNull String message) {
if (EventQueue.isDispatchThread()) {
return Messages.showYesNoDialog(project, message, title, Messages.getQuestionIcon());
}
else {
try {
final Ref<Integer> result = new Ref<Integer>();
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
result.set(Messages.showYesNoDialog(project, message, title, Messages.getQuestionIcon()));
}
});
return result.get();
}
catch (Exception e) {
LOG.error("Notification error", e);
return Messages.CANCEL;
}
}
}
}
@@ -106,8 +106,8 @@ public class GithubRebaseAction extends DumbAwareAction {
final String login = GithubSettings.getInstance().getLogin();
final int index = pushUrl.lastIndexOf(login);
if (index == -1) {
Messages.showErrorDialog(project, "Github remote repository doesn't seem to be your own repository: " + pushUrl,
CANNOT_PERFORM_GITHUB_REBASE);
GithubNotifications.showErrorDialog(project, "Github remote repository doesn't seem to be your own repository: " + pushUrl,
CANNOT_PERFORM_GITHUB_REBASE);
return;
}
String repoName = pushUrl.substring(index + login.length() + 1);
@@ -130,14 +130,14 @@ public class GithubRebaseAction extends DumbAwareAction {
}
});
if (repositoryInfoRef.isNull()) {
Messages.showErrorDialog(project, "Github repository doesn't seem to be your own repository: " + pushUrl,
CANNOT_PERFORM_GITHUB_REBASE);
GithubNotifications.showErrorDialog(project, "Github repository doesn't seem to be your own repository: " + pushUrl,
CANNOT_PERFORM_GITHUB_REBASE);
return;
}
if (!repositoryInfoRef.get().isFork()) {
Messages
.showErrorDialog(project, "Github repository '" + finalRepoName + "' is not a forked one", CANNOT_PERFORM_GITHUB_REBASE);
GithubNotifications
.showErrorDialog(project, CANNOT_PERFORM_GITHUB_REBASE, "Github repository '" + finalRepoName + "' is not a forked one");
return;
}
@@ -160,17 +160,16 @@ public class GithubRebaseAction extends DumbAwareAction {
}
catch (IOException e) {
LOG.info(e);
GithubUtil.notifyError(project, "Couldn't get information about the repository", GithubUtil.getErrorTextFromException(e));
GithubNotifications.showError(project, "Couldn't get information about the repository", e);
}
}
});
final String parentRepoUrl = parentRepoUrlRef.get();
if (remoteForForkParentRepo.isNull()) {
final int result = Messages.showYesNoDialog(project, "It is necessary to have '" +
parentRepoUrl +
"' as a configured remote. Add remote?", "Github Rebase",
Messages.getQuestionIcon());
final int result = GithubNotifications.showYesNoDialog(project, "Github Rebase", "It is necessary to have '" +
parentRepoUrl +
"' as a configured remote. Add remote?");
if (result != Messages.OK){
return;
}
@@ -192,7 +191,8 @@ public class GithubRebaseAction extends DumbAwareAction {
addRemoteHandler.addParameters("add", remoteForForkParentRepo.get(), parentRepoUrl);
addRemoteHandler.run();
if (addRemoteHandler.getExitCode() != 0) {
showErrorMessage(project, "Failed to add GitHub remote: '" + parentRepoUrl + "'", indicator);
GithubNotifications
.showErrorDialog(project, CANNOT_PERFORM_GITHUB_REBASE, "Failed to add GitHub remote: '" + parentRepoUrl + "'");
}
// catch newly added remote
@@ -200,7 +200,7 @@ public class GithubRebaseAction extends DumbAwareAction {
}
catch (VcsException e1) {
final String message = "Error happened during git operation: " + e1.getMessage();
showErrorMessage(project, message, indicator);
GithubNotifications.showErrorDialog(project, CANNOT_PERFORM_GITHUB_REBASE, message);
}
}
@@ -245,13 +245,4 @@ public class GithubRebaseAction extends DumbAwareAction {
}
return true;
}
private static void showErrorMessage(final Project project, final String message, ProgressIndicator indicator) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(project, message, CANNOT_PERFORM_GITHUB_REBASE);
}
}, indicator.getModalityState());
}
}
@@ -17,9 +17,6 @@ package org.jetbrains.plugins.github;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
@@ -30,7 +27,6 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
@@ -41,7 +37,6 @@ import com.intellij.util.ThrowableConsumer;
import com.intellij.util.containers.HashSet;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.Notificator;
import git4idea.actions.BasicAction;
import git4idea.actions.GitInit;
import git4idea.commands.*;
@@ -109,7 +104,8 @@ public class GithubShareAction extends DumbAwareAction {
boolean externalRemoteDetected = false;
if (gitDetected) {
if (GithubUtil.isRepositoryOnGitHub(gitRepository)) {
showNotificationWithLink(project, "Project is already on GitHub", "GitHub", StringUtil.notNullize(GithubUtil.findGithubRemoteUrl(gitRepository)));
GithubNotifications.showInfoURL(project, "Project is already on GitHub", "GitHub",
StringUtil.notNullize(GithubUtil.findGithubRemoteUrl(gitRepository)));
return;
}
else {
@@ -157,7 +153,7 @@ public class GithubShareAction extends DumbAwareAction {
}
});
if (!exceptionRef.isNull()) {
Messages.showErrorDialog(exceptionRef.get().getMessage(), "Failed to connect to GitHub");
GithubNotifications.showErrorDialog(project, "Failed to connect to GitHub", exceptionRef.get().getMessage());
return;
}
if (repoNamesRef.isNull() || userInfoRef.isNull()) {
@@ -188,7 +184,7 @@ public class GithubShareAction extends DumbAwareAction {
LOG.info("Successfully created GitHub repository");
}
else {
showErrorDialog(project, "Failed to create new GitHub repository", "Create GitHub Repository", indicator);
GithubNotifications.showErrorDialog(project, "Create GitHub Repository", "Failed to create new GitHub repository");
return;
}
@@ -216,12 +212,13 @@ public class GithubShareAction extends DumbAwareAction {
addRemoteHandler.run();
repository.update();
if (addRemoteHandler.getExitCode() != 0) {
showErrorDialog("Failed to add GitHub repository as remote", "Failed to add GitHub repository as remote", indicator);
GithubNotifications
.showErrorDialog(project, "Failed to add GitHub repository as remote", "Failed to add GitHub repository as remote");
return;
}
}
catch (VcsException e) {
showErrorDialog(e.getMessage(), "Failed to add GitHub repository as remote", indicator);
GithubNotifications.showErrorDialog(project, "Failed to add GitHub repository as remote", e.getMessage());
LOG.info("Failed to add GitHub as remote: " + e.getMessage());
return;
}
@@ -237,15 +234,10 @@ public class GithubShareAction extends DumbAwareAction {
Git git = ServiceManager.getService(Git.class);
GitCommandResult result = git.push(repository, remoteName, remoteUrl, "refs/heads/master:refs/heads/master");
if (result.success()) {
Notificator.getInstance(project).notify(
new Notification(GithubUtil.GITHUB_NOTIFICATION_GROUP, "Success", "Successfully created project '" + name + "' on GitHub",
NotificationType.INFORMATION));
GithubNotifications.showInfo(project, "Success", "Successfully created project '" + name + "' on GitHub");
}
else {
Notification notification = new Notification(GithubUtil.GITHUB_NOTIFICATION_GROUP, "Push to GitHub failed",
"Push failed: <br/>" + result.getErrorOutputAsHtmlString(),
NotificationType.ERROR);
Notificator.getInstance(project).notify(notification);
GithubNotifications.showError(project, "Push to GitHub failed", "Push failed: <br/>" + result.getErrorOutputAsHtmlString());
}
}
catch (IOException e) {
@@ -254,7 +246,7 @@ public class GithubShareAction extends DumbAwareAction {
}
}.queue();
if (!exceptionRef.isNull()) {
Messages.showErrorDialog(exceptionRef.get().getMessage(), "Failed to create new GitHub repository");
GithubNotifications.showErrorDialog(project, "Failed to create new GitHub repository", exceptionRef.get().getMessage());
}
}
@@ -310,7 +302,7 @@ public class GithubShareAction extends DumbAwareAction {
// get repository
final GitVcs gitVcs = GitVcs.getInstance(project);
if (gitVcs == null){
showErrorDialog(project, "Cannot find git initialized", "Failed to share", indicator);
GithubNotifications.showErrorDialog(project, "Failed to share", "Cannot find git initialized");
return false;
}
@@ -321,7 +313,7 @@ public class GithubShareAction extends DumbAwareAction {
}
GitRepository repository = repositoryManager.getRepositoryForRoot(root);
if (repository == null) {
showErrorDialog(project, "Cannot find git repository for root " + root, "Failed to share", indicator);
GithubNotifications.showErrorDialog(project, "Failed to share", "Cannot find git repository for root " + root);
return false;
}
if (!repository.isFresh()) {
@@ -345,7 +337,7 @@ public class GithubShareAction extends DumbAwareAction {
}, indicator.getModalityState());
final Collection<VirtualFile> files2add = dialog.getSelectedFiles();
if (!dialog.isOK() || files2add.isEmpty()) {
showErrorDialog(project, "No files to commit", "Failed to commit file during post activities", indicator);
GithubNotifications.showErrorDialog(project, "Failed to commit file during post activities", "No files to commit");
return false;
}
GitFileUtils.addFiles(project, root, files2add);
@@ -359,39 +351,12 @@ public class GithubShareAction extends DumbAwareAction {
}
catch (VcsException e) {
LOG.info("Failed to perform initial commit");
showErrorDialog(project, e.getMessage(), "Failed to commit file during post activities", indicator);
GithubNotifications.showErrorDialog(project, "Failed to commit file during post activities", e.getMessage());
return false;
}
return true;
}
private static void showErrorDialog(final String message, final String title, ProgressIndicator indicator) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(message, title);
}
}, indicator.getModalityState());
}
private static void showErrorDialog(final Project project, final String message, final String title, ProgressIndicator indicator) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
@Override
public void run() {
Messages.showErrorDialog(project, message, title);
}
}, indicator.getModalityState());
}
private static void showNotificationWithLink(@NotNull Project project,
@NotNull String message,
@NotNull String title,
@NotNull final String url) {
Notification notification = new Notification(GithubUtil.GITHUB_NOTIFICATION_GROUP, message, "<a href='" + url + "'>" + title + "</a>",
NotificationType.INFORMATION, NotificationListener.URL_OPENING_LISTENER);
Notificator.getInstance(project).notify(notification);
}
private static class GithubUntrackedFilesDialog extends SelectFilesDialog {
public GithubUntrackedFilesDialog(@NotNull Project project, @NotNull List<VirtualFile> untrackedFiles) {
@@ -17,14 +17,11 @@ package org.jetbrains.plugins.github;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ThrowableConsumer;
import git4idea.config.GitVcsApplicationSettings;
@@ -53,8 +50,6 @@ public class GithubUtil {
public static final Logger LOG = Logger.getInstance("github");
static final String GITHUB_NOTIFICATION_GROUP = "github";
@Nullable
public static GithubAuthData runAndGetValidAuth(@NotNull Project project,
@NotNull ProgressIndicator indicator,
@@ -251,13 +246,13 @@ public class GithubUtil {
version = GitVersion.identifyVersion(executable);
}
catch (Exception e) {
Messages.showErrorDialog(project, e.getMessage(), GitBundle.getString("find.git.error.title"));
GithubNotifications.showErrorDialog(project, GitBundle.getString("find.git.error.title"), e.getMessage());
return false;
}
if (!version.isSupported()) {
Messages.showWarningDialog(project, GitBundle.message("find.git.unsupported.message", version.toString(), GitVersion.MIN),
GitBundle.getString("find.git.success.title"));
GithubNotifications.showWarningDialog(project, GitBundle.message("find.git.unsupported.message", version.toString(), GitVersion.MIN),
GitBundle.getString("find.git.success.title"));
return false;
}
return true;
@@ -294,22 +289,22 @@ public class GithubUtil {
if (url.startsWith(getHttpsUrl())) {
index = url.lastIndexOf('/');
if (index == -1) {
Messages
.showErrorDialog(project, "Cannot extract info about repository name: " + url, GithubOpenInBrowserAction.CANNOT_OPEN_IN_BROWSER);
GithubNotifications
.showError(project, "Cannot extract info about repository: " + url, GithubOpenInBrowserAction.CANNOT_OPEN_IN_BROWSER);
return null;
}
index = url.substring(0, index).lastIndexOf('/');
if (index == -1) {
Messages
.showErrorDialog(project, "Cannot extract info about repository owner: " + url, GithubOpenInBrowserAction.CANNOT_OPEN_IN_BROWSER);
GithubNotifications
.showError(project, "Cannot extract info about repository: " + url, GithubOpenInBrowserAction.CANNOT_OPEN_IN_BROWSER);
return null;
}
}
else {
index = url.lastIndexOf(':');
if (index == -1) {
Messages.showErrorDialog(project, "Cannot extract info about repository name and owner: " + url,
GithubOpenInBrowserAction.CANNOT_OPEN_IN_BROWSER);
GithubNotifications
.showError(project, "Cannot extract info about repository: " + url, GithubOpenInBrowserAction.CANNOT_OPEN_IN_BROWSER);
return null;
}
}
@@ -365,8 +360,4 @@ public class GithubUtil {
return e.getMessage();
}
public static void notifyError(@NotNull Project project, @NotNull String title, @NotNull String message) {
new Notification(GITHUB_NOTIFICATION_GROUP, title, message, NotificationType.ERROR).notify(project);
}
}