mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-100968 Gradle: Correctly handle a situation when a project created via 'gradle idea' is linked to a gradle project via JetGradle
Module-local library dependencies are automatically removed and replaced by dependencies to corresponding project-level libraries if necessary
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.manage.GradleDependencyManager"/>
|
||||
|
||||
<!--Auto-import stuff-->
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.GradleDuplicateLibrariesPreProcessor"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.GradleMovedJarsPostProcessor"/>
|
||||
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.sync.GradleOutdatedLibraryVersionPostProcessor"/>
|
||||
|
||||
|
||||
@@ -31,10 +31,7 @@ import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBRadioButton;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.*;
|
||||
import org.jetbrains.plugins.gradle.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -106,13 +103,14 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
|
||||
public GradleConfigurable(@Nullable Project project, @NotNull GradleInstallationManager gradleInstallationManager) {
|
||||
myProject = project;
|
||||
myHelper = new DefaultHelper(gradleInstallationManager);
|
||||
buildContent();
|
||||
buildContent(false);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public GradleConfigurable(@Nullable Project project, @NotNull Helper helper) {
|
||||
myHelper = helper;
|
||||
myProject = project;
|
||||
buildContent();
|
||||
buildContent(true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -141,7 +139,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
if (myComponent == null) {
|
||||
buildContent();
|
||||
buildContent(false);
|
||||
}
|
||||
return myComponent;
|
||||
}
|
||||
@@ -178,11 +176,11 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
|
||||
return myUseWrapperButton;
|
||||
}
|
||||
|
||||
private void buildContent() {
|
||||
private void buildContent(boolean testMode) {
|
||||
initContentPanel();
|
||||
initLinkedGradleProjectPathControl();
|
||||
initLinkedGradleProjectPathControl(testMode);
|
||||
initWrapperVsLocalControls();
|
||||
initGradleHome();
|
||||
initGradleHome(testMode);
|
||||
initServiceDirectoryHome();
|
||||
assert myComponent != null;
|
||||
|
||||
@@ -256,13 +254,17 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
|
||||
}
|
||||
}
|
||||
|
||||
private void initLinkedGradleProjectPathControl() {
|
||||
private void initLinkedGradleProjectPathControl(boolean testMode) {
|
||||
myLinkedGradleProjectPathField = new TextFieldWithBrowseButton();
|
||||
|
||||
FileChooserDescriptor fileChooserDescriptor = testMode ? new FileChooserDescriptor(true, false, false, false, false, false)
|
||||
: GradleUtil.getGradleProjectFileChooserDescriptor();
|
||||
|
||||
myLinkedGradleProjectPathField.addBrowseFolderListener(
|
||||
"",
|
||||
GradleBundle.message("gradle.settings.label.select.project"),
|
||||
myProject,
|
||||
GradleUtil.getGradleProjectFileChooserDescriptor(),
|
||||
fileChooserDescriptor,
|
||||
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT,
|
||||
false
|
||||
);
|
||||
@@ -329,13 +331,17 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
|
||||
group.add(myUseLocalDistributionButton);
|
||||
}
|
||||
|
||||
private void initGradleHome() {
|
||||
private void initGradleHome(boolean testMode) {
|
||||
myGradleHomePathField = new TextFieldWithBrowseButton();
|
||||
|
||||
FileChooserDescriptor fileChooserDescriptor = testMode ? new FileChooserDescriptor(true, false, false, false, false, false)
|
||||
: GradleUtil.getGradleHomeFileChooserDescriptor();
|
||||
|
||||
myGradleHomePathField.addBrowseFolderListener(
|
||||
"",
|
||||
GradleBundle.message("gradle.settings.text.home.path"),
|
||||
null,
|
||||
GradleUtil.getGradleHomeFileChooserDescriptor(),
|
||||
fileChooserDescriptor,
|
||||
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT,
|
||||
false
|
||||
);
|
||||
|
||||
+22
-12
@@ -29,11 +29,11 @@ public class GradleDependencyManager {
|
||||
myLibraryManager = manager;
|
||||
}
|
||||
|
||||
public void importDependency(@NotNull GradleDependency dependency, @NotNull Module module) {
|
||||
importDependencies(Collections.singleton(dependency), module);
|
||||
public void importDependency(@NotNull GradleDependency dependency, @NotNull Module module, boolean synchronous) {
|
||||
importDependencies(Collections.singleton(dependency), module, synchronous);
|
||||
}
|
||||
|
||||
public void importDependencies(@NotNull Iterable<GradleDependency> dependencies, @NotNull Module module) {
|
||||
public void importDependencies(@NotNull Iterable<GradleDependency> dependencies, @NotNull Module module, boolean synchronous) {
|
||||
final List<GradleModuleDependency> moduleDependencies = new ArrayList<GradleModuleDependency>();
|
||||
final List<GradleLibraryDependency> libraryDependencies = new ArrayList<GradleLibraryDependency>();
|
||||
GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() {
|
||||
@@ -50,17 +50,20 @@ public class GradleDependencyManager {
|
||||
for (GradleDependency dependency : dependencies) {
|
||||
dependency.invite(visitor);
|
||||
}
|
||||
importLibraryDependencies(libraryDependencies, module);
|
||||
importModuleDependencies(moduleDependencies, module);
|
||||
importLibraryDependencies(libraryDependencies, module, synchronous);
|
||||
importModuleDependencies(moduleDependencies, module, synchronous);
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void importModuleDependencies(@NotNull final Collection<GradleModuleDependency> dependencies, @NotNull final Module module) {
|
||||
public void importModuleDependencies(@NotNull final Collection<GradleModuleDependency> dependencies,
|
||||
@NotNull final Module module,
|
||||
boolean synchronous)
|
||||
{
|
||||
if (dependencies.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() {
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, synchronous, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
@@ -95,8 +98,11 @@ public class GradleDependencyManager {
|
||||
});
|
||||
}
|
||||
|
||||
public void importLibraryDependencies(@NotNull final Iterable<GradleLibraryDependency> dependencies, @NotNull final Module module) {
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, new Runnable() {
|
||||
public void importLibraryDependencies(@NotNull final Iterable<GradleLibraryDependency> dependencies,
|
||||
@NotNull final Module module,
|
||||
final boolean synchronous)
|
||||
{
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependencies, synchronous, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(module.getProject());
|
||||
@@ -108,7 +114,7 @@ public class GradleDependencyManager {
|
||||
}
|
||||
}
|
||||
if (!librariesToImport.isEmpty()) {
|
||||
myLibraryManager.importLibraries(librariesToImport, module.getProject());
|
||||
myLibraryManager.importLibraries(librariesToImport, module.getProject(), synchronous);
|
||||
}
|
||||
|
||||
for (GradleLibraryDependency dependency : dependencies) {
|
||||
@@ -138,15 +144,19 @@ public class GradleDependencyManager {
|
||||
});
|
||||
}
|
||||
|
||||
public void removeDependency(@NotNull final ExportableOrderEntry dependency, boolean synchronous) {
|
||||
removeDependencies(Collections.singleton(dependency), synchronous);
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
public void removeDependencies(@NotNull final Collection<? extends ExportableOrderEntry> dependencies) {
|
||||
public void removeDependencies(@NotNull final Collection<? extends ExportableOrderEntry> dependencies, boolean synchronous) {
|
||||
if (dependencies.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final ExportableOrderEntry dependency : dependencies) {
|
||||
final Module module = dependency.getOwnerModule();
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependency, new Runnable() {
|
||||
GradleUtil.executeProjectChangeAction(module.getProject(), dependency, synchronous, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
|
||||
@@ -35,10 +35,7 @@ import org.jetbrains.plugins.gradle.util.GradleLog;
|
||||
import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -54,53 +51,62 @@ public class GradleJarManager {
|
||||
myLibraryPathTypeMapper = mapper;
|
||||
}
|
||||
|
||||
public void importJar(@NotNull final GradleJar jar, @NotNull final Project project) {
|
||||
GradleUtil.executeProjectChangeAction(project, jar, new Runnable() {
|
||||
public void importJar(@NotNull final GradleJar jar, @NotNull final Project project, boolean synchronous) {
|
||||
importJars(Collections.singleton(jar), project, synchronous);
|
||||
}
|
||||
|
||||
public void importJars(@NotNull final Collection<? extends GradleJar> jars, @NotNull final Project project, boolean synchronous) {
|
||||
if (jars.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
GradleUtil.executeProjectChangeAction(project, jars, synchronous, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LibraryTable table = myPlatformFacade.getProjectLibraryTable(project);
|
||||
Library library = table.getLibraryByName(jar.getLibraryId().getLibraryName());
|
||||
Library library = table.getLibraryByName(jars.iterator().next().getLibraryId().getLibraryName());
|
||||
if (library == null) {
|
||||
return;
|
||||
}
|
||||
Library.ModifiableModel model = library.getModifiableModel();
|
||||
try {
|
||||
OrderRootType ideJarType = myLibraryPathTypeMapper.map(jar.getPathType());
|
||||
for (VirtualFile file : model.getFiles(ideJarType)) {
|
||||
if (jar.getPath().equals(GradleUtil.getLocalFileSystemPath(file))) {
|
||||
return;
|
||||
for (GradleJar jar : jars) {
|
||||
OrderRootType ideJarType = myLibraryPathTypeMapper.map(jar.getPathType());
|
||||
for (VirtualFile file : model.getFiles(ideJarType)) {
|
||||
if (jar.getPath().equals(GradleUtil.getLocalFileSystemPath(file))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(jar.getPath()));
|
||||
if (virtualFile == null) {
|
||||
//GradleLog.LOG.warn(
|
||||
// String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath())
|
||||
//);
|
||||
return;
|
||||
}
|
||||
if (virtualFile.isDirectory()) {
|
||||
model.addRoot(virtualFile, ideJarType);
|
||||
}
|
||||
else {
|
||||
VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile);
|
||||
if (jarRoot == null) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Can't parse contents of the jar file at path '%s' for the library '%s''", jar.getPath(), library.getName()
|
||||
));
|
||||
VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(jar.getPath()));
|
||||
if (virtualFile == null) {
|
||||
//GradleLog.LOG.warn(
|
||||
// String.format("Can't find %s of the library '%s' at path '%s'", entry.getKey(), libraryName, file.getAbsolutePath())
|
||||
//);
|
||||
return;
|
||||
}
|
||||
model.addRoot(jarRoot, ideJarType);
|
||||
if (virtualFile.isDirectory()) {
|
||||
model.addRoot(virtualFile, ideJarType);
|
||||
}
|
||||
else {
|
||||
VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile);
|
||||
if (jarRoot == null) {
|
||||
GradleLog.LOG.warn(String.format(
|
||||
"Can't parse contents of the jar file at path '%s' for the library '%s''", jar.getPath(), library.getName()
|
||||
));
|
||||
return;
|
||||
}
|
||||
model.addRoot(jarRoot, ideJarType);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
model.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void removeJars(@NotNull Collection<GradleJar> jars, @NotNull Project project) {
|
||||
public void removeJars(@NotNull Collection<? extends GradleJar> jars, @NotNull Project project, boolean synchronous) {
|
||||
if (jars.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -134,7 +140,7 @@ public class GradleJarManager {
|
||||
}
|
||||
|
||||
if (!libraryJars.isEmpty()) {
|
||||
removeLibraryJars(libraryJars, project);
|
||||
removeLibraryJars(libraryJars, project, synchronous);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,8 +151,8 @@ public class GradleJarManager {
|
||||
* @param jars jars to remove
|
||||
* @param project current project
|
||||
*/
|
||||
private void removeLibraryJars(@NotNull final Set<GradleJar> jars, @NotNull final Project project) {
|
||||
GradleUtil.executeProjectChangeAction(project, jars, new Runnable() {
|
||||
private void removeLibraryJars(@NotNull final Set<GradleJar> jars, @NotNull final Project project, boolean synchronous) {
|
||||
GradleUtil.executeProjectChangeAction(project, jars, synchronous, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LibraryTable libraryTable = myPlatformFacade.getProjectLibraryTable(project);
|
||||
|
||||
@@ -7,10 +7,13 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.config.PlatformFacade;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleJar;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType;
|
||||
import org.jetbrains.plugins.gradle.util.GradleLibraryPathTypeMapper;
|
||||
@@ -28,19 +31,59 @@ public class GradleLibraryManager {
|
||||
|
||||
@NotNull private final PlatformFacade myPlatformFacade;
|
||||
@NotNull private final GradleLibraryPathTypeMapper myLibraryPathTypeMapper;
|
||||
@NotNull private final GradleJarManager myJarManager;
|
||||
|
||||
public GradleLibraryManager(@NotNull PlatformFacade platformFacade, @NotNull GradleLibraryPathTypeMapper mapper) {
|
||||
public GradleLibraryManager(@NotNull PlatformFacade platformFacade,
|
||||
@NotNull GradleLibraryPathTypeMapper mapper,
|
||||
@NotNull GradleJarManager manager)
|
||||
{
|
||||
myPlatformFacade = platformFacade;
|
||||
myLibraryPathTypeMapper = mapper;
|
||||
myJarManager = manager;
|
||||
}
|
||||
|
||||
public void importLibraries(@NotNull Collection<? extends GradleLibrary> libraries, @NotNull Project project) {
|
||||
for (GradleLibrary library : libraries) {
|
||||
importLibrary(library, project);
|
||||
public void syncPaths(@NotNull GradleLibrary gradleLibrary,
|
||||
@NotNull final Library ideLibrary,
|
||||
@NotNull Project project,
|
||||
boolean synchronous)
|
||||
{
|
||||
Set<String> toRemove = ContainerUtilRt.newHashSet();
|
||||
Set<String> toAdd = ContainerUtilRt.newHashSet(gradleLibrary.getPaths(LibraryPathType.BINARY));
|
||||
for (VirtualFile ideFile : ideLibrary.getFiles(OrderRootType.CLASSES)) {
|
||||
String idePath = GradleUtil.getLocalFileSystemPath(ideFile);
|
||||
if (!toAdd.remove(idePath)) {
|
||||
toRemove.add(idePath);
|
||||
}
|
||||
}
|
||||
if (toRemove.isEmpty() && toAdd.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Function<String, GradleJar> jarMapper = new Function<String, GradleJar>() {
|
||||
@Override
|
||||
public GradleJar fun(String path) {
|
||||
return new GradleJar(path, LibraryPathType.BINARY, ideLibrary, null);
|
||||
}
|
||||
};
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
List<GradleJar> jarsToRemove = ContainerUtil.map(toRemove, jarMapper);
|
||||
myJarManager.removeJars(jarsToRemove, project, synchronous);
|
||||
}
|
||||
|
||||
if (!toAdd.isEmpty()) {
|
||||
List<GradleJar> jarsToAdd = ContainerUtil.map(toAdd, jarMapper);
|
||||
myJarManager.importJars(jarsToAdd, project, synchronous);
|
||||
}
|
||||
}
|
||||
|
||||
public void importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project) {
|
||||
public void importLibraries(@NotNull Collection<? extends GradleLibrary> libraries, @NotNull Project project, boolean synchronous) {
|
||||
for (GradleLibrary library : libraries) {
|
||||
importLibrary(library, project, synchronous);
|
||||
}
|
||||
}
|
||||
|
||||
public void importLibrary(@NotNull final GradleLibrary library, @NotNull final Project project, boolean synchronous) {
|
||||
Map<OrderRootType, Collection<File>> libraryFiles = new HashMap<OrderRootType, Collection<File>>();
|
||||
for (LibraryPathType pathType : LibraryPathType.values()) {
|
||||
final Set<String> paths = library.getPaths(pathType);
|
||||
@@ -55,14 +98,15 @@ public class GradleLibraryManager {
|
||||
}
|
||||
}));
|
||||
}
|
||||
importLibrary(library.getName(), libraryFiles, project);
|
||||
importLibrary(library.getName(), libraryFiles, project, synchronous);
|
||||
}
|
||||
|
||||
public void importLibrary(@NotNull final String libraryName,
|
||||
@NotNull final Map<OrderRootType, ? extends Collection<File>> libraryFiles,
|
||||
@NotNull final Project project)
|
||||
@NotNull final Project project,
|
||||
boolean synchronous)
|
||||
{
|
||||
GradleUtil.executeProjectChangeAction(project, libraryName, new Runnable() {
|
||||
GradleUtil.executeProjectChangeAction(project, libraryName, synchronous, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Is assumed to be called from the EDT.
|
||||
|
||||
+6
-6
@@ -253,26 +253,26 @@ public class GradleLocalNodeManageHelper {
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibrary library) {
|
||||
myLibraryManager.importLibrary(library, myProjectStructureHelper.getProject());
|
||||
myLibraryManager.importLibrary(library, myProjectStructureHelper.getProject(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleJar jar) {
|
||||
myJarManager.importJar(jar, myProjectStructureHelper.getProject());
|
||||
myJarManager.importJar(jar, myProjectStructureHelper.getProject(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleModuleDependency dependency) {
|
||||
final Module module = myProjectStructureHelper.findIdeModule(dependency.getOwnerModule());
|
||||
assert module != null;
|
||||
myModuleDependencyManager.importDependency(dependency, module);
|
||||
myModuleDependencyManager.importDependency(dependency, module, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibraryDependency dependency) {
|
||||
final Module module = myProjectStructureHelper.findIdeModule(dependency.getOwnerModule());
|
||||
assert module != null;
|
||||
myModuleDependencyManager.importDependency(dependency, module);
|
||||
myModuleDependencyManager.importDependency(dependency, module, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -320,9 +320,9 @@ public class GradleLocalNodeManageHelper {
|
||||
}
|
||||
}
|
||||
|
||||
myJarManager.removeJars(jars, myProjectStructureHelper.getProject());
|
||||
myJarManager.removeJars(jars, myProjectStructureHelper.getProject(), false);
|
||||
myContentRootManager.removeContentRoots(contentRoots);
|
||||
myModuleDependencyManager.removeDependencies(dependencies);
|
||||
myModuleDependencyManager.removeDependencies(dependencies, false);
|
||||
myModuleManager.removeModules(modules);
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class GradleModuleManager {
|
||||
for (GradleModule gradleModule : modules) {
|
||||
final Module intellijModule = moduleMappings.get(gradleModule);
|
||||
myContentRootImporter.importContentRoots(gradleModule.getContentRoots(), intellijModule);
|
||||
myDependencyImporter.importDependencies(gradleModule.getDependencies(), intellijModule);
|
||||
myDependencyImporter.importDependencies(gradleModule.getDependencies(), intellijModule, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+2
-2
@@ -125,12 +125,12 @@ public class GradleOutdatedLibraryManager {
|
||||
libraryDependenciesToImport.add(Pair.create(gradleLibraryDependency, ideModule));
|
||||
}
|
||||
}
|
||||
myDependencyManager.removeDependencies(ideLibraryDependenciesToRemove);
|
||||
myDependencyManager.removeDependencies(ideLibraryDependenciesToRemove, false);
|
||||
myLibraryManager.removeLibraries(ideLibsToRemove.values(), myProject);
|
||||
for (Pair<GradleLibraryDependency, Module> pair : libraryDependenciesToImport) {
|
||||
// Assuming that dependency manager is smart enough to import library for a given library dependency if it hasn't been
|
||||
// imported yet.
|
||||
myDependencyManager.importDependency(pair.first, pair.second);
|
||||
myDependencyManager.importDependency(pair.first, pair.second, false);
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
|
||||
+2
-2
@@ -235,12 +235,12 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder<GradleProje
|
||||
}
|
||||
|
||||
// Register libraries.
|
||||
myLibraryManager.importLibraries(projectWithResolvedLibraries.getLibraries(), project);
|
||||
myLibraryManager.importLibraries(projectWithResolvedLibraries.getLibraries(), project, false);
|
||||
GradleProjectStructureHelper helper = ServiceManager.getService(project, GradleProjectStructureHelper.class);
|
||||
for (GradleModule module : projectWithResolvedLibraries.getModules()) {
|
||||
Module intellijModule = helper.findIdeModule(module);
|
||||
assert intellijModule != null;
|
||||
myDependencyManager.importDependencies(module.getDependencies(), intellijModule);
|
||||
myDependencyManager.importDependencies(module.getDependencies(), intellijModule, false);
|
||||
}
|
||||
|
||||
GradleProjectStructureChangesModel changesModel = ServiceManager.getService(project, GradleProjectStructureChangesModel.class);
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.plugins.gradle.util.GradleUtil;
|
||||
*/
|
||||
public class GradleEntityIdMapper {
|
||||
|
||||
@NotNull GradleProjectStructureContext myMappingContext;
|
||||
@NotNull private final GradleProjectStructureContext myMappingContext;
|
||||
|
||||
public GradleEntityIdMapper(@NotNull GradleProjectStructureContext context) {
|
||||
myMappingContext = context;
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.gradle.sync;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.manage.GradleDependencyManager;
|
||||
import org.jetbrains.plugins.gradle.manage.GradleLibraryManager;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.*;
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper;
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleLibraryDependencyId;
|
||||
|
||||
/**
|
||||
* There is a possible situation that there are module-local libraries which reference jars similar to those provided by gradle
|
||||
* as project libraries (IDEA-100968). This class manages that by auto-removing module-local libraries and replacing it by
|
||||
* references to project-level libraries instead.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/13/13 9:15 AM
|
||||
*/
|
||||
public class GradleDuplicateLibrariesPreProcessor implements GradleProjectStructureChangesPreProcessor {
|
||||
|
||||
@NotNull private final GradleDependencyManager myDependencyManager;
|
||||
@NotNull private final GradleLibraryManager myLibraryManager;
|
||||
|
||||
public GradleDuplicateLibrariesPreProcessor(@NotNull GradleDependencyManager manager, @NotNull GradleLibraryManager manager1) {
|
||||
myDependencyManager = manager;
|
||||
myLibraryManager = manager1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GradleProject preProcess(@NotNull GradleProject gradleProject, @NotNull final Project ideProject) {
|
||||
final GradleProjectStructureHelper projectStructureHelper = ServiceManager.getService(ideProject, GradleProjectStructureHelper.class);
|
||||
for (GradleModule gradleModule : gradleProject.getModules()) {
|
||||
final Module ideModule = projectStructureHelper.findIdeModule(gradleModule);
|
||||
if (ideModule == null) {
|
||||
continue;
|
||||
}
|
||||
GradleEntityVisitor visitor = new GradleEntityVisitorAdapter() {
|
||||
@Override
|
||||
public void visit(@NotNull GradleLibraryDependency gradleDependency) {
|
||||
GradleLibraryDependencyId id = GradleEntityIdMapper.mapEntityToId(gradleDependency);
|
||||
LibraryOrderEntry ideDependency = projectStructureHelper.findIdeModuleLocalLibraryDependency(
|
||||
id.getOwnerModuleName(), id.getDependencyName()
|
||||
);
|
||||
if (ideDependency == null) {
|
||||
return;
|
||||
}
|
||||
myDependencyManager.removeDependency(ideDependency, true);
|
||||
|
||||
ideDependency = projectStructureHelper.findIdeLibraryDependency(id);
|
||||
if (ideDependency == null) {
|
||||
myDependencyManager.importDependency(gradleDependency, ideModule, true);
|
||||
}
|
||||
|
||||
GradleLibrary gradleLibrary = gradleDependency.getTarget();
|
||||
Library ideLibrary = projectStructureHelper.findIdeLibrary(gradleLibrary);
|
||||
if (ideLibrary == null) {
|
||||
myLibraryManager.importLibrary(gradleLibrary, ideProject, true);
|
||||
}
|
||||
else {
|
||||
myLibraryManager.syncPaths(gradleLibrary, ideLibrary, ideProject, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
for (GradleDependency dependency : gradleModule.getDependencies()) {
|
||||
dependency.invite(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
return gradleProject;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -85,8 +85,8 @@ public class GradleMovedJarsPostProcessor implements GradleProjectStructureChang
|
||||
@Override
|
||||
public void run() {
|
||||
for (MergeInfo info : toMerge) {
|
||||
myJarManager.removeJars(Collections.singleton(info.ideJar), project);
|
||||
myJarManager.importJar(info.gradleJar, project);
|
||||
myJarManager.removeJars(Collections.singleton(info.ideJar), project, true);
|
||||
myJarManager.importJar(info.gradleJar, project, true);
|
||||
changes.removeAll(info.changes);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -34,6 +34,7 @@ public class GradleProjectStructureChangesModel {
|
||||
new AtomicReference<Set<GradleProjectStructureChange>>(new HashSet<GradleProjectStructureChange>());
|
||||
|
||||
private final AtomicReference<GradleProject> myGradleProject = new AtomicReference<GradleProject>();
|
||||
private final Collection<GradleProjectStructureChangesPreProcessor> myPreProcessors = ContainerUtilRt.createEmptyCOWList();
|
||||
private final Collection<GradleProjectStructureChangesPostProcessor> myPostProcessors = ContainerUtilRt.createEmptyCOWList();
|
||||
|
||||
@NotNull private final GradleStructureChangesCalculator<GradleProject, Project> myChangesCalculator;
|
||||
@@ -45,6 +46,7 @@ public class GradleProjectStructureChangesModel {
|
||||
@NotNull GradleStructureChangesCalculator<GradleProject, Project> changesCalculator,
|
||||
@NotNull PlatformFacade platformFacade,
|
||||
@NotNull GradleLibraryPathTypeMapper mapper,
|
||||
@NotNull GradleDuplicateLibrariesPreProcessor duplicateLibrariesPreProcessor,
|
||||
@NotNull GradleMovedJarsPostProcessor movedJarsPostProcessor,
|
||||
@NotNull GradleOutdatedLibraryVersionPostProcessor changedLibraryVersionPostProcessor)
|
||||
{
|
||||
@@ -52,6 +54,7 @@ public class GradleProjectStructureChangesModel {
|
||||
myChangesCalculator = changesCalculator;
|
||||
myPlatformFacade = platformFacade;
|
||||
myLibraryPathTypeMapper = mapper;
|
||||
myPreProcessors.add(duplicateLibrariesPreProcessor);
|
||||
myPostProcessors.add(movedJarsPostProcessor);
|
||||
myPostProcessors.add(changedLibraryVersionPostProcessor);
|
||||
}
|
||||
@@ -81,8 +84,12 @@ public class GradleProjectStructureChangesModel {
|
||||
* change (an alternative is a manual project structure changes refresh implied by a user)
|
||||
*/
|
||||
public void update(@NotNull GradleProject gradleProject, boolean onIdeProjectStructureChange) {
|
||||
myGradleProject.set(gradleProject);
|
||||
final GradleChangesCalculationContext context = getCurrentChangesContext(gradleProject, onIdeProjectStructureChange);
|
||||
GradleProject projectToUse = gradleProject;
|
||||
for (GradleProjectStructureChangesPreProcessor preProcessor : myPreProcessors) {
|
||||
projectToUse = preProcessor.preProcess(projectToUse, myProject);
|
||||
}
|
||||
myGradleProject.set(projectToUse);
|
||||
final GradleChangesCalculationContext context = getCurrentChangesContext(projectToUse, onIdeProjectStructureChange);
|
||||
if (!context.hasNewChanges()) {
|
||||
return;
|
||||
}
|
||||
@@ -99,7 +106,13 @@ public class GradleProjectStructureChangesModel {
|
||||
public GradleProject getGradleProject() {
|
||||
return myGradleProject.get();
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@TestOnly
|
||||
public Collection<GradleProjectStructureChangesPreProcessor> getPreProcessors() {
|
||||
return myPreProcessors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@TestOnly
|
||||
public Collection<GradleProjectStructureChangesPostProcessor> getPostProcessors() {
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.gradle.sync;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleProject;
|
||||
|
||||
/**
|
||||
* Defines a contract for a callback which is triggered before a project structure changes calculation.
|
||||
* <p/>
|
||||
* Implementations of this interface are expected to be thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 2/13/13 9:05 AM
|
||||
*/
|
||||
public interface GradleProjectStructureChangesPreProcessor {
|
||||
|
||||
@NotNull
|
||||
GradleProject preProcess(@NotNull GradleProject gradleProject, @NotNull Project ideProject);
|
||||
}
|
||||
+31
@@ -3,6 +3,7 @@ package org.jetbrains.plugins.gradle.sync;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.ModuleLibraryOrderEntryImpl;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
@@ -219,6 +220,36 @@ public class GradleProjectStructureHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ModuleLibraryOrderEntryImpl findIdeModuleLocalLibraryDependency(@NotNull final String moduleName,
|
||||
@NotNull final String libraryName)
|
||||
{
|
||||
final Module ideModule = findIdeModule(moduleName);
|
||||
if (ideModule == null) {
|
||||
return null;
|
||||
}
|
||||
RootPolicy<ModuleLibraryOrderEntryImpl> visitor = new RootPolicy<ModuleLibraryOrderEntryImpl>() {
|
||||
@Override
|
||||
public ModuleLibraryOrderEntryImpl visitLibraryOrderEntry(LibraryOrderEntry ideDependency, ModuleLibraryOrderEntryImpl value) {
|
||||
Library library = ideDependency.getLibrary();
|
||||
if (library == null) {
|
||||
return value;
|
||||
}
|
||||
if (ideDependency instanceof ModuleLibraryOrderEntryImpl && libraryName.equals(GradleUtil.getLibraryName(library))) {
|
||||
return (ModuleLibraryOrderEntryImpl)ideDependency;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
for (OrderEntry entry : myFacade.getOrderEntries(ideModule)) {
|
||||
final ModuleLibraryOrderEntryImpl result = entry.accept(visitor, null);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LibraryOrderEntry findIdeLibraryDependency(@NotNull final String libraryName,
|
||||
@NotNull ModifiableRootModel model)
|
||||
|
||||
-2
@@ -29,8 +29,6 @@ public class GradleLocalNodeManageHelperTest extends AbstractGradleTest {
|
||||
protected void configureContainer(MutablePicoContainer container) {
|
||||
container.registerComponentImplementation(GradleLocalNodeManageHelper)
|
||||
container.registerComponentImplementation(GradleModuleManager)
|
||||
container.registerComponentImplementation(GradleLibraryManager)
|
||||
container.registerComponentImplementation(GradleDependencyManager)
|
||||
container.registerComponentImplementation(GradleContentRootManager)
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -15,13 +15,16 @@ import org.jetbrains.plugins.gradle.diff.dependency.GradleModuleDependencyStruct
|
||||
import org.jetbrains.plugins.gradle.diff.library.GradleLibraryStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.diff.module.GradleModuleStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.diff.project.GradleProjectStructureChangesCalculator
|
||||
import org.jetbrains.plugins.gradle.manage.GradleDependencyManager
|
||||
import org.jetbrains.plugins.gradle.manage.GradleJarManager
|
||||
import org.jetbrains.plugins.gradle.manage.GradleLibraryManager
|
||||
import org.jetbrains.plugins.gradle.model.GradleEntityOwner
|
||||
import org.jetbrains.plugins.gradle.model.gradle.GradleLibrary
|
||||
import org.jetbrains.plugins.gradle.model.gradle.LibraryPathType
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleEntityIdMapper
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleJarId
|
||||
import org.jetbrains.plugins.gradle.model.id.GradleLibraryId
|
||||
import org.jetbrains.plugins.gradle.sync.GradleDuplicateLibrariesPreProcessor
|
||||
import org.jetbrains.plugins.gradle.sync.GradleMovedJarsPostProcessor
|
||||
import org.jetbrains.plugins.gradle.sync.GradleOutdatedLibraryVersionPostProcessor
|
||||
import org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesModel
|
||||
@@ -83,7 +86,10 @@ public abstract class AbstractGradleTest {
|
||||
container.registerComponentImplementation(GradleEntityIdMapper)
|
||||
container.registerComponentImplementation(GradleProjectStructureContext)
|
||||
container.registerComponentImplementation(GradleLibraryPathTypeMapper, TestGradleLibraryPathTypeMapper)
|
||||
container.registerComponentImplementation(GradleDependencyManager)
|
||||
container.registerComponentImplementation(GradleLibraryManager)
|
||||
container.registerComponentImplementation(GradleJarManager, TestGradleJarManager)
|
||||
container.registerComponentImplementation(GradleDuplicateLibrariesPreProcessor)
|
||||
container.registerComponentImplementation(GradleMovedJarsPostProcessor, TestGradleMovedJarsPostProcessor)
|
||||
container.registerComponentImplementation(GradleOutdatedLibraryVersionPostProcessor)
|
||||
configureContainer(container)
|
||||
@@ -99,6 +105,7 @@ public abstract class AbstractGradleTest {
|
||||
}
|
||||
|
||||
protected void clearChangePostProcessors() {
|
||||
changesModel.preProcessors.clear()
|
||||
changesModel.postProcessors.clear()
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -36,12 +36,12 @@ class TestGradleJarManager extends GradleJarManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
void importJar(@NotNull GradleJar jar, @NotNull Project project) {
|
||||
importedJars << jar
|
||||
void importJars(@NotNull Collection<? extends GradleJar> jars, @NotNull Project project, boolean synchronous) {
|
||||
importedJars.addAll(jars)
|
||||
}
|
||||
|
||||
@Override
|
||||
void removeJars(@NotNull Collection<GradleJar> jars, @NotNull Project project) {
|
||||
void removeJars(@NotNull Collection<? extends GradleJar> jars, @NotNull Project project, boolean synchronous) {
|
||||
removedJars.addAll(jars)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user