From 37574d8f5a27f55334ad31fa68634e4f90f40b2a Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 6 May 2010 17:12:38 +0400 Subject: [PATCH] attach sources when multiple libraries found for jar --- .../AttachSourcesNotificationProvider.java | 100 ++++++++++++------ .../codeInsight/AttachSourcesProvider.java | 7 +- .../utils/MavenAttachSourcesProvider.java | 24 ++--- 3 files changed, 85 insertions(+), 46 deletions(-) diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java index 7f2ea324eaf8..6e67899786e3 100644 --- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java +++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java @@ -24,31 +24,31 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; -import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; -import com.intellij.openapi.fileEditor.impl.EditorWindow; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.PathUIUtils; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListSeparator; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.ActionCallback; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import com.intellij.psi.impl.compiled.ClsClassImpl; -import com.intellij.psi.impl.compiled.ClsFileImpl; -import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.EditorNotifications; import com.intellij.ui.GuiUtils; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.Comparator; -import java.util.List; -import java.util.TreeSet; +import java.util.*; /** * @author Dmitry Avdeev @@ -80,8 +80,8 @@ public class AttachSourcesNotificationProvider implements EditorNotifications.Pr public EditorNotificationPanel createNotificationPanel(final VirtualFile file) { if (file.getFileType() != JavaClassFileType.INSTANCE) return null; - final Library library = findLibrary(file); - if (library == null) return null; + final List libraries = findOrderEntriesContainingFile(file); + if (libraries == null) return null; PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); final String fqn = JavaEditorFileSwapper.getFQN(psiFile); @@ -92,7 +92,7 @@ public class AttachSourcesNotificationProvider implements EditorNotifications.Pr final EditorNotificationPanel panel = new EditorNotificationPanel(); panel.setText(ProjectBundle.message("library.sources.not.found")); - final AttachSourcesProvider.AttachSourcesAction defaultAction = createDefaultAction(library, file); + final AttachSourcesProvider.AttachSourcesAction defaultAction = createDefaultAction(); TreeSet actions = new TreeSet( new Comparator() { @@ -106,13 +106,13 @@ public class AttachSourcesNotificationProvider implements EditorNotifications.Pr actions.add(defaultAction); for (AttachSourcesProvider each : Extensions.getExtensions(EXTENSION_POINT_NAME)) { - actions.addAll(each.getActions(library, psiFile)); + actions.addAll(each.getActions(libraries, psiFile)); } for (final AttachSourcesProvider.AttachSourcesAction each : actions) { panel.createActionLabel(GuiUtils.getTextWithoutMnemonicEscaping(each.getName()), new Runnable() { public void run() { - if (library != findLibrary(file)) { + if (!Comparing.equal(libraries, findOrderEntriesContainingFile(file))) { Messages.showErrorDialog(myProject, "Cannot find library for " + StringUtil.getShortName(fqn), "Error"); return; } @@ -128,7 +128,7 @@ public class AttachSourcesNotificationProvider implements EditorNotifications.Pr }); } }; - ActionCallback callback = each.perform(); + ActionCallback callback = each.perform(findOrderEntriesContainingFile(file)); callback.doWhenRejected(onFinish); callback.doWhenDone(onFinish); } @@ -138,7 +138,7 @@ public class AttachSourcesNotificationProvider implements EditorNotifications.Pr return panel; } - private AttachSourcesProvider.AttachSourcesAction createDefaultAction(final Library library, final VirtualFile file) { + private AttachSourcesProvider.AttachSourcesAction createDefaultAction() { return new AttachSourcesProvider.AttachSourcesAction() { public String getName() { return ProjectBundle.message("module.libraries.attach.sources.button"); @@ -148,41 +148,79 @@ public class AttachSourcesNotificationProvider implements EditorNotifications.Pr return ProjectBundle.message("library.attach.sources.action.busy.text"); } - public ActionCallback perform() { + public ActionCallback perform(final List libraries) { FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, true, false, true, true); descriptor.setTitle(ProjectBundle.message("library.attach.sources.action")); descriptor.setDescription(ProjectBundle.message("library.attach.sources.description")); - VirtualFile[] roots = library.getFiles(OrderRootType.CLASSES); + final Library firstLibrary = libraries.get(0).getLibrary(); + VirtualFile[] roots = firstLibrary != null ? firstLibrary.getFiles(OrderRootType.CLASSES) : VirtualFile.EMPTY_ARRAY; VirtualFile[] candidates = FileChooser.chooseFiles(myProject, descriptor, roots.length == 0 ? null : roots[0]); final VirtualFile[] files = PathUIUtils.scanAndSelectDetectedJavaSourceRoots(myProject, candidates); if (files.length == 0) { return new ActionCallback.Rejected(); } - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - final Library library = findLibrary(file); - assert library != null; - Library.ModifiableModel model = library.getModifiableModel(); - for (VirtualFile virtualFile : files) { - model.addRoot(virtualFile, OrderRootType.SOURCES); + if (libraries.size() == 1) { + appendSources(firstLibrary, files); + } else { + final List librariesToAppendSourcesTo = new ArrayList(libraries); + librariesToAppendSourcesTo.add(null); + JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Multiple libraries contain file.
Choose libraries to attach sources to", librariesToAppendSourcesTo){ + @Override + public ListSeparator getSeparatorAbove(LibraryOrderEntry value) { + return value == null ? new ListSeparator() : null; } - model.commit(); - } - }); + + @NotNull + @Override + public String getTextFor(LibraryOrderEntry value) { + if (value != null) { + return value.getPresentableName() + " (" + value.getOwnerModule().getName() + ")"; + } + else { + return "All"; + } + } + + @Override + public PopupStep onChosen(LibraryOrderEntry libraryOrderEntry, boolean finalChoice) { + if (libraryOrderEntry != null) { + appendSources(libraryOrderEntry.getLibrary(), files); + } else { + for (LibraryOrderEntry libOrderEntry : libraries) { + appendSources(libOrderEntry.getLibrary(), files); + } + } + return FINAL_CHOICE; + } + }).showCenteredInCurrentWindow(myProject); + } return new ActionCallback.Done(); } }; } + private static void appendSources(final Library library, final VirtualFile[] files) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + Library.ModifiableModel model = library.getModifiableModel(); + for (VirtualFile virtualFile : files) { + model.addRoot(virtualFile, OrderRootType.SOURCES); + } + model.commit(); + } + }); + } + @Nullable - private Library findLibrary(VirtualFile file) { + private List findOrderEntriesContainingFile(VirtualFile file) { + final List libs = new ArrayList(); List entries = ProjectRootManager.getInstance(myProject).getFileIndex().getOrderEntriesForFile(file); for (OrderEntry entry : entries) { if (entry instanceof LibraryOrderEntry) { - return ((LibraryOrderEntry)entry).getLibrary(); + libs.add ((LibraryOrderEntry)entry); } } - return null; + return libs.isEmpty() ? null : libs; } } diff --git a/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java b/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java index a9e0a6b67d11..f0651c6d88e1 100644 --- a/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java +++ b/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java @@ -15,18 +15,19 @@ */ package com.intellij.codeInsight; -import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.util.ActionCallback; import com.intellij.psi.PsiFile; import java.util.Collection; +import java.util.List; public interface AttachSourcesProvider { - Collection getActions(Library library, PsiFile psiFile); + Collection getActions(List orderEntries, PsiFile psiFile); interface AttachSourcesAction { String getName(); String getBusyText(); - ActionCallback perform(); + ActionCallback perform(List orderEntriesContainingFile); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenAttachSourcesProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenAttachSourcesProvider.java index 54269460b2f5..49467a4918ba 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenAttachSourcesProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenAttachSourcesProvider.java @@ -20,9 +20,9 @@ import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; import com.intellij.psi.PsiFile; @@ -31,15 +31,13 @@ import org.jetbrains.idea.maven.importing.MavenRootModelAdapter; import org.jetbrains.idea.maven.project.*; import javax.swing.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.util.*; public class MavenAttachSourcesProvider implements AttachSourcesProvider { - public Collection getActions(final Library library, final PsiFile psiFile) { + public Collection getActions(final List orderEntries, final PsiFile psiFile) { Collection projects = getMavenProjects(psiFile); if (projects.isEmpty()) return Collections.emptyList(); - if (findArtifacts(projects, library).isEmpty()) return Collections.emptyList(); + if (findArtifacts(projects, orderEntries).isEmpty()) return Collections.emptyList(); return Collections.singleton(new AttachSourcesAction() { public String getName() { @@ -50,14 +48,14 @@ public class MavenAttachSourcesProvider implements AttachSourcesProvider { return ProjectBundle.message("maven.action.download.sources.busy.text"); } - public ActionCallback perform() { + public ActionCallback perform(List orderEntries) { // may have been changed by this time... Collection mavenProjects = getMavenProjects(psiFile); if (mavenProjects.isEmpty()) return new ActionCallback.Rejected(); MavenProjectsManager manager = MavenProjectsManager.getInstance(psiFile.getProject()); - Collection artifacts = findArtifacts(mavenProjects, library); + Collection artifacts = findArtifacts(mavenProjects, orderEntries); if (artifacts.isEmpty()) return new ActionCallback.Rejected(); final AsyncResult result = new AsyncResult(); @@ -105,16 +103,18 @@ public class MavenAttachSourcesProvider implements AttachSourcesProvider { }); } - private Collection findArtifacts(Collection mavenProjects, Library library) { + private static Collection findArtifacts(Collection mavenProjects, List orderEntries) { Collection artifacts = new THashSet(); for (MavenProject each : mavenProjects) { - final MavenArtifact artifact = MavenRootModelAdapter.findArtifact(each, library); - if (artifact != null) artifacts.add(artifact); + for (LibraryOrderEntry entry : orderEntries) { + final MavenArtifact artifact = MavenRootModelAdapter.findArtifact(each, entry.getLibrary()); + if (artifact != null) artifacts.add(artifact); + } } return artifacts; } - private Collection getMavenProjects(PsiFile psiFile) { + private static Collection getMavenProjects(PsiFile psiFile) { Project project = psiFile.getProject(); Collection result = new ArrayList(); for (OrderEntry each : ProjectRootManager.getInstance(project).getFileIndex().getOrderEntriesForFile(psiFile.getVirtualFile())) {