From 6998b3f6c9d9105dfa7e30b776eff24f0c29643e Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 10 Oct 2011 13:10:43 +0400 Subject: [PATCH] allow to ignore invalid facets from error notification --- .../ArtifactLoadingErrorDescription.java | 8 +- .../impl/FacetLoadingErrorDescription.java | 13 +-- .../module/ConfigurationErrorDescription.java | 14 +-- .../module/ConfigurationErrorType.java | 37 ++++++++ .../impl/ModuleLoadingErrorDescription.java | 8 +- .../ProjectLoadingErrorsNotifierImpl.java | 87 ++++++++----------- .../impl/RemoveInvalidElementsDialog.java | 32 ++++--- .../src/messages/ProjectBundle.properties | 7 +- 8 files changed, 122 insertions(+), 84 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorType.java diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java index 5ca3007d10e4..2b990dc055ef 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java @@ -18,6 +18,7 @@ package com.intellij.packaging.impl.artifacts; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.module.ConfigurationErrorDescription; +import com.intellij.openapi.module.ConfigurationErrorType; import com.intellij.openapi.project.Project; import com.intellij.packaging.artifacts.ArtifactManager; import com.intellij.packaging.artifacts.ModifiableArtifactModel; @@ -26,17 +27,18 @@ import com.intellij.packaging.artifacts.ModifiableArtifactModel; * @author nik */ public class ArtifactLoadingErrorDescription extends ConfigurationErrorDescription { + private static final ConfigurationErrorType INVALID_ARTIFACT = new ConfigurationErrorType("artifact", false); private final Project myProject; private final InvalidArtifact myArtifact; public ArtifactLoadingErrorDescription(Project project, InvalidArtifact artifact) { - super(artifact.getName(), "artifact", artifact.getErrorMessage()); + super(artifact.getName(), artifact.getErrorMessage(), INVALID_ARTIFACT); myProject = project; myArtifact = artifact; } @Override - public void removeInvalidElement() { + public void ignoreInvalidElement() { final ModifiableArtifactModel model = ArtifactManager.getInstance(myProject).createModifiableModel(); model.removeArtifact(myArtifact); new WriteAction() { @@ -47,7 +49,7 @@ public class ArtifactLoadingErrorDescription extends ConfigurationErrorDescripti } @Override - public String getRemoveConfirmationMessage() { + public String getIgnoreConfirmationMessage() { return "Would you like to remove artifact '" + myArtifact.getName() + "?"; } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetLoadingErrorDescription.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetLoadingErrorDescription.java index e525849c232f..26cd306d5e79 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/FacetLoadingErrorDescription.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetLoadingErrorDescription.java @@ -17,28 +17,31 @@ package com.intellij.facet.impl; import com.intellij.facet.impl.invalid.InvalidFacet; +import com.intellij.facet.impl.invalid.InvalidFacetManager; import com.intellij.openapi.module.ConfigurationErrorDescription; +import com.intellij.openapi.module.ConfigurationErrorType; import com.intellij.openapi.project.ProjectBundle; /** * @author nik */ public class FacetLoadingErrorDescription extends ConfigurationErrorDescription { + private static final ConfigurationErrorType INVALID_FACET = new ConfigurationErrorType(ProjectBundle.message("element.kind.name.facet"), true); private final InvalidFacet myFacet; public FacetLoadingErrorDescription(final InvalidFacet facet) { - super(facet.getName() + " (" + facet.getModule().getName() + ")", ProjectBundle.message("element.kind.name.facet"), facet.getErrorMessage()); + super(facet.getName() + " (" + facet.getModule().getName() + ")", facet.getErrorMessage(), INVALID_FACET); myFacet = facet; } @Override - public String getRemoveConfirmationMessage() { - return ProjectBundle.message("confirmation.message.would.you.like.to.remove.facet", myFacet.getName(), myFacet.getModule().getName()); + public String getIgnoreConfirmationMessage() { + return ProjectBundle.message("confirmation.message.would.you.like.to.ignore.facet", myFacet.getName(), myFacet.getModule().getName()); } @Override - public void removeInvalidElement() { - FacetUtil.deleteFacet(myFacet); + public void ignoreInvalidElement() { + InvalidFacetManager.getInstance(myFacet.getModule().getProject()).setIgnored(myFacet, true); } @Override diff --git a/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorDescription.java b/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorDescription.java index e295fca5277d..1a26e430ba98 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorDescription.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorDescription.java @@ -21,12 +21,12 @@ package com.intellij.openapi.module; */ public abstract class ConfigurationErrorDescription { private final String myElementName; - private final String myElementKind; private final String myDescription; + private ConfigurationErrorType myErrorType; - protected ConfigurationErrorDescription(String elementName, String elementKind, String description) { + protected ConfigurationErrorDescription(String elementName, String description, ConfigurationErrorType errorType) { myElementName = elementName; - myElementKind = elementKind; + myErrorType = errorType; myDescription = description; } @@ -34,17 +34,17 @@ public abstract class ConfigurationErrorDescription { return myElementName; } - public String getElementKind() { - return myElementKind; + public ConfigurationErrorType getErrorType() { + return myErrorType; } public String getDescription() { return myDescription; } - public abstract void removeInvalidElement(); + public abstract void ignoreInvalidElement(); - public abstract String getRemoveConfirmationMessage(); + public abstract String getIgnoreConfirmationMessage(); public boolean isValid() { return true; diff --git a/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorType.java b/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorType.java new file mode 100644 index 000000000000..e71d29633bf9 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/module/ConfigurationErrorType.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2011 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.module; + +/** + * @author nik + */ +public class ConfigurationErrorType { + private String myElementKind; + private boolean myCanIgnore; + + public ConfigurationErrorType(String elementKind, boolean canIgnore) { + myElementKind = elementKind; + myCanIgnore = canIgnore; + } + + public String getElementKind() { + return myElementKind; + } + + public boolean canIgnore() { + return myCanIgnore; + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleLoadingErrorDescription.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleLoadingErrorDescription.java index 063ae7820153..cbdb156c5cbd 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleLoadingErrorDescription.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleLoadingErrorDescription.java @@ -17,6 +17,7 @@ package com.intellij.openapi.module.impl; import com.intellij.openapi.module.ConfigurationErrorDescription; +import com.intellij.openapi.module.ConfigurationErrorType; import com.intellij.openapi.project.ProjectBundle; import java.io.File; @@ -25,12 +26,13 @@ import java.io.File; * @author nik */ public class ModuleLoadingErrorDescription extends ConfigurationErrorDescription { + private static final ConfigurationErrorType INVALID_MODULE = new ConfigurationErrorType(ProjectBundle.message("element.kind.name.module"), false); private final ModuleManagerImpl.ModulePath myModulePath; private final ModuleManagerImpl myModuleManager; private ModuleLoadingErrorDescription(final String description, final ModuleManagerImpl.ModulePath modulePath, ModuleManagerImpl moduleManager, final String elementName) { - super(elementName, ProjectBundle.message("element.kind.name.module"), description); + super(elementName, description, INVALID_MODULE); myModulePath = modulePath; myModuleManager = moduleManager; } @@ -40,12 +42,12 @@ public class ModuleLoadingErrorDescription extends ConfigurationErrorDescription } @Override - public void removeInvalidElement() { + public void ignoreInvalidElement() { myModuleManager.removeFailedModulePath(myModulePath); } @Override - public String getRemoveConfirmationMessage() { + public String getIgnoreConfirmationMessage() { return ProjectBundle.message("module.remove.from.project.confirmation", getElementName()); } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java index 7ce18ccb7fc2..ab63d2bd19f2 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java @@ -22,6 +22,7 @@ import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.module.ConfigurationErrorDescription; +import com.intellij.openapi.module.ConfigurationErrorType; import com.intellij.openapi.module.ProjectLoadingErrorsNotifier; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; @@ -29,12 +30,10 @@ import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; -import gnu.trove.TObjectIntHashMap; -import gnu.trove.TObjectIntProcedure; +import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import javax.swing.event.HyperlinkEvent; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -43,7 +42,7 @@ import java.util.List; * @author nik */ public class ProjectLoadingErrorsNotifierImpl extends ProjectLoadingErrorsNotifier { - private final List myErrors = new ArrayList(); + private final MultiMap myErrors = new MultiMap(); private final Object myLock = new Object(); private final Project myProject; @@ -63,7 +62,9 @@ public class ProjectLoadingErrorsNotifierImpl extends ProjectLoadingErrorsNotifi boolean first; synchronized (myLock) { first = myErrors.isEmpty(); - myErrors.addAll(errorDescriptions); + for (ConfigurationErrorDescription description : errorDescriptions) { + myErrors.putValue(description.getErrorType(), description); + } } if (myProject.isInitialized()) { fireNotifications(); @@ -78,63 +79,47 @@ public class ProjectLoadingErrorsNotifierImpl extends ProjectLoadingErrorsNotifi } private void fireNotifications() { - final ConfigurationErrorDescription[] descriptions; + final MultiMap descriptionsMap = new MultiMap(); synchronized (myLock) { if (myErrors.isEmpty()) return; - descriptions = myErrors.toArray(new ConfigurationErrorDescription[myErrors.size()]); + descriptionsMap.putAllValues(myErrors); myErrors.clear(); } - final String invalidElements = getInvalidElementsString(descriptions); - final String errorText = ProjectBundle.message("error.message.configuration.cannot.load") + " " + invalidElements + " Details..."; + for (final ConfigurationErrorType type : descriptionsMap.keySet()) { + final Collection descriptions = descriptionsMap.get(type); + if (descriptions.isEmpty()) continue; - Notifications.Bus.notify(new Notification("Project Loading Error", "Error Loading Project", errorText, NotificationType.ERROR, - new NotificationListener() { - public void hyperlinkUpdate(@NotNull Notification notification, - @NotNull HyperlinkEvent event) { - final List validDescriptions = - ContainerUtil.findAll(descriptions, new Condition() { - public boolean value(ConfigurationErrorDescription errorDescription) { - return errorDescription.isValid(); - } - }); - RemoveInvalidElementsDialog - .showDialog(myProject, CommonBundle.getErrorTitle(), invalidElements, - validDescriptions); + final String invalidElements = getInvalidElementsString(type, descriptions); + final String errorText = ProjectBundle.message("error.message.configuration.cannot.load") + " " + invalidElements + " Details..."; - notification.expire(); - } - }), myProject); + Notifications.Bus.notify(new Notification("Project Loading Error", "Error Loading Project", errorText, NotificationType.ERROR, + new NotificationListener() { + public void hyperlinkUpdate(@NotNull Notification notification, + @NotNull HyperlinkEvent event) { + final List validDescriptions = + ContainerUtil.findAll(descriptions, new Condition() { + public boolean value(ConfigurationErrorDescription errorDescription) { + return errorDescription.isValid(); + } + }); + RemoveInvalidElementsDialog + .showDialog(myProject, CommonBundle.getErrorTitle(), type, invalidElements, + validDescriptions); + + notification.expire(); + } + }), myProject); + } } - private static String getInvalidElementsString(ConfigurationErrorDescription[] descriptions) { - if (descriptions.length == 1) { - final ConfigurationErrorDescription description = descriptions[0]; - return description.getElementKind() + " " + description.getElementName(); + private static String getInvalidElementsString(ConfigurationErrorType type, Collection descriptions) { + if (descriptions.size() == 1) { + final ConfigurationErrorDescription description = ContainerUtil.getFirstItem(descriptions); + return type.getElementKind() + " " + description.getElementName(); } - TObjectIntHashMap kind2count = new TObjectIntHashMap(); - for (ConfigurationErrorDescription description : descriptions) { - final String kind = description.getElementKind(); - if (!kind2count.contains(kind)) { - kind2count.put(kind, 1); - } - else { - kind2count.increment(kind); - } - } - - final StringBuilder message = new StringBuilder(); - kind2count.forEachEntry(new TObjectIntProcedure() { - public boolean execute(String a, int b) { - if (message.length() > 0) { - message.append(' ').append(ProjectBundle.message("text.and")).append(' '); - } - message.append(b).append(' ').append(b > 1 ? StringUtil.pluralize(a) : a); - return true; - } - }); - return message.toString(); + return descriptions.size() + " " + StringUtil.pluralize(type.getElementKind()); } } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java index 973d1f62b4f2..4fc802aeb62a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java @@ -16,8 +16,8 @@ package com.intellij.openapi.module.impl; -import com.intellij.CommonBundle; import com.intellij.openapi.module.ConfigurationErrorDescription; +import com.intellij.openapi.module.ConfigurationErrorType; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.ui.DialogWrapper; @@ -28,8 +28,10 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author nik @@ -40,10 +42,14 @@ public class RemoveInvalidElementsDialog extends DialogWrapper { private JLabel myDescriptionLabel; private final Map myCheckboxes = new HashMap(); - private RemoveInvalidElementsDialog(final String title, String invalidElements, final Project project, List errors) { + private RemoveInvalidElementsDialog(final String title, + ConfigurationErrorType type, + String invalidElements, + final Project project, + List errors) { super(project, true); setTitle(title); - myDescriptionLabel.setText(ProjectBundle.message("label.text.0.cannot.be.loaded", invalidElements)); + myDescriptionLabel.setText(ProjectBundle.message(type.canIgnore() ? "label.text.0.cannot.be.loaded.ignore" : "label.text.0.cannot.be.loaded.remove", invalidElements)); myContentPanel.setLayout(new VerticalFlowLayout()); for (ConfigurationErrorDescription error : errors) { JCheckBox checkBox = new JCheckBox(error.getElementName() + "."); @@ -62,32 +68,34 @@ public class RemoveInvalidElementsDialog extends DialogWrapper { myContentPanel.add(panel); } init(); - setOKButtonText(ProjectBundle.message("button.text.remove.selected")); + setOKButtonText(ProjectBundle.message(type.canIgnore() ? "button.text.ignore.selected" : "button.text.remove.selected")); setCancelButtonText(ProjectBundle.message("button.text.keep.all")); } - public static void showDialog(@NotNull Project project, @NotNull String title, @NotNull String invalidElements, + public static void showDialog(@NotNull Project project, + @NotNull String title, + ConfigurationErrorType type, + @NotNull String invalidElements, @NotNull List errors) { if (errors.isEmpty()) { return; } if (errors.size() == 1) { ConfigurationErrorDescription error = errors.get(0); - String message = error.getDescription() + "\n" + error.getRemoveConfirmationMessage(); - final int answer = Messages.showOkCancelDialog(project, message, title, CommonBundle.getNoButtonText(), - CommonBundle.getYesButtonText(), Messages.getErrorIcon()); + String message = error.getDescription() + "\n" + error.getIgnoreConfirmationMessage(); + final int answer = Messages.showYesNoDialog(project, message, title, Messages.getErrorIcon()); if (answer == 1) { - error.removeInvalidElement(); + error.ignoreInvalidElement(); } return; } - RemoveInvalidElementsDialog dialog = new RemoveInvalidElementsDialog(title, invalidElements, project, errors); + RemoveInvalidElementsDialog dialog = new RemoveInvalidElementsDialog(title, type, invalidElements, project, errors); dialog.show(); if (dialog.isOK()) { for (ConfigurationErrorDescription errorDescription : dialog.getSelectedItems()) { - errorDescription.removeInvalidElement(); + errorDescription.ignoreInvalidElement(); } } } diff --git a/platform/platform-resources-en/src/messages/ProjectBundle.properties b/platform/platform-resources-en/src/messages/ProjectBundle.properties index cf3e1051171a..8bfebb22c8f2 100644 --- a/platform/platform-resources-en/src/messages/ProjectBundle.properties +++ b/platform/platform-resources-en/src/messages/ProjectBundle.properties @@ -359,13 +359,14 @@ error.message.0.facet.must.be.placed.under.1.facet={0} facet must be placed unde error.message.0.cannot.be.placed.under.1={0} cannot be placed under {1} error.message.0.facets.are.not.allowed.in.1={0} facets are not allowed in {1} button.text.remove.selected=Remove Selected +button.text.ignore.selected=Ignore Selected button.text.keep.all=Keep All -confirmation.message.would.you.like.to.remove.facet=Would you like to remove facet ''{0}'' from module ''{1}''? +confirmation.message.would.you.like.to.ignore.facet=Would you like to ignore facet ''{0}'' from module ''{1}''? element.kind.name.facet=facet error.message.configuration.cannot.load=Cannot load -label.text.0.cannot.be.loaded={0} cannot be loaded. You can remove them from the project (no files will be deleted). -text.and=and +label.text.0.cannot.be.loaded.remove={0} cannot be loaded. You can remove them from the project (no files will be deleted). +label.text.0.cannot.be.loaded.ignore={0} cannot be loaded. You can mark them as ignored to suppress this error notification. #artifacts display.name.artifacts=Artifacts