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:
Denis.Zhdanov
2013-02-13 12:22:02 +04:00
parent a79ba4e5b0
commit 6238bcf0a3
18 changed files with 331 additions and 90 deletions
+1
View File
@@ -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
);
@@ -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.
@@ -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);
}
}
});
@@ -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
}
@@ -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;
@@ -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;
}
}
@@ -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);
}
}
@@ -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() {
@@ -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);
}
@@ -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)
@@ -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)
}
@@ -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()
}
@@ -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)
}
}