Maven jobs ordering

This commit is contained in:
Nikolay Mikhaylov
2015-09-23 16:12:51 +03:00
parent 6440b60ff6
commit f069f634d3
12 changed files with 543 additions and 350 deletions
@@ -43,14 +43,14 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.Function;
import com.intellij.util.PairProcessor;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.JBIterable;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.MavenVersionComparable;
import org.jetbrains.idea.maven.execution.SoutMavenConsole;
import org.jetbrains.idea.maven.importing.MavenExtraArtifactType;
import org.jetbrains.idea.maven.model.*;
@@ -63,6 +63,7 @@ import org.jetbrains.idea.maven.utils.MavenLog;
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
import org.jetbrains.idea.maven.utils.MavenProgressIndicator;
import org.jetbrains.idea.maven.utils.RepositoryAttachDialog;
import org.jetbrains.idea.maven.utils.library.remote.MavenDependenciesRemoteManager;
import javax.swing.*;
import java.io.File;
@@ -99,30 +100,21 @@ public class RepositoryAttachHandler {
return configuration;
}
public static List<MavenArtifact> resolveAndDownload(final Project project, final String coord, List<MavenRepositoryInfo> repositories) {
final SmartList<MavenExtraArtifactType> extraTypes = new SmartList<MavenExtraArtifactType>();
final Ref<List<MavenArtifact>> result = Ref.create(null);
resolveLibrary(project, coord, extraTypes, repositories, new Processor<List<MavenArtifact>>() {
public boolean process(final List<MavenArtifact> artifacts) {
result.set(artifacts);
if (!artifacts.isEmpty()) {
notifyArtifactsDownloaded(project, artifacts);
}
return true;
}
});
return result.get();
}
public static NewLibraryConfiguration resolveAndDownload(final Project project,
final String coord,
boolean attachJavaDoc,
boolean attachSources,
@Nullable final String copyTo,
List<MavenRepositoryInfo> repositories) {
final List<OrderRoot> roots = resolveAndDownloadImpl(project, coord, attachJavaDoc, attachSources, copyTo, repositories);
return new NewLibraryConfiguration(coord, RepositoryLibraryType.getInstance(), new RepositoryLibraryProperties(coord)) {
RepositoryLibraryProperties libraryProperties = new RepositoryLibraryProperties(coord);
final List<OrderRoot> roots = MavenDependenciesRemoteManager.getInstance(project)
.downloadDependenciesModal(libraryProperties, attachSources, attachJavaDoc, copyTo);
notifyArtifactsDownloaded(project, roots);
RepositoryLibraryDescription libraryDescription = RepositoryLibraryDescription.findDescription(libraryProperties);
return new NewLibraryConfiguration(
libraryDescription.getDisplayName(libraryProperties.getVersion()),
RepositoryLibraryType.getInstance(),
new RepositoryLibraryProperties(coord)) {
@Override
public void addRoots(@NotNull LibraryEditor editor) {
editor.addRoots(roots);
@@ -135,12 +127,13 @@ public class RepositoryAttachHandler {
boolean attachJavaDoc,
boolean attachSources,
@Nullable final String copyTo,
List<MavenRepositoryInfo> repositories) {
List<MavenRepositoryInfo> repositories,
ProgressIndicator indicator) {
final SmartList<MavenExtraArtifactType> extraTypes = new SmartList<MavenExtraArtifactType>();
if (attachSources) extraTypes.add(MavenExtraArtifactType.SOURCES);
if (attachJavaDoc) extraTypes.add(MavenExtraArtifactType.DOCS);
final Ref<List<OrderRoot>> result = Ref.create(null);
resolveLibrary(project, coord, extraTypes, repositories, new Processor<List<MavenArtifact>>() {
doResolveInner(project, getMavenId(coord), extraTypes, repositories, new Processor<List<MavenArtifact>>() {
public boolean process(final List<MavenArtifact> artifacts) {
if (!artifacts.isEmpty()) {
AccessToken accessToken = WriteAction.start();
@@ -151,27 +144,20 @@ public class RepositoryAttachHandler {
finally {
accessToken.finish();
}
notifyArtifactsDownloaded(project, artifacts);
}
return true;
}
});
}, indicator);
return result.get();
}
public static void notifyArtifactsDownloaded(Project project, List<MavenArtifact> artifacts) {
public static void notifyArtifactsDownloaded(Project project, List<OrderRoot> roots) {
final StringBuilder sb = new StringBuilder();
final String title = "The following files were downloaded:";
sb.append("<ol>");
for (MavenArtifact each : artifacts) {
for (OrderRoot root : roots) {
sb.append("<li>");
sb.append(each.getFile().getName());
final String scope = each.getScope();
if (scope != null) {
sb.append(" (");
sb.append(scope);
sb.append(")");
}
sb.append(root.getFile().getName());
sb.append("</li>");
}
sb.append("</ol>");
@@ -326,59 +312,8 @@ public class RepositoryAttachHandler {
});
}
private static void resolveLibrary(final Project project,
final String coord,
final List<MavenExtraArtifactType> extraTypes,
final Collection<MavenRepositoryInfo> repositories,
final Processor<List<MavenArtifact>> resultProcessor) {
final MavenId mavenId = getMavenId(coord);
final Task task = new Task.Modal(project, "Maven", false) {
public void run(@NotNull ProgressIndicator indicator) {
doResolveInner(project, mavenId, extraTypes, repositories, resultProcessor, indicator);
}
};
ProgressManager.getInstance().run(task);
}
private static void doResolveInner(Project project,
MavenId mavenId,
List<MavenExtraArtifactType> extraTypes,
Collection<MavenRepositoryInfo> repositories,
final Processor<List<MavenArtifact>> resultProcessor,
ProgressIndicator indicator) {
doResolveInner(project, Collections.singletonList(mavenId), extraTypes, repositories, resultProcessor, indicator);
}
public static List<String> retrieveVersions(@NotNull final Project project,
@NotNull final String groupId,
@NotNull final String artifactId,
@NotNull final List<MavenRepositoryInfo> repositories) {
MavenEmbeddersManager manager = MavenProjectsManager.getInstance(project).getEmbeddersManager();
MavenEmbedderWrapper embedder = manager.getEmbedder(MavenEmbeddersManager.FOR_GET_VERSIONS);
embedder.customizeForGetVersions();
try {
List<MavenRemoteRepository> remoteRepositories = convertRepositories(repositories);
List<String> versions = embedder.retrieveVersions(groupId, artifactId, remoteRepositories);
Collections.sort(versions, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
MavenVersionComparable v1 = new MavenVersionComparable(o1);
MavenVersionComparable v2 = new MavenVersionComparable(o2);
return v2.compareTo(v1);
}
});
return versions;
}
catch (MavenProcessCanceledException e) {
return Collections.emptyList();
}
finally {
manager.release(embedder);
}
}
public static void doResolveInner(Project project,
List<MavenId> mavenIds,
final MavenId mavenId,
List<MavenExtraArtifactType> extraTypes,
Collection<MavenRepositoryInfo> repositories,
@Nullable final Processor<List<MavenArtifact>> resultProcessor,
@@ -393,10 +328,7 @@ public class RepositoryAttachHandler {
new SoutMavenConsole(mavenGeneralSettings.getOutputLevel(), mavenGeneralSettings.isPrintErrorStackTraces()),
new MavenProgressIndicator(indicator));
List<MavenRemoteRepository> remoteRepositories = convertRepositories(repositories);
List<MavenArtifactInfo> artifacts = new ArrayList<MavenArtifactInfo>(mavenIds.size());
for (MavenId id : mavenIds) {
artifacts.add(new MavenArtifactInfo(id, "jar", null));
}
List<MavenArtifactInfo> artifacts = Collections.singletonList(new MavenArtifactInfo(mavenId, "jar", null));
List<MavenArtifact> firstResult = embedder.resolveTransitively(artifacts, remoteRepositories);
for (MavenArtifact artifact : firstResult) {
if (!artifact.isResolved() || MavenConstants.SCOPE_TEST.equals(artifact.getScope())) {
@@ -406,15 +338,19 @@ public class RepositoryAttachHandler {
}
// download docs & sources
if (!extraTypes.isEmpty()) {
Set<String> allowedClassifiers = new THashSet<String>();
Collection<MavenArtifactInfo> resolve = new LinkedHashSet<MavenArtifactInfo>();
for (MavenExtraArtifactType extraType : extraTypes) {
allowedClassifiers.add(extraType.getDefaultClassifier());
for (MavenId id : mavenIds) {
resolve.add(new MavenArtifactInfo(id, extraType.getDefaultExtension(), extraType.getDefaultClassifier()));
Set<String> allowedClassifiers = JBIterable.from(extraTypes).transform(new Function<MavenExtraArtifactType, String>() {
@Override
public String fun(MavenExtraArtifactType extraType) {
return extraType.getDefaultClassifier();
}
// skip sources/javadoc for dependencies
}
}).toSet();
List<MavenArtifactInfo> resolve = JBIterable.from(extraTypes).transform(new Function<MavenExtraArtifactType, MavenArtifactInfo>() {
@Override
public MavenArtifactInfo fun(MavenExtraArtifactType extraType) {
return new MavenArtifactInfo(mavenId, extraType.getDefaultExtension(), extraType.getDefaultClassifier());
}
}).toList();
// skip sources/javadoc for dependencies
for (MavenArtifact artifact : embedder.resolveTransitively(new ArrayList<MavenArtifactInfo>(resolve), remoteRepositories)) {
if (!artifact.isResolved() || MavenConstants.SCOPE_TEST.equals(artifact.getScope()) || !allowedClassifiers.contains(artifact.getClassifier())) {
continue;
@@ -428,15 +364,13 @@ public class RepositoryAttachHandler {
}
finally {
manager.release(embedder);
if (!cancelled) {
if (!cancelled && resultProcessor != null) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
public void run() {
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
@Override
public void run() {
if (resultProcessor != null) {
resultProcessor.process(new ArrayList<MavenArtifact>(result));
}
resultProcessor.process(new ArrayList<MavenArtifact>(result));
}
});
}
@@ -1,53 +0,0 @@
/*
* 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 org.jetbrains.idea.maven.utils.library;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.NewLibraryConfiguration;
import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorBase;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryPropertiesEditorBase;
/**
* @author nik
*/
public class RepositoryLibraryEditor extends LibraryPropertiesEditorBase<RepositoryLibraryProperties, RepositoryLibraryType> {
public RepositoryLibraryEditor(LibraryEditorComponent<RepositoryLibraryProperties> component, RepositoryLibraryType libraryType) {
super(component, libraryType, null);
}
@Override
protected void edit() {
final Project project = myEditorComponent.getProject();
final NewLibraryConfiguration configuration = RepositoryAttachHandler.chooseLibraryAndDownload(project,
myEditorComponent.getProperties().getMavenId(),
getMainPanel());
if (configuration == null) return;
final LibraryEditorBase target = (LibraryEditorBase)myEditorComponent.getLibraryEditor();
target.removeAllRoots();
myEditorComponent.renameLibrary(configuration.getDefaultLibraryName());
target.setType(myLibraryType);
target.setProperties(configuration.getProperties());
configuration.addRoots(target);
myEditorComponent.updateRootsTree();
setModified();
}
@Override
public void apply() {
}
}
@@ -19,9 +19,6 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
@@ -100,18 +97,12 @@ public class RepositoryLibrarySupport {
modifiableModel.commit();
}
});
Task task = new Task.Backgroundable(project, "Maven", false) {
public void run(@NotNull ProgressIndicator indicator) {
RepositoryUtils.loadDependencies(
indicator,
module.getProject(),
library,
model.isDownloadSources(),
model.isDownloadJavaDocs());
}
};
ProgressManager.getInstance().run(task);
RepositoryUtils.loadDependencies(
module.getProject(),
library,
model.isDownloadSources(),
model.isDownloadJavaDocs(),
null);
return library;
}
@@ -19,9 +19,6 @@ import com.google.common.base.Predicate;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
@@ -33,6 +30,7 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -57,7 +55,7 @@ public class RepositoryLibrarySynchronizer implements StartupActivity, DumbAware
}
private static Collection<Library> collectLibraries(final @NotNull Project project, final @NotNull Predicate<Library> predicate) {
final com.intellij.util.containers.HashSet<Library> result = new com.intellij.util.containers.HashSet<Library>();
final HashSet<Library> result = new HashSet<Library>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
@@ -101,23 +99,10 @@ public class RepositoryLibrarySynchronizer implements StartupActivity, DumbAware
libraryEx.getProperties() instanceof RepositoryLibraryProperties;
}
});
if (libraries.isEmpty()) return;
Task task = new Task.Backgroundable(project, "Maven", false) {
public void run(@NotNull ProgressIndicator indicator) {
for (Library library : libraries) {
LibraryEx libraryEx = (LibraryEx)library;
RepositoryLibraryProperties properties = (RepositoryLibraryProperties)libraryEx.getProperties();
if (isLibraryNeedToBeReloaded(libraryEx, properties)) {
RepositoryUtils.reloadDependencies(
indicator,
project,
libraryEx);
}
}
}
};
ProgressManager.getInstance().run(task);
for (Library library : libraries) {
final LibraryEx libraryEx = (LibraryEx)library;
RepositoryUtils.reloadDependencies(project, libraryEx);
}
}
}, project.getDisposed());
}
@@ -1,10 +1,17 @@
package org.jetbrains.idea.maven.utils.library;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryPropertiesEditorBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.utils.library.propertiesEditor.RepositoryLibraryPropertiesDialog;
import org.jetbrains.idea.maven.utils.library.propertiesEditor.RepositoryLibraryPropertiesModel;
import org.jetbrains.idea.maven.utils.library.remote.MavenDependenciesRemoteManager;
import org.jetbrains.idea.maven.utils.library.remote.MavenRemoteTask;
import java.util.List;
public class RepositoryLibraryWithDescriptionEditor
extends LibraryPropertiesEditorBase<RepositoryLibraryProperties, RepositoryLibraryType> {
@@ -39,11 +46,21 @@ public class RepositoryLibraryWithDescriptionEditor
if (wasGeneratedName) {
myEditorComponent.renameLibrary(RepositoryLibraryType.getInstance().getDescription(properties));
}
myEditorComponent.getLibraryEditor().removeAllRoots();
myEditorComponent.getLibraryEditor().addRoots(RepositoryUtils.download(
myEditorComponent.getProject(),
model.isDownloadSources(),
model.isDownloadJavaDocs(),
properties));
final LibraryEditor libraryEditor = myEditorComponent.getLibraryEditor();
MavenDependenciesRemoteManager.getInstance(myEditorComponent.getProject())
.downloadDependenciesAsync(
properties,
model.isDownloadSources(),
model.isDownloadJavaDocs(),
RepositoryUtils.getStorageRoot(myEditorComponent.getLibraryEditor().getUrls(OrderRootType.CLASSES), myEditorComponent.getProject()),
new MavenRemoteTask.ResultProcessor<List<OrderRoot>>() {
@Override
public void process(List<OrderRoot> roots) {
libraryEditor.removeAllRoots();
libraryEditor.addRoots(roots);
}
}
);
}
}
@@ -20,9 +20,6 @@ import com.google.common.collect.Iterables;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.OrderRootType;
@@ -36,15 +33,13 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.JBIterable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.importing.MavenExtraArtifactType;
import org.jetbrains.idea.maven.model.MavenArtifact;
import org.jetbrains.idea.maven.model.MavenId;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.project.ProjectBundle;
import org.jetbrains.idea.maven.utils.library.remote.MavenDependenciesRemoteManager;
import org.jetbrains.idea.maven.utils.library.remote.MavenRemoteTask;
import org.jetbrains.idea.maven.utils.library.remote.MavenVersionsRemoteManager;
import java.util.*;
@@ -56,34 +51,6 @@ public class RepositoryUtils {
@NotNull static public final String SnapshotVersionSuffix = "-SNAPSHOT";
@NotNull static public final String DefaultVersionId = ReleaseVersionId;
public static void downloadAsync(final Project project,
final boolean downloadSources,
final boolean downloadJavaDocs,
@NotNull final RepositoryLibraryProperties properties) {
String displayName = RepositoryLibraryDescription.findDescription(properties).getDisplayName();
Task task = new Task.Backgroundable(project, ProjectBundle.message("maven.loading.library.hint", displayName), false) {
public void run(@NotNull ProgressIndicator indicator) {
List<OrderRoot> download = download(project, downloadSources, downloadJavaDocs, properties);
}
};
ProgressManager.getInstance().run(task);
}
public static List<OrderRoot> download(Project project,
boolean downloadSources,
boolean downloadJavaDocs,
@NotNull RepositoryLibraryProperties properties) {
String coordinates = properties.getGroupId() + ":" +
properties.getArtifactId() + ":" +
resolveEffectiveVersion(project, properties);
return RepositoryAttachHandler.resolveAndDownloadImpl(
project,
coordinates,
downloadJavaDocs,
downloadSources,
null,
RepositoryLibraryDescription.findDescription(properties).getRemoteRepositories());
}
public static boolean libraryHasSources(@Nullable Library library) {
return library != null && library.getUrls(OrderRootType.SOURCES).length > 0;
}
@@ -101,7 +68,11 @@ public class RepositoryUtils {
}
public static String getStorageRoot(Library library, Project project) {
final String[] urls = library.getUrls(OrderRootType.CLASSES);
return getStorageRoot(library.getUrls(OrderRootType.CLASSES), project);
}
public static String getStorageRoot(String[] urls, Project project) {
if (urls.length == 0) {
return null;
}
@@ -127,16 +98,14 @@ public class RepositoryUtils {
}).getKey();
}
private static String resolveEffectiveVersion(@NotNull Project project, @NotNull RepositoryLibraryProperties properties) {
public static String resolveEffectiveVersion(@NotNull Project project, @NotNull RepositoryLibraryProperties properties) {
String version = properties.getVersion();
boolean isLatest = LatestVersionId.equals(version);
boolean isRelease = ReleaseVersionId.equals(version);
if (isLatest || isRelease) {
Iterable<String> versions = RepositoryAttachHandler.retrieveVersions(
project,
Iterable<String> versions = MavenVersionsRemoteManager.getInstance(project).getMavenArtifactVersions(
properties.getGroupId(),
properties.getArtifactId(),
RepositoryLibraryDescription.findDescription(properties).getRemoteRepositories());
properties.getArtifactId());
if (isRelease) {
versions = Iterables.filter(versions, new Predicate<String>() {
@Override
@@ -153,99 +122,52 @@ public class RepositoryUtils {
return version;
}
public static void reloadDependenciesAsync(@NotNull final Project project,
@NotNull final LibraryEx library) {
Task task = new Task.Backgroundable(project, "Maven", false) {
public void run(@NotNull ProgressIndicator indicator) {
reloadDependencies(
indicator,
project,
library);
}
};
ProgressManager.getInstance().run(task);
}
public static List<MavenExtraArtifactType> createExtraArtifactTypeList(boolean sources, boolean javaDocs) {
List<MavenExtraArtifactType> result = new ArrayList<MavenExtraArtifactType>();
if (sources) {
result.add(MavenExtraArtifactType.SOURCES);
}
if (javaDocs) {
result.add(MavenExtraArtifactType.DOCS);
}
return result;
}
public static synchronized void loadDependencies(@NotNull ProgressIndicator indicator,
@NotNull final Project project,
RepositoryLibraryProperties libraryProperties,
boolean downloadSources,
boolean downloadJavaDocs,
String displayName,
Processor<List<MavenArtifact>> processor) {
indicator.setText(ProjectBundle.message("maven.loading.library.hint", displayName));
RepositoryAttachHandler.doResolveInner(
project,
Collections
.singletonList(new MavenId(libraryProperties.getGroupId(), libraryProperties.getArtifactId(),
resolveEffectiveVersion(project, libraryProperties))),
createExtraArtifactTypeList(downloadSources, downloadJavaDocs),
RepositoryLibraryDescription.findDescription(libraryProperties).getRemoteRepositories(),
processor,
indicator);
}
public static void loadDependencies(@NotNull ProgressIndicator indicator,
@NotNull final Project project,
public static void loadDependencies(@NotNull final Project project,
@NotNull final LibraryEx library,
boolean downloadSources,
boolean downloadJavaDocs) {
final String storageRoot = getStorageRoot(library, project);
final RepositoryLibraryProperties libraryProperties = (RepositoryLibraryProperties)library.getProperties();
loadDependencies(indicator,
project,
libraryProperties,
downloadSources,
downloadJavaDocs,
library.getName(),
new Processor<List<MavenArtifact>>() {
@Override
public boolean process(List<MavenArtifact> artifacts) {
if (artifacts == null || artifacts.isEmpty()) {
return true;
}
final List<OrderRoot> roots = RepositoryAttachHandler.createRoots(artifacts, storageRoot);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (library.isDisposed()) {
return;
}
AccessToken token = WriteAction.start();
try {
final NewLibraryEditor editor = new NewLibraryEditor(null, libraryProperties);
editor.removeAllRoots();
editor.addRoots(roots);
final Library.ModifiableModel model = library.getModifiableModel();
editor.applyTo((LibraryEx.ModifiableModelEx)model);
model.commit();
}
finally {
token.finish();
}
}
});
return true;
}
});
boolean downloadJavaDocs,
@Nullable String copyTo) {
if (library.getKind() != RepositoryLibraryType.REPOSITORY_LIBRARY_KIND) {
return;
}
final RepositoryLibraryProperties properties = (RepositoryLibraryProperties)library.getProperties();
MavenDependenciesRemoteManager.getInstance(project)
.downloadDependenciesAsync(
properties,
downloadSources,
downloadJavaDocs,
copyTo,
new MavenRemoteTask.ResultProcessor<List<OrderRoot>>() {
@Override
public void process(final List<OrderRoot> roots) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (library.isDisposed()) {
return;
}
AccessToken token = WriteAction.start();
try {
final NewLibraryEditor editor = new NewLibraryEditor(null, properties);
editor.removeAllRoots();
editor.addRoots(roots);
final Library.ModifiableModel model = library.getModifiableModel();
editor.applyTo((LibraryEx.ModifiableModelEx)model);
model.commit();
}
finally {
token.finish();
}
}
});
}
}
);
}
public static void reloadDependencies(@NotNull ProgressIndicator indicator,
@NotNull final Project project,
public static void reloadDependencies(@NotNull final Project project,
@NotNull final LibraryEx library) {
loadDependencies(indicator, project, library, libraryHasSources(library), libraryHasJavaDocs(library));
loadDependencies(project, library, libraryHasSources(library), libraryHasJavaDocs(library), getStorageRoot(library, project));
}
}
@@ -3,9 +3,6 @@ package org.jetbrains.idea.maven.utils.library.propertiesEditor;
import com.google.common.base.Strings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.ComboBox;
@@ -17,9 +14,10 @@ import com.intellij.util.containers.JBIterable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.project.ProjectBundle;
import org.jetbrains.idea.maven.utils.library.RepositoryAttachHandler;
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryDescription;
import org.jetbrains.idea.maven.utils.library.RepositoryUtils;
import org.jetbrains.idea.maven.utils.library.remote.MavenRemoteTask;
import org.jetbrains.idea.maven.utils.library.remote.MavenVersionsRemoteManager;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
@@ -202,25 +200,16 @@ public class RepositoryLibraryPropertiesEditor {
private void reloadVersionsAsync() {
setState(State.Loading);
Task task = new Task.Backgroundable(
project,
ProjectBundle.message("maven.loading.library.version.hint", repositoryLibraryDescription.getDisplayName()),
false) {
public void run(@NotNull ProgressIndicator indicator) {
try {
List<String> versions = RepositoryAttachHandler.retrieveVersions(
project,
repositoryLibraryDescription.getGroupId(),
repositoryLibraryDescription.getArtifactId(),
repositoryLibraryDescription.getRemoteRepositories());
versionsLoaded(versions);
}
catch (Exception e) {
versionsFailedToLoad();
}
}
};
ProgressManager.getInstance().run(task);
MavenVersionsRemoteManager.getInstance(project)
.getMavenArtifactVersionsAsync(
repositoryLibraryDescription.getGroupId(),
repositoryLibraryDescription.getArtifactId(),
new MavenRemoteTask.ResultProcessor<List<String>>() {
@Override
public void process(List<String> versions) {
versionsLoaded(versions);
}
});
}
private void initVersionsPanel() {
@@ -0,0 +1,107 @@
/*
* Copyright 2000-2015 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.idea.maven.utils.library.remote;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.project.ProjectBundle;
import org.jetbrains.idea.maven.utils.library.RepositoryAttachHandler;
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryDescription;
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryProperties;
import org.jetbrains.idea.maven.utils.library.RepositoryUtils;
import java.util.List;
public class MavenDependenciesRemoteManager
extends MavenRemoteManager<List<OrderRoot>, MavenDependenciesRemoteManager.Argument, MavenDependenciesRemoteManager>
implements MavenRemoteTask<List<OrderRoot>, MavenDependenciesRemoteManager.Argument> {
public MavenDependenciesRemoteManager(Project project) {
super(project);
}
public static MavenDependenciesRemoteManager getInstance(Project project) {
return project.getComponent(MavenDependenciesRemoteManager.class);
}
public void downloadDependenciesAsync(
RepositoryLibraryProperties libraryProperties,
boolean downloadSources,
boolean downloadJavaDocs,
String copyTo,
MavenRemoteTask.ResultProcessor<List<OrderRoot>> resultProcessor) {
schedule(this, new Argument(libraryProperties, downloadSources, downloadJavaDocs, copyTo), resultProcessor, false);
}
public List<OrderRoot> downloadDependencies(
RepositoryLibraryProperties libraryProperties,
boolean downloadSources,
boolean downloadJavaDocs,
String copyTo) {
return getSynchronously(this, new Argument(libraryProperties, downloadSources, downloadJavaDocs, copyTo));
}
public List<OrderRoot> downloadDependenciesModal(
final RepositoryLibraryProperties libraryProperties,
final boolean downloadSources,
final boolean downloadJavaDocs,
final String copyTo) {
return getSynchronouslyWithModal(this,
new Argument(libraryProperties, downloadSources, downloadJavaDocs, copyTo),
ProjectBundle.message("maven.resolving"));
}
@Override
public List<OrderRoot> execute(@NotNull Argument arg, ProgressIndicator indicator) {
String coordinates = arg.libraryProperties.getGroupId() + ":" +
arg.libraryProperties.getArtifactId() + ":" +
RepositoryUtils.resolveEffectiveVersion(myProject, arg.libraryProperties);
return RepositoryAttachHandler.resolveAndDownloadImpl(
myProject,
coordinates,
arg.downloadJavaDocs,
arg.downloadSources,
arg.copyTo,
RepositoryLibraryDescription.findDescription(arg.libraryProperties).getRemoteRepositories(),
indicator);
}
@Override
public String getName(@NotNull Argument arg) {
RepositoryLibraryDescription libraryDescription = RepositoryLibraryDescription.findDescription(arg.libraryProperties);
return ProjectBundle.message("maven.loading.library.hint", libraryDescription.getDisplayName());
}
public static class Argument {
public RepositoryLibraryProperties libraryProperties;
public boolean downloadSources;
public boolean downloadJavaDocs;
@Nullable public String copyTo;
public Argument(RepositoryLibraryProperties libraryProperties,
boolean downloadSources,
boolean downloadJavaDocs,
@Nullable String copyTo) {
this.libraryProperties = libraryProperties;
this.downloadSources = downloadSources;
this.downloadJavaDocs = downloadJavaDocs;
this.copyTo = copyTo;
}
}
}
@@ -0,0 +1,164 @@
/*
* Copyright 2000-2015 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.idea.maven.utils.library.remote;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.util.concurrency.FutureResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public abstract class MavenRemoteManager<Result, Argument, RemoteTask extends MavenRemoteTask<Result, Argument>>
extends AbstractProjectComponent {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.maven.utils.library.remote.MavenRemoteManager");
private Deque<DequeItem<Result, Argument, RemoteTask>> tasks = new ArrayDeque<DequeItem<Result, Argument, RemoteTask>>();
private boolean busy;
protected MavenRemoteManager(Project project) {
super(project);
}
public synchronized boolean busy() {
return busy;
}
protected synchronized void schedule(@NotNull RemoteTask task,
@NotNull Argument argument,
RemoteTask.ResultProcessor<Result> resultProcessor,
boolean force) {
DequeItem<Result, Argument, RemoteTask> dequeItem = new DequeItem<Result, Argument, RemoteTask>(task, argument, resultProcessor);
if (!busy) {
tasks.addFirst(dequeItem);
startNextTask();
return;
}
if (force) {
tasks.addFirst(dequeItem);
}
else {
tasks.addLast(dequeItem);
}
}
protected Future<Result> schedule(@NotNull RemoteTask task, @NotNull Argument argument) {
final FutureResult<Result> future = new FutureResult<Result>();
schedule(task, argument, new MavenRemoteTask.ResultProcessor<Result>() {
@Override
public void process(Result result) {
future.set(result);
}
}, true);
return future;
}
protected Result getSynchronously(@NotNull RemoteTask task, @NotNull Argument argument) {
try {
return schedule(task, argument).get();
}
catch (InterruptedException e) {
LOG.error("Got unexpected exception during maven remote task", e);
}
catch (ExecutionException e) {
LOG.error("Got unexpected exception during maven remote task", e);
}
return null;
}
protected Result getSynchronouslyWithModal(@NotNull final RemoteTask task, @NotNull final Argument argument, String title) {
final Ref<Result> result = Ref.create();
new Task.Modal(myProject, title, false) {
public void run(@NotNull ProgressIndicator indicator) {
indicator.setText(task.getName(argument));
result.set(getSynchronously(task, argument));
}
}.queue();
return result.get();
}
private synchronized void startNextTask() {
busy = true;
if (ApplicationManager.getApplication().isDispatchThread()) {
startTask();
}
else {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
startTask();
}
}, ModalityState.any());
}
}
private synchronized void startTask() {
final DequeItem<Result, Argument, RemoteTask> item = tasks.pollFirst();
busy = item != null;
if (item == null) {
return;
}
new Task.Backgroundable(myProject, "Maven", false) {
public void run(@NotNull ProgressIndicator indicator) {
indicator.setText(item.getTask().getName(item.getArgument()));
Result result = item.getTask().execute(item.getArgument(), indicator);
MavenRemoteTask.ResultProcessor<Result> resultProcessor = item.getResultProcessor();
if (resultProcessor != null) {
resultProcessor.process(result);
}
startNextTask();
}
}.queue();
}
private static class DequeItem<Result, Argument, Task extends MavenRemoteTask<Result, Argument>> {
@NotNull private final Task task;
@NotNull private final Argument argument;
@Nullable private final Task.ResultProcessor<Result> resultProcessor;
private DequeItem(@NotNull Task task, @NotNull Argument argument, @Nullable MavenRemoteTask.ResultProcessor<Result> processor) {
this.task = task;
this.argument = argument;
resultProcessor = processor;
}
@NotNull
public Task getTask() {
return task;
}
@NotNull
public Argument getArgument() {
return argument;
}
@Nullable
public Task.ResultProcessor<Result> getResultProcessor() {
return resultProcessor;
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2000-2015 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.idea.maven.utils.library.remote;
import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.annotations.NotNull;
public interface MavenRemoteTask<Result, Argument> {
Result execute(@NotNull Argument arg, ProgressIndicator indicator);
String getName(@NotNull Argument arg);
interface ResultProcessor<Result> {
void process(Result result);
}
}
@@ -0,0 +1,100 @@
/*
* Copyright 2000-2015 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.idea.maven.utils.library.remote;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenVersionComparable;
import org.jetbrains.idea.maven.model.MavenRemoteRepository;
import org.jetbrains.idea.maven.model.MavenRepositoryInfo;
import org.jetbrains.idea.maven.project.MavenEmbeddersManager;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.idea.maven.project.ProjectBundle;
import org.jetbrains.idea.maven.server.MavenEmbedderWrapper;
import org.jetbrains.idea.maven.utils.MavenProcessCanceledException;
import org.jetbrains.idea.maven.utils.library.RepositoryLibraryDescription;
import java.util.*;
public class MavenVersionsRemoteManager
extends MavenRemoteManager<List<String>, RepositoryLibraryDescription, MavenVersionsRemoteManager>
implements MavenRemoteTask<List<String>, RepositoryLibraryDescription> {
public MavenVersionsRemoteManager(Project project) {
super(project);
}
public static MavenVersionsRemoteManager getInstance(Project project) {
return project.getComponent(MavenVersionsRemoteManager.class);
}
public void getMavenArtifactVersionsAsync(String groupId,
String artifactId,
MavenRemoteTask.ResultProcessor<List<String>> resultProcessor) {
schedule(this, RepositoryLibraryDescription.findDescription(groupId, artifactId), resultProcessor, false);
}
public List<String> getMavenArtifactVersions(String groupId, String artifactId) {
return getSynchronously(this, RepositoryLibraryDescription.findDescription(groupId, artifactId));
}
@Override
public List<String> execute(@NotNull RepositoryLibraryDescription repositoryLibraryDescription, ProgressIndicator indicator) {
MavenEmbeddersManager manager = MavenProjectsManager.getInstance(myProject).getEmbeddersManager();
MavenEmbedderWrapper embedder = manager.getEmbedder(MavenEmbeddersManager.FOR_GET_VERSIONS);
embedder.customizeForGetVersions();
try {
List<MavenRemoteRepository> remoteRepositories = convertRepositories(repositoryLibraryDescription.getRemoteRepositories());
List<String> versions = embedder.retrieveVersions(
repositoryLibraryDescription.getGroupId(),
repositoryLibraryDescription.getArtifactId(),
remoteRepositories);
Collections.sort(versions, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
MavenVersionComparable v1 = new MavenVersionComparable(o1);
MavenVersionComparable v2 = new MavenVersionComparable(o2);
return v2.compareTo(v1);
}
});
return versions;
}
catch (MavenProcessCanceledException e) {
return Collections.emptyList();
}
finally {
manager.release(embedder);
}
}
private static List<MavenRemoteRepository> convertRepositories(Collection<MavenRepositoryInfo> infos) {
List<MavenRemoteRepository> result = new ArrayList<MavenRemoteRepository>(infos.size());
for (MavenRepositoryInfo each : infos) {
if (each.getUrl() != null) {
result.add(new MavenRemoteRepository(each.getId(), each.getName(), each.getUrl(), null, null, null));
}
}
return result;
}
@Override
public String getName(@NotNull RepositoryLibraryDescription repositoryLibraryDescription) {
return ProjectBundle.message("maven.loading.library.version.hint", repositoryLibraryDescription.getDisplayName());
}
}
@@ -317,6 +317,14 @@
<implementation-class>org.jetbrains.idea.maven.project.MavenProjectsManager</implementation-class>
<loadForDefaultProject/>
</component>
<component>
<implementation-class>org.jetbrains.idea.maven.utils.library.remote.MavenVersionsRemoteManager</implementation-class>
<loadForDefaultProject/>
</component>
<component>
<implementation-class>org.jetbrains.idea.maven.utils.library.remote.MavenDependenciesRemoteManager</implementation-class>
<loadForDefaultProject/>
</component>
<component>
<implementation-class>org.jetbrains.idea.maven.indices.MavenProjectIndicesManager</implementation-class>
</component>