'attach from maven' button downloads jars with modal progress dialog so they can be reliable added to library

This commit is contained in:
nik
2010-09-17 15:49:25 +04:00
parent 812f23a6fb
commit ecfdcd20a2
6 changed files with 63 additions and 44 deletions
@@ -82,6 +82,11 @@ public class ExistingLibraryEditor implements LibraryEditor {
getModel().addRoot(file, rootType);
}
@Override
public void addRoot(String url, OrderRootType rootType) {
getModel().addRoot(url, rootType);
}
@Override
public void addJarDirectory(VirtualFile file, boolean recursive) {
getModel().addJarDirectory(file, recursive);
@@ -33,6 +33,8 @@ public interface LibraryEditor extends Disposable {
void addRoot(VirtualFile file, OrderRootType rootType);
void addRoot(String url, OrderRootType rootType);
void addJarDirectory(VirtualFile file, boolean recursive);
void removeRoot(String url, OrderRootType rootType);
@@ -166,11 +166,11 @@ public class LibraryRootsComponent implements Disposable {
final LibraryTableAttachHandler[] handlers = LibraryTableAttachHandler.EP_NAME.getExtensions();
final LibraryEditor libraryEditor = getLibraryEditor();
if (handlers.length == 0 || myProject == null || !(libraryEditor instanceof ExistingLibraryEditor)) {
if (handlers.length == 0 || myProject == null) {
myAttachMoreButton.setVisible(false);
}
else {
myAttachMoreButton.addActionListener(new AttachMoreAction(handlers, (ExistingLibraryEditor)libraryEditor));
myAttachMoreButton.addActionListener(new AttachMoreAction(handlers, libraryEditor));
if (handlers.length == 1) {
myAttachMoreButton.setText(handlers[0].getLongName());
}
@@ -642,35 +642,44 @@ public class LibraryRootsComponent implements Disposable {
private class AttachMoreAction implements ActionListener {
private final LibraryTableAttachHandler[] myHandlers;
private final ExistingLibraryEditor myLibraryEditor;
private final LibraryEditor myLibraryEditor;
public AttachMoreAction(LibraryTableAttachHandler[] handlers, final ExistingLibraryEditor libraryEditor) {
public AttachMoreAction(LibraryTableAttachHandler[] handlers, final LibraryEditor libraryEditor) {
myHandlers = handlers;
myLibraryEditor = libraryEditor;
}
public void actionPerformed(ActionEvent e) {
final Ref<Library.ModifiableModel> modelRef = Ref.create(null);
final NullableComputable<Library.ModifiableModel> computable = new NullableComputable<Library.ModifiableModel>() {
public Library.ModifiableModel compute() {
if (myTreeBuilder == null) {
// The following lines were born in severe pain & suffering, please respect
final Library library = myLibraryEditor.getLibrary();
final InvocationHandler invocationHandler = Proxy.isProxyClass(library.getClass())? Proxy.getInvocationHandler(library) : null;
final Library realLibrary = invocationHandler instanceof ModuleEditor.ProxyDelegateAccessor? (Library)((ModuleEditor.ProxyDelegateAccessor)invocationHandler)
.getDelegate() : library;
final Module module = realLibrary instanceof LibraryImpl && ((LibraryImpl)realLibrary).isDisposed()? ((LibraryImpl)realLibrary).getModule() : null;
if (module != null && module.isDisposed()) return null; // no way
final Library targetLibrary = module != null? LibraryUtil.findLibrary(module, realLibrary.getName()) : realLibrary;
final Library.ModifiableModel model = targetLibrary.getModifiableModel();
modelRef.set(model);
return model;
final NullableComputable<Library.ModifiableModel> computable;
if (myLibraryEditor instanceof ExistingLibraryEditor) {
final ExistingLibraryEditor libraryEditor = (ExistingLibraryEditor)myLibraryEditor;
//todo[nik, greg] actually we cannot reliable find target library if the editor is closed so jars are downloaded under the modal progress dialog now
computable = new NullableComputable<Library.ModifiableModel>() {
public Library.ModifiableModel compute() {
if (myTreeBuilder == null) {
// The following lines were born in severe pain & suffering, please respect
final Library library = libraryEditor.getLibrary();
final InvocationHandler invocationHandler = Proxy.isProxyClass(library.getClass())? Proxy.getInvocationHandler(library) : null;
final Library realLibrary = invocationHandler instanceof ModuleEditor.ProxyDelegateAccessor? (Library)((ModuleEditor.ProxyDelegateAccessor)invocationHandler)
.getDelegate() : library;
final Module module = realLibrary instanceof LibraryImpl && ((LibraryImpl)realLibrary).isDisposed()? ((LibraryImpl)realLibrary).getModule() : null;
if (module != null && module.isDisposed()) return null; // no way
final Library targetLibrary = module != null? LibraryUtil.findLibrary(module, realLibrary.getName()) : realLibrary;
final Library.ModifiableModel model = targetLibrary.getModifiableModel();
modelRef.set(model);
return model;
}
else {
return libraryEditor.getModel();
}
}
else {
return myLibraryEditor.getModel();
}
}
};
};
}
else {
computable = null;
}
final Runnable successRunnable = new Runnable() {
public void run() {
if (modelRef.get() != null) {
@@ -679,8 +688,8 @@ public class LibraryRootsComponent implements Disposable {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
if (myTreeBuilder != null) myTreeBuilder.queueUpdate();
if (myProject != null) {
ModuleStructureConfigurable.getInstance(myProject).fireItemsChangeListener(myLibraryEditor.getLibrary());
if (myProject != null && myLibraryEditor instanceof ExistingLibraryEditor) {
ModuleStructureConfigurable.getInstance(myProject).fireItemsChangeListener(((ExistingLibraryEditor)myLibraryEditor).getLibrary());
}
}
});
@@ -694,7 +703,7 @@ public class LibraryRootsComponent implements Disposable {
}
};
if (myHandlers.length == 1) {
myHandlers[0].performAttach(myProject, computable).doWhenDone(successRunnable).doWhenRejected(rejectRunnable);
myHandlers[0].performAttach(myProject, myLibraryEditor, computable).doWhenDone(successRunnable).doWhenRejected(rejectRunnable);
}
else {
final ListPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<LibraryTableAttachHandler>(null, myHandlers) {
@@ -710,7 +719,7 @@ public class LibraryRootsComponent implements Disposable {
public PopupStep onChosen(final LibraryTableAttachHandler handler, final boolean finalChoice) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
handler.performAttach(myProject, computable).doWhenProcessed(successRunnable).doWhenRejected(rejectRunnable);
handler.performAttach(myProject, myLibraryEditor, computable).doWhenProcessed(successRunnable).doWhenRejected(rejectRunnable);
}
});
return PopupStep.FINAL_CHOICE;
@@ -33,5 +33,5 @@ public interface LibraryTableAttachHandler {
String getShortName();
Icon getIcon();
ActionCallback performAttach(Project project, NullableComputable<Library.ModifiableModel> modelProvider);
ActionCallback performAttach(Project project, LibraryEditor libraryEditor, NullableComputable<Library.ModifiableModel> modelProvider);
}
@@ -67,6 +67,11 @@ public class NewLibraryEditor implements LibraryEditor {
myRoots.get(rootType).add(file);
}
@Override
public void addRoot(String url, OrderRootType rootType) {
myRoots.get(rootType).add(url);
}
@Override
public void addJarDirectory(VirtualFile file, boolean recursive) {
myRoots.get(OrderRootType.CLASSES).add(file);
@@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryTableAttachHandler;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
@@ -42,6 +43,7 @@ import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.execution.SoutMavenConsole;
import org.jetbrains.idea.maven.facade.MavenEmbedderWrapper;
import org.jetbrains.idea.maven.facade.MavenFacadeManager;
@@ -73,7 +75,9 @@ public class RepositoryAttachHandler implements LibraryTableAttachHandler {
return MavenIcons.MAVEN_ICON;
}
public ActionCallback performAttach(final Project project, final NullableComputable<Library.ModifiableModel> modelProvider) {
public ActionCallback performAttach(final Project project,
final LibraryEditor libraryEditor,
final @Nullable NullableComputable<Library.ModifiableModel> modelProvider) {
MavenService.getInstance(project);
final RepositoryAttachDialog dialog = new RepositoryAttachDialog(project, false);
@@ -88,18 +92,12 @@ public class RepositoryAttachHandler implements LibraryTableAttachHandler {
final SmartList<MavenExtraArtifactType> extraTypes = new SmartList<MavenExtraArtifactType>();
if (attachSources) extraTypes.add(MavenExtraArtifactType.SOURCES);
if (attachJavaDoc) extraTypes.add(MavenExtraArtifactType.DOCS);
resolveLibrary(project, coord, extraTypes, dialog.getRepositories(), false, new Processor<List<MavenArtifact>>() {
resolveLibrary(project, coord, extraTypes, dialog.getRepositories(), true, new Processor<List<MavenArtifact>>() {
public boolean process(final List<MavenArtifact> artifacts) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
final Library.ModifiableModel modifiableModel = modelProvider.compute();
if (modifiableModel == null) {
callback.setRejected();
}
else {
replaceLibraryData(project, modifiableModel, artifacts, copyTo);
callback.setDone();
}
replaceLibraryData(project, libraryEditor, artifacts, copyTo);
callback.setDone();
}
});
final boolean nothingRetrieved = artifacts.isEmpty();
@@ -139,14 +137,14 @@ public class RepositoryAttachHandler implements LibraryTableAttachHandler {
}
private static void replaceLibraryData(Project project,
Library.ModifiableModel library,
LibraryEditor libraryEditor,
Collection<MavenArtifact> artifacts,
String copyTo) {
final String repoUrl = getLocalRepositoryUrl(project);
for (OrderRootType type : OrderRootType.getAllTypes()) {
for (String url : library.getUrls(type)) {
for (String url : libraryEditor.getUrls(type)) {
if (url.startsWith(repoUrl)) {
library.removeRoot(url, type);
libraryEditor.removeRoot(url, type);
}
}
}
@@ -164,13 +162,13 @@ public class RepositoryAttachHandler implements LibraryTableAttachHandler {
String url = VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(toFile.getPath()));
manager.refreshAndFindFileByUrl(url);
if (MavenExtraArtifactType.DOCS.getDefaultClassifier().equals(each.getClassifier())) {
library.addRoot(url, JavadocOrderRootType.getInstance());
libraryEditor.addRoot(url, JavadocOrderRootType.getInstance());
}
else if (MavenExtraArtifactType.SOURCES.getDefaultClassifier().equals(each.getClassifier())) {
library.addRoot(url, OrderRootType.SOURCES);
libraryEditor.addRoot(url, OrderRootType.SOURCES);
}
else {
library.addRoot(url, OrderRootType.CLASSES);
libraryEditor.addRoot(url, OrderRootType.CLASSES);
}
}
catch (MalformedURLException e) {